Skip to content

Commit 99ddaab

Browse files
committed
fix: real virtualization
1 parent db4bda6 commit 99ddaab

File tree

3 files changed

+35
-68
lines changed

3 files changed

+35
-68
lines changed

src/components/PaginatedTable/TableChunk.tsx

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {getArray} from '../../utils';
66
import {useAutoRefreshInterval} from '../../utils/hooks';
77
import {ResponseError} from '../Errors/ResponseError';
88

9-
import {EmptyTableRow, LoadingTableRow, TableRow} from './TableRow';
9+
import {EmptyTableRow, TableRow} from './TableRow';
1010
import i18n from './i18n';
1111
import type {
1212
Column,
@@ -117,40 +117,31 @@ export const TableChunk = typedMemo(function TableChunk<T, F>({
117117
return null;
118118
}
119119

120-
if (!currentData) {
121-
if (error) {
122-
const errorData = error as IResponseError;
123-
return (
124-
<EmptyTableRow columns={columns}>
125-
{renderErrorMessage ? (
126-
renderErrorMessage(errorData)
127-
) : (
128-
<ResponseError error={errorData} />
129-
)}
130-
</EmptyTableRow>
131-
);
132-
} else {
133-
return getArray(dataLength).map((value) => (
134-
<LoadingTableRow
135-
key={value}
136-
columns={columns}
137-
height={rowHeight}
138-
isVisible={isRowVisible(value)}
139-
/>
140-
));
141-
}
120+
if (!currentData && error) {
121+
const errorData = error as IResponseError;
122+
return (
123+
<EmptyTableRow columns={columns}>
124+
{renderErrorMessage ? (
125+
renderErrorMessage(errorData)
126+
) : (
127+
<ResponseError error={errorData} />
128+
)}
129+
</EmptyTableRow>
130+
);
142131
}
143132

144133
// Data is loaded, but there are no entities in the chunk
145-
if (!currentData.data?.length) {
134+
if (currentData?.data && !currentData.data?.length) {
146135
return (
147136
<EmptyTableRow columns={columns}>
148137
{renderEmptyDataMessage ? renderEmptyDataMessage() : i18n('empty')}
149138
</EmptyTableRow>
150139
);
151140
}
152141

153-
return currentData.data.map((rowData, index) => (
142+
const data = currentData?.data || getArray(dataLength);
143+
144+
return data.map((rowData, index) => (
154145
<TableRow
155146
key={index}
156147
row={rowData as T}

src/components/PaginatedTable/TableRow.tsx

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import React from 'react';
2+
13
import {Skeleton} from '@gravity-ui/uikit';
24

35
import {DEFAULT_ALIGN, DEFAULT_RESIZEABLE} from './constants';
@@ -37,57 +39,27 @@ const TableRowCell = ({
3739
);
3840
};
3941

40-
interface LoadingTableRowProps<T> {
41-
columns: Column<T>[];
42-
height: number;
43-
}
44-
4542
interface VisibilityProps {
4643
isVisible?: boolean;
4744
}
4845

49-
export const LoadingTableRow = typedMemo(function <T>({
50-
columns,
51-
height,
52-
isVisible = true,
53-
}: LoadingTableRowProps<T> & VisibilityProps) {
54-
return (
55-
<tr className={b('row', {loading: true})}>
56-
{columns.map((column) => {
57-
const resizeable = column.resizeable ?? DEFAULT_RESIZEABLE;
58-
59-
return (
60-
<TableRowCell
61-
key={column.name}
62-
height={height}
63-
width={column.width}
64-
align={column.align}
65-
className={column.className}
66-
resizeable={resizeable}
67-
>
68-
{isVisible ? (
69-
<Skeleton
70-
className={b('row-skeleton')}
71-
style={{width: '80%', height: '50%'}}
72-
/>
73-
) : null}
74-
</TableRowCell>
75-
);
76-
})}
77-
</tr>
78-
);
79-
});
80-
8146
interface TableRowColumnProps<T> {
8247
column: Column<T>;
83-
row: T;
48+
row?: T;
8449
height: number;
8550
}
8651

8752
export const TableRowColumn = typedMemo(
8853
<T,>({row, column, height, isVisible = true}: TableRowColumnProps<T> & VisibilityProps) => {
8954
const resizeable = column.resizeable ?? DEFAULT_RESIZEABLE;
9055

56+
const renderedCell = React.useMemo(() => {
57+
if (row) {
58+
return column.render({row});
59+
}
60+
return null;
61+
}, [column, row]);
62+
9163
return (
9264
<TableRowCell
9365
key={column.name}
@@ -97,15 +69,19 @@ export const TableRowColumn = typedMemo(
9769
className={column.className}
9870
resizeable={resizeable}
9971
>
100-
{isVisible ? column.render({row}) : null}
72+
{isVisible && row ? (
73+
renderedCell
74+
) : (
75+
<Skeleton className={b('row-skeleton')} style={{width: '80%', height: '50%'}} />
76+
)}
10177
</TableRowCell>
10278
);
10379
},
10480
);
10581

10682
interface TableRowProps<T> {
10783
columns: Column<T>[];
108-
row: T;
84+
row?: T;
10985
height: number;
11086
getRowClassName?: GetRowClassName<T>;
11187
}
@@ -117,7 +93,7 @@ export const TableRow = <T,>({
11793
height,
11894
isVisible = true,
11995
}: TableRowProps<T> & VisibilityProps) => {
120-
const additionalClassName = getRowClassName?.(row);
96+
const additionalClassName = row ? getRowClassName?.(row) : undefined;
12197

12298
return (
12399
<tr className={b('row', additionalClassName)}>

src/utils/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
export const getArray = (arrayLength: number) => {
2-
return [...Array(arrayLength).keys()];
1+
export const getArray = (arrayLength: number): undefined[] => {
2+
return Array.from({length: arrayLength});
33
};
44

55
export function valueIsDefined<T>(value: T | null | undefined): value is T {

0 commit comments

Comments
 (0)