Skip to content

Commit fc12a38

Browse files
authored
feat(VDisk): show VDisk donors inside popup (#1422)
1 parent 5ecaecb commit fc12a38

File tree

9 files changed

+75
-44
lines changed

9 files changed

+75
-44
lines changed

src/components/VDisk/VDisk.scss

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
border-radius: 4px; // to match interactive area with disk shape
33

44
&__content {
5+
display: block;
6+
57
border-radius: 4px; // to match interactive area with disk shape
68
}
79
}

src/components/VDisk/VDisk.tsx

+3-28
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
import React from 'react';
22

3-
import {STRUCTURE} from '../../containers/Node/NodePages';
4-
import routes, {createHref, getVDiskPagePath} from '../../routes';
5-
import {useDiskPagesAvailable} from '../../store/reducers/capabilities/hooks';
6-
import {valueIsDefined} from '../../utils';
73
import {cn} from '../../utils/cn';
8-
import {isFullVDiskData} from '../../utils/disks/helpers';
94
import type {PreparedVDisk} from '../../utils/disks/types';
105
import {DiskStateProgressBar} from '../DiskStateProgressBar/DiskStateProgressBar';
116
import {InternalLink} from '../InternalLink';
127
import {VDiskPopup} from '../VDiskPopup/VDiskPopup';
138

9+
import {getVDiskLink} from './utils';
10+
1411
import './VDisk.scss';
1512

1613
const b = cn('ydb-vdisk-component');
@@ -34,10 +31,6 @@ export const VDisk = ({
3431
onHidePopup,
3532
progressBarClassName,
3633
}: VDiskProps) => {
37-
const isFullData = isFullVDiskData(data);
38-
39-
const diskPagesAvailable = useDiskPagesAvailable();
40-
4134
const [isPopupVisible, setIsPopupVisible] = React.useState(false);
4235

4336
const anchor = React.useRef(null);
@@ -52,25 +45,7 @@ export const VDisk = ({
5245
onHidePopup?.();
5346
};
5447

55-
let vDiskPath: string | undefined;
56-
57-
if (
58-
diskPagesAvailable &&
59-
valueIsDefined(data.VDiskSlotId) &&
60-
valueIsDefined(data.PDiskId) &&
61-
valueIsDefined(data.NodeId)
62-
) {
63-
vDiskPath = getVDiskPagePath(data.VDiskSlotId, data.PDiskId, data.NodeId);
64-
} else if (valueIsDefined(data.NodeId) && isFullData) {
65-
vDiskPath = createHref(
66-
routes.node,
67-
{id: data.NodeId, activeTab: STRUCTURE},
68-
{
69-
pdiskId: data.PDiskId,
70-
vdiskId: data.StringifiedId,
71-
},
72-
);
73-
}
48+
const vDiskPath = getVDiskLink(data);
7449

7550
return (
7651
<React.Fragment>

src/components/VDisk/VDiskWithDonorsStack.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ export function VDiskWithDonorsStack({
1818
stackClassName,
1919
...restProps
2020
}: VDiskWithDonorsStackProps) {
21-
const donors = data?.Donors;
21+
const {Donors: donors, ...restData} = data || {};
2222

2323
const content =
2424
donors && donors.length > 0 ? (
2525
<Stack className={stackClassName}>
26-
<VDisk data={data} {...restProps} />
26+
<VDisk data={restData} {...restProps} />
2727
{donors.map((donor) => {
2828
const isFullData = isFullVDiskData(donor);
2929

src/components/VDisk/utils.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {STRUCTURE} from '../../containers/Node/NodePages';
2+
import routes, {createHref, getVDiskPagePath} from '../../routes';
3+
import type {TVDiskStateInfo, TVSlotId} from '../../types/api/vdisk';
4+
import {valueIsDefined} from '../../utils';
5+
import {stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters';
6+
import {isFullVDiskData} from '../../utils/disks/helpers';
7+
8+
export function getVDiskLink(data: TVDiskStateInfo | TVSlotId) {
9+
let vDiskPath: string | undefined;
10+
11+
const isFullData = isFullVDiskData(data);
12+
const VDiskSlotId = isFullData ? data.VDiskSlotId : data.VSlotId;
13+
14+
if (
15+
valueIsDefined(VDiskSlotId) &&
16+
valueIsDefined(data.PDiskId) &&
17+
valueIsDefined(data.NodeId)
18+
) {
19+
vDiskPath = getVDiskPagePath(VDiskSlotId, data.PDiskId, data.NodeId);
20+
} else if (valueIsDefined(data.NodeId) && isFullVDiskData(data)) {
21+
vDiskPath = createHref(
22+
routes.node,
23+
{id: data.NodeId, activeTab: STRUCTURE},
24+
{
25+
pdiskId: data.PDiskId,
26+
vdiskId: stringifyVdiskId(data.VDiskId),
27+
},
28+
);
29+
}
30+
31+
return vDiskPath;
32+
}

src/components/VDiskPopup/VDiskPopup.tsx

+28
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@ import {EFlag} from '../../types/api/enums';
88
import {valueIsDefined} from '../../utils';
99
import {cn} from '../../utils/cn';
1010
import {EMPTY_DATA_PLACEHOLDER} from '../../utils/constants';
11+
import {stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters';
1112
import {isFullVDiskData} from '../../utils/disks/helpers';
1213
import type {PreparedVDisk, UnavailableDonor} from '../../utils/disks/types';
1314
import {useTypedSelector} from '../../utils/hooks';
1415
import {bytesToGB, bytesToSpeed} from '../../utils/utils';
1516
import type {InfoViewerItem} from '../InfoViewer';
1617
import {InfoViewer} from '../InfoViewer';
18+
import {InternalLink} from '../InternalLink';
1719
import {preparePDiskData} from '../PDiskPopup/PDiskPopup';
20+
import {getVDiskLink} from '../VDisk/utils';
1821

1922
import './VDiskPopup.scss';
2023

@@ -146,6 +149,30 @@ export const VDiskPopup = ({data, ...props}: VDiskPopupProps) => {
146149
[data, nodeHost, isFullData],
147150
);
148151

152+
const donorsInfo: InfoViewerItem[] = [];
153+
if ('Donors' in data && data.Donors) {
154+
const donors = data.Donors;
155+
for (const donor of donors) {
156+
const isFullDonorData = isFullVDiskData(donor);
157+
donorsInfo.push({
158+
label: 'VDisk',
159+
value: (
160+
<InternalLink to={getVDiskLink(donor)}>
161+
{stringifyVdiskId(
162+
isFullDonorData
163+
? donor.VDiskId
164+
: {
165+
NodeId: donor.NodeId,
166+
PDiskId: donor.PDiskId,
167+
VSlotId: donor.VSlotId,
168+
},
169+
)}
170+
</InternalLink>
171+
),
172+
});
173+
}
174+
}
175+
149176
return (
150177
<Popup
151178
contentClassName={b()}
@@ -159,6 +186,7 @@ export const VDiskPopup = ({data, ...props}: VDiskPopupProps) => {
159186
{data.DonorMode && <Label className={b('donor-label')}>Donor</Label>}
160187
<InfoViewer title="VDisk" info={vdiskInfo} size="s" />
161188
{pdiskInfo && <InfoViewer title="PDisk" info={pdiskInfo} size="s" />}
189+
{donorsInfo.length > 0 && <InfoViewer title="Donors" info={donorsInfo} size="s" />}
162190
</Popup>
163191
);
164192
};

src/containers/Storage/Disks/Disks.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22

3-
import {VDiskWithDonorsStack} from '../../../components/VDisk/VDiskWithDonorsStack';
3+
import {VDisk} from '../../../components/VDisk/VDisk';
44
import {cn} from '../../../utils/cn';
55
import {getPDiskId} from '../../../utils/disks/helpers';
66
import type {PreparedVDisk} from '../../../utils/disks/types';
@@ -72,7 +72,7 @@ function VDiskItem({vDisk, highlightedVDisk, inactive, setHighlightedVDisk}: Dis
7272
}}
7373
className={b('vdisk-item')}
7474
>
75-
<VDiskWithDonorsStack
75+
<VDisk
7676
data={vDiskToShow}
7777
compact
7878
inactive={inactive}

src/containers/Storage/PDisk/PDisk.tsx

+3-7
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import React from 'react';
33
import {DiskStateProgressBar} from '../../../components/DiskStateProgressBar/DiskStateProgressBar';
44
import {InternalLink} from '../../../components/InternalLink';
55
import {PDiskPopup} from '../../../components/PDiskPopup/PDiskPopup';
6-
import {VDiskWithDonorsStack} from '../../../components/VDisk/VDiskWithDonorsStack';
6+
import {VDisk} from '../../../components/VDisk/VDisk';
77
import routes, {createHref, getPDiskPagePath} from '../../../routes';
8-
import {useDiskPagesAvailable} from '../../../store/reducers/capabilities/hooks';
98
import {valueIsDefined} from '../../../utils';
109
import {cn} from '../../../utils/cn';
1110
import type {PreparedPDisk, PreparedVDisk} from '../../../utils/disks/types';
@@ -40,8 +39,6 @@ export const PDisk = ({
4039
}: PDiskProps) => {
4140
const [isPopupVisible, setIsPopupVisible] = React.useState(false);
4241

43-
const diskPagesAvailable = useDiskPagesAvailable();
44-
4542
const anchor = React.useRef(null);
4643

4744
const {NodeId, PDiskId} = data;
@@ -75,10 +72,9 @@ export const PDisk = ({
7572
flexGrow: Number(vdisk.AllocatedSize) || 1,
7673
}}
7774
>
78-
<VDiskWithDonorsStack
75+
<VDisk
7976
data={vdisk}
8077
inactive={!isVdiskActive(vdisk, viewContext)}
81-
stackClassName={b('donors-stack')}
8278
compact
8379
/>
8480
</div>
@@ -94,7 +90,7 @@ export const PDisk = ({
9490
pDiskPath = createHref(routes.node, {id: NodeId, activeTab: STRUCTURE}, {pdiskId: PDiskId});
9591
}
9692

97-
if (pDiskIdsDefined && diskPagesAvailable) {
93+
if (pDiskIdsDefined) {
9894
pDiskPath = getPDiskPagePath(PDiskId, NodeId);
9995
}
10096

src/utils/disks/__test__/calculateVDiskSeverity.test.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,7 @@ describe('VDisk state', () => {
148148
DonorMode: true,
149149
});
150150

151-
expect(severity1).not.toEqual(DISK_COLOR_STATE_TO_NUMERIC_SEVERITY.Blue);
152-
expect(severity1).toEqual(DISK_COLOR_STATE_TO_NUMERIC_SEVERITY.Green);
151+
expect(severity1).toEqual(DISK_COLOR_STATE_TO_NUMERIC_SEVERITY.Blue);
153152
expect(severity2).toEqual(DISK_COLOR_STATE_TO_NUMERIC_SEVERITY.Yellow);
154153
expect(severity3).toEqual(DISK_COLOR_STATE_TO_NUMERIC_SEVERITY.Red);
155154
});

src/utils/disks/calculateVDiskSeverity.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export function calculateVDiskSeverity(vDisk: TVDiskStateInfo) {
1313
return NOT_AVAILABLE_SEVERITY;
1414
}
1515

16-
const {DiskSpace, VDiskState, FrontQueues, Replicated, DonorMode} = vDisk;
16+
const {DiskSpace, VDiskState, FrontQueues, Replicated} = vDisk;
1717

1818
// if the disk is not available, this determines its status severity regardless of other features
1919
if (!VDiskState) {
@@ -30,8 +30,7 @@ export function calculateVDiskSeverity(vDisk: TVDiskStateInfo) {
3030
let severity = Math.max(DiskSpaceSeverity, VDiskSpaceSeverity, FrontQueuesSeverity);
3131

3232
// donors are always in the not replicated state since they are leftovers
33-
// painting them blue is useless
34-
if (!Replicated && !DonorMode && severity === DISK_COLOR_STATE_TO_NUMERIC_SEVERITY.Green) {
33+
if (!Replicated && severity === DISK_COLOR_STATE_TO_NUMERIC_SEVERITY.Green) {
3534
severity = DISK_COLOR_STATE_TO_NUMERIC_SEVERITY.Blue;
3635
}
3736

0 commit comments

Comments
 (0)