es-grid-template 1.3.4 → 1.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/assets/index.css CHANGED
@@ -222,6 +222,9 @@
222
222
  .ui-rc-table-wrapper.grid-editable .ui-rc-table .ui-rc-table-tbody .rc-ui-cell-editable.cell-editable.cell-paste-border-left {
223
223
  border-inline-end: 1px dashed #949494;
224
224
  }
225
+ .ui-rc-table-wrapper.grid-editable .ui-rc-table .ui-rc-table-tbody .rc-ui-cell-editable.cell-editable.cell-paste-border-top {
226
+ border-bottom: 1px dashed #949494 !important;
227
+ }
225
228
  .ui-rc-table-wrapper.grid-editable .ui-rc-table .ui-rc-table-tbody .rc-ui-cell-editable.cell-editable.cell-border-right {
226
229
  border-inline-end: 1px solid #0550C5;
227
230
  }
package/assets/index.scss CHANGED
@@ -426,6 +426,9 @@ $fontFamily: "Montserrat",Helvetica,Arial,serif !default;
426
426
  &.cell-paste-border-left {
427
427
  border-inline-end: 1px dashed #949494;
428
428
  }
429
+ &.cell-paste-border-top {
430
+ border-bottom: 1px dashed #949494 !important;
431
+ }
429
432
 
430
433
  &.cell-border-right {
431
434
  border-inline-end: 1px solid $border-selected-color;
@@ -572,6 +572,7 @@ const EditableCell = props => {
572
572
  },
573
573
  treeCheckable: column?.editSelectSettings?.selectMode === 'checkbox',
574
574
  filterTreeNode: filterTreeNode,
575
+ popupMatchSelectWidth: menuWidth ? menuWidth + 10 : undefined,
575
576
  onSelect: (val, option) => {
576
577
  onChange(val ?? '');
577
578
  const formState = getValues();
@@ -512,7 +512,10 @@ const TableGrid = props => {
512
512
  ,
513
513
  showTotal: (total, range) => `${range[0]}-${range[1]} / ${total} ${t ? t(pagination?.locale?.items ?? 'items') : 'items'}`
514
514
  }, pagination)), bottomToolbar?.(), /*#__PURE__*/React.createElement(Tooltip, {
515
- id: "tooltip-header"
515
+ id: "tooltip-header",
516
+ style: {
517
+ zIndex: 1999
518
+ }
516
519
  }));
517
520
  };
518
521
  export default TableGrid;
@@ -7,10 +7,14 @@ import { DatePicker, Empty, Input, Select } from "rc-master-ui";
7
7
  import CheckboxFilter from "../../CheckboxFilter";
8
8
  import { SELECTION_COLUMN } from "rc-master-ui/es/table/hooks/useSelection";
9
9
  import NumberRange from "../../number-range";
10
- import Number from "../../number";
10
+ import NumberInput from "../../number";
11
+ // import {Typography} from "antd";
11
12
  const {
12
13
  RangePicker
13
14
  } = DatePicker;
15
+
16
+ // const { Text } = Typography;
17
+
14
18
  export function flatColumns(columns, parentKey = 'key') {
15
19
  // @ts-ignore
16
20
  return columns.filter(column => column && typeof column === 'object').reduce((list, column, index) => {
@@ -72,7 +76,8 @@ export const getValueCell = (column, value, format) => {
72
76
 
73
77
  // const contentNumber = !isEmpty(value) ? ((dec || dec === 0) ? parseFloat(Number(value).toFixed(dec)).toString() : value.toString()) : '0'
74
78
 
75
- const contentNumber = !isEmpty(value) ? dec || dec === 0 ? parseFloat(value.toFixed(dec)).toString() : value.toString() : '0';
79
+ const tmpval = typeof value === 'string' ? Number(value) : value;
80
+ const contentNumber = !isEmpty(value) ? dec || dec === 0 ? tmpval.toFixed(dec) : tmpval.toString() : '0';
76
81
  const numericFormatProps = {
77
82
  thousandSeparator: checkThousandSeparator(thousandSeparator, decimalSeparator),
78
83
  decimalSeparator: checkDecimalSeparator(thousandSeparator, decimalSeparator),
@@ -140,7 +145,7 @@ export const renderFilter = (column, selectedKeys, setSelectedKeys, confirm, vis
140
145
  case 'Number':
141
146
  return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
142
147
  className: 'mb-1'
143
- }, /*#__PURE__*/React.createElement(Number, {
148
+ }, /*#__PURE__*/React.createElement(NumberInput, {
144
149
  t: t,
145
150
  value: selectedKeys[0],
146
151
  onChange: vals => {
@@ -67,7 +67,9 @@ const HeaderContent = props => {
67
67
  // style={{flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', wordBreak: 'keep-all'}}
68
68
  // style={{flex: 1}}
69
69
  className: classnames('', {}),
70
- "data-tooltip-id": "tooltip-header",
70
+ "data-tooltip-id": "tooltip-header"
71
+ // data-tooltip-id="tooltip-cell-content"
72
+ ,
71
73
  "data-tooltip-content": tooltip,
72
74
  "data-tooltip-offset": 16
73
75
  }, headerTemplate ? getTemplate(headerTemplate) : t ? t(text) : text));
@@ -62,6 +62,13 @@ export declare function addRows8(arr: any, n: number): {
62
62
  combined: any[];
63
63
  addedRows: any[];
64
64
  };
65
+ export declare function addRowsUp(array: any, n: number): {
66
+ combined: any;
67
+ addedRows: any[];
68
+ } | {
69
+ combined: any[];
70
+ addedRows: any[];
71
+ };
65
72
  export declare const transformColumns: <RecordType>(cols: ColumnsTable<RecordType>, convertColumns: any[], t?: any) => ColumnsTable<RecordType>;
66
73
  export declare const transformColumns1: <RecordType>(cols: ColumnsTable<RecordType>, sortMultiple?: boolean) => ColumnsTable<RecordType>;
67
74
  export declare const removeColumns: <RecordType>(columns: ColumnTable<RecordType>[], groupColumns: string[]) => ColumnsTable<RecordType>;
@@ -93,3 +100,7 @@ export declare function isRightMostInRegion(rowIndex: number, colIndex: number,
93
100
  export declare function isEqualSet(setA: any, setB: any): boolean;
94
101
  export declare function isBottomMostInRanges(rowIndex: number, colIndex: number, regions: any[]): boolean;
95
102
  export declare const mergedSets: (arr: any[]) => Set<unknown>;
103
+ export declare const sortedSetASC: (setValue: any) => Set<unknown>;
104
+ export declare const sortedSetDSC: (setValue: any) => Set<unknown>;
105
+ export declare const onAddClassSelectedCell: (selectedCells: any, id?: string) => void;
106
+ export declare const onRemoveClassSelectedCell: (selectedCells: any, id?: string) => void;
@@ -623,6 +623,146 @@ export function addRows8(arr, n) {
623
623
  addedRows
624
624
  };
625
625
  }
626
+ export function addRowsUp(array, n) {
627
+ const arr = array.reverse();
628
+ if (!Array.isArray(arr) || arr.length === 0) return {
629
+ combined: arr,
630
+ addedRows: []
631
+ };
632
+ const m = arr.length;
633
+ const numCols = arr[0].length;
634
+ const addedRows = [];
635
+
636
+ // Hàm kiểm tra kiểu date hợp lệ
637
+ const isValidDate = item => {
638
+ // console.log('!isNaN(Date.parse(d))', !isNaN(Date.parse(d)))
639
+ // return !isNaN(Date.parse(d))
640
+
641
+ if (typeof item === 'number') {
642
+ // return 'number'
643
+ return false;
644
+ }
645
+ if (typeof item === 'string') {
646
+ // Kiểm tra nếu là chuỗi ISO date hợp lệ
647
+ const date = new Date(item);
648
+ if (!isNaN(date.getTime()) && item.includes('T')) {
649
+ // return 'date'
650
+ return true;
651
+ }
652
+ // return 'string'
653
+ return false;
654
+ }
655
+ return !isNaN(Date.parse(item));
656
+ };
657
+
658
+ // Lấy giá trị mẫu của cột j từ hàng đầu tiên
659
+ const getSample = j => arr[0][j];
660
+
661
+ // Xác định chế độ xử lý cho mỗi cột:
662
+ // mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
663
+ const modes = [];
664
+ const steps = []; // bước tăng, nếu có (cho number hoặc date)
665
+
666
+ for (let j = 0; j < numCols; j++) {
667
+ const sample = getSample(j);
668
+ if (m === 1) {
669
+ // Nếu mảng chỉ có 1 hàng: nếu là số thì giữ nguyên; nếu là date thì tăng 1 ngày; còn lại giữ nguyên.
670
+ if (typeof sample === "number") {
671
+ modes[j] = "number-constant";
672
+ } else if (isValidDate(sample)) {
673
+ modes[j] = "date-stepping";
674
+ steps[j] = 24 * 3600 * 1000; // 1 ngày = 86400000 ms
675
+ } else {
676
+ modes[j] = "cycle";
677
+ }
678
+ } else if (m === 2) {
679
+ // Nếu mảng có 2 hàng: nếu là số thì tính bước = row2 - row1, tương tự với date
680
+ const first = arr[0][j],
681
+ second = arr[1][j];
682
+ if (typeof first === "number" && typeof second === "number") {
683
+ modes[j] = "number-stepping";
684
+ steps[j] = second - first;
685
+ } else if (isValidDate(first) && isValidDate(second)) {
686
+ modes[j] = "date-stepping";
687
+ steps[j] = Date.parse(second) - Date.parse(first);
688
+ } else {
689
+ modes[j] = "cycle";
690
+ }
691
+ } else {
692
+ // Nếu mảng có >2 hàng
693
+ const first = arr[0][j],
694
+ second = arr[1][j],
695
+ third = arr[2][j];
696
+ if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
697
+ const step1 = second - first;
698
+ const step2 = third - second;
699
+ if (step1 === step2) {
700
+ modes[j] = "number-stepping";
701
+ steps[j] = step1;
702
+ } else {
703
+ modes[j] = "cycle";
704
+ }
705
+ } else if (isValidDate(first) && isValidDate(second) && isValidDate(third)) {
706
+ const step1 = Date.parse(second) - Date.parse(first);
707
+ const step2 = Date.parse(third) - Date.parse(second);
708
+ if (step1 === step2) {
709
+ modes[j] = "date-stepping";
710
+ steps[j] = step1;
711
+ } else {
712
+ modes[j] = "cycle";
713
+ }
714
+ } else {
715
+ modes[j] = "cycle";
716
+ }
717
+ }
718
+ }
719
+
720
+ // Tạo các dòng mới (thêm n dòng)
721
+ // Với mỗi cột, nếu chế độ là stepping thì lấy giá trị cuối của mảng ban đầu và cộng thêm (i+1)*step
722
+ // Nếu chế độ là cycle thì dùng arr[i mod m][j]
723
+ for (let i = n - 1; i >= 0; i--) {
724
+ const newRow = [];
725
+ for (let j = 0; j < numCols; j++) {
726
+ let newValue;
727
+ switch (modes[j]) {
728
+ case "number-constant":
729
+ // Mảng có 1 hàng, số giữ nguyên
730
+ newValue = arr[0][j];
731
+ break;
732
+ case "number-stepping":
733
+ {
734
+ // Lấy giá trị cuối của cột j trong mảng ban đầu
735
+
736
+ const lastValue = arr[m - 1][j];
737
+ newValue = lastValue - (i + 1) * steps[j] * -1;
738
+ }
739
+ break;
740
+ case "date-stepping":
741
+ {
742
+ // Lấy giá trị cuối, chuyển về date, cộng thêm (i+1)*step, chuyển lại về định dạng ISO
743
+
744
+ const lastDate = new Date(array[m - 1][j]);
745
+ const newTime = lastDate.getTime() - (i + 1) * steps[j] * -1;
746
+ newValue = moment(new Date(newTime)).format();
747
+ }
748
+ break;
749
+ case "cycle":
750
+ default:
751
+ // Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
752
+
753
+ newValue = arr[i % m][j];
754
+ break;
755
+ }
756
+ newRow.push(newValue);
757
+ }
758
+ addedRows.push(newRow);
759
+ }
760
+ const combined = arr.concat(addedRows);
761
+ return {
762
+ combined,
763
+ addedRows
764
+ };
765
+ }
626
766
  export const transformColumns = (cols, convertColumns, t) => {
627
767
  // @ts-ignore
628
768
  return cols.map(column => {
@@ -1196,4 +1336,54 @@ export function isBottomMostInRanges(rowIndex, colIndex, regions) {
1196
1336
  }
1197
1337
  export const mergedSets = arr => {
1198
1338
  return new Set(arr.flatMap(set => Array.from(set)));
1339
+ };
1340
+ export const sortedSetASC = setValue => {
1341
+ const sorted = Array.from(setValue).sort((a, b) => {
1342
+ const [a1, a2] = a.split("-").map(Number);
1343
+ const [b1, b2] = b.split("-").map(Number);
1344
+ return a1 - b1 || a2 - b2;
1345
+ });
1346
+ return new Set(sorted);
1347
+ };
1348
+ export const sortedSetDSC = setValue => {
1349
+ const sorted = Array.from(setValue).sort((a, b) => {
1350
+ const [a1, a2] = a.split("-").map(Number);
1351
+ const [b1, b2] = b.split("-").map(Number);
1352
+ return b1 - a1 || b2 - a2;
1353
+ });
1354
+ return new Set(sorted);
1355
+ };
1356
+ export const onAddClassSelectedCell = (selectedCells, id) => {
1357
+ const selectors = Array.from(selectedCells).map(pos => {
1358
+ const [row1, col1] = pos.split('-');
1359
+ return `[data-row-index="${row1}"][data-col-index="${col1}"]`;
1360
+ });
1361
+
1362
+ // const cells = document.querySelectorAll(selectors.join(','));
1363
+
1364
+ const table = document.querySelector(`#${id}`);
1365
+ console.log('table', table);
1366
+ const cells = table?.querySelectorAll(selectors.join(','));
1367
+ if (cells) {
1368
+ cells.forEach(cell => {
1369
+ cell.classList.add('selected');
1370
+ });
1371
+ }
1372
+ };
1373
+ export const onRemoveClassSelectedCell = (selectedCells, id) => {
1374
+ const selectors = Array.from(selectedCells).map(pos => {
1375
+ const [row, col] = pos.split('-');
1376
+ return `[data-row-index="${row}"][data-col-index="${col}"]`;
1377
+ });
1378
+ const table = document.querySelector(`#${id}`);
1379
+ const cells = table?.querySelectorAll(selectors.join(','));
1380
+ // const cells = table?.querySelectorAll(selectors.join(','))
1381
+
1382
+ // const cells = table?.querySelectorAll('.ui-rc-table-cell.selected');
1383
+
1384
+ if (cells) {
1385
+ cells.forEach(cell => {
1386
+ cell.classList.remove('selected');
1387
+ });
1388
+ }
1199
1389
  };
@@ -6,5 +6,5 @@ type Props = {
6
6
  value: number | string | undefined;
7
7
  onChange?: (values: any[]) => void;
8
8
  };
9
- declare const Number: (props: Props) => React.JSX.Element;
10
- export default Number;
9
+ declare const NumberInput: (props: Props) => React.JSX.Element;
10
+ export default NumberInput;
@@ -2,7 +2,7 @@ import React, { Fragment } from "react";
2
2
  import { NumericFormat } from "react-numeric-component";
3
3
  import { Input } from "rc-master-ui";
4
4
  import { checkDecimalSeparator, checkThousandSeparator } from "../hooks";
5
- const Number = props => {
5
+ const NumberInput = props => {
6
6
  const {
7
7
  t,
8
8
  value,
@@ -36,4 +36,4 @@ const Number = props => {
36
36
  autoFocus: true
37
37
  }));
38
38
  };
39
- export default Number;
39
+ export default NumberInput;
@@ -426,6 +426,9 @@ $fontFamily: "Montserrat",Helvetica,Arial,serif !default;
426
426
  &.cell-paste-border-left {
427
427
  border-inline-end: 1px dashed #949494;
428
428
  }
429
+ &.cell-paste-border-top {
430
+ border-bottom: 1px dashed #949494 !important;
431
+ }
429
432
 
430
433
  &.cell-border-right {
431
434
  border-inline-end: 1px solid $border-selected-color;
@@ -13,7 +13,7 @@ import dayjs from "dayjs";
13
13
  import 'dayjs/locale/es';
14
14
  import 'dayjs/locale/vi';
15
15
  import TableGrid from "../TableGrid";
16
- import { addRows8, checkChild, editAbleColumns, findAllChildrenKeys, findItemByKey, findItemPath, flattenArray, flattenData, getDefaultValue, getEditType, getFirstSelectCell, getLastSelectCell, getRowNumber, getRowsPasteIndex,
16
+ import { addRows8, addRowsUp, checkChild, editAbleColumns, findAllChildrenKeys, findItemByKey, findItemPath, flattenArray, flattenData, getDefaultValue, getEditType, getFirstSelectCell, getLastSelectCell, getRowNumber, getRowsPasteIndex,
17
17
  // isBottomMostInRanges,
18
18
  isBottomMostInRegion,
19
19
  // isContinuous,
@@ -21,7 +21,7 @@ isEditable,
21
21
  // isEqualSet,
22
22
  isObjEmpty, isRightMostInRegion, isTopMostInRegion,
23
23
  // mergedSets,
24
- newGuid, totalFixedWidth, updateArrayByKey } from "../hooks";
24
+ newGuid, sortedSetASC, totalFixedWidth, updateArrayByKey } from "../hooks";
25
25
  import Message from "../../Message/Message";
26
26
  // import Command from "../Command";
27
27
 
@@ -801,8 +801,6 @@ const GridEdit = props => {
801
801
  };
802
802
  }, []);
803
803
  const handleMouseDown = (record, row, col, e) => {
804
- // setEditingKey('')
805
-
806
804
  if (e.button === 2) {
807
805
  e.stopPropagation();
808
806
  return;
@@ -851,8 +849,14 @@ const GridEdit = props => {
851
849
  };
852
850
  const triggerDragPaste = pastesArray => {
853
851
  const mergedSet = new Set([...selectedCells, ...pastesArray]);
854
- setSelectedCells(mergedSet);
852
+
853
+ // console.log('pastesArray', pastesArray)
854
+ // console.log('selectedCells', selectedCells)
855
+
856
+ setSelectedCells(sortedSetASC(mergedSet));
855
857
  setPasteCells(new Set());
858
+ const rowSelectedFirst = getFirstSelectCell(selectedCells).row;
859
+ const rowPasteLast = getLastSelectCell(pasteCells).row;
856
860
  const selectedArray = Array.from(selectedCells).map(key => {
857
861
  const [row, col] = key.split("-").map(Number);
858
862
  // @ts-ignore
@@ -886,7 +890,17 @@ const GridEdit = props => {
886
890
  }) => {
887
891
  table[row - minRow][col - minCol] = value;
888
892
  });
889
- const newRange = addRows8(table, getRowsPasteIndex(pastesArray).length);
893
+ let newRange = {
894
+ combined: [],
895
+ addedRows: []
896
+ };
897
+ if (rowPasteLast > rowSelectedFirst) {
898
+ // kéo xuóng
899
+ newRange = addRows8(table, getRowsPasteIndex(pastesArray).length);
900
+ } else {
901
+ // kéo lên
902
+ newRange = addRowsUp(table, getRowsPasteIndex(pastesArray).length);
903
+ }
890
904
  const record = flattenData(childrenColumnName, dataSource)[getFirstSelectCell(pastesArray).row];
891
905
  if (!record?.parentId) {
892
906
  // Cập nhật data mới
@@ -1049,6 +1063,17 @@ const GridEdit = props => {
1049
1063
  }
1050
1064
  if (row < rowSelectedEnd) {
1051
1065
  // kéo lên trên
1066
+
1067
+ const rowSelectedStart = getFirstSelectCell(selectedCells).row;
1068
+ if (row < rowSelectedStart) {
1069
+ const newPasteCells = new Set();
1070
+ for (let r = Math.min(rowSelectedStart, row); r <= Math.max(rowSelectedStart, row) - 1; r++) {
1071
+ for (let c = Math.min(colStart, col); c <= Math.max(colStart, colEnd); c++) {
1072
+ newPasteCells.add(`${r}-${c}`);
1073
+ }
1074
+ }
1075
+ setPasteCells(newPasteCells);
1076
+ }
1052
1077
  }
1053
1078
  if (col > colEnd) {
1054
1079
  // kéo sang phải
@@ -1153,7 +1178,7 @@ const GridEdit = props => {
1153
1178
  return {
1154
1179
  row,
1155
1180
  col,
1156
- value: flattenData(childrenColumnName, dataSource)[row][columnKey]
1181
+ value: flattenData(childrenColumnName, dataSource)[row][columnKey] ?? ''
1157
1182
  };
1158
1183
  // return { row, col, value: '' };
1159
1184
  });
@@ -1297,7 +1322,7 @@ const GridEdit = props => {
1297
1322
  };
1298
1323
  const handlePaste = (record, indexCol, rowNumber, e) => {
1299
1324
  // const clipboard: any = (e.clipboardData || (window && window?.Clipboard)).getData("text")
1300
- const pasteData = e.clipboardData.getData("text/plain").trim();
1325
+ const pasteData = e.clipboardData.getData("text/plain");
1301
1326
 
1302
1327
  // Chuyển đổi dữ liệu từ clipboard thành mảng
1303
1328
  const rowsPasted = pasteData.split("\n").map(row =>
@@ -1695,7 +1720,9 @@ const GridEdit = props => {
1695
1720
  const isTopSelected = selectedCells.has(topCellKey);
1696
1721
  const isLeftSelected = selectedCells.has(leftCellKey);
1697
1722
  const isRightSelected = selectedCells.has(rightCellKey);
1723
+ const topPasteCellKey = `${rowIndex + 1}-${colIndex}`;
1698
1724
  const isPasteSelected = pasteCells.has(cellKey);
1725
+ const isPasteTopSelected = pasteCells.has(topPasteCellKey);
1699
1726
  const isPasteLeftSelected = pasteCells.has(leftCellKey);
1700
1727
  const isPasteRightSelected = pasteCells.has(rightCellKey);
1701
1728
  const cellClass = isEditing(record) ? 'rc-ui-cell-editable cell-editing' : 'rc-ui-cell-editable cell-editable';
@@ -1704,15 +1731,20 @@ const GridEdit = props => {
1704
1731
  const cellEnd = getLastSelectCell(selectedCells);
1705
1732
  const cellPasteStart = getFirstSelectCell(pasteCells);
1706
1733
  const cellPasteSEnd = getLastSelectCell(pasteCells);
1707
- const isPasteBottom = pasteCells.size && cellPasteSEnd && rowIndex === Math.max(cellPasteStart.row, cellPasteSEnd.row);
1734
+ const isPasteBottom = cellPasteSEnd.row > cellStart.row && pasteCells.size && cellPasteSEnd && rowIndex === Math.max(cellPasteStart.row, cellPasteSEnd.row);
1735
+
1736
+ // const rowSelectedFirst = getFirstSelectCell(selectedCells).row
1737
+ // const rowPasteLast = getLastSelectCell(pasteCells).row
1738
+
1708
1739
  if (!isSelected && !isPasteSelected) {
1709
1740
  // const isTop = prevRecordEditing && !isEditing(prevRecordEditing) && rowIndex === Math.min(cellStart.row - 1, cellEnd?.row);
1710
1741
  const isTop = prevRecordEditing && !isEditing(prevRecordEditing) && isTopMostInRegion(rowIndex + 1, colIndex, selectedCells);
1711
1742
  const isLeft = colIndex + 1 === Math.min(cellStart.col, cellEnd?.col);
1712
1743
  const isRight = colIndex - 1 === Math.max(cellStart.col, cellEnd?.col);
1744
+ const isPasteTop = cellPasteSEnd.row < cellStart.row && isTopMostInRegion(rowIndex + 1, colIndex, pasteCells);
1713
1745
  const isPasteLeft = colIndex + 1 === Math.min(cellPasteStart.col, cellPasteSEnd?.col);
1714
1746
  const isPasteRight = colIndex - 1 === Math.max(cellPasteStart.col, cellPasteSEnd?.col);
1715
- return isTopSelected || isLeftSelected || isRightSelected ? `${cellClass} ${isTop ? `cell-border-top` : ''} ${isLeft ? `cell-border-left` : ''} ${isPasteBottom ? `cell-paste-border-bottom` : ''} ${isRight ? `next-cell-border-left` : ''}` : isPasteLeftSelected || isPasteRightSelected ? `${cellClass} ${isPasteLeft ? `cell-paste-border-left` : ''} ${isPasteRight ? `next-cell-paste-border-left` : ''}` : cellClass;
1747
+ return isTopSelected || isLeftSelected || isRightSelected ? `${cellClass} ${isTop ? `cell-border-top` : ''} ${isLeft ? `cell-border-left` : ''} ${isPasteBottom ? `cell-paste-border-bottom` : ''} ${isRight ? `next-cell-border-left` : ''}` : isPasteLeftSelected || isPasteRightSelected || isPasteTopSelected ? `${cellClass} ${isPasteLeft ? `cell-paste-border-left` : ''} ${isPasteRight ? `next-cell-paste-border-left` : ''} ${isPasteTop ? `cell-paste-border-top` : ''}` : cellClass;
1716
1748
  }
1717
1749
  const isBottom = isBottomMostInRegion(rowIndex, colIndex, selectedCells);
1718
1750
  // const isBottom = isBottomMostInRanges(rowIndex, colIndex, [selectedCells, ...ctrlCells])
@@ -1724,7 +1756,7 @@ const GridEdit = props => {
1724
1756
  const isPasteLeft = colIndex === Math.min(cellPasteStart.col, cellPasteSEnd?.col);
1725
1757
  return `${cellClass} ${isPasteBottom ? `cell-paste-border-bottom` : ''} ${isPasteSelected && isPasteRight ? `cell-paste-border-right` : ''} ${isPasteSelected && isPasteLeft ? `fixed-cell-paste-border-left` : ''} ${isBottom ? `cell-border-bottom` : ''} ${isRight ? `cell-border-right` : ''} ${isLeft ? `fixed-cell-border-left` : ''} ${isBottom && isRight ? `cell-border-end` : ''}`;
1726
1758
  };
1727
- const convertColumns = flatColumns2(columns).map((column, colIndex) => {
1759
+ const convertColumns = flatColumns2(columns.filter(it => it.visible !== false)).map((column, colIndex) => {
1728
1760
  if (!column?.field && !column?.key) {
1729
1761
  return column;
1730
1762
  }
@@ -1918,6 +1950,10 @@ const GridEdit = props => {
1918
1950
  title: getValueCell(column, record[column.field], format),
1919
1951
  'data-col-index': colIndex,
1920
1952
  'data-row-index': rowNumber,
1953
+ // 'data-tooltip-id': "tooltip-cell-content",
1954
+ // 'data-tooltip-content': 'tooltip-cell-content',
1955
+ // 'data-tooltip-delay-show': 1000,
1956
+ // 'data-tooltip-content': getValueCell(column, record[column.field as any], format),
1921
1957
  editing: isEditing(record) && rowEditable?.(record) !== false && isEditable(column, record),
1922
1958
  cellEditing,
1923
1959
  t,
@@ -1978,7 +2014,9 @@ const GridEdit = props => {
1978
2014
  // onMouseEnter={(event) => handlePointEnter(event)}
1979
2015
  // onMouseLeave={() => handlePointLeave()}
1980
2016
  ,
1981
- onMouseDown: () => {
2017
+ onMouseDown: e => {
2018
+ // e.stopPropagation()
2019
+ e.preventDefault();
1982
2020
  setIsPasteDragging(true);
1983
2021
  },
1984
2022
  onDoubleClick: handlePointDoubleClick
@@ -2000,6 +2038,11 @@ const GridEdit = props => {
2000
2038
  ...find
2001
2039
  };
2002
2040
  }
2041
+ if (!find) {
2042
+ return {
2043
+ ...column
2044
+ };
2045
+ }
2003
2046
 
2004
2047
  // Xử lý đệ quy cho children
2005
2048
  if (column.children?.length) {
@@ -574,6 +574,7 @@ const EditableCell = props => {
574
574
  },
575
575
  treeCheckable: column?.editSelectSettings?.selectMode === 'checkbox',
576
576
  filterTreeNode: filterTreeNode,
577
+ popupMatchSelectWidth: menuWidth ? menuWidth + 10 : undefined,
577
578
  onSelect: (val, option) => {
578
579
  onChange(val ?? '');
579
580
  const formState = getValues();
@@ -513,7 +513,10 @@ const TableGrid = props => {
513
513
  ,
514
514
  showTotal: (total, range) => `${range[0]}-${range[1]} / ${total} ${t ? t(pagination?.locale?.items ?? 'items') : 'items'}`
515
515
  }, pagination)), bottomToolbar?.(), /*#__PURE__*/_react.default.createElement(_reactTooltip.Tooltip, {
516
- id: "tooltip-header"
516
+ id: "tooltip-header",
517
+ style: {
518
+ zIndex: 1999
519
+ }
517
520
  }));
518
521
  };
519
522
  var _default = exports.default = TableGrid;
@@ -19,9 +19,13 @@ var _numberRange = _interopRequireDefault(require("../../number-range"));
19
19
  var _number = _interopRequireDefault(require("../../number"));
20
20
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
21
21
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
22
+ // import {Typography} from "antd";
22
23
  const {
23
24
  RangePicker
24
25
  } = _rcMasterUi.DatePicker;
26
+
27
+ // const { Text } = Typography;
28
+
25
29
  function flatColumns(columns, parentKey = 'key') {
26
30
  // @ts-ignore
27
31
  return columns.filter(column => column && typeof column === 'object').reduce((list, column, index) => {
@@ -83,7 +87,8 @@ const getValueCell = (column, value, format) => {
83
87
 
84
88
  // const contentNumber = !isEmpty(value) ? ((dec || dec === 0) ? parseFloat(Number(value).toFixed(dec)).toString() : value.toString()) : '0'
85
89
 
86
- const contentNumber = !(0, _utils.isEmpty)(value) ? dec || dec === 0 ? parseFloat(value.toFixed(dec)).toString() : value.toString() : '0';
90
+ const tmpval = typeof value === 'string' ? Number(value) : value;
91
+ const contentNumber = !(0, _utils.isEmpty)(value) ? dec || dec === 0 ? tmpval.toFixed(dec) : tmpval.toString() : '0';
87
92
  const numericFormatProps = {
88
93
  thousandSeparator: (0, _utils.checkThousandSeparator)(thousandSeparator, decimalSeparator),
89
94
  decimalSeparator: (0, _utils.checkDecimalSeparator)(thousandSeparator, decimalSeparator),
@@ -76,7 +76,9 @@ const HeaderContent = props => {
76
76
  // style={{flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', wordBreak: 'keep-all'}}
77
77
  // style={{flex: 1}}
78
78
  className: (0, _classnames.default)('', {}),
79
- "data-tooltip-id": "tooltip-header",
79
+ "data-tooltip-id": "tooltip-header"
80
+ // data-tooltip-id="tooltip-cell-content"
81
+ ,
80
82
  "data-tooltip-content": tooltip,
81
83
  "data-tooltip-offset": 16
82
84
  }, headerTemplate ? (0, _utils.getTemplate)(headerTemplate) : t ? t(text) : text));
@@ -62,6 +62,13 @@ export declare function addRows8(arr: any, n: number): {
62
62
  combined: any[];
63
63
  addedRows: any[];
64
64
  };
65
+ export declare function addRowsUp(array: any, n: number): {
66
+ combined: any;
67
+ addedRows: any[];
68
+ } | {
69
+ combined: any[];
70
+ addedRows: any[];
71
+ };
65
72
  export declare const transformColumns: <RecordType>(cols: ColumnsTable<RecordType>, convertColumns: any[], t?: any) => ColumnsTable<RecordType>;
66
73
  export declare const transformColumns1: <RecordType>(cols: ColumnsTable<RecordType>, sortMultiple?: boolean) => ColumnsTable<RecordType>;
67
74
  export declare const removeColumns: <RecordType>(columns: ColumnTable<RecordType>[], groupColumns: string[]) => ColumnsTable<RecordType>;
@@ -93,3 +100,7 @@ export declare function isRightMostInRegion(rowIndex: number, colIndex: number,
93
100
  export declare function isEqualSet(setA: any, setB: any): boolean;
94
101
  export declare function isBottomMostInRanges(rowIndex: number, colIndex: number, regions: any[]): boolean;
95
102
  export declare const mergedSets: (arr: any[]) => Set<unknown>;
103
+ export declare const sortedSetASC: (setValue: any) => Set<unknown>;
104
+ export declare const sortedSetDSC: (setValue: any) => Set<unknown>;
105
+ export declare const onAddClassSelectedCell: (selectedCells: any, id?: string) => void;
106
+ export declare const onRemoveClassSelectedCell: (selectedCells: any, id?: string) => void;
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.addRowIdArray = void 0;
8
8
  exports.addRows8 = addRows8;
9
+ exports.addRowsUp = addRowsUp;
9
10
  exports.checkThousandSeparator = exports.checkFieldKey = exports.checkDecimalSeparator = exports.checkChild = exports.buildConnectedRegions = void 0;
10
11
  exports.compareDate = compareDate;
11
12
  exports.compareDates = compareDates;
@@ -23,7 +24,7 @@ exports.isEmpty = exports.isEditable = exports.isDisable = void 0;
23
24
  exports.isEqualSet = isEqualSet;
24
25
  exports.isObjEmpty = exports.isNullOrUndefined = exports.isNameColor = void 0;
25
26
  exports.isRightMostInRegion = isRightMostInRegion;
26
- exports.updateData = exports.updateColumnsByGroup = exports.updateColumns = exports.updateArrayByKey = exports.transformColumns1 = exports.transformColumns = exports.totalFixedWidth = exports.sumDataByField = exports.removeFieldRecursive = exports.removeColumns = exports.parseCells = exports.parseBooleanToValue = exports.newGuid = exports.mergedSets = exports.isTopMostInRegion = void 0;
27
+ exports.updateData = exports.updateColumnsByGroup = exports.updateColumns = exports.updateArrayByKey = exports.transformColumns1 = exports.transformColumns = exports.totalFixedWidth = exports.sumDataByField = exports.sortedSetDSC = exports.sortedSetASC = exports.removeFieldRecursive = exports.removeColumns = exports.parseCells = exports.parseBooleanToValue = exports.onRemoveClassSelectedCell = exports.onAddClassSelectedCell = exports.newGuid = exports.mergedSets = exports.isTopMostInRegion = void 0;
27
28
  var _dayjs = _interopRequireDefault(require("dayjs"));
28
29
  var _moment = _interopRequireDefault(require("moment/moment"));
29
30
  var _uuid = require("uuid");
@@ -690,6 +691,146 @@ function addRows8(arr, n) {
690
691
  addedRows
691
692
  };
692
693
  }
694
+ function addRowsUp(array, n) {
695
+ const arr = array.reverse();
696
+ if (!Array.isArray(arr) || arr.length === 0) return {
697
+ combined: arr,
698
+ addedRows: []
699
+ };
700
+ const m = arr.length;
701
+ const numCols = arr[0].length;
702
+ const addedRows = [];
703
+
704
+ // Hàm kiểm tra kiểu date hợp lệ
705
+ const isValidDate = item => {
706
+ // console.log('!isNaN(Date.parse(d))', !isNaN(Date.parse(d)))
707
+ // return !isNaN(Date.parse(d))
708
+
709
+ if (typeof item === 'number') {
710
+ // return 'number'
711
+ return false;
712
+ }
713
+ if (typeof item === 'string') {
714
+ // Kiểm tra nếu là chuỗi ISO date hợp lệ
715
+ const date = new Date(item);
716
+ if (!isNaN(date.getTime()) && item.includes('T')) {
717
+ // return 'date'
718
+ return true;
719
+ }
720
+ // return 'string'
721
+ return false;
722
+ }
723
+ return !isNaN(Date.parse(item));
724
+ };
725
+
726
+ // Lấy giá trị mẫu của cột j từ hàng đầu tiên
727
+ const getSample = j => arr[0][j];
728
+
729
+ // Xác định chế độ xử lý cho mỗi cột:
730
+ // mode = 'number-stepping' | 'date-stepping' | 'number-constant' | 'cycle'
731
+ const modes = [];
732
+ const steps = []; // bước tăng, nếu có (cho number hoặc date)
733
+
734
+ for (let j = 0; j < numCols; j++) {
735
+ const sample = getSample(j);
736
+ if (m === 1) {
737
+ // Nếu mảng chỉ có 1 hàng: nếu là số thì giữ nguyên; nếu là date thì tăng 1 ngày; còn lại giữ nguyên.
738
+ if (typeof sample === "number") {
739
+ modes[j] = "number-constant";
740
+ } else if (isValidDate(sample)) {
741
+ modes[j] = "date-stepping";
742
+ steps[j] = 24 * 3600 * 1000; // 1 ngày = 86400000 ms
743
+ } else {
744
+ modes[j] = "cycle";
745
+ }
746
+ } else if (m === 2) {
747
+ // Nếu mảng có 2 hàng: nếu là số thì tính bước = row2 - row1, tương tự với date
748
+ const first = arr[0][j],
749
+ second = arr[1][j];
750
+ if (typeof first === "number" && typeof second === "number") {
751
+ modes[j] = "number-stepping";
752
+ steps[j] = second - first;
753
+ } else if (isValidDate(first) && isValidDate(second)) {
754
+ modes[j] = "date-stepping";
755
+ steps[j] = Date.parse(second) - Date.parse(first);
756
+ } else {
757
+ modes[j] = "cycle";
758
+ }
759
+ } else {
760
+ // Nếu mảng có >2 hàng
761
+ const first = arr[0][j],
762
+ second = arr[1][j],
763
+ third = arr[2][j];
764
+ if (typeof first === "number" && typeof second === "number" && typeof third === "number") {
765
+ const step1 = second - first;
766
+ const step2 = third - second;
767
+ if (step1 === step2) {
768
+ modes[j] = "number-stepping";
769
+ steps[j] = step1;
770
+ } else {
771
+ modes[j] = "cycle";
772
+ }
773
+ } else if (isValidDate(first) && isValidDate(second) && isValidDate(third)) {
774
+ const step1 = Date.parse(second) - Date.parse(first);
775
+ const step2 = Date.parse(third) - Date.parse(second);
776
+ if (step1 === step2) {
777
+ modes[j] = "date-stepping";
778
+ steps[j] = step1;
779
+ } else {
780
+ modes[j] = "cycle";
781
+ }
782
+ } else {
783
+ modes[j] = "cycle";
784
+ }
785
+ }
786
+ }
787
+
788
+ // Tạo các dòng mới (thêm n dòng)
789
+ // Với mỗi cột, nếu chế độ là stepping thì lấy giá trị cuối của mảng ban đầu và cộng thêm (i+1)*step
790
+ // Nếu chế độ là cycle thì dùng arr[i mod m][j]
791
+ for (let i = n - 1; i >= 0; i--) {
792
+ const newRow = [];
793
+ for (let j = 0; j < numCols; j++) {
794
+ let newValue;
795
+ switch (modes[j]) {
796
+ case "number-constant":
797
+ // Mảng có 1 hàng, số giữ nguyên
798
+ newValue = arr[0][j];
799
+ break;
800
+ case "number-stepping":
801
+ {
802
+ // Lấy giá trị cuối của cột j trong mảng ban đầu
803
+
804
+ const lastValue = arr[m - 1][j];
805
+ newValue = lastValue - (i + 1) * steps[j] * -1;
806
+ }
807
+ break;
808
+ case "date-stepping":
809
+ {
810
+ // Lấy giá trị cuối, chuyển về date, cộng thêm (i+1)*step, chuyển lại về định dạng ISO
811
+
812
+ const lastDate = new Date(array[m - 1][j]);
813
+ const newTime = lastDate.getTime() - (i + 1) * steps[j] * -1;
814
+ newValue = (0, _moment.default)(new Date(newTime)).format();
815
+ }
816
+ break;
817
+ case "cycle":
818
+ default:
819
+ // Lặp lại nội dung theo vòng tròn: dùng hàng thứ (i mod m)
820
+
821
+ newValue = arr[i % m][j];
822
+ break;
823
+ }
824
+ newRow.push(newValue);
825
+ }
826
+ addedRows.push(newRow);
827
+ }
828
+ const combined = arr.concat(addedRows);
829
+ return {
830
+ combined,
831
+ addedRows
832
+ };
833
+ }
693
834
  const transformColumns = (cols, convertColumns, t) => {
694
835
  // @ts-ignore
695
836
  return cols.map(column => {
@@ -1282,4 +1423,58 @@ function isBottomMostInRanges(rowIndex, colIndex, regions) {
1282
1423
  const mergedSets = arr => {
1283
1424
  return new Set(arr.flatMap(set => Array.from(set)));
1284
1425
  };
1285
- exports.mergedSets = mergedSets;
1426
+ exports.mergedSets = mergedSets;
1427
+ const sortedSetASC = setValue => {
1428
+ const sorted = Array.from(setValue).sort((a, b) => {
1429
+ const [a1, a2] = a.split("-").map(Number);
1430
+ const [b1, b2] = b.split("-").map(Number);
1431
+ return a1 - b1 || a2 - b2;
1432
+ });
1433
+ return new Set(sorted);
1434
+ };
1435
+ exports.sortedSetASC = sortedSetASC;
1436
+ const sortedSetDSC = setValue => {
1437
+ const sorted = Array.from(setValue).sort((a, b) => {
1438
+ const [a1, a2] = a.split("-").map(Number);
1439
+ const [b1, b2] = b.split("-").map(Number);
1440
+ return b1 - a1 || b2 - a2;
1441
+ });
1442
+ return new Set(sorted);
1443
+ };
1444
+ exports.sortedSetDSC = sortedSetDSC;
1445
+ const onAddClassSelectedCell = (selectedCells, id) => {
1446
+ const selectors = Array.from(selectedCells).map(pos => {
1447
+ const [row1, col1] = pos.split('-');
1448
+ return `[data-row-index="${row1}"][data-col-index="${col1}"]`;
1449
+ });
1450
+
1451
+ // const cells = document.querySelectorAll(selectors.join(','));
1452
+
1453
+ const table = document.querySelector(`#${id}`);
1454
+ console.log('table', table);
1455
+ const cells = table?.querySelectorAll(selectors.join(','));
1456
+ if (cells) {
1457
+ cells.forEach(cell => {
1458
+ cell.classList.add('selected');
1459
+ });
1460
+ }
1461
+ };
1462
+ exports.onAddClassSelectedCell = onAddClassSelectedCell;
1463
+ const onRemoveClassSelectedCell = (selectedCells, id) => {
1464
+ const selectors = Array.from(selectedCells).map(pos => {
1465
+ const [row, col] = pos.split('-');
1466
+ return `[data-row-index="${row}"][data-col-index="${col}"]`;
1467
+ });
1468
+ const table = document.querySelector(`#${id}`);
1469
+ const cells = table?.querySelectorAll(selectors.join(','));
1470
+ // const cells = table?.querySelectorAll(selectors.join(','))
1471
+
1472
+ // const cells = table?.querySelectorAll('.ui-rc-table-cell.selected');
1473
+
1474
+ if (cells) {
1475
+ cells.forEach(cell => {
1476
+ cell.classList.remove('selected');
1477
+ });
1478
+ }
1479
+ };
1480
+ exports.onRemoveClassSelectedCell = onRemoveClassSelectedCell;
@@ -6,5 +6,5 @@ type Props = {
6
6
  value: number | string | undefined;
7
7
  onChange?: (values: any[]) => void;
8
8
  };
9
- declare const Number: (props: Props) => React.JSX.Element;
10
- export default Number;
9
+ declare const NumberInput: (props: Props) => React.JSX.Element;
10
+ export default NumberInput;
@@ -10,7 +10,7 @@ var _rcMasterUi = require("rc-master-ui");
10
10
  var _hooks = require("../hooks");
11
11
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
12
12
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
- const Number = props => {
13
+ const NumberInput = props => {
14
14
  const {
15
15
  t,
16
16
  value,
@@ -44,4 +44,4 @@ const Number = props => {
44
44
  autoFocus: true
45
45
  }));
46
46
  };
47
- var _default = exports.default = Number;
47
+ var _default = exports.default = NumberInput;
@@ -426,6 +426,9 @@ $fontFamily: "Montserrat",Helvetica,Arial,serif !default;
426
426
  &.cell-paste-border-left {
427
427
  border-inline-end: 1px dashed #949494;
428
428
  }
429
+ &.cell-paste-border-top {
430
+ border-bottom: 1px dashed #949494 !important;
431
+ }
429
432
 
430
433
  &.cell-border-right {
431
434
  border-inline-end: 1px solid $border-selected-color;
@@ -801,8 +801,6 @@ const GridEdit = props => {
801
801
  };
802
802
  }, []);
803
803
  const handleMouseDown = (record, row, col, e) => {
804
- // setEditingKey('')
805
-
806
804
  if (e.button === 2) {
807
805
  e.stopPropagation();
808
806
  return;
@@ -851,8 +849,14 @@ const GridEdit = props => {
851
849
  };
852
850
  const triggerDragPaste = pastesArray => {
853
851
  const mergedSet = new Set([...selectedCells, ...pastesArray]);
854
- setSelectedCells(mergedSet);
852
+
853
+ // console.log('pastesArray', pastesArray)
854
+ // console.log('selectedCells', selectedCells)
855
+
856
+ setSelectedCells((0, _hooks.sortedSetASC)(mergedSet));
855
857
  setPasteCells(new Set());
858
+ const rowSelectedFirst = (0, _hooks.getFirstSelectCell)(selectedCells).row;
859
+ const rowPasteLast = (0, _hooks.getLastSelectCell)(pasteCells).row;
856
860
  const selectedArray = Array.from(selectedCells).map(key => {
857
861
  const [row, col] = key.split("-").map(Number);
858
862
  // @ts-ignore
@@ -886,7 +890,17 @@ const GridEdit = props => {
886
890
  }) => {
887
891
  table[row - minRow][col - minCol] = value;
888
892
  });
889
- const newRange = (0, _hooks.addRows8)(table, (0, _hooks.getRowsPasteIndex)(pastesArray).length);
893
+ let newRange = {
894
+ combined: [],
895
+ addedRows: []
896
+ };
897
+ if (rowPasteLast > rowSelectedFirst) {
898
+ // kéo xuóng
899
+ newRange = (0, _hooks.addRows8)(table, (0, _hooks.getRowsPasteIndex)(pastesArray).length);
900
+ } else {
901
+ // kéo lên
902
+ newRange = (0, _hooks.addRowsUp)(table, (0, _hooks.getRowsPasteIndex)(pastesArray).length);
903
+ }
890
904
  const record = (0, _hooks.flattenData)(childrenColumnName, dataSource)[(0, _hooks.getFirstSelectCell)(pastesArray).row];
891
905
  if (!record?.parentId) {
892
906
  // Cập nhật data mới
@@ -1049,6 +1063,17 @@ const GridEdit = props => {
1049
1063
  }
1050
1064
  if (row < rowSelectedEnd) {
1051
1065
  // kéo lên trên
1066
+
1067
+ const rowSelectedStart = (0, _hooks.getFirstSelectCell)(selectedCells).row;
1068
+ if (row < rowSelectedStart) {
1069
+ const newPasteCells = new Set();
1070
+ for (let r = Math.min(rowSelectedStart, row); r <= Math.max(rowSelectedStart, row) - 1; r++) {
1071
+ for (let c = Math.min(colStart, col); c <= Math.max(colStart, colEnd); c++) {
1072
+ newPasteCells.add(`${r}-${c}`);
1073
+ }
1074
+ }
1075
+ setPasteCells(newPasteCells);
1076
+ }
1052
1077
  }
1053
1078
  if (col > colEnd) {
1054
1079
  // kéo sang phải
@@ -1153,7 +1178,7 @@ const GridEdit = props => {
1153
1178
  return {
1154
1179
  row,
1155
1180
  col,
1156
- value: (0, _hooks.flattenData)(childrenColumnName, dataSource)[row][columnKey]
1181
+ value: (0, _hooks.flattenData)(childrenColumnName, dataSource)[row][columnKey] ?? ''
1157
1182
  };
1158
1183
  // return { row, col, value: '' };
1159
1184
  });
@@ -1297,7 +1322,7 @@ const GridEdit = props => {
1297
1322
  };
1298
1323
  const handlePaste = (record, indexCol, rowNumber, e) => {
1299
1324
  // const clipboard: any = (e.clipboardData || (window && window?.Clipboard)).getData("text")
1300
- const pasteData = e.clipboardData.getData("text/plain").trim();
1325
+ const pasteData = e.clipboardData.getData("text/plain");
1301
1326
 
1302
1327
  // Chuyển đổi dữ liệu từ clipboard thành mảng
1303
1328
  const rowsPasted = pasteData.split("\n").map(row =>
@@ -1695,7 +1720,9 @@ const GridEdit = props => {
1695
1720
  const isTopSelected = selectedCells.has(topCellKey);
1696
1721
  const isLeftSelected = selectedCells.has(leftCellKey);
1697
1722
  const isRightSelected = selectedCells.has(rightCellKey);
1723
+ const topPasteCellKey = `${rowIndex + 1}-${colIndex}`;
1698
1724
  const isPasteSelected = pasteCells.has(cellKey);
1725
+ const isPasteTopSelected = pasteCells.has(topPasteCellKey);
1699
1726
  const isPasteLeftSelected = pasteCells.has(leftCellKey);
1700
1727
  const isPasteRightSelected = pasteCells.has(rightCellKey);
1701
1728
  const cellClass = isEditing(record) ? 'rc-ui-cell-editable cell-editing' : 'rc-ui-cell-editable cell-editable';
@@ -1704,15 +1731,20 @@ const GridEdit = props => {
1704
1731
  const cellEnd = (0, _hooks.getLastSelectCell)(selectedCells);
1705
1732
  const cellPasteStart = (0, _hooks.getFirstSelectCell)(pasteCells);
1706
1733
  const cellPasteSEnd = (0, _hooks.getLastSelectCell)(pasteCells);
1707
- const isPasteBottom = pasteCells.size && cellPasteSEnd && rowIndex === Math.max(cellPasteStart.row, cellPasteSEnd.row);
1734
+ const isPasteBottom = cellPasteSEnd.row > cellStart.row && pasteCells.size && cellPasteSEnd && rowIndex === Math.max(cellPasteStart.row, cellPasteSEnd.row);
1735
+
1736
+ // const rowSelectedFirst = getFirstSelectCell(selectedCells).row
1737
+ // const rowPasteLast = getLastSelectCell(pasteCells).row
1738
+
1708
1739
  if (!isSelected && !isPasteSelected) {
1709
1740
  // const isTop = prevRecordEditing && !isEditing(prevRecordEditing) && rowIndex === Math.min(cellStart.row - 1, cellEnd?.row);
1710
1741
  const isTop = prevRecordEditing && !isEditing(prevRecordEditing) && (0, _hooks.isTopMostInRegion)(rowIndex + 1, colIndex, selectedCells);
1711
1742
  const isLeft = colIndex + 1 === Math.min(cellStart.col, cellEnd?.col);
1712
1743
  const isRight = colIndex - 1 === Math.max(cellStart.col, cellEnd?.col);
1744
+ const isPasteTop = cellPasteSEnd.row < cellStart.row && (0, _hooks.isTopMostInRegion)(rowIndex + 1, colIndex, pasteCells);
1713
1745
  const isPasteLeft = colIndex + 1 === Math.min(cellPasteStart.col, cellPasteSEnd?.col);
1714
1746
  const isPasteRight = colIndex - 1 === Math.max(cellPasteStart.col, cellPasteSEnd?.col);
1715
- return isTopSelected || isLeftSelected || isRightSelected ? `${cellClass} ${isTop ? `cell-border-top` : ''} ${isLeft ? `cell-border-left` : ''} ${isPasteBottom ? `cell-paste-border-bottom` : ''} ${isRight ? `next-cell-border-left` : ''}` : isPasteLeftSelected || isPasteRightSelected ? `${cellClass} ${isPasteLeft ? `cell-paste-border-left` : ''} ${isPasteRight ? `next-cell-paste-border-left` : ''}` : cellClass;
1747
+ return isTopSelected || isLeftSelected || isRightSelected ? `${cellClass} ${isTop ? `cell-border-top` : ''} ${isLeft ? `cell-border-left` : ''} ${isPasteBottom ? `cell-paste-border-bottom` : ''} ${isRight ? `next-cell-border-left` : ''}` : isPasteLeftSelected || isPasteRightSelected || isPasteTopSelected ? `${cellClass} ${isPasteLeft ? `cell-paste-border-left` : ''} ${isPasteRight ? `next-cell-paste-border-left` : ''} ${isPasteTop ? `cell-paste-border-top` : ''}` : cellClass;
1716
1748
  }
1717
1749
  const isBottom = (0, _hooks.isBottomMostInRegion)(rowIndex, colIndex, selectedCells);
1718
1750
  // const isBottom = isBottomMostInRanges(rowIndex, colIndex, [selectedCells, ...ctrlCells])
@@ -1724,7 +1756,7 @@ const GridEdit = props => {
1724
1756
  const isPasteLeft = colIndex === Math.min(cellPasteStart.col, cellPasteSEnd?.col);
1725
1757
  return `${cellClass} ${isPasteBottom ? `cell-paste-border-bottom` : ''} ${isPasteSelected && isPasteRight ? `cell-paste-border-right` : ''} ${isPasteSelected && isPasteLeft ? `fixed-cell-paste-border-left` : ''} ${isBottom ? `cell-border-bottom` : ''} ${isRight ? `cell-border-right` : ''} ${isLeft ? `fixed-cell-border-left` : ''} ${isBottom && isRight ? `cell-border-end` : ''}`;
1726
1758
  };
1727
- const convertColumns = (0, _columns.flatColumns2)(columns).map((column, colIndex) => {
1759
+ const convertColumns = (0, _columns.flatColumns2)(columns.filter(it => it.visible !== false)).map((column, colIndex) => {
1728
1760
  if (!column?.field && !column?.key) {
1729
1761
  return column;
1730
1762
  }
@@ -1918,6 +1950,10 @@ const GridEdit = props => {
1918
1950
  title: (0, _columns.getValueCell)(column, record[column.field], format),
1919
1951
  'data-col-index': colIndex,
1920
1952
  'data-row-index': rowNumber,
1953
+ // 'data-tooltip-id': "tooltip-cell-content",
1954
+ // 'data-tooltip-content': 'tooltip-cell-content',
1955
+ // 'data-tooltip-delay-show': 1000,
1956
+ // 'data-tooltip-content': getValueCell(column, record[column.field as any], format),
1921
1957
  editing: isEditing(record) && rowEditable?.(record) !== false && (0, _hooks.isEditable)(column, record),
1922
1958
  cellEditing,
1923
1959
  t,
@@ -1978,7 +2014,9 @@ const GridEdit = props => {
1978
2014
  // onMouseEnter={(event) => handlePointEnter(event)}
1979
2015
  // onMouseLeave={() => handlePointLeave()}
1980
2016
  ,
1981
- onMouseDown: () => {
2017
+ onMouseDown: e => {
2018
+ // e.stopPropagation()
2019
+ e.preventDefault();
1982
2020
  setIsPasteDragging(true);
1983
2021
  },
1984
2022
  onDoubleClick: handlePointDoubleClick
@@ -2000,6 +2038,11 @@ const GridEdit = props => {
2000
2038
  ...find
2001
2039
  };
2002
2040
  }
2041
+ if (!find) {
2042
+ return {
2043
+ ...column
2044
+ };
2045
+ }
2003
2046
 
2004
2047
  // Xử lý đệ quy cho children
2005
2048
  if (column.children?.length) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "es-grid-template",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "description": "es-grid-template",
5
5
  "keywords": [
6
6
  "react",
@@ -60,7 +60,7 @@
60
60
  "rc-checkbox": "^3.5.0",
61
61
  "rc-dropdown": "^4.2.1",
62
62
  "rc-field-form": "^2.6.0",
63
- "rc-master-ui": "^1.1.23",
63
+ "rc-master-ui": "^1.1.24",
64
64
  "rc-select": "^14.16.3",
65
65
  "rc-tooltip": "^6.3.0",
66
66
  "rc-tree": "^5.10.1",