Skip to content

Commit f31a19a

Browse files
chore: add proper types for Node PDisk and VDisk (#558)
1 parent ca23c14 commit f31a19a

File tree

2 files changed

+83
-101
lines changed

2 files changed

+83
-101
lines changed

src/containers/Node/NodeStructure/Pdisk.tsx

Lines changed: 74 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,34 @@
11
import {useState} from 'react';
22
import cn from 'bem-cn-lite';
3-
import _ from 'lodash';
3+
import {isEmpty} from 'lodash/fp';
44

55
import {ArrowToggle, Button, Popover} from '@gravity-ui/uikit';
66

7-
import DataTable, {Column, Settings} from '@gravity-ui/react-data-table';
8-
9-
import EntityStatus from '../../../components/EntityStatus/EntityStatus';
10-
import InfoViewer from '../../../components/InfoViewer/InfoViewer';
11-
import {ProgressViewer} from '../../../components/ProgressViewer/ProgressViewer';
12-
import {Icon} from '../../../components/Icon';
13-
import {Vdisk} from './Vdisk';
7+
import DataTable, {type Column} from '@gravity-ui/react-data-table';
148

9+
import type {ValueOf} from '../../../types/common';
10+
import type {
11+
PreparedStructurePDisk,
12+
PreparedStructureVDisk,
13+
} from '../../../store/reducers/node/types';
14+
import {EVDiskState} from '../../../types/api/vdisk';
1515
import {bytesToGB, pad9} from '../../../utils/utils';
1616
import {formatStorageValuesToGb} from '../../../utils/dataFormatters/dataFormatters';
1717
import {getPDiskType} from '../../../utils/pdisk';
18-
1918
import {DEFAULT_TABLE_SETTINGS} from '../../../utils/constants';
19+
import EntityStatus from '../../../components/EntityStatus/EntityStatus';
20+
import InfoViewer, {type InfoViewerItem} from '../../../components/InfoViewer/InfoViewer';
21+
import {ProgressViewer} from '../../../components/ProgressViewer/ProgressViewer';
22+
import {Icon} from '../../../components/Icon';
23+
24+
import {Vdisk} from './Vdisk';
2025
import {valueIsDefined} from './NodeStructure';
2126
import {PDiskTitleBadge} from './PDiskTitleBadge';
2227

2328
const b = cn('kv-node-structure');
2429

2530
interface PDiskProps {
26-
data: Record<string, any>;
31+
data: PreparedStructurePDisk;
2732
unfolded?: boolean;
2833
id: string;
2934
selectedVdiskId?: string;
@@ -37,8 +42,7 @@ enum VDiskTableColumnsIds {
3742
Info = 'Info',
3843
}
3944

40-
type VDiskTableColumnsIdsKeys = keyof typeof VDiskTableColumnsIds;
41-
type VDiskTableColumnsIdsValues = typeof VDiskTableColumnsIds[VDiskTableColumnsIdsKeys];
45+
type VDiskTableColumnsIdsValues = ValueOf<typeof VDiskTableColumnsIds>;
4246

4347
const vDiskTableColumnsNames: Record<VDiskTableColumnsIdsValues, string> = {
4448
VDiskSlotId: 'Slot id',
@@ -47,39 +51,35 @@ const vDiskTableColumnsNames: Record<VDiskTableColumnsIdsValues, string> = {
4751
Info: '',
4852
};
4953

50-
interface RowType {
51-
id: string;
52-
[VDiskTableColumnsIds.slotId]: number;
53-
[VDiskTableColumnsIds.VDiskState]: string;
54-
AllocatedSize: string;
55-
AvailableSize: string;
56-
}
57-
5854
function getColumns({
5955
pDiskId,
6056
selectedVdiskId,
6157
nodeHref,
6258
}: {
63-
pDiskId: number;
59+
pDiskId: number | undefined;
6460
selectedVdiskId?: string;
6561
nodeHref?: string | null;
6662
}) {
67-
const columns: Column<RowType>[] = [
63+
const columns: Column<PreparedStructureVDisk>[] = [
6864
{
69-
name: VDiskTableColumnsIds.slotId as string,
65+
name: VDiskTableColumnsIds.slotId,
7066
header: vDiskTableColumnsNames[VDiskTableColumnsIds.slotId],
7167
width: 100,
72-
render: ({value, row}) => {
68+
render: ({row}) => {
7369
let vdiskInternalViewerLink = '';
7470

75-
if (nodeHref && value !== undefined) {
71+
if (nodeHref && pDiskId !== undefined && row.VDiskSlotId !== undefined) {
7672
vdiskInternalViewerLink +=
77-
nodeHref + 'actors/vdisks/vdisk' + pad9(pDiskId) + '_' + pad9(value);
73+
nodeHref +
74+
'actors/vdisks/vdisk' +
75+
pad9(pDiskId) +
76+
'_' +
77+
pad9(row.VDiskSlotId);
7878
}
7979

8080
return (
8181
<div className={b('vdisk-id', {selected: row.id === selectedVdiskId})}>
82-
<span>{value as number}</span>
82+
<span>{row.VDiskSlotId}</span>
8383
{vdiskInternalViewerLink && (
8484
<Button
8585
size="s"
@@ -96,17 +96,19 @@ function getColumns({
9696
align: DataTable.LEFT,
9797
},
9898
{
99-
name: VDiskTableColumnsIds.VDiskState as string,
99+
name: VDiskTableColumnsIds.VDiskState,
100100
header: vDiskTableColumnsNames[VDiskTableColumnsIds.VDiskState],
101101
width: 70,
102-
render: ({value}) => {
103-
return <EntityStatus status={value === 'OK' ? 'green' : 'red'} />;
102+
render: ({row}) => {
103+
return (
104+
<EntityStatus status={row.VDiskState === EVDiskState.OK ? 'green' : 'red'} />
105+
);
104106
},
105-
sortAccessor: (row) => (row[VDiskTableColumnsIds.VDiskState] === 'OK' ? 1 : 0),
107+
sortAccessor: (row) => (row.VDiskState === EVDiskState.OK ? 1 : 0),
106108
align: DataTable.CENTER,
107109
},
108110
{
109-
name: VDiskTableColumnsIds.Size as string,
111+
name: VDiskTableColumnsIds.Size,
110112
header: vDiskTableColumnsNames[VDiskTableColumnsIds.Size],
111113
width: 100,
112114
render: ({row}) => {
@@ -123,7 +125,7 @@ function getColumns({
123125
align: DataTable.CENTER,
124126
},
125127
{
126-
name: VDiskTableColumnsIds.Info as string,
128+
name: VDiskTableColumnsIds.Info,
127129
header: vDiskTableColumnsNames[VDiskTableColumnsIds.Info],
128130
width: 70,
129131
render: ({row}) => {
@@ -150,10 +152,31 @@ function getColumns({
150152
return columns;
151153
}
152154

153-
export function PDisk(props: PDiskProps) {
154-
const [unfolded, setUnfolded] = useState(props.unfolded ?? false);
155+
export function PDisk({
156+
id,
157+
data,
158+
selectedVdiskId,
159+
nodeHref,
160+
unfolded: unfoldedFromProps,
161+
}: PDiskProps) {
162+
const [unfolded, setUnfolded] = useState(unfoldedFromProps ?? false);
163+
164+
const {
165+
TotalSize = 0,
166+
AvailableSize = 0,
167+
Device,
168+
Guid,
169+
PDiskId,
170+
Path,
171+
Realtime,
172+
State,
173+
Category,
174+
SerialNumber,
175+
vDisks,
176+
} = data;
155177

156-
const data = props.data ?? {};
178+
const total = Number(TotalSize);
179+
const available = Number(AvailableSize);
157180

158181
const onOpenPDiskDetails = () => {
159182
setUnfolded(true);
@@ -163,15 +186,12 @@ export function PDisk(props: PDiskProps) {
163186
};
164187

165188
const renderVDisks = () => {
166-
const {selectedVdiskId, data, nodeHref} = props;
167-
const {vDisks} = data;
168-
169189
return (
170190
<DataTable
171191
theme="yandex-cloud"
172192
data={vDisks}
173-
columns={getColumns({nodeHref, pDiskId: data.PDiskId, selectedVdiskId})}
174-
settings={{...DEFAULT_TABLE_SETTINGS, dynamicRender: false} as Settings}
193+
columns={getColumns({nodeHref, pDiskId: PDiskId, selectedVdiskId})}
194+
settings={{...DEFAULT_TABLE_SETTINGS, dynamicRender: false}}
175195
rowClassName={(row) => {
176196
return row.id === selectedVdiskId ? b('selected-vdisk') : '';
177197
}}
@@ -180,30 +200,16 @@ export function PDisk(props: PDiskProps) {
180200
};
181201

182202
const renderPDiskDetails = () => {
183-
if (_.isEmpty(data)) {
203+
if (isEmpty(data)) {
184204
return <div>No information about PDisk</div>;
185205
}
186-
const {nodeHref} = props;
187-
const {
188-
TotalSize,
189-
AvailableSize,
190-
Device,
191-
Guid,
192-
PDiskId,
193-
Path,
194-
Realtime,
195-
State,
196-
Category,
197-
SerialNumber,
198-
} = data;
199-
200206
let pDiskInternalViewerLink = '';
201207

202208
if (nodeHref) {
203209
pDiskInternalViewerLink += nodeHref + 'actors/pdisks/pdisk' + pad9(PDiskId);
204210
}
205211

206-
const pdiskInfo: any = [
212+
const pdiskInfo: InfoViewerItem[] = [
207213
{
208214
label: 'PDisk Id',
209215
value: (
@@ -236,19 +242,19 @@ export function PDisk(props: PDiskProps) {
236242
}
237243
pdiskInfo.push({
238244
label: 'Allocated Size',
239-
value: bytesToGB(TotalSize - AvailableSize),
245+
value: bytesToGB(total - available),
240246
});
241247
pdiskInfo.push({
242248
label: 'Available Size',
243-
value: bytesToGB(AvailableSize),
249+
value: bytesToGB(available),
244250
});
245-
if (Number(TotalSize) >= 0 && Number(AvailableSize) >= 0) {
251+
if (total >= 0 && available >= 0) {
246252
pdiskInfo.push({
247253
label: 'Size',
248254
value: (
249255
<ProgressViewer
250-
value={TotalSize - AvailableSize}
251-
capacity={TotalSize}
256+
value={total - available}
257+
capacity={total}
252258
formatValues={formatStorageValuesToGb}
253259
colorizeProgress={true}
254260
className={b('size')}
@@ -286,24 +292,24 @@ export function PDisk(props: PDiskProps) {
286292
};
287293

288294
return (
289-
<div className={b('pdisk')} id={props.id}>
295+
<div className={b('pdisk')} id={id}>
290296
<div className={b('pdisk-header')}>
291297
<div className={b('pdisk-title-wrapper')}>
292-
<EntityStatus status={data.Device} />
298+
<EntityStatus status={Device} />
293299
<PDiskTitleBadge
294300
label="PDiskID"
295-
value={data.PDiskId}
301+
value={PDiskId}
296302
className={b('pdisk-title-id')}
297303
/>
298304
<PDiskTitleBadge value={getPDiskType(data)} className={b('pdisk-title-type')} />
299305
<ProgressViewer
300-
value={data.TotalSize - data.AvailableSize}
301-
capacity={data.TotalSize}
306+
value={total - available}
307+
capacity={total}
302308
formatValues={formatStorageValuesToGb}
303309
colorizeProgress={true}
304310
className={b('pdisk-title-size')}
305311
/>
306-
<PDiskTitleBadge label="VDisks" value={data.vDisks.length} />
312+
<PDiskTitleBadge label="VDisks" value={vDisks.length} />
307313
</div>
308314
<Button
309315
onClick={unfolded ? onClosePDiskDetails : onOpenPDiskDetails}

src/containers/Node/NodeStructure/Vdisk.tsx

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,19 @@
11
import React from 'react';
22
import cn from 'bem-cn-lite';
33

4-
import {ProgressViewer} from '../../../components/ProgressViewer/ProgressViewer';
4+
import type {TVDiskStateInfo} from '../../../types/api/vdisk';
55
import {
66
formatStorageValuesToGb,
77
stringifyVdiskId,
88
} from '../../../utils/dataFormatters/dataFormatters';
99
import {bytesToGB, bytesToSpeed} from '../../../utils/utils';
1010
import EntityStatus from '../../../components/EntityStatus/EntityStatus';
11-
import {valueIsDefined} from './NodeStructure';
1211
import InfoViewer from '../../../components/InfoViewer/InfoViewer';
12+
import {ProgressViewer} from '../../../components/ProgressViewer/ProgressViewer';
1313

14-
const b = cn('kv-node-structure');
14+
import {valueIsDefined} from './NodeStructure';
1515

16-
interface VdiskProps {
17-
AllocatedSize?: string;
18-
DiskSpace?: string;
19-
FrontQueues?: string;
20-
Guid?: string;
21-
Replicated?: boolean;
22-
VDiskState?: string;
23-
VDiskId?: {
24-
GroupId: number;
25-
GroupGeneration: number;
26-
Ring: number;
27-
Domain: number;
28-
VDisk: number;
29-
};
30-
VDiskSlotId?: number;
31-
Kind?: string;
32-
SatisfactionRank?: {FreshRank: {Flag: string}; LevelRank: {Flag: string}};
33-
AvailableSize?: string;
34-
HasUnreadableBlobs?: boolean;
35-
IncarnationGuid?: string;
36-
InstanceGuid?: string;
37-
StoragePoolName?: string;
38-
ReadThroughput?: string;
39-
WriteThroughput?: string;
40-
}
16+
const b = cn('kv-node-structure');
4117

4218
export function Vdisk({
4319
AllocatedSize,
@@ -57,7 +33,7 @@ export function Vdisk({
5733
StoragePoolName,
5834
ReadThroughput,
5935
WriteThroughput,
60-
}: VdiskProps) {
36+
}: TVDiskStateInfo) {
6137
const vdiskInfo = [];
6238

6339
if (valueIsDefined(VDiskSlotId)) {
@@ -81,16 +57,16 @@ export function Vdisk({
8157
value: <EntityStatus status={DiskSpace} />,
8258
});
8359
}
84-
if (valueIsDefined(SatisfactionRank?.FreshRank.Flag)) {
60+
if (valueIsDefined(SatisfactionRank?.FreshRank?.Flag)) {
8561
vdiskInfo.push({
8662
label: 'Fresh Rank Satisfaction',
87-
value: <EntityStatus status={SatisfactionRank?.FreshRank.Flag} />,
63+
value: <EntityStatus status={SatisfactionRank?.FreshRank?.Flag} />,
8864
});
8965
}
90-
if (valueIsDefined(SatisfactionRank?.LevelRank.Flag)) {
66+
if (valueIsDefined(SatisfactionRank?.LevelRank?.Flag)) {
9167
vdiskInfo.push({
9268
label: 'Level Rank Satisfaction',
93-
value: <EntityStatus status={SatisfactionRank?.LevelRank.Flag} />,
69+
value: <EntityStatus status={SatisfactionRank?.LevelRank?.Flag} />,
9470
});
9571
}
9672
vdiskInfo.push({label: 'Replicated', value: Replicated ? 'Yes' : 'No'});

0 commit comments

Comments
 (0)