Skip to content

Commit d017661

Browse files
feat(Storage,Nodes): request only needed fields
1 parent a36d40c commit d017661

32 files changed

+281
-133
lines changed

src/components/PaginatedTable/PaginatedTable.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ import {useScrollBasedChunks} from './useScrollBasedChunks';
2323

2424
import './PaginatedTable.scss';
2525

26-
export interface PaginatedTableProps<T, F> {
26+
export interface PaginatedTableProps<EntityType, Filters, DataFieldType> {
2727
limit: number;
2828
initialEntitiesCount?: number;
29-
fetchData: FetchData<T, F>;
30-
filters?: F;
29+
fetchData: FetchData<EntityType, Filters, DataFieldType>;
30+
filters?: Filters;
31+
dataFieldsRequired?: DataFieldType[];
3132
tableName: string;
32-
columns: Column<T>[];
33-
getRowClassName?: GetRowClassName<T>;
33+
columns: Column<EntityType>[];
34+
getRowClassName?: GetRowClassName<EntityType>;
3435
rowHeight?: number;
3536
parentRef?: React.RefObject<HTMLElement>;
3637
initialSortParams?: SortParams;
@@ -41,11 +42,12 @@ export interface PaginatedTableProps<T, F> {
4142
containerClassName?: string;
4243
}
4344

44-
export const PaginatedTable = <T, F>({
45+
export const PaginatedTable = <EntityType, Filters, DataFieldType>({
4546
limit,
4647
initialEntitiesCount,
4748
fetchData,
4849
filters,
50+
dataFieldsRequired,
4951
tableName,
5052
columns,
5153
getRowClassName,
@@ -57,7 +59,7 @@ export const PaginatedTable = <T, F>({
5759
renderErrorMessage,
5860
renderEmptyDataMessage,
5961
containerClassName,
60-
}: PaginatedTableProps<T, F>) => {
62+
}: PaginatedTableProps<EntityType, Filters, DataFieldType>) => {
6163
const initialTotal = initialEntitiesCount || limit;
6264
const initialFound = initialEntitiesCount || 0;
6365

@@ -108,7 +110,7 @@ export const PaginatedTable = <T, F>({
108110
const chunksCount = Math.ceil(totalLength / limit);
109111

110112
return getArray(chunksCount).map((value) => (
111-
<TableChunk<T, F>
113+
<TableChunk<EntityType, Filters, DataFieldType>
112114
key={value}
113115
id={value}
114116
limit={limit}
@@ -117,6 +119,7 @@ export const PaginatedTable = <T, F>({
117119
columns={columns}
118120
fetchData={fetchData}
119121
filters={filters}
122+
dataFieldsRequired={dataFieldsRequired}
120123
tableName={tableName}
121124
sortParams={sortParams}
122125
getRowClassName={getRowClassName}

src/components/PaginatedTable/ResizeablePaginatedTable.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,25 @@ import {PaginatedTable} from './PaginatedTable';
77
import {b} from './shared';
88
import type {Column} from './types';
99

10-
function updateColumnsWidth<T>(columns: Column<T>[], columnsWidthSetup: ColumnWidthByName) {
10+
function updateColumnsWidth<EntityType>(
11+
columns: Column<EntityType>[],
12+
columnsWidthSetup: ColumnWidthByName,
13+
) {
1114
return columns.map((column) => {
1215
return {...column, width: columnsWidthSetup[column.name] ?? column.width};
1316
});
1417
}
1518

16-
interface ResizeablePaginatedTableProps<T, F>
17-
extends Omit<PaginatedTableProps<T, F>, 'onColumnsResize'> {
19+
interface ResizeablePaginatedTableProps<EntityType, Filters, DataFieldType>
20+
extends Omit<PaginatedTableProps<EntityType, Filters, DataFieldType>, 'onColumnsResize'> {
1821
columnsWidthLSKey: string;
1922
}
2023

21-
export function ResizeablePaginatedTable<T, F>({
24+
export function ResizeablePaginatedTable<EntityType, Filters, DataFieldType>({
2225
columnsWidthLSKey,
2326
columns,
2427
...props
25-
}: ResizeablePaginatedTableProps<T, F>) {
28+
}: ResizeablePaginatedTableProps<EntityType, Filters, DataFieldType>) {
2629
const [tableColumnsWidth, setTableColumnsWidth] = useTableResize(columnsWidthLSKey);
2730

2831
const updatedColumns = updateColumnsWidth(columns, tableColumnsWidth);

src/components/PaginatedTable/TableChunk.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,26 @@ import type {Column, FetchData, GetRowClassName, SortParams} from './types';
1111

1212
const DEBOUNCE_TIMEOUT = 200;
1313

14-
interface TableChunkProps<T, F> {
14+
interface TableChunkProps<EntityType, Filters, DataFieldType> {
1515
id: number;
1616
limit: number;
1717
totalLength: number;
1818
rowHeight: number;
19-
columns: Column<T>[];
20-
filters?: F;
19+
columns: Column<EntityType>[];
20+
filters?: Filters;
21+
dataFieldsRequired?: DataFieldType[];
2122
sortParams?: SortParams;
2223
isActive: boolean;
2324
tableName: string;
2425

25-
fetchData: FetchData<T, F>;
26-
getRowClassName?: GetRowClassName<T>;
26+
fetchData: FetchData<EntityType, Filters, DataFieldType>;
27+
getRowClassName?: GetRowClassName<EntityType>;
2728
renderErrorMessage?: (error: IResponseError) => React.ReactNode;
2829
onDataFetched: (total: number, found: number) => void;
2930
}
3031

3132
// Memoisation prevents chunks rerenders that could cause perfomance issues on big tables
32-
export const TableChunk = <T, F>({
33+
export const TableChunk = <EntityType, Filters, DataFieldType>({
3334
id,
3435
limit,
3536
totalLength,
@@ -38,20 +39,22 @@ export const TableChunk = <T, F>({
3839
fetchData,
3940
tableName,
4041
filters,
42+
dataFieldsRequired,
4143
sortParams,
4244
getRowClassName,
4345
renderErrorMessage,
4446
onDataFetched,
4547
isActive,
46-
}: TableChunkProps<T, F>) => {
48+
}: TableChunkProps<EntityType, Filters, DataFieldType>) => {
4749
const [isTimeoutActive, setIsTimeoutActive] = React.useState(true);
4850
const [autoRefreshInterval] = useAutoRefreshInterval();
4951

5052
const queryParams = {
5153
offset: id * limit,
5254
limit,
53-
fetchData: fetchData as FetchData<T, unknown>,
55+
fetchData: fetchData as FetchData<EntityType, unknown, unknown>,
5456
filters,
57+
dataFieldsRequired,
5558
sortParams,
5659
tableName,
5760
};
@@ -123,7 +126,7 @@ export const TableChunk = <T, F>({
123126
<TableRow
124127
key={index}
125128
index={index}
126-
row={rowData as T}
129+
row={rowData as EntityType}
127130
columns={columns}
128131
height={rowHeight}
129132
getRowClassName={getRowClassName}

src/components/PaginatedTable/types.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import type {IResponseError} from '../../types/api/error';
22

33
import type {ASCENDING, CENTER, DESCENDING, LEFT, RIGHT} from './constants';
44

5-
export interface Chunk<T> {
5+
export interface Chunk<EntityType> {
66
active: boolean;
77
loading: boolean;
88
wasLoaded: boolean;
9-
data?: T[];
9+
data?: EntityType[];
1010
error?: IResponseError;
1111
}
1212

@@ -23,36 +23,42 @@ export type OnSort = (params: SortParams) => void;
2323

2424
export type HandleTableColumnsResize = (columnId: string, width: number) => void;
2525

26-
export interface Column<T> {
26+
export interface Column<EntityType> {
2727
name: string;
2828
header?: React.ReactNode;
2929
className?: string;
3030
sortable?: boolean;
3131
resizeable?: boolean;
32-
render: (props: {row: T; index: number}) => React.ReactNode;
32+
render: (props: {row: EntityType; index: number}) => React.ReactNode;
3333
width?: number;
3434
resizeMaxWidth?: number;
3535
resizeMinWidth?: number;
3636
align: AlignType;
3737
}
3838

39-
export interface PaginatedTableData<T> {
40-
data: T[];
39+
export interface PaginatedTableData<EntityType> {
40+
data: EntityType[];
4141
total: number;
4242
found: number;
4343
}
4444

45-
type FetchDataParams<F, E = {}> = {
45+
type FetchDataParams<Filters, DataFieldType = undefined, AdditionalParams = {}> = {
4646
limit: number;
4747
offset: number;
48-
filters?: F;
48+
filters?: Filters;
49+
dataFieldsRequired?: DataFieldType[];
4950
sortParams?: SortParams;
5051
signal?: AbortSignal;
51-
} & E;
52+
} & AdditionalParams;
5253

53-
export type FetchData<T, F = undefined, E = {}> = (
54-
params: FetchDataParams<F, E>,
55-
) => Promise<PaginatedTableData<T>>;
54+
export type FetchData<
55+
EntityType,
56+
Filters = undefined,
57+
DataFieldType = undefined,
58+
AdditionalParams = {},
59+
> = (
60+
params: FetchDataParams<Filters, DataFieldType, AdditionalParams>,
61+
) => Promise<PaginatedTableData<EntityType>>;
5662

5763
export type OnError = (error?: IResponseError) => void;
5864

@@ -66,4 +72,4 @@ export type RenderControls = (params: ControlsParams) => React.ReactNode;
6672
export type RenderEmptyDataMessage = () => React.ReactNode;
6773
export type RenderErrorMessage = (error: IResponseError) => React.ReactNode;
6874

69-
export type GetRowClassName<T> = (row: T) => string | undefined;
75+
export type GetRowClassName<EntityType> = (row: EntityType) => string | undefined;

src/components/nodesColumns/columns.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {valueIsDefined} from '../../utils';
77
import {EMPTY_DATA_PLACEHOLDER} from '../../utils/constants';
88
import {formatStorageValuesToGb} from '../../utils/dataFormatters/dataFormatters';
99
import {getSpaceUsageSeverity} from '../../utils/storage';
10+
import type {Column} from '../../utils/tableUtils/types';
1011
import {CellWithPopover} from '../CellWithPopover/CellWithPopover';
1112
import {NodeHostWrapper} from '../NodeHostWrapper/NodeHostWrapper';
1213
import type {NodeHostData} from '../NodeHostWrapper/NodeHostWrapper';
@@ -16,7 +17,7 @@ import {TabletsStatistic} from '../TabletsStatistic';
1617
import {UsageLabel} from '../UsageLabel/UsageLabel';
1718

1819
import {NODES_COLUMNS_IDS, NODES_COLUMNS_TITLES} from './constants';
19-
import type {Column, GetNodesColumnsParams} from './types';
20+
import type {GetNodesColumnsParams} from './types';
2021

2122
export function getNodeIdColumn<T extends {NodeId?: string | number}>(): Column<T> {
2223
return {

src/components/nodesColumns/constants.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type {NodesRequiredField} from '../../types/api/nodes';
12
import type {ValueOf} from '../../types/common';
23

34
import i18n from './i18n';
@@ -21,6 +22,7 @@ export const NODES_COLUMNS_IDS = {
2122
TotalSessions: 'TotalSessions',
2223
Missing: 'Missing',
2324
Tablets: 'Tablets',
25+
PDisks: 'PDisks',
2426
} as const;
2527

2628
export type NodesColumnId = ValueOf<typeof NODES_COLUMNS_IDS>;
@@ -76,4 +78,29 @@ export const NODES_COLUMNS_TITLES = {
7678
get Tablets() {
7779
return i18n('tablets');
7880
},
81+
get PDisks() {
82+
return i18n('pdisks');
83+
},
7984
} as const satisfies Record<NodesColumnId, string>;
85+
86+
// Although columns ids mostly similar to backend fields, there might be some difference
87+
// Also for some columns we may use more than one field
88+
export const NODES_COLUMNS_TO_DATA_FIELDS: Record<NodesColumnId, NodesRequiredField[]> = {
89+
NodeId: ['NodeId'],
90+
Host: ['Host', 'Rack', 'Database', 'SystemState'],
91+
NodeName: ['NodeName'],
92+
DC: ['DC'],
93+
Rack: ['Rack'],
94+
Version: ['Version'],
95+
Uptime: ['Uptime'],
96+
Memory: ['Memory'],
97+
CPU: ['CPU'],
98+
LoadAverage: ['LoadAverage'],
99+
Load: ['LoadAverage'],
100+
DiskSpaceUsage: ['DiskSpaceUsage'],
101+
SharedCacheUsage: ['SystemState'],
102+
TotalSessions: ['SystemState'],
103+
Missing: ['Missing'],
104+
Tablets: ['Tablets', 'Database'],
105+
PDisks: ['PDisks'],
106+
};

src/components/nodesColumns/i18n/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@
1414
"load": "Load",
1515
"caches": "Caches",
1616
"sessions": "Sessions",
17-
"missing": "Missing"
17+
"missing": "Missing",
18+
"pdisks": "PDisks"
1819
}

src/components/nodesColumns/types.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
import type {Column as DataTableColumn} from '@gravity-ui/react-data-table';
2-
31
import type {GetNodeRefFunc} from '../../types/additionalProps';
4-
import type {Column as PaginatedTableColumn} from '../PaginatedTable';
5-
6-
export type Column<T> = PaginatedTableColumn<T> & DataTableColumn<T>;
72

83
export interface GetNodesColumnsParams {
94
getNodeRef?: GetNodeRefFunc;

src/containers/Nodes/PaginatedNodes.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,11 @@ export const PaginatedNodes = ({path, database, parentRef, additionalNodesProps}
6464
return {path, database, searchValue, problemFilter, uptimeFilter};
6565
}, [path, database, searchValue, problemFilter, uptimeFilter]);
6666

67-
const {columnsToShow, columnsToSelect, setColumns} = useNodesSelectedColumns({
68-
getNodeRef: additionalNodesProps?.getNodeRef,
69-
database,
70-
});
67+
const {columnsToShow, columnsToSelect, setColumns, dataFieldsRequired} =
68+
useNodesSelectedColumns({
69+
getNodeRef: additionalNodesProps?.getNodeRef,
70+
database,
71+
});
7172

7273
const getRowClassName: GetRowClassName<NodesPreparedEntity> = (row) => {
7374
return b('node', {unavailable: isUnavailableNode(row)});
@@ -144,6 +145,7 @@ export const PaginatedNodes = ({path, database, parentRef, additionalNodesProps}
144145
renderEmptyDataMessage={renderEmptyDataMessage}
145146
getRowClassName={getRowClassName}
146147
filters={tableFilters}
148+
dataFieldsRequired={dataFieldsRequired}
147149
tableName="nodes"
148150
/>
149151
);

src/containers/Nodes/columns/columns.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import {
1111
getUptimeColumn,
1212
getVersionColumn,
1313
} from '../../../components/nodesColumns/columns';
14-
import type {Column, GetNodesColumnsParams} from '../../../components/nodesColumns/types';
14+
import type {GetNodesColumnsParams} from '../../../components/nodesColumns/types';
1515
import type {NodesPreparedEntity} from '../../../store/reducers/nodes/types';
1616
import {isSortableNodesProperty} from '../../../utils/nodes';
17+
import type {Column} from '../../../utils/tableUtils/types';
1718

1819
export function getNodesColumns(params: GetNodesColumnsParams): Column<NodesPreparedEntity>[] {
1920
const columns = [

src/containers/Nodes/columns/hooks.ts

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

3-
import {NODES_COLUMNS_TITLES} from '../../../components/nodesColumns/constants';
3+
import {
4+
NODES_COLUMNS_TITLES,
5+
NODES_COLUMNS_TO_DATA_FIELDS,
6+
} from '../../../components/nodesColumns/constants';
47
import type {GetNodesColumnsParams} from '../../../components/nodesColumns/types';
58
import {useSelectedColumns} from '../../../utils/hooks/useSelectedColumns';
9+
import {getRequiredDataFields} from '../../../utils/tableUtils/getRequiredDataFields';
610

711
import {getNodesColumns} from './columns';
812
import {
@@ -16,11 +20,22 @@ export function useNodesSelectedColumns(params: GetNodesColumnsParams) {
1620
return getNodesColumns(params);
1721
}, [params]);
1822

19-
return useSelectedColumns(
23+
const {columnsToSelect, columnsToShow, setColumns} = useSelectedColumns(
2024
columns,
2125
NODES_TABLE_SELECTED_COLUMNS_LS_KEY,
2226
NODES_COLUMNS_TITLES,
2327
DEFAULT_NODES_COLUMNS,
2428
REQUIRED_NODES_COLUMNS,
2529
);
30+
31+
const dataFieldsRequired = React.useMemo(() => {
32+
return getRequiredDataFields(columnsToShow, NODES_COLUMNS_TO_DATA_FIELDS);
33+
}, [columnsToShow]);
34+
35+
return {
36+
columnsToSelect,
37+
columnsToShow,
38+
setColumns,
39+
dataFieldsRequired,
40+
};
2641
}

0 commit comments

Comments
 (0)