Skip to content

Commit 29e38e2

Browse files
committed
feat(VDisk): show VDisk donors inside popup
1 parent 27484a0 commit 29e38e2

File tree

8 files changed

+73
-43
lines changed

8 files changed

+73
-43
lines changed

src/components/VDisk/VDisk.scss

Lines changed: 2 additions & 0 deletions
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

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +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 {stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters';
9-
import {isFullVDiskData} from '../../utils/disks/helpers';
104
import type {PreparedVDisk} from '../../utils/disks/types';
115
import {DiskStateProgressBar} from '../DiskStateProgressBar/DiskStateProgressBar';
126
import {InternalLink} from '../InternalLink';
137
import {VDiskPopup} from '../VDiskPopup/VDiskPopup';
148

9+
import {getVDiskLink} from './utils';
10+
1511
import './VDisk.scss';
1612

1713
const b = cn('ydb-vdisk-component');
@@ -35,10 +31,6 @@ export const VDisk = ({
3531
onHidePopup,
3632
progressBarClassName,
3733
}: VDiskProps) => {
38-
const isFullData = isFullVDiskData(data);
39-
40-
const diskPagesAvailable = useDiskPagesAvailable();
41-
4234
const [isPopupVisible, setIsPopupVisible] = React.useState(false);
4335

4436
const anchor = React.useRef(null);
@@ -53,25 +45,7 @@ export const VDisk = ({
5345
onHidePopup?.();
5446
};
5547

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

7650
return (
7751
<React.Fragment>

src/components/VDisk/VDiskWithDonorsStack.tsx

Lines changed: 2 additions & 2 deletions
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

Lines changed: 32 additions & 0 deletions
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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import {useTypedSelector} from '../../utils/hooks';
1616
import {bytesToGB, bytesToSpeed} from '../../utils/utils';
1717
import type {InfoViewerItem} from '../InfoViewer';
1818
import {InfoViewer} from '../InfoViewer';
19+
import {InternalLink} from '../InternalLink';
1920
import {preparePDiskData} from '../PDiskPopup/PDiskPopup';
21+
import {getVDiskLink} from '../VDisk/utils';
2022

2123
import './VDiskPopup.scss';
2224

@@ -148,6 +150,30 @@ export const VDiskPopup = ({data, ...props}: VDiskPopupProps) => {
148150
[data, nodeHost, isFullData],
149151
);
150152

153+
const donorsInfo: InfoViewerItem[] = [];
154+
if ('Donors' in data && data.Donors) {
155+
const donors = data.Donors;
156+
for (const donor of donors) {
157+
const isFullDonorData = isFullVDiskData(donor);
158+
donorsInfo.push({
159+
label: 'VDisk',
160+
value: (
161+
<InternalLink to={getVDiskLink(donor)}>
162+
{stringifyVdiskId(
163+
isFullDonorData
164+
? donor.VDiskId
165+
: {
166+
NodeId: donor.NodeId,
167+
PDiskId: donor.PDiskId,
168+
VSlotId: donor.VSlotId,
169+
},
170+
)}
171+
</InternalLink>
172+
),
173+
});
174+
}
175+
}
176+
151177
return (
152178
<Popup
153179
contentClassName={b()}
@@ -161,6 +187,7 @@ export const VDiskPopup = ({data, ...props}: VDiskPopupProps) => {
161187
{data.DonorMode && <Label className={b('donor-label')}>Donor</Label>}
162188
<InfoViewer title="VDisk" info={vdiskInfo} size="s" />
163189
{pdiskInfo && <InfoViewer title="PDisk" info={pdiskInfo} size="s" />}
190+
{donorsInfo.length > 0 && <InfoViewer title="Donors" info={donorsInfo} size="s" />}
164191
</Popup>
165192
);
166193
};

src/containers/Storage/Disks/Disks.tsx

Lines changed: 2 additions & 2 deletions
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 {stringifyVdiskId} from '../../../utils/dataFormatters/dataFormatters';
66
import {getPDiskId} from '../../../utils/disks/helpers';
@@ -73,7 +73,7 @@ function VDiskItem({vDisk, highlightedVDisk, inactive, setHighlightedVDisk}: Dis
7373
}}
7474
className={b('vdisk-item')}
7575
>
76-
<VDiskWithDonorsStack
76+
<VDisk
7777
data={vDiskToShow}
7878
compact
7979
inactive={inactive}

src/containers/Storage/PDisk/PDisk.tsx

Lines changed: 3 additions & 7 deletions
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 {stringifyVdiskId} from '../../../utils/dataFormatters/dataFormatters';
@@ -41,8 +40,6 @@ export const PDisk = ({
4140
}: PDiskProps) => {
4241
const [isPopupVisible, setIsPopupVisible] = React.useState(false);
4342

44-
const diskPagesAvailable = useDiskPagesAvailable();
45-
4643
const anchor = React.useRef(null);
4744

4845
const {NodeId, PDiskId} = data;
@@ -76,10 +73,9 @@ export const PDisk = ({
7673
flexGrow: Number(vdisk.AllocatedSize) || 1,
7774
}}
7875
>
79-
<VDiskWithDonorsStack
76+
<VDisk
8077
data={vdisk}
8178
inactive={!isVdiskActive(vdisk, viewContext)}
82-
stackClassName={b('donors-stack')}
8379
compact
8480
/>
8581
</div>
@@ -95,7 +91,7 @@ export const PDisk = ({
9591
pDiskPath = createHref(routes.node, {id: NodeId, activeTab: STRUCTURE}, {pdiskId: PDiskId});
9692
}
9793

98-
if (pDiskIdsDefined && diskPagesAvailable) {
94+
if (pDiskIdsDefined) {
9995
pDiskPath = getPDiskPagePath(PDiskId, NodeId);
10096
}
10197

src/utils/disks/calculateVDiskSeverity.ts

Lines changed: 2 additions & 3 deletions
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)