es-grid-template 1.9.79 → 1.9.83
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/es/ali-table/utils/convertColumnsChoose.js +2 -1
- package/es/grid-component/type.d.ts +2 -0
- package/es/group-component/TableContainerEdit.js +18 -0
- package/es/group-component/body/TableBodyCellEdit.js +5 -0
- package/es/group-component/hook/utils.d.ts +3 -3
- package/es/group-component/hook/utils.js +12 -3
- package/es/table-component/TableContainerEdit.js +18 -0
- package/es/table-component/body/TableBodyCellEdit.js +5 -0
- package/es/table-component/hook/utils.js +11 -4
- package/es/table-virtuoso/InternalTable.js +6 -1
- package/es/table-virtuoso/hook/utils.js +12 -2
- package/es/table-virtuoso/table/TableContainer.js +12 -2
- package/lib/ali-table/utils/convertColumnsChoose.js +2 -1
- package/lib/grid-component/type.d.ts +2 -0
- package/lib/group-component/TableContainerEdit.js +18 -0
- package/lib/group-component/body/TableBodyCellEdit.js +5 -0
- package/lib/group-component/hook/utils.d.ts +9 -9
- package/lib/group-component/hook/utils.js +12 -3
- package/lib/table-component/TableContainerEdit.js +18 -0
- package/lib/table-component/body/TableBodyCellEdit.js +5 -0
- package/lib/table-component/hook/utils.js +11 -4
- package/lib/table-virtuoso/InternalTable.js +6 -1
- package/lib/table-virtuoso/hook/utils.js +12 -2
- package/lib/table-virtuoso/table/TableContainer.js +12 -2
- package/package.json +1 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { nonActionColumn } from "../../grid-component/hooks";
|
|
1
2
|
export function convertColumnsToTreeData(columns, groupColumns, t) {
|
|
2
3
|
if (!columns) {
|
|
3
4
|
return [];
|
|
4
5
|
}
|
|
5
6
|
return columns.filter(col => {
|
|
6
7
|
const inGroup = groupColumns ? groupColumns.includes(String(col.field)) : false;
|
|
7
|
-
if (col.showInColumnChoose === false) return false;
|
|
8
|
+
if (col.showInColumnChoose === false || nonActionColumn.includes(col.field)) return false;
|
|
8
9
|
if (inGroup && !('children' in col && Array.isArray(col.children))) {
|
|
9
10
|
return false;
|
|
10
11
|
}
|
|
@@ -76,6 +76,8 @@ export type Locale = {
|
|
|
76
76
|
export type PaginationConfig = Omit<TablePaginationConfig, 'locale' | 'current'> & {
|
|
77
77
|
currentPage?: number;
|
|
78
78
|
locale?: PagingLocale;
|
|
79
|
+
/** Chế độ phân trang. Mặc định là client để giữ tương thích với hành vi hiện tại. */
|
|
80
|
+
mode?: 'client' | 'server';
|
|
79
81
|
};
|
|
80
82
|
export type AnyObject = Record<PropertyKey, any>;
|
|
81
83
|
export type IFormat = {
|
|
@@ -2023,7 +2023,25 @@ const TableContainerEdit = props => {
|
|
|
2023
2023
|
}
|
|
2024
2024
|
contextMenuClick?.(args);
|
|
2025
2025
|
};
|
|
2026
|
+
|
|
2027
|
+
// Chống fire onCellClick trùng lặp: double-click = 2 lần mousedown nên callback sẽ bị gọi 2 lần.
|
|
2028
|
+
// Chỉ bỏ qua khi click LIÊN TIẾP cùng 1 cell trong khoảng thời gian rất ngắn.
|
|
2029
|
+
const lastCellClickRef = React.useRef({
|
|
2030
|
+
key: '',
|
|
2031
|
+
time: 0
|
|
2032
|
+
});
|
|
2026
2033
|
const handleCellClick = (rowNumber, record, column, rowId, cellValue) => {
|
|
2034
|
+
const clickKey = `${rowId}::${column.field ?? ''}`;
|
|
2035
|
+
const now = Date.now();
|
|
2036
|
+
|
|
2037
|
+
// cùng cell && trong vòng 300ms => coi là double-click, bỏ qua lần lặp
|
|
2038
|
+
if (lastCellClickRef.current.key === clickKey && now - lastCellClickRef.current.time < 300) {
|
|
2039
|
+
return;
|
|
2040
|
+
}
|
|
2041
|
+
lastCellClickRef.current = {
|
|
2042
|
+
key: clickKey,
|
|
2043
|
+
time: now
|
|
2044
|
+
};
|
|
2027
2045
|
const cellClickCallback = newOptions => {
|
|
2028
2046
|
if (newOptions) {
|
|
2029
2047
|
const newElem = {
|
|
@@ -1260,6 +1260,11 @@ const TableBodyCellEdit = props => {
|
|
|
1260
1260
|
}
|
|
1261
1261
|
} else {
|
|
1262
1262
|
handleMouseDown(cell.row.id, cell.column.id);
|
|
1263
|
+
|
|
1264
|
+
// fire onCellClick ngay lần click đầu (trước đây chỉ fire khi cell đã ở trạng thái editing)
|
|
1265
|
+
if (canEdit) {
|
|
1266
|
+
handleCellClick?.(rowNumber, record, columnMeta, record[rowKey], record[columnMeta.field ?? '']);
|
|
1267
|
+
}
|
|
1263
1268
|
if (editingKey) {
|
|
1264
1269
|
setTimeout(() => {
|
|
1265
1270
|
setEditingKey?.('');
|
|
@@ -196,10 +196,10 @@ export declare const fixColumnsLeft: <RecordType>(columns: ColumnTable<RecordTyp
|
|
|
196
196
|
value: any;
|
|
197
197
|
rowData: RecordType;
|
|
198
198
|
}) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | import("react").ReactNode);
|
|
199
|
-
onCellStyles?: Omit<CSSProperties, "
|
|
200
|
-
onCellHeaderStyles?: Omit<CSSProperties, "
|
|
199
|
+
onCellStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cellValue: any, cell: import("@tanstack/react-table").Cell<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
|
|
200
|
+
onCellHeaderStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
|
|
201
201
|
onCell?: (rowData: RecordType, index: number) => import("react").TdHTMLAttributes<HTMLTableCellElement>;
|
|
202
|
-
onCellFooterStyles?: Omit<CSSProperties, "
|
|
202
|
+
onCellFooterStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cellValue: any, cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
|
|
203
203
|
getValue?: (row: any, rowIndex: number) => any;
|
|
204
204
|
getCellProps?: (value: any, row: any, rowIndex: number) => import("./../../grid-component/type").CellProps;
|
|
205
205
|
headerCellProps?: import("./../../grid-component/type").CellProps;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { nonActionColumn } from "./../../grid-component/hooks";
|
|
1
2
|
import { v4 as uuidv4 } from 'uuid';
|
|
2
3
|
import { presetPalettes } from "@ant-design/colors";
|
|
3
4
|
import dayjs from "dayjs";
|
|
@@ -5,7 +6,6 @@ import moment from "moment";
|
|
|
5
6
|
export const newGuid = () => {
|
|
6
7
|
for (let i = 0; i < 20; i++) {
|
|
7
8
|
// @ts-ignore
|
|
8
|
-
// const id = crypto.randomUUID()
|
|
9
9
|
return uuidv4();
|
|
10
10
|
}
|
|
11
11
|
};
|
|
@@ -1916,8 +1916,8 @@ export function convertColumnsToTreeData(columns, groupColumns) {
|
|
|
1916
1916
|
|
|
1917
1917
|
// Điều kiện filter:
|
|
1918
1918
|
// - Nếu meta.showInColumnChoose = false => loại bỏ
|
|
1919
|
-
// - Nếu
|
|
1920
|
-
if (meta.showInColumnChoose === false) return false;
|
|
1919
|
+
// - Nếu là column đặc biệt (selection_column, #, command...) => loại bỏ
|
|
1920
|
+
if (meta.showInColumnChoose === false || nonActionColumn.includes(col.id)) return false;
|
|
1921
1921
|
if (inGroup && !('columns' in col && Array.isArray(col.columns))) {
|
|
1922
1922
|
return false;
|
|
1923
1923
|
}
|
|
@@ -1948,6 +1948,15 @@ export const updateColumns1 = (columns, includes) => {
|
|
|
1948
1948
|
if (!column.field) {
|
|
1949
1949
|
return column;
|
|
1950
1950
|
}
|
|
1951
|
+
|
|
1952
|
+
// Bỏ qua column đặc biệt (selection_column, #, command, drag-handle) — giữ nguyên visible
|
|
1953
|
+
// nhưng vẫn phải đệ quy children để không bỏ sót column con
|
|
1954
|
+
if (nonActionColumn.includes(newColumn.field)) {
|
|
1955
|
+
if (newColumn.children) {
|
|
1956
|
+
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
1957
|
+
}
|
|
1958
|
+
return newColumn;
|
|
1959
|
+
}
|
|
1951
1960
|
if (newColumn.children) {
|
|
1952
1961
|
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
1953
1962
|
hasVisibleChild = newColumn.children.some(child => !child.hidden);
|
|
@@ -2078,7 +2078,25 @@ const TableContainerEdit = props => {
|
|
|
2078
2078
|
}
|
|
2079
2079
|
contextMenuClick?.(args);
|
|
2080
2080
|
};
|
|
2081
|
+
|
|
2082
|
+
// Chống fire onCellClick trùng lặp: double-click = 2 lần mousedown nên callback sẽ bị gọi 2 lần.
|
|
2083
|
+
// Chỉ bỏ qua khi click LIÊN TIẾP cùng 1 cell trong khoảng thời gian rất ngắn.
|
|
2084
|
+
const lastCellClickRef = React.useRef({
|
|
2085
|
+
key: '',
|
|
2086
|
+
time: 0
|
|
2087
|
+
});
|
|
2081
2088
|
const handleCellClick = (rowNumber, record, column, rowId, cellValue) => {
|
|
2089
|
+
const clickKey = `${rowId}::${column.field ?? ''}`;
|
|
2090
|
+
const now = Date.now();
|
|
2091
|
+
|
|
2092
|
+
// cùng cell && trong vòng 300ms => coi là double-click, bỏ qua lần lặp
|
|
2093
|
+
if (lastCellClickRef.current.key === clickKey && now - lastCellClickRef.current.time < 300) {
|
|
2094
|
+
return;
|
|
2095
|
+
}
|
|
2096
|
+
lastCellClickRef.current = {
|
|
2097
|
+
key: clickKey,
|
|
2098
|
+
time: now
|
|
2099
|
+
};
|
|
2082
2100
|
const cellClickCallback = newOptions => {
|
|
2083
2101
|
if (newOptions) {
|
|
2084
2102
|
const newElem = {
|
|
@@ -1344,6 +1344,11 @@ const TableBodyCellEdit = props => {
|
|
|
1344
1344
|
}
|
|
1345
1345
|
} else {
|
|
1346
1346
|
handleMouseDown(cell.row.id, cell.column.id);
|
|
1347
|
+
|
|
1348
|
+
// fire onCellClick ngay lần click đầu (trước đây chỉ fire khi cell đã ở trạng thái editing)
|
|
1349
|
+
if (canEdit) {
|
|
1350
|
+
handleCellClick?.(rowNumber, record, columnMeta, record[rowKey], record[columnMeta.field ?? '']);
|
|
1351
|
+
}
|
|
1347
1352
|
if (editingKey) {
|
|
1348
1353
|
setTimeout(() => {
|
|
1349
1354
|
setEditingKey?.('');
|
|
@@ -6,7 +6,6 @@ import { nonActionColumn } from "../../grid-component/hooks";
|
|
|
6
6
|
export const newGuid = () => {
|
|
7
7
|
for (let i = 0; i < 20; i++) {
|
|
8
8
|
// @ts-ignore
|
|
9
|
-
// const id = crypto.randomUUID()
|
|
10
9
|
return uuidv4();
|
|
11
10
|
}
|
|
12
11
|
};
|
|
@@ -2481,9 +2480,8 @@ export function convertColumnsToTreeData(columns, groupColumns) {
|
|
|
2481
2480
|
|
|
2482
2481
|
// Điều kiện filter:
|
|
2483
2482
|
// - Nếu meta.showInColumnChoose = false => loại bỏ
|
|
2484
|
-
// - Nếu
|
|
2485
|
-
|
|
2486
|
-
if (meta.showInColumnChoose === false) return false;
|
|
2483
|
+
// - Nếu là column đặc biệt (selection_column, #, command...) => loại bỏ
|
|
2484
|
+
if (meta.showInColumnChoose === false || nonActionColumn.includes(col.id)) return false;
|
|
2487
2485
|
// if (inGroup && !('columns' in col && Array.isArray((col as any).columns))) {
|
|
2488
2486
|
if (inGroup && !('columns' in col && Array.isArray(col.columns))) {
|
|
2489
2487
|
return false;
|
|
@@ -2515,6 +2513,15 @@ export const updateColumns1 = (columns, includes) => {
|
|
|
2515
2513
|
if (!column.field) {
|
|
2516
2514
|
return column;
|
|
2517
2515
|
}
|
|
2516
|
+
|
|
2517
|
+
// Bỏ qua column đặc biệt (selection_column, #, command, drag-handle) — giữ nguyên visible
|
|
2518
|
+
// nhưng vẫn phải đệ quy children để không bỏ sót column con
|
|
2519
|
+
if (nonActionColumn.includes(newColumn.field)) {
|
|
2520
|
+
if (newColumn.children) {
|
|
2521
|
+
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
2522
|
+
}
|
|
2523
|
+
return newColumn;
|
|
2524
|
+
}
|
|
2518
2525
|
if (newColumn.children) {
|
|
2519
2526
|
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
2520
2527
|
hasVisibleChild = newColumn.children.some(child => !child.hidden);
|
|
@@ -89,6 +89,8 @@ const InternalTable = props => {
|
|
|
89
89
|
pageIndex: pagination && pagination.currentPage ? pagination.currentPage - 1 : 0,
|
|
90
90
|
pageSize: pagination && pagination.pageSize ? pagination.pageSize : 20
|
|
91
91
|
});
|
|
92
|
+
const isServerPagination = Boolean(pagination && pagination.mode === 'server');
|
|
93
|
+
const shouldUseClientPagination = Boolean(pagination) && !infiniteScroll && !isServerPagination;
|
|
92
94
|
const [columnSizing, setColumnSizing] = React.useState({});
|
|
93
95
|
const [columnSizingInfo, setColumnSizingInfo] = React.useState({});
|
|
94
96
|
|
|
@@ -264,7 +266,10 @@ const InternalTable = props => {
|
|
|
264
266
|
getGroupedRowModel: getGroupedRowModel(),
|
|
265
267
|
// onExpandedChange: setExpanded,
|
|
266
268
|
getExpandedRowModel: getExpandedRowModel(),
|
|
267
|
-
|
|
269
|
+
manualPagination: isServerPagination,
|
|
270
|
+
// Chỉ để TanStack tự phân trang khi có pagination, không dùng infinite scroll và đang ở chế độ client.
|
|
271
|
+
// Với server pagination, dữ liệu đã được BE phân trang nên không chạy getPaginationRowModel() để tránh phân trang lần 2.
|
|
272
|
+
getPaginationRowModel: shouldUseClientPagination ? getPaginationRowModel() : undefined,
|
|
268
273
|
onPaginationChange: setPagination,
|
|
269
274
|
onColumnVisibilityChange: setColumnVisibility
|
|
270
275
|
// onColumnPinningChange,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { nonActionColumn } from "../../grid-component/hooks";
|
|
1
2
|
import { SELECTION_COLUMN } from "rc-master-ui/es/table/hooks/useSelection";
|
|
2
3
|
import { v4 as uuidv4 } from 'uuid';
|
|
3
4
|
import { presetPalettes } from "@ant-design/colors";
|
|
@@ -1888,8 +1889,8 @@ export function convertColumnsToTreeData(columns, groupColumns) {
|
|
|
1888
1889
|
|
|
1889
1890
|
// Điều kiện filter:
|
|
1890
1891
|
// - Nếu meta.showInColumnChoose = false => loại bỏ
|
|
1891
|
-
// - Nếu
|
|
1892
|
-
if (meta.showInColumnChoose === false) return false;
|
|
1892
|
+
// - Nếu là column đặc biệt (selection_column, #, command...) => loại bỏ
|
|
1893
|
+
if (meta.showInColumnChoose === false || nonActionColumn.includes(col.id)) return false;
|
|
1893
1894
|
if (inGroup && !('columns' in col && Array.isArray(col.columns))) {
|
|
1894
1895
|
return false;
|
|
1895
1896
|
}
|
|
@@ -1920,6 +1921,15 @@ export const updateColumns1 = (columns, includes) => {
|
|
|
1920
1921
|
if (!column.field) {
|
|
1921
1922
|
return column;
|
|
1922
1923
|
}
|
|
1924
|
+
|
|
1925
|
+
// Bỏ qua column đặc biệt (selection_column, #, command, drag-handle) — giữ nguyên visible
|
|
1926
|
+
// nhưng vẫn phải đệ quy children để không bỏ sót column con
|
|
1927
|
+
if (nonActionColumn.includes(newColumn.field)) {
|
|
1928
|
+
if (newColumn.children) {
|
|
1929
|
+
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
1930
|
+
}
|
|
1931
|
+
return newColumn;
|
|
1932
|
+
}
|
|
1923
1933
|
if (newColumn.children) {
|
|
1924
1934
|
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
1925
1935
|
hasVisibleChild = newColumn.children.some(child => !child.hidden);
|
|
@@ -79,6 +79,16 @@ const TableContainer = props => {
|
|
|
79
79
|
} = props;
|
|
80
80
|
const [paginationLocal] = useLocale('Pagination');
|
|
81
81
|
const [tableLocal] = useLocale('Table');
|
|
82
|
+
const paginationProps = React.useMemo(() => {
|
|
83
|
+
if (!pagination) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
const paginationConfig = {
|
|
87
|
+
...pagination
|
|
88
|
+
};
|
|
89
|
+
delete paginationConfig.mode;
|
|
90
|
+
return paginationConfig;
|
|
91
|
+
}, [pagination]);
|
|
82
92
|
const tableContainerRef = React.useRef(null);
|
|
83
93
|
const containerRef = React.useRef(null);
|
|
84
94
|
const bottomToolbarRef = React.useRef(null);
|
|
@@ -210,7 +220,7 @@ const TableContainer = props => {
|
|
|
210
220
|
showTotal: (totalItems, range) =>
|
|
211
221
|
// @ts-ignore
|
|
212
222
|
`${range[0]}-${range[1]} / ${totalItems} ${t ? t(pagination?.locale?.items ?? 'items') : 'items'}`
|
|
213
|
-
},
|
|
223
|
+
}, paginationProps)), typeof actionTemplate === 'function' ? actionTemplate() : actionTemplate, toolbarItemTopRight && /*#__PURE__*/React.createElement("div", {
|
|
214
224
|
style: {
|
|
215
225
|
flex: 1,
|
|
216
226
|
overflow: 'hidden'
|
|
@@ -299,7 +309,7 @@ const TableContainer = props => {
|
|
|
299
309
|
})} / ${numericFormatter((totalItems ?? 0).toString(), {
|
|
300
310
|
thousandSeparator: '.'
|
|
301
311
|
})} ${pagination?.locale?.items || paginationLocal?.items || ''}`
|
|
302
|
-
},
|
|
312
|
+
}, paginationProps, {
|
|
303
313
|
onChange: (page, pageSize1) => {
|
|
304
314
|
if (pagination.onChange) {
|
|
305
315
|
pagination.onChange(page, pageSize1);
|
|
@@ -6,13 +6,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.convertColumnsToTreeData = convertColumnsToTreeData;
|
|
7
7
|
exports.filterColumnsByField = filterColumnsByField;
|
|
8
8
|
exports.filterVisibleColumns = filterVisibleColumns;
|
|
9
|
+
var _hooks = require("../../grid-component/hooks");
|
|
9
10
|
function convertColumnsToTreeData(columns, groupColumns, t) {
|
|
10
11
|
if (!columns) {
|
|
11
12
|
return [];
|
|
12
13
|
}
|
|
13
14
|
return columns.filter(col => {
|
|
14
15
|
const inGroup = groupColumns ? groupColumns.includes(String(col.field)) : false;
|
|
15
|
-
if (col.showInColumnChoose === false) return false;
|
|
16
|
+
if (col.showInColumnChoose === false || _hooks.nonActionColumn.includes(col.field)) return false;
|
|
16
17
|
if (inGroup && !('children' in col && Array.isArray(col.children))) {
|
|
17
18
|
return false;
|
|
18
19
|
}
|
|
@@ -76,6 +76,8 @@ export type Locale = {
|
|
|
76
76
|
export type PaginationConfig = Omit<TablePaginationConfig, 'locale' | 'current'> & {
|
|
77
77
|
currentPage?: number;
|
|
78
78
|
locale?: PagingLocale;
|
|
79
|
+
/** Chế độ phân trang. Mặc định là client để giữ tương thích với hành vi hiện tại. */
|
|
80
|
+
mode?: 'client' | 'server';
|
|
79
81
|
};
|
|
80
82
|
export type AnyObject = Record<PropertyKey, any>;
|
|
81
83
|
export type IFormat = {
|
|
@@ -2031,7 +2031,25 @@ const TableContainerEdit = props => {
|
|
|
2031
2031
|
}
|
|
2032
2032
|
contextMenuClick?.(args);
|
|
2033
2033
|
};
|
|
2034
|
+
|
|
2035
|
+
// Chống fire onCellClick trùng lặp: double-click = 2 lần mousedown nên callback sẽ bị gọi 2 lần.
|
|
2036
|
+
// Chỉ bỏ qua khi click LIÊN TIẾP cùng 1 cell trong khoảng thời gian rất ngắn.
|
|
2037
|
+
const lastCellClickRef = _react.default.useRef({
|
|
2038
|
+
key: '',
|
|
2039
|
+
time: 0
|
|
2040
|
+
});
|
|
2034
2041
|
const handleCellClick = (rowNumber, record, column, rowId, cellValue) => {
|
|
2042
|
+
const clickKey = `${rowId}::${column.field ?? ''}`;
|
|
2043
|
+
const now = Date.now();
|
|
2044
|
+
|
|
2045
|
+
// cùng cell && trong vòng 300ms => coi là double-click, bỏ qua lần lặp
|
|
2046
|
+
if (lastCellClickRef.current.key === clickKey && now - lastCellClickRef.current.time < 300) {
|
|
2047
|
+
return;
|
|
2048
|
+
}
|
|
2049
|
+
lastCellClickRef.current = {
|
|
2050
|
+
key: clickKey,
|
|
2051
|
+
time: now
|
|
2052
|
+
};
|
|
2035
2053
|
const cellClickCallback = newOptions => {
|
|
2036
2054
|
if (newOptions) {
|
|
2037
2055
|
const newElem = {
|
|
@@ -1267,6 +1267,11 @@ const TableBodyCellEdit = props => {
|
|
|
1267
1267
|
}
|
|
1268
1268
|
} else {
|
|
1269
1269
|
handleMouseDown(cell.row.id, cell.column.id);
|
|
1270
|
+
|
|
1271
|
+
// fire onCellClick ngay lần click đầu (trước đây chỉ fire khi cell đã ở trạng thái editing)
|
|
1272
|
+
if (canEdit) {
|
|
1273
|
+
handleCellClick?.(rowNumber, record, columnMeta, record[rowKey], record[columnMeta.field ?? '']);
|
|
1274
|
+
}
|
|
1270
1275
|
if (editingKey) {
|
|
1271
1276
|
setTimeout(() => {
|
|
1272
1277
|
setEditingKey?.('');
|
|
@@ -167,7 +167,7 @@ export declare const fixColumnsLeft: <RecordType>(columns: ColumnTable<RecordTyp
|
|
|
167
167
|
haveSum?: boolean;
|
|
168
168
|
isSummary?: boolean;
|
|
169
169
|
sumGroup?: boolean;
|
|
170
|
-
summaryTemplate?: (data: number, key: string) => import("react").
|
|
170
|
+
summaryTemplate?: (data: number, key: string) => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
171
171
|
sorter?: boolean;
|
|
172
172
|
allowFiltering?: boolean;
|
|
173
173
|
allowSortering?: boolean;
|
|
@@ -179,27 +179,27 @@ export declare const fixColumnsLeft: <RecordType>(columns: ColumnTable<RecordTyp
|
|
|
179
179
|
showFilterSearch?: boolean;
|
|
180
180
|
hidden?: boolean;
|
|
181
181
|
visible?: boolean;
|
|
182
|
-
headerTooltip?: string | boolean | (() => import("react").
|
|
182
|
+
headerTooltip?: string | boolean | (() => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>);
|
|
183
183
|
columnGroupText?: string;
|
|
184
184
|
headerTextAlign?: import("./../../grid-component/type").ITextAlign;
|
|
185
|
-
headerTemplate?: import("react").
|
|
185
|
+
headerTemplate?: import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | ((column: ColumnTable<RecordType>) => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>);
|
|
186
186
|
fixedType?: import("./../../grid-component/type").FixedType;
|
|
187
187
|
headerTextWrap?: boolean;
|
|
188
188
|
ellipsis?: boolean;
|
|
189
189
|
allowResizing?: boolean;
|
|
190
190
|
align?: import("./../../grid-component/type").ITextAlign;
|
|
191
191
|
textAlign?: import("./../../grid-component/type").ITextAlign;
|
|
192
|
-
template?: import("react").
|
|
193
|
-
linkTemplate?: import("react").
|
|
192
|
+
template?: import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | ((args: import("./../../grid-component/type").ColumnTemplate<RecordType>) => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>);
|
|
193
|
+
linkTemplate?: import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>> | ((args: import("./../../grid-component/type").ColumnTemplate<RecordType>) => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>);
|
|
194
194
|
showTooltip?: boolean;
|
|
195
195
|
tooltipDescription?: string | ((args: {
|
|
196
196
|
value: any;
|
|
197
197
|
rowData: RecordType;
|
|
198
|
-
}) => import("react").
|
|
199
|
-
onCellStyles?: Omit<CSSProperties, "
|
|
200
|
-
onCellHeaderStyles?: Omit<CSSProperties, "
|
|
198
|
+
}) => import("react").ReactNode | import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>);
|
|
199
|
+
onCellStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cellValue: any, cell: import("@tanstack/react-table").Cell<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
|
|
200
|
+
onCellHeaderStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
|
|
201
201
|
onCell?: (rowData: RecordType, index: number) => import("react").TdHTMLAttributes<HTMLTableCellElement>;
|
|
202
|
-
onCellFooterStyles?: Omit<CSSProperties, "
|
|
202
|
+
onCellFooterStyles?: Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width"> | ((cellValue: any, cell: import("@tanstack/react-table").Header<RecordType, unknown>) => Omit<CSSProperties, "left" | "right" | "display" | "minWidth" | "position" | "width">);
|
|
203
203
|
getValue?: (row: any, rowIndex: number) => any;
|
|
204
204
|
getCellProps?: (value: any, row: any, rowIndex: number) => import("./../../grid-component/type").CellProps;
|
|
205
205
|
headerCellProps?: import("./../../grid-component/type").CellProps;
|
|
@@ -60,6 +60,7 @@ exports.updateColumnWidthsRecursive = updateColumnWidthsRecursive;
|
|
|
60
60
|
exports.updateColumnsByGroup = exports.updateColumns1 = void 0;
|
|
61
61
|
exports.updateOrInsert = updateOrInsert;
|
|
62
62
|
exports.updateWidthsByOther = updateWidthsByOther;
|
|
63
|
+
var _hooks = require("./../../grid-component/hooks");
|
|
63
64
|
var _uuid = require("uuid");
|
|
64
65
|
var _colors = require("@ant-design/colors");
|
|
65
66
|
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
@@ -67,7 +68,6 @@ var _moment = _interopRequireDefault(require("moment"));
|
|
|
67
68
|
const newGuid = () => {
|
|
68
69
|
for (let i = 0; i < 20; i++) {
|
|
69
70
|
// @ts-ignore
|
|
70
|
-
// const id = crypto.randomUUID()
|
|
71
71
|
return (0, _uuid.v4)();
|
|
72
72
|
}
|
|
73
73
|
};
|
|
@@ -2030,8 +2030,8 @@ function convertColumnsToTreeData(columns, groupColumns) {
|
|
|
2030
2030
|
|
|
2031
2031
|
// Điều kiện filter:
|
|
2032
2032
|
// - Nếu meta.showInColumnChoose = false => loại bỏ
|
|
2033
|
-
// - Nếu
|
|
2034
|
-
if (meta.showInColumnChoose === false) return false;
|
|
2033
|
+
// - Nếu là column đặc biệt (selection_column, #, command...) => loại bỏ
|
|
2034
|
+
if (meta.showInColumnChoose === false || _hooks.nonActionColumn.includes(col.id)) return false;
|
|
2035
2035
|
if (inGroup && !('columns' in col && Array.isArray(col.columns))) {
|
|
2036
2036
|
return false;
|
|
2037
2037
|
}
|
|
@@ -2062,6 +2062,15 @@ const updateColumns1 = (columns, includes) => {
|
|
|
2062
2062
|
if (!column.field) {
|
|
2063
2063
|
return column;
|
|
2064
2064
|
}
|
|
2065
|
+
|
|
2066
|
+
// Bỏ qua column đặc biệt (selection_column, #, command, drag-handle) — giữ nguyên visible
|
|
2067
|
+
// nhưng vẫn phải đệ quy children để không bỏ sót column con
|
|
2068
|
+
if (_hooks.nonActionColumn.includes(newColumn.field)) {
|
|
2069
|
+
if (newColumn.children) {
|
|
2070
|
+
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
2071
|
+
}
|
|
2072
|
+
return newColumn;
|
|
2073
|
+
}
|
|
2065
2074
|
if (newColumn.children) {
|
|
2066
2075
|
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
2067
2076
|
hasVisibleChild = newColumn.children.some(child => !child.hidden);
|
|
@@ -2077,7 +2077,25 @@ const TableContainerEdit = props => {
|
|
|
2077
2077
|
}
|
|
2078
2078
|
contextMenuClick?.(args);
|
|
2079
2079
|
};
|
|
2080
|
+
|
|
2081
|
+
// Chống fire onCellClick trùng lặp: double-click = 2 lần mousedown nên callback sẽ bị gọi 2 lần.
|
|
2082
|
+
// Chỉ bỏ qua khi click LIÊN TIẾP cùng 1 cell trong khoảng thời gian rất ngắn.
|
|
2083
|
+
const lastCellClickRef = _react.default.useRef({
|
|
2084
|
+
key: '',
|
|
2085
|
+
time: 0
|
|
2086
|
+
});
|
|
2080
2087
|
const handleCellClick = (rowNumber, record, column, rowId, cellValue) => {
|
|
2088
|
+
const clickKey = `${rowId}::${column.field ?? ''}`;
|
|
2089
|
+
const now = Date.now();
|
|
2090
|
+
|
|
2091
|
+
// cùng cell && trong vòng 300ms => coi là double-click, bỏ qua lần lặp
|
|
2092
|
+
if (lastCellClickRef.current.key === clickKey && now - lastCellClickRef.current.time < 300) {
|
|
2093
|
+
return;
|
|
2094
|
+
}
|
|
2095
|
+
lastCellClickRef.current = {
|
|
2096
|
+
key: clickKey,
|
|
2097
|
+
time: now
|
|
2098
|
+
};
|
|
2081
2099
|
const cellClickCallback = newOptions => {
|
|
2082
2100
|
if (newOptions) {
|
|
2083
2101
|
const newElem = {
|
|
@@ -1349,6 +1349,11 @@ const TableBodyCellEdit = props => {
|
|
|
1349
1349
|
}
|
|
1350
1350
|
} else {
|
|
1351
1351
|
handleMouseDown(cell.row.id, cell.column.id);
|
|
1352
|
+
|
|
1353
|
+
// fire onCellClick ngay lần click đầu (trước đây chỉ fire khi cell đã ở trạng thái editing)
|
|
1354
|
+
if (canEdit) {
|
|
1355
|
+
handleCellClick?.(rowNumber, record, columnMeta, record[rowKey], record[columnMeta.field ?? '']);
|
|
1356
|
+
}
|
|
1352
1357
|
if (editingKey) {
|
|
1353
1358
|
setTimeout(() => {
|
|
1354
1359
|
setEditingKey?.('');
|
|
@@ -86,7 +86,6 @@ var _hooks = require("../../grid-component/hooks");
|
|
|
86
86
|
const newGuid = () => {
|
|
87
87
|
for (let i = 0; i < 20; i++) {
|
|
88
88
|
// @ts-ignore
|
|
89
|
-
// const id = crypto.randomUUID()
|
|
90
89
|
return (0, _uuid.v4)();
|
|
91
90
|
}
|
|
92
91
|
};
|
|
@@ -2625,9 +2624,8 @@ function convertColumnsToTreeData(columns, groupColumns) {
|
|
|
2625
2624
|
|
|
2626
2625
|
// Điều kiện filter:
|
|
2627
2626
|
// - Nếu meta.showInColumnChoose = false => loại bỏ
|
|
2628
|
-
// - Nếu
|
|
2629
|
-
|
|
2630
|
-
if (meta.showInColumnChoose === false) return false;
|
|
2627
|
+
// - Nếu là column đặc biệt (selection_column, #, command...) => loại bỏ
|
|
2628
|
+
if (meta.showInColumnChoose === false || _hooks.nonActionColumn.includes(col.id)) return false;
|
|
2631
2629
|
// if (inGroup && !('columns' in col && Array.isArray((col as any).columns))) {
|
|
2632
2630
|
if (inGroup && !('columns' in col && Array.isArray(col.columns))) {
|
|
2633
2631
|
return false;
|
|
@@ -2659,6 +2657,15 @@ const updateColumns1 = (columns, includes) => {
|
|
|
2659
2657
|
if (!column.field) {
|
|
2660
2658
|
return column;
|
|
2661
2659
|
}
|
|
2660
|
+
|
|
2661
|
+
// Bỏ qua column đặc biệt (selection_column, #, command, drag-handle) — giữ nguyên visible
|
|
2662
|
+
// nhưng vẫn phải đệ quy children để không bỏ sót column con
|
|
2663
|
+
if (_hooks.nonActionColumn.includes(newColumn.field)) {
|
|
2664
|
+
if (newColumn.children) {
|
|
2665
|
+
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
2666
|
+
}
|
|
2667
|
+
return newColumn;
|
|
2668
|
+
}
|
|
2662
2669
|
if (newColumn.children) {
|
|
2663
2670
|
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
2664
2671
|
hasVisibleChild = newColumn.children.some(child => !child.hidden);
|
|
@@ -99,6 +99,8 @@ const InternalTable = props => {
|
|
|
99
99
|
pageIndex: pagination && pagination.currentPage ? pagination.currentPage - 1 : 0,
|
|
100
100
|
pageSize: pagination && pagination.pageSize ? pagination.pageSize : 20
|
|
101
101
|
});
|
|
102
|
+
const isServerPagination = Boolean(pagination && pagination.mode === 'server');
|
|
103
|
+
const shouldUseClientPagination = Boolean(pagination) && !infiniteScroll && !isServerPagination;
|
|
102
104
|
const [columnSizing, setColumnSizing] = _react.default.useState({});
|
|
103
105
|
const [columnSizingInfo, setColumnSizingInfo] = _react.default.useState({});
|
|
104
106
|
|
|
@@ -274,7 +276,10 @@ const InternalTable = props => {
|
|
|
274
276
|
getGroupedRowModel: (0, _reactTable.getGroupedRowModel)(),
|
|
275
277
|
// onExpandedChange: setExpanded,
|
|
276
278
|
getExpandedRowModel: (0, _reactTable.getExpandedRowModel)(),
|
|
277
|
-
|
|
279
|
+
manualPagination: isServerPagination,
|
|
280
|
+
// Chỉ để TanStack tự phân trang khi có pagination, không dùng infinite scroll và đang ở chế độ client.
|
|
281
|
+
// Với server pagination, dữ liệu đã được BE phân trang nên không chạy getPaginationRowModel() để tránh phân trang lần 2.
|
|
282
|
+
getPaginationRowModel: shouldUseClientPagination ? (0, _reactTable.getPaginationRowModel)() : undefined,
|
|
278
283
|
onPaginationChange: setPagination,
|
|
279
284
|
onColumnVisibilityChange: setColumnVisibility
|
|
280
285
|
// onColumnPinningChange,
|
|
@@ -66,6 +66,7 @@ exports.updateColumnWidthsRecursive = updateColumnWidthsRecursive;
|
|
|
66
66
|
exports.updateColumnsByGroup = exports.updateColumns1 = void 0;
|
|
67
67
|
exports.updateOrInsert = updateOrInsert;
|
|
68
68
|
exports.updateWidthsByOther = updateWidthsByOther;
|
|
69
|
+
var _hooks = require("../../grid-component/hooks");
|
|
69
70
|
var _useSelection = require("rc-master-ui/es/table/hooks/useSelection");
|
|
70
71
|
var _uuid = require("uuid");
|
|
71
72
|
var _colors = require("@ant-design/colors");
|
|
@@ -2010,8 +2011,8 @@ function convertColumnsToTreeData(columns, groupColumns) {
|
|
|
2010
2011
|
|
|
2011
2012
|
// Điều kiện filter:
|
|
2012
2013
|
// - Nếu meta.showInColumnChoose = false => loại bỏ
|
|
2013
|
-
// - Nếu
|
|
2014
|
-
if (meta.showInColumnChoose === false) return false;
|
|
2014
|
+
// - Nếu là column đặc biệt (selection_column, #, command...) => loại bỏ
|
|
2015
|
+
if (meta.showInColumnChoose === false || _hooks.nonActionColumn.includes(col.id)) return false;
|
|
2015
2016
|
if (inGroup && !('columns' in col && Array.isArray(col.columns))) {
|
|
2016
2017
|
return false;
|
|
2017
2018
|
}
|
|
@@ -2042,6 +2043,15 @@ const updateColumns1 = (columns, includes) => {
|
|
|
2042
2043
|
if (!column.field) {
|
|
2043
2044
|
return column;
|
|
2044
2045
|
}
|
|
2046
|
+
|
|
2047
|
+
// Bỏ qua column đặc biệt (selection_column, #, command, drag-handle) — giữ nguyên visible
|
|
2048
|
+
// nhưng vẫn phải đệ quy children để không bỏ sót column con
|
|
2049
|
+
if (_hooks.nonActionColumn.includes(newColumn.field)) {
|
|
2050
|
+
if (newColumn.children) {
|
|
2051
|
+
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
2052
|
+
}
|
|
2053
|
+
return newColumn;
|
|
2054
|
+
}
|
|
2045
2055
|
if (newColumn.children) {
|
|
2046
2056
|
newColumn.children = updateColumns1(newColumn.children, includes);
|
|
2047
2057
|
hasVisibleChild = newColumn.children.some(child => !child.hidden);
|
|
@@ -87,6 +87,16 @@ const TableContainer = props => {
|
|
|
87
87
|
} = props;
|
|
88
88
|
const [paginationLocal] = (0, _locale.useLocale)('Pagination');
|
|
89
89
|
const [tableLocal] = (0, _locale.useLocale)('Table');
|
|
90
|
+
const paginationProps = _react.default.useMemo(() => {
|
|
91
|
+
if (!pagination) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const paginationConfig = {
|
|
95
|
+
...pagination
|
|
96
|
+
};
|
|
97
|
+
delete paginationConfig.mode;
|
|
98
|
+
return paginationConfig;
|
|
99
|
+
}, [pagination]);
|
|
90
100
|
const tableContainerRef = _react.default.useRef(null);
|
|
91
101
|
const containerRef = _react.default.useRef(null);
|
|
92
102
|
const bottomToolbarRef = _react.default.useRef(null);
|
|
@@ -218,7 +228,7 @@ const TableContainer = props => {
|
|
|
218
228
|
showTotal: (totalItems, range) =>
|
|
219
229
|
// @ts-ignore
|
|
220
230
|
`${range[0]}-${range[1]} / ${totalItems} ${t ? t(pagination?.locale?.items ?? 'items') : 'items'}`
|
|
221
|
-
},
|
|
231
|
+
}, paginationProps)), typeof actionTemplate === 'function' ? actionTemplate() : actionTemplate, toolbarItemTopRight && /*#__PURE__*/_react.default.createElement("div", {
|
|
222
232
|
style: {
|
|
223
233
|
flex: 1,
|
|
224
234
|
overflow: 'hidden'
|
|
@@ -307,7 +317,7 @@ const TableContainer = props => {
|
|
|
307
317
|
})} / ${(0, _reactNumericComponent.numericFormatter)((totalItems ?? 0).toString(), {
|
|
308
318
|
thousandSeparator: '.'
|
|
309
319
|
})} ${pagination?.locale?.items || paginationLocal?.items || ''}`
|
|
310
|
-
},
|
|
320
|
+
}, paginationProps, {
|
|
311
321
|
onChange: (page, pageSize1) => {
|
|
312
322
|
if (pagination.onChange) {
|
|
313
323
|
pagination.onChange(page, pageSize1);
|