Skip to content

Commit d5905f0

Browse files
CopilotRaubzeug
andcommitted
Refactor VDisk tablets table to use project patterns with ResizeableDataTable
Co-authored-by: Raubzeug <[email protected]>
1 parent 246d95c commit d5905f0

File tree

2 files changed

+52
-97
lines changed

2 files changed

+52
-97
lines changed

src/containers/VDiskPage/VDiskTablets/VDiskTablets.tsx

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
11
import React from 'react';
22

3-
import {useTable} from '@gravity-ui/table';
3+
import type {Column} from '@gravity-ui/react-data-table';
4+
import DataTable from '@gravity-ui/react-data-table';
45
import {skipToken} from '@reduxjs/toolkit/query';
5-
import type {SortingState} from '@tanstack/react-table';
66

77
import {InfoViewerSkeleton} from '../../../components/InfoViewerSkeleton/InfoViewerSkeleton';
8-
import {Table} from '../../../components/Table/Table';
8+
import {ResizeableDataTable} from '../../../components/ResizeableDataTable/ResizeableDataTable';
99
import {vDiskApi} from '../../../store/reducers/vdisk/vdisk';
1010
import type {VDiskBlobIndexItem} from '../../../types/api/vdiskBlobIndex';
1111
import {cn} from '../../../utils/cn';
1212
import {useAutoRefreshInterval} from '../../../utils/hooks';
1313

1414
import {getColumns} from './columns';
15+
import {vDiskPageKeyset} from '../i18n';
1516

1617
import './VDiskTablets.scss';
1718

1819
const vDiskTabletsCn = cn('ydb-vdisk-tablets');
20+
const VDISK_TABLETS_COLUMNS_WIDTH_LS_KEY = 'vdiskTabletsColumnsWidth';
21+
22+
const TABLE_SETTINGS = {
23+
displayIndices: false,
24+
highlightRows: true,
25+
stickyHead: DataTable.MOVING,
26+
};
1927

2028
interface VDiskTabletsProps {
2129
nodeId?: string | number;
@@ -26,9 +34,6 @@ interface VDiskTabletsProps {
2634

2735
export function VDiskTablets({nodeId, pDiskId, vDiskSlotId, className}: VDiskTabletsProps) {
2836
const [autoRefreshInterval] = useAutoRefreshInterval();
29-
const [sorting, setSorting] = React.useState<SortingState>([
30-
{id: 'Size', desc: true}, // Default sort by size descending
31-
]);
3237

3338
const params = nodeId && pDiskId && vDiskSlotId ? {nodeId, pDiskId, vDiskSlotId} : skipToken;
3439

@@ -38,19 +43,14 @@ export function VDiskTablets({nodeId, pDiskId, vDiskSlotId, className}: VDiskTab
3843

3944
const loading = isFetching && currentData === undefined;
4045

41-
// Remove the manual sorting since we'll let the table handle it with enableSorting
4246
const tableData: VDiskBlobIndexItem[] = React.useMemo(() => {
4347
if (!currentData) {
4448
return [];
4549
}
4650

47-
// Debug: Log the actual response structure
48-
console.info('VDisk BlobIndexStat Response:', currentData);
49-
5051
// Check if we have the expected structure: {stat: {tablets: [...]}}
5152
const stat = currentData.stat;
5253
if (!stat || !Array.isArray(stat.tablets)) {
53-
console.info('No stat.tablets array found in response');
5454
return [];
5555
}
5656

@@ -76,24 +76,11 @@ export function VDiskTablets({nodeId, pDiskId, vDiskSlotId, className}: VDiskTab
7676
});
7777
});
7878

79-
console.info('Transformed data:', flatData);
8079
return flatData;
8180
}, [currentData]);
8281

8382
const columns = React.useMemo(() => getColumns(), []);
8483

85-
const table = useTable({
86-
columns,
87-
data: tableData,
88-
enableSorting: true,
89-
enableColumnResizing: true,
90-
columnResizeMode: 'onChange',
91-
onSortingChange: setSorting,
92-
state: {
93-
sorting,
94-
},
95-
});
96-
9784
if (error) {
9885
return (
9986
<div className={vDiskTabletsCn('error', className)}>
@@ -108,7 +95,17 @@ export function VDiskTablets({nodeId, pDiskId, vDiskSlotId, className}: VDiskTab
10895

10996
return (
11097
<div className={vDiskTabletsCn(null, className)}>
111-
<Table table={table} stickyHeader width="max" />
98+
<ResizeableDataTable
99+
columnsWidthLSKey={VDISK_TABLETS_COLUMNS_WIDTH_LS_KEY}
100+
data={tableData}
101+
columns={columns}
102+
settings={TABLE_SETTINGS}
103+
loading={loading}
104+
initialSortOrder={{
105+
columnId: vDiskPageKeyset('size'),
106+
order: DataTable.DESCENDING,
107+
}}
108+
/>
112109
</div>
113110
);
114111
}
Lines changed: 30 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,47 @@
1-
import type {CellContext, ColumnDef} from '@tanstack/react-table';
1+
import type {Column} from '@gravity-ui/react-data-table';
2+
import DataTable from '@gravity-ui/react-data-table';
23

34
import {InternalLink} from '../../../components/InternalLink/InternalLink';
4-
import {ColumnHeader} from '../../../components/Table/Table';
55
import {getTabletPagePath} from '../../../routes';
66
import type {VDiskBlobIndexItem} from '../../../types/api/vdiskBlobIndex';
7-
import {cn} from '../../../utils/cn';
87
import {formatBytes} from '../../../utils/dataFormatters/dataFormatters';
98
import {vDiskPageKeyset} from '../i18n';
109

11-
const b = cn('ydb-vdisk-tablets');
12-
13-
function TabletIdCell({row}: CellContext<VDiskBlobIndexItem, unknown>) {
14-
const item = row.original;
15-
const tabletId = item.TabletId || item.tabletId;
16-
17-
if (!tabletId) {
18-
return <span>-</span>;
19-
}
20-
21-
return <InternalLink to={getTabletPagePath(String(tabletId))}>{tabletId}</InternalLink>;
22-
}
23-
24-
function MetricsCell({row, column}: CellContext<VDiskBlobIndexItem, unknown>) {
25-
const item = row.original;
26-
const fieldName = column.id;
27-
28-
// Handle both PascalCase and camelCase field names
29-
let value;
30-
if (fieldName === 'ChannelId') {
31-
value = item.ChannelId ?? item.channelId;
32-
} else if (fieldName === 'Count') {
33-
value = item.Count ?? item.count;
34-
} else {
35-
value = item[fieldName];
36-
}
37-
38-
return <span className={b('metrics-cell')}>{value ?? '-'}</span>;
39-
}
40-
41-
function SizeCell({row}: CellContext<VDiskBlobIndexItem, unknown>) {
42-
const item = row.original;
43-
const size = item.Size ?? item.size;
44-
const numericSize = Number(size) || 0;
45-
return <span className={b('size-cell')}>{formatBytes(numericSize)}</span>;
46-
}
47-
48-
export function getColumns() {
49-
const columns: ColumnDef<VDiskBlobIndexItem>[] = [
10+
export function getColumns(): Column<VDiskBlobIndexItem>[] {
11+
return [
5012
{
51-
accessorKey: 'TabletId',
52-
header: () => <ColumnHeader>{vDiskPageKeyset('tablet-id')}</ColumnHeader>,
53-
size: 150,
54-
minSize: 100,
55-
cell: TabletIdCell,
56-
enableSorting: true,
13+
name: vDiskPageKeyset('tablet-id'),
14+
render: ({row}) => {
15+
const tabletId = row.TabletId;
16+
if (!tabletId) {
17+
return <span>-</span>;
18+
}
19+
return <InternalLink to={getTabletPagePath(String(tabletId))}>{tabletId}</InternalLink>;
20+
},
21+
width: 150,
5722
},
5823
{
59-
accessorKey: 'ChannelId',
60-
header: () => <ColumnHeader>{vDiskPageKeyset('channel-id')}</ColumnHeader>,
61-
size: 100,
62-
minSize: 80,
63-
cell: MetricsCell,
64-
meta: {align: 'right'},
65-
enableSorting: true,
24+
name: vDiskPageKeyset('channel-id'),
25+
align: DataTable.RIGHT,
26+
render: ({row}) => row.ChannelId ?? '-',
27+
width: 100,
6628
},
6729
{
68-
accessorKey: 'Count',
69-
header: () => <ColumnHeader>{vDiskPageKeyset('count')}</ColumnHeader>,
70-
size: 100,
71-
minSize: 80,
72-
cell: MetricsCell,
73-
meta: {align: 'right'},
74-
enableSorting: true,
30+
name: vDiskPageKeyset('count'),
31+
align: DataTable.RIGHT,
32+
render: ({row}) => row.Count ?? '-',
33+
width: 100,
7534
},
7635
{
77-
accessorKey: 'Size',
78-
header: () => <ColumnHeader>{vDiskPageKeyset('size')}</ColumnHeader>,
79-
size: 120,
80-
minSize: 100,
81-
cell: SizeCell,
82-
meta: {align: 'right'},
83-
enableSorting: true,
84-
sortingFn: 'basic', // Use basic sorting for numeric values
36+
name: vDiskPageKeyset('size'),
37+
align: DataTable.RIGHT,
38+
render: ({row}) => {
39+
const size = row.Size;
40+
const numericSize = Number(size) || 0;
41+
return formatBytes(numericSize);
42+
},
43+
width: 120,
44+
sortAccessor: (row) => row.Size || 0,
8545
},
8646
];
87-
88-
return columns;
8947
}

0 commit comments

Comments
 (0)