From a6b5b8e8de939c4aab99dccb10007adee144bea7 Mon Sep 17 00:00:00 2001 From: mufazalov Date: Mon, 7 Oct 2024 22:58:18 +0300 Subject: [PATCH 1/2] fix(Storage): prevent duplicating vdisks when no whiteboard --- src/components/VDisk/VDisk.tsx | 3 +-- src/components/VDiskInfo/VDiskInfo.tsx | 7 ++---- src/components/VDiskPopup/VDiskPopup.tsx | 12 ++++----- src/containers/Storage/Disks/Disks.tsx | 7 +++--- src/containers/Storage/PDisk/PDisk.tsx | 3 +-- .../Storage/StorageGroups/columns/columns.tsx | 4 +-- src/containers/VDiskPage/VDiskPage.tsx | 3 +-- src/store/reducers/storage/utils.ts | 25 ++++++++++++++++--- src/utils/disks/prepareDisks.ts | 4 +++ src/utils/disks/types.ts | 1 + 10 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/components/VDisk/VDisk.tsx b/src/components/VDisk/VDisk.tsx index 76455a314a..9cc6d62727 100644 --- a/src/components/VDisk/VDisk.tsx +++ b/src/components/VDisk/VDisk.tsx @@ -5,7 +5,6 @@ import routes, {createHref, getVDiskPagePath} from '../../routes'; import {useDiskPagesAvailable} from '../../store/reducers/capabilities/hooks'; import {valueIsDefined} from '../../utils'; import {cn} from '../../utils/cn'; -import {stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters'; import {isFullVDiskData} from '../../utils/disks/helpers'; import type {PreparedVDisk} from '../../utils/disks/types'; import {DiskStateProgressBar} from '../DiskStateProgressBar/DiskStateProgressBar'; @@ -68,7 +67,7 @@ export const VDisk = ({ {id: data.NodeId, activeTab: STRUCTURE}, { pdiskId: data.PDiskId, - vdiskId: stringifyVdiskId(data.VDiskId), + vdiskId: data.StringifiedId, }, ); } diff --git a/src/components/VDiskInfo/VDiskInfo.tsx b/src/components/VDiskInfo/VDiskInfo.tsx index 7c2bcaf815..da798ba462 100644 --- a/src/components/VDiskInfo/VDiskInfo.tsx +++ b/src/components/VDiskInfo/VDiskInfo.tsx @@ -4,7 +4,7 @@ import {getVDiskPagePath} from '../../routes'; import {selectIsUserAllowedToMakeChanges} from '../../store/reducers/authentication/authentication'; import {valueIsDefined} from '../../utils'; import {cn} from '../../utils/cn'; -import {formatStorageValuesToGb, stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters'; +import {formatStorageValuesToGb} from '../../utils/dataFormatters/dataFormatters'; import {createVDiskDeveloperUILink} from '../../utils/developerUI/developerUI'; import {getSeverityColor} from '../../utils/disks/helpers'; import type {PreparedVDisk} from '../../utils/disks/types'; @@ -201,10 +201,7 @@ function VDiskTitle({data}: VDiskTitleProps) { return (
{vDiskInfoKeyset('vdiks-title')} - +
); } diff --git a/src/components/VDiskPopup/VDiskPopup.tsx b/src/components/VDiskPopup/VDiskPopup.tsx index a5185581f7..e2a587d00f 100644 --- a/src/components/VDiskPopup/VDiskPopup.tsx +++ b/src/components/VDiskPopup/VDiskPopup.tsx @@ -5,13 +5,11 @@ import {Label, Popup} from '@gravity-ui/uikit'; import {selectNodeHostsMap} from '../../store/reducers/nodesList'; import {EFlag} from '../../types/api/enums'; -import type {TVDiskStateInfo} from '../../types/api/vdisk'; import {valueIsDefined} from '../../utils'; import {cn} from '../../utils/cn'; import {EMPTY_DATA_PLACEHOLDER} from '../../utils/constants'; -import {stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters'; import {isFullVDiskData} from '../../utils/disks/helpers'; -import type {UnavailableDonor} from '../../utils/disks/types'; +import type {PreparedVDisk, UnavailableDonor} from '../../utils/disks/types'; import {useTypedSelector} from '../../utils/hooks'; import {bytesToGB, bytesToSpeed} from '../../utils/utils'; import type {InfoViewerItem} from '../InfoViewer'; @@ -40,9 +38,9 @@ const prepareUnavailableVDiskData = (data: UnavailableDonor) => { return vdiskData; }; -const prepareVDiskData = (data: TVDiskStateInfo) => { +const prepareVDiskData = (data: PreparedVDisk) => { const { - VDiskId, + StringifiedId, VDiskState, SatisfactionRank, DiskSpace, @@ -56,7 +54,7 @@ const prepareVDiskData = (data: TVDiskStateInfo) => { } = data; const vdiskData: InfoViewerItem[] = [ - {label: 'VDisk', value: stringifyVdiskId(VDiskId)}, + {label: 'VDisk', value: StringifiedId}, {label: 'State', value: VDiskState ?? 'not available'}, ]; @@ -130,7 +128,7 @@ const prepareVDiskData = (data: TVDiskStateInfo) => { }; interface VDiskPopupProps extends PopupProps { - data: TVDiskStateInfo | UnavailableDonor; + data: PreparedVDisk | UnavailableDonor; } export const VDiskPopup = ({data, ...props}: VDiskPopupProps) => { diff --git a/src/containers/Storage/Disks/Disks.tsx b/src/containers/Storage/Disks/Disks.tsx index 3a1f67db76..3e96c55044 100644 --- a/src/containers/Storage/Disks/Disks.tsx +++ b/src/containers/Storage/Disks/Disks.tsx @@ -2,7 +2,6 @@ import React from 'react'; import {VDiskWithDonorsStack} from '../../../components/VDisk/VDiskWithDonorsStack'; import {cn} from '../../../utils/cn'; -import {stringifyVdiskId} from '../../../utils/dataFormatters/dataFormatters'; import {getPDiskId} from '../../../utils/disks/helpers'; import type {PreparedVDisk} from '../../../utils/disks/types'; import {PDisk} from '../PDisk'; @@ -30,7 +29,7 @@ export function Disks({vDisks = [], viewContext}: DisksProps) {
{vDisks?.map((vDisk) => ( { return (
(
{row.VDisks?.map((vDisk) => ( ); }; diff --git a/src/store/reducers/storage/utils.ts b/src/store/reducers/storage/utils.ts index 3eb872ebc9..97f18f6522 100644 --- a/src/store/reducers/storage/utils.ts +++ b/src/store/reducers/storage/utils.ts @@ -263,20 +263,37 @@ export function prepareGroupsResponse(data: StorageGroupsResponse): PreparedStor } = group; const vDisks = VDisks.map((disk) => { - const whiteboardVDisk = disk.Whiteboard; - const whiteboardPDisk = disk.PDisk?.Whiteboard; + const { + Whiteboard: whiteboardVDisk, + PDisk, + VDiskId, + NodeId, + AllocatedSize, + AvailableSize, + DiskSpace, + Status, + } = disk; + const whiteboardPDisk = PDisk?.Whiteboard; - const NodeId = disk.NodeId; const PDiskId = whiteboardPDisk?.PDiskId; const whiteboardVDiskData = { ...whiteboardVDisk, PDiskId, NodeId, + AllocatedSize, + AvailableSize, + DiskSpace, + Status, PDisk: {...whiteboardPDisk, NodeId}, }; - return prepareVDiskData(whiteboardVDiskData); + const preparedVDiskData = prepareVDiskData(whiteboardVDiskData); + + return { + ...preparedVDiskData, + StringifiedId: preparedVDiskData.StringifiedId || VDiskId, + }; }); const diskSpaceStatus = getGroupDiskSpaceStatus(group); diff --git a/src/utils/disks/prepareDisks.ts b/src/utils/disks/prepareDisks.ts index f27d05bf43..745a0a981a 100644 --- a/src/utils/disks/prepareDisks.ts +++ b/src/utils/disks/prepareDisks.ts @@ -1,5 +1,6 @@ import type {TPDiskInfo, TPDiskStateInfo} from '../../types/api/pdisk'; import type {TVDiskStateInfo} from '../../types/api/vdisk'; +import {stringifyVdiskId} from '../dataFormatters/dataFormatters'; import {calculatePDiskSeverity} from './calculatePDiskSeverity'; import {calculateVDiskSeverity} from './calculateVDiskSeverity'; @@ -28,12 +29,15 @@ export function prepareVDiskData(vdiskState: TVDiskStateInfo = {}): PreparedVDis const Severity = calculateVDiskSeverity(vdiskState); + const StringifiedId = stringifyVdiskId(vdiskState.VDiskId); + return { ...vdiskState, PDisk, PDiskId, Donors, Severity, + StringifiedId, TotalSize: total, AllocatedPercent: allocatedPercent, diff --git a/src/utils/disks/types.ts b/src/utils/disks/types.ts index 8b88aaf817..ad7e93d262 100644 --- a/src/utils/disks/types.ts +++ b/src/utils/disks/types.ts @@ -16,6 +16,7 @@ export type PreparedPDisk = TPDiskStateInfo & export interface PreparedVDisk extends TVDiskStateInfo { PDisk?: PreparedPDisk; Severity?: number; + StringifiedId?: string; TotalSize?: number; AllocatedPercent?: number; From e9c34b6b624d554e5eef557c334ce4b2ec0724eb Mon Sep 17 00:00:00 2001 From: mufazalov Date: Tue, 8 Oct 2024 19:19:52 +0300 Subject: [PATCH 2/2] add comment --- src/store/reducers/storage/utils.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/store/reducers/storage/utils.ts b/src/store/reducers/storage/utils.ts index 97f18f6522..1cf28e4b75 100644 --- a/src/store/reducers/storage/utils.ts +++ b/src/store/reducers/storage/utils.ts @@ -292,6 +292,9 @@ export function prepareGroupsResponse(data: StorageGroupsResponse): PreparedStor return { ...preparedVDiskData, + // There might be no Whiteboard data if cluster is not healthy + // StringifiedId is formed from Whiteboard.VDiskId object + // Use VDiskId string from backend in such case StringifiedId: preparedVDiskData.StringifiedId || VDiskId, }; });