Skip to content

Commit e107cdb

Browse files
fix(ResizeableDataTable): rework loading state
1 parent 351dbfb commit e107cdb

File tree

4 files changed

+50
-20
lines changed

4 files changed

+50
-20
lines changed

src/components/ResizeableDataTable/ResizeableDataTable.tsx

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

3-
import type {Column, DataTableProps, Settings, SortOrder} from '@gravity-ui/react-data-table';
3+
import type {Column, DataTableProps, SortOrder} from '@gravity-ui/react-data-table';
44
import DataTable, {updateColumnsWidth} from '@gravity-ui/react-data-table';
55
import {Skeleton} from '@gravity-ui/uikit';
66

77
import {cn} from '../../utils/cn';
88
import {useTableResize} from '../../utils/hooks/useTableResize';
9+
import {TableSkeleton} from '../TableSkeleton/TableSkeleton';
910

1011
import './ResizeableDataTable.scss';
1112

@@ -14,7 +15,19 @@ const b = cn('ydb-resizeable-data-table');
1415
export interface ResizeableDataTableProps<T> extends Omit<DataTableProps<T>, 'theme' | 'onResize'> {
1516
columnsWidthLSKey?: string;
1617
wrapperClassName?: string;
17-
loading?: boolean;
18+
19+
/**
20+
* Not enough meta data (settings, sizes, features, etc.) to properly render table columns
21+
* Use case: initial load
22+
*/
23+
isLoading?: boolean;
24+
/**
25+
* No table data, but columns data is loaded and they could be rendered
26+
* Use case: you need to preserve table headers on sort change when backend sort
27+
*/
28+
isFetching?: boolean;
29+
loadingSkeletonRowsCount?: number;
30+
1831
onSortChange?: (params: SortOrder | SortOrder[] | undefined) => void;
1932
}
2033

@@ -23,9 +36,12 @@ export function ResizeableDataTable<T>({
2336
columns,
2437
settings,
2538
wrapperClassName,
26-
loading,
39+
isLoading,
40+
isFetching,
41+
loadingSkeletonRowsCount = 2,
2742
onSort,
2843
onSortChange,
44+
data,
2945
...props
3046
}: ResizeableDataTableProps<T>) {
3147
const [tableColumnsWidth, setTableColumnsWidth] = useTableResize(columnsWidthLSKey);
@@ -39,19 +55,36 @@ export function ResizeableDataTable<T>({
3955
);
4056

4157
// If loading is true, override the render method of each column to display a Skeleton
42-
const processedColumns = loading
43-
? columns.map((column: Column<T>) => ({
44-
...column,
45-
render: () => <Skeleton className={b('row-skeleton')} />,
46-
}))
47-
: columns;
58+
const processedColumns = React.useMemo(() => {
59+
if (isFetching) {
60+
return columns.map((column: Column<T>) => ({
61+
...column,
62+
render: () => <Skeleton className={b('row-skeleton')} />,
63+
}));
64+
}
65+
return columns;
66+
}, [isFetching, columns]);
4867

4968
const updatedColumns = updateColumnsWidth(processedColumns, tableColumnsWidth);
5069

51-
const newSettings: Settings = {
52-
...settings,
53-
defaultResizeable: true,
54-
};
70+
const processedData = React.useMemo(() => {
71+
if (isFetching && !data?.length) {
72+
// We do not use data in render method when loading, so we can return an array of empty objects
73+
return Array(loadingSkeletonRowsCount).fill({}) as T[];
74+
}
75+
return data;
76+
}, [isFetching, data, loadingSkeletonRowsCount]);
77+
78+
const newSettings = React.useMemo(() => {
79+
return {
80+
...settings,
81+
defaultResizeable: true,
82+
};
83+
}, [settings]);
84+
85+
if (isLoading) {
86+
return <TableSkeleton rows={loadingSkeletonRowsCount} />;
87+
}
5588

5689
return (
5790
<div className={b(null, wrapperClassName)}>
@@ -61,6 +94,7 @@ export function ResizeableDataTable<T>({
6194
onResize={setTableColumnsWidth}
6295
onSort={handleSort}
6396
settings={newSettings}
97+
data={processedData}
6498
{...props}
6599
/>
66100
</div>

src/containers/Node/Threads/Threads.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export function Threads({nodeId, className, scrollContainerRef}: ThreadsProps) {
3737
columns={columns}
3838
settings={DEFAULT_TABLE_SETTINGS}
3939
emptyDataMessage={i18n('alert_no-thread-data')}
40-
loading={isLoading}
40+
isLoading={isLoading}
4141
/>
4242
</TableWithControlsLayout.Table>
4343
</TableWithControlsLayout>

src/containers/Tenant/Diagnostics/Partitions/Partitions.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {skipToken} from '@reduxjs/toolkit/query';
55
import {ResponseError} from '../../../../components/Errors/ResponseError';
66
import {ResizeableDataTable} from '../../../../components/ResizeableDataTable/ResizeableDataTable';
77
import {TableColumnSetup} from '../../../../components/TableColumnSetup/TableColumnSetup';
8-
import {TableSkeleton} from '../../../../components/TableSkeleton/TableSkeleton';
98
import {TableWithControlsLayout} from '../../../../components/TableWithControlsLayout/TableWithControlsLayout';
109
import {nodesListApi, selectNodesMap} from '../../../../store/reducers/nodesList';
1110
import {partitionsApi, setSelectedConsumer} from '../../../../store/reducers/partitions/partitions';
@@ -112,16 +111,13 @@ export const Partitions = ({path, database, databaseFullPath}: PartitionsProps)
112111
};
113112

114113
const renderContent = () => {
115-
if (loading) {
116-
return <TableSkeleton className={b('loader')} />;
117-
}
118-
119114
return (
120115
<ResizeableDataTable
121116
columnsWidthLSKey={PARTITIONS_COLUMNS_WIDTH_LS_KEY}
122117
wrapperClassName={b('table')}
123118
data={partitionsToRender}
124119
columns={columnsToShow}
120+
isLoading={loading}
125121
settings={DEFAULT_TABLE_SETTINGS}
126122
emptyDataMessage={i18n('table.emptyDataMessage')}
127123
/>

src/containers/Tenant/Diagnostics/TopQueries/QueriesTableWithDrawer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export function QueriesTableWithDrawer({
104104
columnsWidthLSKey={columnsWidthLSKey}
105105
columns={columns}
106106
data={data}
107-
loading={loading}
107+
isFetching={loading}
108108
settings={tableSettings}
109109
onRowClick={handleRowClick}
110110
rowClassName={(row) => b('row', {active: isEqual(row, selectedRow)})}

0 commit comments

Comments
 (0)