Skip to content

Commit 5d2f295

Browse files
committed
fix: count pdisk-vdisk column width for skeletons
1 parent 714e7c7 commit 5d2f295

File tree

11 files changed

+152
-37
lines changed

11 files changed

+152
-37
lines changed

src/components/PaginatedTable/PaginatedTable.tsx

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
FetchData,
1212
GetRowClassName,
1313
HandleTableColumnsResize,
14+
PaginatedTableData,
1415
RenderControls,
1516
RenderEmptyDataMessage,
1617
RenderErrorMessage,
@@ -36,6 +37,8 @@ export interface PaginatedTableProps<T, F> {
3637
renderEmptyDataMessage?: RenderEmptyDataMessage;
3738
renderErrorMessage?: RenderErrorMessage;
3839
containerClassName?: string;
40+
tableStyle?: React.CSSProperties;
41+
onDataFetched?: (data: PaginatedTableData<T>) => void;
3942
}
4043

4144
const DEFAULT_PAGINATION_LIMIT = 20;
@@ -56,6 +59,8 @@ export const PaginatedTable = <T, F>({
5659
renderErrorMessage,
5760
renderEmptyDataMessage,
5861
containerClassName,
62+
tableStyle,
63+
onDataFetched,
5964
}: PaginatedTableProps<T, F>) => {
6065
const initialTotal = initialEntitiesCount || 0;
6166
const initialFound = initialEntitiesCount || 1;
@@ -84,11 +89,17 @@ export const PaginatedTable = <T, F>({
8489
return foundEntities % chunkSize || chunkSize;
8590
}, [foundEntities, chunkSize]);
8691

87-
const handleDataFetched = React.useCallback((total: number, found: number) => {
88-
setTotalEntities(total);
89-
setFoundEntities(found);
90-
setIsInitialLoad(false);
91-
}, []);
92+
const handleDataFetched = React.useCallback(
93+
(data?: PaginatedTableData<T>) => {
94+
if (data) {
95+
setTotalEntities(data.total);
96+
setFoundEntities(data.found);
97+
setIsInitialLoad(false);
98+
onDataFetched?.(data);
99+
}
100+
},
101+
[onDataFetched],
102+
);
92103

93104
// reset table on filters change
94105
React.useLayoutEffect(() => {
@@ -145,7 +156,7 @@ export const PaginatedTable = <T, F>({
145156
};
146157

147158
return (
148-
<div ref={tableRef} className={b(null, containerClassName)}>
159+
<div ref={tableRef} className={b(null, containerClassName)} style={tableStyle}>
149160
{renderContent()}
150161
</div>
151162
);

src/components/PaginatedTable/ResizeablePaginatedTable.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ function updateColumnsWidth<T>(columns: Column<T>[], columnsWidthSetup: ColumnWi
1616
interface ResizeablePaginatedTableProps<T, F>
1717
extends Omit<PaginatedTableProps<T, F>, 'onColumnsResize'> {
1818
columnsWidthLSKey: string;
19+
tableStyle?: React.CSSProperties;
1920
}
2021

2122
export function ResizeablePaginatedTable<T, F>({

src/components/PaginatedTable/TableChunk.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
Column,
1313
FetchData,
1414
GetRowClassName,
15+
PaginatedTableData,
1516
RenderEmptyDataMessage,
1617
RenderErrorMessage,
1718
SortParams,
@@ -35,7 +36,7 @@ interface TableChunkProps<T, F> {
3536
getRowClassName?: GetRowClassName<T>;
3637
renderErrorMessage?: RenderErrorMessage;
3738
renderEmptyDataMessage?: RenderEmptyDataMessage;
38-
onDataFetched: (total: number, found: number) => void;
39+
onDataFetched: (data?: PaginatedTableData<T>) => void;
3940
}
4041

4142
// Memoisation prevents chunks rerenders that could cause perfomance issues on big tables
@@ -93,8 +94,12 @@ export const TableChunk = typedMemo(function TableChunk<T, F>({
9394

9495
React.useEffect(() => {
9596
if (currentData && isActive) {
96-
const {total = 0, found = 0} = currentData;
97-
onDataFetched(total, found);
97+
onDataFetched({
98+
...currentData,
99+
data: currentData.data as T[],
100+
found: currentData.found || 0,
101+
total: currentData.total || 0,
102+
} as PaginatedTableData<T>);
98103
}
99104
}, [currentData, isActive, onDataFetched]);
100105

src/components/PaginatedTable/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,14 @@ export interface Column<T> {
3636
align: AlignType;
3737
}
3838

39-
export interface PaginatedTableData<T> {
39+
interface StorageNodesTableDataExtension {
40+
columnSettings?: {
41+
maxSlotsPerDisk: number;
42+
maxDisksPerNode: number;
43+
};
44+
}
45+
46+
export interface PaginatedTableData<T> extends StorageNodesTableDataExtension {
4047
data: T[];
4148
total: number;
4249
found: number;

src/containers/Storage/PaginatedStorageNodes.tsx

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ import React from 'react';
33
import {ResponseError} from '../../components/Errors/ResponseError';
44
import {LoaderWrapper} from '../../components/LoaderWrapper/LoaderWrapper';
55
import type {RenderControls} from '../../components/PaginatedTable';
6+
import type {PaginatedTableData} from '../../components/PaginatedTable/types';
67
import {TableWithControlsLayout} from '../../components/TableWithControlsLayout/TableWithControlsLayout';
78
import {
89
useCapabilitiesLoaded,
910
useViewerNodesHandlerHasGrouping,
1011
} from '../../store/reducers/capabilities/hooks';
1112
import {storageApi} from '../../store/reducers/storage/storage';
13+
import type {PreparedStorageNode} from '../../store/reducers/storage/types';
14+
import type {NodesGroupByField} from '../../types/api/nodes';
1215
import {useAutoRefreshInterval} from '../../utils/hooks';
1316
import {useAdditionalNodesProps} from '../../utils/hooks/useAdditionalNodesProps';
1417
import {NodesUptimeFilterValues} from '../../utils/nodes';
@@ -17,6 +20,7 @@ import type {PaginatedStorageProps} from './PaginatedStorage';
1720
import {StorageNodesControls} from './StorageControls/StorageControls';
1821
import {PaginatedStorageNodesTable} from './StorageNodes/PaginatedStorageNodesTable';
1922
import {useStorageNodesSelectedColumns} from './StorageNodes/columns/hooks';
23+
import type {StorageNodesColumn} from './StorageNodes/columns/types';
2024
import {TableGroup} from './TableGroup/TableGroup';
2125
import {useExpandedGroups} from './TableGroup/useExpandedTableGroups';
2226
import i18n from './i18n';
@@ -55,6 +59,9 @@ export const PaginatedStorageNodes = (props: PaginatedStorageProps) => {
5559
return <LoaderWrapper loading={!capabilitiesLoaded}>{renderContent()}</LoaderWrapper>;
5660
};
5761

62+
const MAX_SLOTS_CSS_VAR = '--maximum-slots';
63+
const MAX_DISKS_CSS_VAR = '--maximum-disks';
64+
5865
function StorageNodesComponent({
5966
database,
6067
nodeId,
@@ -73,6 +80,18 @@ function StorageNodesComponent({
7380
viewContext,
7481
});
7582

83+
const [tableStyle, setTableStyle] = React.useState<React.CSSProperties>({});
84+
85+
const handleDataFetched = React.useCallback((data: any) => {
86+
if (data?.columnSettings) {
87+
const {maxSlotsPerDisk, maxDisksPerNode} = data.columnSettings;
88+
setTableStyle({
89+
[MAX_SLOTS_CSS_VAR]: maxSlotsPerDisk,
90+
[MAX_DISKS_CSS_VAR]: maxDisksPerNode,
91+
} as React.CSSProperties);
92+
}
93+
}, []);
94+
7695
const renderControls: RenderControls = ({totalEntities, foundEntities, inited}) => {
7796
return (
7897
<StorageNodesControls
@@ -101,6 +120,8 @@ function StorageNodesComponent({
101120
renderErrorMessage={renderPaginatedTableErrorMessage}
102121
columns={columnsToShow}
103122
initialEntitiesCount={initialEntitiesCount}
123+
tableStyle={tableStyle}
124+
onDataFetched={handleDataFetched}
104125
/>
105126
);
106127
}
@@ -168,18 +189,15 @@ function GroupedStorageNodesComponent({
168189
expanded={isExpanded}
169190
onIsExpandedChange={setIsGroupExpanded}
170191
>
171-
<PaginatedStorageNodesTable
192+
<StorageNodesTableGroupContent
172193
database={database}
173194
parentRef={parentRef}
174195
nodeId={nodeId}
175196
groupId={groupId}
176197
searchValue={searchValue}
177-
visibleEntities={'all'}
178-
nodesUptimeFilter={NodesUptimeFilterValues.All}
179-
onShowAll={handleShowAllNodes}
198+
handleShowAllNodes={handleShowAllNodes}
180199
filterGroup={name}
181200
filterGroupBy={storageNodesGroupByParam}
182-
renderErrorMessage={renderPaginatedTableErrorMessage}
183201
columns={columnsToShow}
184202
initialEntitiesCount={count}
185203
/>
@@ -206,6 +224,64 @@ function GroupedStorageNodesComponent({
206224
);
207225
}
208226

227+
interface StorageNodesTableGroupContentProps {
228+
database?: string;
229+
parentRef: React.RefObject<HTMLElement>;
230+
nodeId?: string | number;
231+
groupId?: string | number;
232+
searchValue: string;
233+
handleShowAllNodes: VoidFunction;
234+
filterGroup: string;
235+
filterGroupBy?: NodesGroupByField;
236+
columns: StorageNodesColumn[];
237+
initialEntitiesCount: number;
238+
}
239+
240+
function StorageNodesTableGroupContent({
241+
database,
242+
parentRef,
243+
nodeId,
244+
groupId,
245+
searchValue,
246+
handleShowAllNodes,
247+
filterGroup,
248+
filterGroupBy,
249+
columns,
250+
initialEntitiesCount,
251+
}: StorageNodesTableGroupContentProps) {
252+
const [tableStyle, setTableStyle] = React.useState<React.CSSProperties>({});
253+
254+
const handleDataFetched = React.useCallback((data: PaginatedTableData<PreparedStorageNode>) => {
255+
if (data?.columnSettings) {
256+
const {maxSlotsPerDisk, maxDisksPerNode} = data.columnSettings;
257+
setTableStyle({
258+
[MAX_SLOTS_CSS_VAR]: maxSlotsPerDisk,
259+
[MAX_DISKS_CSS_VAR]: maxDisksPerNode,
260+
} as React.CSSProperties);
261+
}
262+
}, []);
263+
264+
return (
265+
<PaginatedStorageNodesTable
266+
database={database}
267+
parentRef={parentRef}
268+
nodeId={nodeId}
269+
groupId={groupId}
270+
searchValue={searchValue}
271+
visibleEntities={'all'}
272+
nodesUptimeFilter={NodesUptimeFilterValues.All}
273+
onShowAll={handleShowAllNodes}
274+
filterGroup={filterGroup}
275+
filterGroupBy={filterGroupBy}
276+
renderErrorMessage={renderPaginatedTableErrorMessage}
277+
columns={columns}
278+
initialEntitiesCount={initialEntitiesCount}
279+
tableStyle={tableStyle}
280+
onDataFetched={handleDataFetched}
281+
/>
282+
);
283+
}
284+
209285
function useStorageNodesColumnsToSelect({
210286
database,
211287
viewContext,

src/containers/Storage/StorageNodes/PaginatedStorageNodesTable.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import React from 'react';
22

3-
import type {RenderControls, RenderErrorMessage} from '../../../components/PaginatedTable';
3+
import type {
4+
PaginatedTableData,
5+
RenderControls,
6+
RenderErrorMessage,
7+
} from '../../../components/PaginatedTable';
48
import {ResizeablePaginatedTable} from '../../../components/PaginatedTable';
59
import {VISIBLE_ENTITIES} from '../../../store/reducers/storage/constants';
610
import type {PreparedStorageNode, VisibleEntities} from '../../../store/reducers/storage/types';
@@ -40,6 +44,8 @@ interface PaginatedStorageNodesTableProps {
4044
renderControls?: RenderControls;
4145
renderErrorMessage: RenderErrorMessage;
4246
initialEntitiesCount?: number;
47+
tableStyle?: React.CSSProperties;
48+
onDataFetched?: (data: PaginatedTableData<PreparedStorageNode>) => void;
4349
}
4450

4551
export const PaginatedStorageNodesTable = ({
@@ -57,6 +63,8 @@ export const PaginatedStorageNodesTable = ({
5763
renderControls,
5864
renderErrorMessage,
5965
initialEntitiesCount,
66+
tableStyle,
67+
onDataFetched,
6068
}: PaginatedStorageNodesTableProps) => {
6169
const tableFilters = React.useMemo(() => {
6270
return {
@@ -111,6 +119,8 @@ export const PaginatedStorageNodesTable = ({
111119
getRowClassName={getRowUnavailableClassName}
112120
filters={tableFilters}
113121
tableName="storage-nodes"
122+
tableStyle={tableStyle}
123+
onDataFetched={onDataFetched}
114124
/>
115125
);
116126
};

src/containers/Storage/StorageNodes/columns/StorageNodesColumns.scss

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
.ydb-storage-nodes-columns {
44
&__pdisks-column {
55
overflow: visible; // to enable stacked disks overflow the row
6+
7+
@include calculate-storage-nodes-pdisk-variables();
8+
9+
& .ydb-paginated-table__row-skeleton {
10+
width: var(--pdisks-container-width) !important;
11+
}
612
}
713

814
&__pdisks-wrapper {
@@ -11,8 +17,6 @@
1117

1218
width: var(--pdisks-container-width);
1319
height: 40px;
14-
15-
@include calculate-storage-nodes-pdisk-variables();
1620
}
1721

1822
&__pdisks-item {

src/containers/Storage/StorageNodes/columns/columns.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,14 @@ import './StorageNodesColumns.scss';
3030

3131
const b = cn('ydb-storage-nodes-columns');
3232

33-
const MAX_SLOTS_CSS_VAR = '--maximum-slots';
34-
const MAX_DISKS_CSS_VAR = '--maximum-disks';
35-
3633
const getPDisksColumn = ({viewContext}: GetStorageNodesColumnsParams): StorageNodesColumn => {
3734
return {
3835
name: NODES_COLUMNS_IDS.PDisks,
3936
header: NODES_COLUMNS_TITLES.PDisks,
4037
className: b('pdisks-column'),
4138
render: ({row}) => {
42-
const pDiskStyles = {
43-
[MAX_SLOTS_CSS_VAR]: row.MaximumSlotsPerDisk,
44-
[MAX_DISKS_CSS_VAR]: row.MaximumDisksPerNode,
45-
} as React.CSSProperties;
46-
4739
return (
48-
<div className={b('pdisks-wrapper')} style={pDiskStyles}>
40+
<div className={b('pdisks-wrapper')}>
4941
{row.PDisks?.map((pDisk) => {
5042
const vDisks = row.VDisks?.filter(
5143
(vdisk) => vdisk.PDiskId === pDisk.PDiskId,

src/containers/Storage/StorageNodes/getNodes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,6 @@ export const getStorageNodes: FetchData<
6565
data: preparedResponse.nodes || [],
6666
found: preparedResponse.found || 0,
6767
total: preparedResponse.total || 0,
68+
columnSettings: preparedResponse.columnSettings,
6869
};
6970
};

src/store/reducers/storage/types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ export interface PreparedStorageNode extends PreparedNodeSystemState {
3535
VDisks?: PreparedVDisk[];
3636

3737
Missing: number;
38-
MaximumSlotsPerDisk: string;
39-
MaximumDisksPerNode: string;
38+
MaximumSlotsPerDisk: number;
39+
MaximumDisksPerNode: number;
4040
}
4141

4242
export interface PreparedStorageGroupFilters {
@@ -107,4 +107,8 @@ export interface PreparedStorageResponse {
107107
found: number | undefined;
108108
total: number | undefined;
109109
tableGroups?: TableGroup[];
110+
columnSettings?: {
111+
maxSlotsPerDisk: number;
112+
maxDisksPerNode: number;
113+
};
110114
}

0 commit comments

Comments
 (0)