Skip to content

Commit 73e9e6b

Browse files
fix(Storage): prevent duplicating vdisks when no whiteboard (#1420)
1 parent 10f817e commit 73e9e6b

File tree

10 files changed

+44
-28
lines changed

10 files changed

+44
-28
lines changed

src/components/VDisk/VDisk.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import routes, {createHref, getVDiskPagePath} from '../../routes';
55
import {useDiskPagesAvailable} from '../../store/reducers/capabilities/hooks';
66
import {valueIsDefined} from '../../utils';
77
import {cn} from '../../utils/cn';
8-
import {stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters';
98
import {isFullVDiskData} from '../../utils/disks/helpers';
109
import type {PreparedVDisk} from '../../utils/disks/types';
1110
import {DiskStateProgressBar} from '../DiskStateProgressBar/DiskStateProgressBar';
@@ -68,7 +67,7 @@ export const VDisk = ({
6867
{id: data.NodeId, activeTab: STRUCTURE},
6968
{
7069
pdiskId: data.PDiskId,
71-
vdiskId: stringifyVdiskId(data.VDiskId),
70+
vdiskId: data.StringifiedId,
7271
},
7372
);
7473
}

src/components/VDiskInfo/VDiskInfo.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {getVDiskPagePath} from '../../routes';
44
import {selectIsUserAllowedToMakeChanges} from '../../store/reducers/authentication/authentication';
55
import {valueIsDefined} from '../../utils';
66
import {cn} from '../../utils/cn';
7-
import {formatStorageValuesToGb, stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters';
7+
import {formatStorageValuesToGb} from '../../utils/dataFormatters/dataFormatters';
88
import {createVDiskDeveloperUILink} from '../../utils/developerUI/developerUI';
99
import {getSeverityColor} from '../../utils/disks/helpers';
1010
import type {PreparedVDisk} from '../../utils/disks/types';
@@ -201,10 +201,7 @@ function VDiskTitle<T extends PreparedVDisk>({data}: VDiskTitleProps<T>) {
201201
return (
202202
<div className={b('title')}>
203203
{vDiskInfoKeyset('vdiks-title')}
204-
<EntityStatus
205-
status={getSeverityColor(data.Severity)}
206-
name={stringifyVdiskId(data.VDiskId)}
207-
/>
204+
<EntityStatus status={getSeverityColor(data.Severity)} name={data.StringifiedId} />
208205
</div>
209206
);
210207
}

src/components/VDiskPopup/VDiskPopup.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ import {Label, Popup} from '@gravity-ui/uikit';
55

66
import {selectNodeHostsMap} from '../../store/reducers/nodesList';
77
import {EFlag} from '../../types/api/enums';
8-
import type {TVDiskStateInfo} from '../../types/api/vdisk';
98
import {valueIsDefined} from '../../utils';
109
import {cn} from '../../utils/cn';
1110
import {EMPTY_DATA_PLACEHOLDER} from '../../utils/constants';
12-
import {stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters';
1311
import {isFullVDiskData} from '../../utils/disks/helpers';
14-
import type {UnavailableDonor} from '../../utils/disks/types';
12+
import type {PreparedVDisk, UnavailableDonor} from '../../utils/disks/types';
1513
import {useTypedSelector} from '../../utils/hooks';
1614
import {bytesToGB, bytesToSpeed} from '../../utils/utils';
1715
import type {InfoViewerItem} from '../InfoViewer';
@@ -40,9 +38,9 @@ const prepareUnavailableVDiskData = (data: UnavailableDonor) => {
4038
return vdiskData;
4139
};
4240

43-
const prepareVDiskData = (data: TVDiskStateInfo) => {
41+
const prepareVDiskData = (data: PreparedVDisk) => {
4442
const {
45-
VDiskId,
43+
StringifiedId,
4644
VDiskState,
4745
SatisfactionRank,
4846
DiskSpace,
@@ -56,7 +54,7 @@ const prepareVDiskData = (data: TVDiskStateInfo) => {
5654
} = data;
5755

5856
const vdiskData: InfoViewerItem[] = [
59-
{label: 'VDisk', value: stringifyVdiskId(VDiskId)},
57+
{label: 'VDisk', value: StringifiedId},
6058
{label: 'State', value: VDiskState ?? 'not available'},
6159
];
6260

@@ -130,7 +128,7 @@ const prepareVDiskData = (data: TVDiskStateInfo) => {
130128
};
131129

132130
interface VDiskPopupProps extends PopupProps {
133-
data: TVDiskStateInfo | UnavailableDonor;
131+
data: PreparedVDisk | UnavailableDonor;
134132
}
135133

136134
export const VDiskPopup = ({data, ...props}: VDiskPopupProps) => {

src/containers/Storage/Disks/Disks.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React from 'react';
22

33
import {VDiskWithDonorsStack} from '../../../components/VDisk/VDiskWithDonorsStack';
44
import {cn} from '../../../utils/cn';
5-
import {stringifyVdiskId} from '../../../utils/dataFormatters/dataFormatters';
65
import {getPDiskId} from '../../../utils/disks/helpers';
76
import type {PreparedVDisk} from '../../../utils/disks/types';
87
import {PDisk} from '../PDisk';
@@ -30,7 +29,7 @@ export function Disks({vDisks = [], viewContext}: DisksProps) {
3029
<div className={b('vdisks-wrapper')}>
3130
{vDisks?.map((vDisk) => (
3231
<VDiskItem
33-
key={stringifyVdiskId(vDisk.VDiskId)}
32+
key={vDisk.StringifiedId}
3433
vDisk={vDisk}
3534
inactive={!isVdiskActive(vDisk, viewContext)}
3635
highlightedVDisk={highlightedVDisk}
@@ -64,7 +63,7 @@ function VDiskItem({vDisk, highlightedVDisk, inactive, setHighlightedVDisk}: Dis
6463
// Do not show PDisk popup for VDisk
6564
const vDiskToShow = {...vDisk, PDisk: undefined};
6665

67-
const vDiskId = stringifyVdiskId(vDisk.VDiskId);
66+
const vDiskId = vDisk.StringifiedId;
6867

6968
return (
7069
<div
@@ -87,7 +86,7 @@ function VDiskItem({vDisk, highlightedVDisk, inactive, setHighlightedVDisk}: Dis
8786
}
8887

8988
function PDiskItem({vDisk, highlightedVDisk, setHighlightedVDisk}: DisksItemProps) {
90-
const vDiskId = stringifyVdiskId(vDisk.VDiskId);
89+
const vDiskId = vDisk.StringifiedId;
9190

9291
if (!vDisk.PDisk) {
9392
return null;

src/containers/Storage/PDisk/PDisk.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import routes, {createHref, getPDiskPagePath} from '../../../routes';
88
import {useDiskPagesAvailable} from '../../../store/reducers/capabilities/hooks';
99
import {valueIsDefined} from '../../../utils';
1010
import {cn} from '../../../utils/cn';
11-
import {stringifyVdiskId} from '../../../utils/dataFormatters/dataFormatters';
1211
import type {PreparedPDisk, PreparedVDisk} from '../../../utils/disks/types';
1312
import {STRUCTURE} from '../../Node/NodePages';
1413
import type {StorageViewContext} from '../types';
@@ -68,7 +67,7 @@ export const PDisk = ({
6867
{vDisks.map((vdisk) => {
6968
return (
7069
<div
71-
key={stringifyVdiskId(vdisk.VDiskId)}
70+
key={vdisk.StringifiedId}
7271
className={b('vdisks-item')}
7372
style={{
7473
// 1 is small enough for empty disks to be of the minimum width

src/containers/Storage/StorageGroups/columns/columns.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {getStorageGroupPath} from '../../../../routes';
1313
import {valueIsDefined} from '../../../../utils';
1414
import {cn} from '../../../../utils/cn';
1515
import {EMPTY_DATA_PLACEHOLDER} from '../../../../utils/constants';
16-
import {formatNumber, stringifyVdiskId} from '../../../../utils/dataFormatters/dataFormatters';
16+
import {formatNumber} from '../../../../utils/dataFormatters/dataFormatters';
1717
import {isSortableStorageProperty} from '../../../../utils/storage';
1818
import {formatToMs} from '../../../../utils/timeParsers';
1919
import {bytesToGB, bytesToSpeed} from '../../../../utils/utils';
@@ -217,7 +217,7 @@ const getVDisksColumn = (data?: GetStorageColumnsData): StorageGroupsColumn => (
217217
<div className={b('vdisks-wrapper')}>
218218
{row.VDisks?.map((vDisk) => (
219219
<VDiskWithDonorsStack
220-
key={stringifyVdiskId(vDisk.VDiskId)}
220+
key={vDisk.StringifiedId}
221221
data={vDisk}
222222
inactive={!isVdiskActive(vDisk, data?.viewContext)}
223223
className={b('vdisks-item')}

src/containers/VDiskPage/VDiskPage.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {setHeaderBreadcrumbs} from '../../store/reducers/header/header';
1919
import {vDiskApi} from '../../store/reducers/vdisk/vdisk';
2020
import {valueIsDefined} from '../../utils';
2121
import {cn} from '../../utils/cn';
22-
import {stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters';
2322
import {getSeverityColor, getVDiskSlotBasedId} from '../../utils/disks/helpers';
2423
import {useAutoRefreshInterval, useTypedDispatch, useTypedSelector} from '../../utils/hooks';
2524
import {StorageWrapper} from '../Storage/StorageWrapper';
@@ -142,7 +141,7 @@ export function VDiskPage() {
142141
className={vDiskPageCn('title')}
143142
entityName={vDiskPageKeyset('vdisk')}
144143
status={getSeverityColor(Severity)}
145-
id={stringifyVdiskId(vDiskData?.VDiskId)}
144+
id={vDiskData?.StringifiedId}
146145
/>
147146
);
148147
};

src/store/reducers/storage/utils.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,20 +263,40 @@ export function prepareGroupsResponse(data: StorageGroupsResponse): PreparedStor
263263
} = group;
264264

265265
const vDisks = VDisks.map((disk) => {
266-
const whiteboardVDisk = disk.Whiteboard;
267-
const whiteboardPDisk = disk.PDisk?.Whiteboard;
266+
const {
267+
Whiteboard: whiteboardVDisk,
268+
PDisk,
269+
VDiskId,
270+
NodeId,
271+
AllocatedSize,
272+
AvailableSize,
273+
DiskSpace,
274+
Status,
275+
} = disk;
276+
const whiteboardPDisk = PDisk?.Whiteboard;
268277

269-
const NodeId = disk.NodeId;
270278
const PDiskId = whiteboardPDisk?.PDiskId;
271279

272280
const whiteboardVDiskData = {
273281
...whiteboardVDisk,
274282
PDiskId,
275283
NodeId,
284+
AllocatedSize,
285+
AvailableSize,
286+
DiskSpace,
287+
Status,
276288
PDisk: {...whiteboardPDisk, NodeId},
277289
};
278290

279-
return prepareVDiskData(whiteboardVDiskData);
291+
const preparedVDiskData = prepareVDiskData(whiteboardVDiskData);
292+
293+
return {
294+
...preparedVDiskData,
295+
// There might be no Whiteboard data if cluster is not healthy
296+
// StringifiedId is formed from Whiteboard.VDiskId object
297+
// Use VDiskId string from backend in such case
298+
StringifiedId: preparedVDiskData.StringifiedId || VDiskId,
299+
};
280300
});
281301

282302
const diskSpaceStatus = getGroupDiskSpaceStatus(group);

src/utils/disks/prepareDisks.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type {TPDiskInfo, TPDiskStateInfo} from '../../types/api/pdisk';
22
import type {TVDiskStateInfo} from '../../types/api/vdisk';
3+
import {stringifyVdiskId} from '../dataFormatters/dataFormatters';
34

45
import {calculatePDiskSeverity} from './calculatePDiskSeverity';
56
import {calculateVDiskSeverity} from './calculateVDiskSeverity';
@@ -28,12 +29,15 @@ export function prepareVDiskData(vdiskState: TVDiskStateInfo = {}): PreparedVDis
2829

2930
const Severity = calculateVDiskSeverity(vdiskState);
3031

32+
const StringifiedId = stringifyVdiskId(vdiskState.VDiskId);
33+
3134
return {
3235
...vdiskState,
3336
PDisk,
3437
PDiskId,
3538
Donors,
3639
Severity,
40+
StringifiedId,
3741

3842
TotalSize: total,
3943
AllocatedPercent: allocatedPercent,

src/utils/disks/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export type PreparedPDisk = TPDiskStateInfo &
1616
export interface PreparedVDisk extends TVDiskStateInfo {
1717
PDisk?: PreparedPDisk;
1818
Severity?: number;
19+
StringifiedId?: string;
1920

2021
TotalSize?: number;
2122
AllocatedPercent?: number;

0 commit comments

Comments
 (0)