Skip to content

Commit 3d780aa

Browse files
feat(Storage): add advanced disks view (#1235)
1 parent 2d06930 commit 3d780aa

File tree

28 files changed

+396
-151
lines changed

28 files changed

+396
-151
lines changed

src/components/DiskStateProgressBar/DiskStateProgressBar.scss

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
--progress-bar-border-color: var(--g-color-base-misc-heavy);
99
--progress-bar-background-color: var(--g-color-base-misc-light);
1010
--progress-bar-fill-color: var(--g-color-base-misc-medium);
11+
--progress-bar-full-height: var(--g-text-body-3-line-height);
12+
--progress-bar-compact-height: 12px;
1113

1214
position: relative;
1315
z-index: 0;
1416

1517
min-width: 50px;
16-
height: var(--g-text-body-3-line-height);
18+
height: var(--progress-bar-full-height);
1719

1820
text-align: center;
1921

@@ -24,7 +26,7 @@
2426

2527
&_compact {
2628
min-width: 0;
27-
height: 12px;
29+
height: var(--progress-bar-compact-height);
2830

2931
border-radius: 2px;
3032
}
@@ -101,7 +103,7 @@
101103

102104
font-size: var(--g-text-body-1-font-size);
103105
// bar height minus borders
104-
line-height: calc(var(--g-text-body-3-line-height) - #{$border-width * 2});
106+
line-height: calc(var(--progress-bar-full-height) - #{$border-width * 2});
105107

106108
color: inherit;
107109
}

src/components/PDiskPopup/PDiskPopup.tsx

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

66
import {EFlag} from '../../types/api/enums';
77
import type {NodesMap} from '../../types/store/nodesList';
8-
import {valueIsDefined} from '../../utils';
98
import {cn} from '../../utils/cn';
109
import {EMPTY_DATA_PLACEHOLDER} from '../../utils/constants';
1110
import {getPDiskId} from '../../utils/disks/helpers';
@@ -26,10 +25,7 @@ export const preparePDiskData = (data: PreparedPDisk, nodes?: NodesMap) => {
2625
const pdiskData: InfoViewerItem[] = [
2726
{
2827
label: 'PDisk',
29-
value:
30-
valueIsDefined(NodeId) && valueIsDefined(PDiskId)
31-
? getPDiskId(NodeId, PDiskId)
32-
: EMPTY_DATA_PLACEHOLDER,
28+
value: getPDiskId(NodeId, PDiskId) ?? EMPTY_DATA_PLACEHOLDER,
3329
},
3430
{label: 'State', value: State || 'not available'},
3531
{label: 'Type', value: Type || 'unknown'},
@@ -75,6 +71,7 @@ export const PDiskPopup = ({data, nodes, ...props}: PDiskPopupProps) => {
7571
<Popup
7672
contentClassName={b()}
7773
placement={['top', 'bottom']}
74+
hasArrow
7875
// bigger offset for easier switching to neighbour nodes
7976
// matches the default offset for popup with arrow out of a sense of beauty
8077
offset={[0, 12]}

src/components/VDisk/VDisk.tsx

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,25 @@ import './VDisk.scss';
1717

1818
const b = cn('ydb-vdisk-component');
1919

20-
interface VDiskProps {
20+
export interface VDiskProps {
2121
data?: PreparedVDisk;
2222
nodes?: NodesMap;
2323
compact?: boolean;
24+
showPopup?: boolean;
25+
onShowPopup?: VoidFunction;
26+
onHidePopup?: VoidFunction;
27+
progressBarClassName?: string;
2428
}
2529

26-
export const VDisk = ({data = {}, nodes, compact}: VDiskProps) => {
30+
export const VDisk = ({
31+
data = {},
32+
nodes,
33+
compact,
34+
showPopup,
35+
onShowPopup,
36+
onHidePopup,
37+
progressBarClassName,
38+
}: VDiskProps) => {
2739
const isFullData = isFullVDiskData(data);
2840

2941
const diskPagesAvailable = useDiskPagesAvailable();
@@ -32,12 +44,14 @@ export const VDisk = ({data = {}, nodes, compact}: VDiskProps) => {
3244

3345
const anchor = React.useRef(null);
3446

35-
const showPopup = () => {
47+
const handleShowPopup = () => {
3648
setIsPopupVisible(true);
49+
onShowPopup?.();
3750
};
3851

39-
const hidePopup = () => {
52+
const handleHidePopup = () => {
4053
setIsPopupVisible(false);
54+
onHidePopup?.();
4155
};
4256

4357
let vDiskPath: string | undefined;
@@ -62,24 +76,27 @@ export const VDisk = ({data = {}, nodes, compact}: VDiskProps) => {
6276

6377
return (
6478
<React.Fragment>
65-
<VDiskPopup data={data} nodes={nodes} anchorRef={anchor} open={isPopupVisible} />
66-
<div className={b()} ref={anchor} onMouseEnter={showPopup} onMouseLeave={hidePopup}>
67-
{vDiskPath ? (
68-
<InternalLink to={vDiskPath} className={b('content')}>
69-
<DiskStateProgressBar
70-
diskAllocatedPercent={data.AllocatedPercent}
71-
severity={data.Severity}
72-
compact={compact}
73-
/>
74-
</InternalLink>
75-
) : (
79+
<div
80+
className={b()}
81+
ref={anchor}
82+
onMouseEnter={handleShowPopup}
83+
onMouseLeave={handleHidePopup}
84+
>
85+
<InternalLink to={vDiskPath} className={b('content')}>
7686
<DiskStateProgressBar
7787
diskAllocatedPercent={data.AllocatedPercent}
7888
severity={data.Severity}
7989
compact={compact}
90+
className={progressBarClassName}
8091
/>
81-
)}
92+
</InternalLink>
8293
</div>
94+
<VDiskPopup
95+
data={data}
96+
nodes={nodes}
97+
anchorRef={anchor}
98+
open={isPopupVisible || showPopup}
99+
/>
83100
</React.Fragment>
84101
);
85102
};

src/components/VDisk/VDiskWithDonorsStack.tsx

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,29 @@
1-
import type {NodesMap} from '../../types/store/nodesList';
21
import {stringifyVdiskId} from '../../utils/dataFormatters/dataFormatters';
32
import {isFullVDiskData} from '../../utils/disks/helpers';
43
import type {PreparedVDisk} from '../../utils/disks/types';
54
import {Stack} from '../Stack/Stack';
65

6+
import type {VDiskProps} from './VDisk';
77
import {VDisk} from './VDisk';
88

9-
interface VDiskWithDonorsStackProps {
9+
interface VDiskWithDonorsStackProps extends VDiskProps {
1010
data?: PreparedVDisk;
11-
nodes?: NodesMap;
12-
compact?: boolean;
1311
className?: string;
1412
stackClassName?: string;
1513
}
1614

1715
export function VDiskWithDonorsStack({
1816
data,
19-
nodes,
20-
compact,
2117
className,
2218
stackClassName,
19+
...restProps
2320
}: VDiskWithDonorsStackProps) {
2421
const donors = data?.Donors;
2522

2623
const content =
2724
donors && donors.length > 0 ? (
2825
<Stack className={stackClassName}>
29-
<VDisk data={data} nodes={nodes} compact={compact} />
26+
<VDisk data={data} {...restProps} />
3027
{donors.map((donor) => {
3128
const isFullData = isFullVDiskData(donor);
3229

@@ -35,14 +32,13 @@ export function VDiskWithDonorsStack({
3532
<VDisk
3633
key={stringifyVdiskId(isFullData ? donor.VDiskId : donor)}
3734
data={donor}
38-
nodes={nodes}
39-
compact={compact}
35+
{...restProps}
4036
/>
4137
);
4238
})}
4339
</Stack>
4440
) : (
45-
<VDisk data={data} nodes={nodes} compact={compact} />
41+
<VDisk data={data} {...restProps} />
4642
);
4743

4844
return <div className={className}>{content}</div>;

src/components/VDiskPopup/VDiskPopup.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ export const VDiskPopup = ({data, nodes, ...props}: VDiskPopupProps) => {
148148
<Popup
149149
contentClassName={b()}
150150
placement={['top', 'bottom']}
151+
hasArrow
151152
// bigger offset for easier switching to neighbour nodes
152153
// matches the default offset for popup with arrow out of a sense of beauty
153154
offset={[0, 12]}

src/containers/PDiskPage/PDiskGroups/PDiskGroups.tsx

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
1-
import React from 'react';
2-
31
import {ResizeableDataTable} from '../../../components/ResizeableDataTable/ResizeableDataTable';
42
import {TableSkeleton} from '../../../components/TableSkeleton/TableSkeleton';
5-
import {selectNodesMap} from '../../../store/reducers/nodesList';
63
import {pDiskApi} from '../../../store/reducers/pdisk/pdisk';
74
import {DEFAULT_TABLE_SETTINGS} from '../../../utils/constants';
8-
import {useAutoRefreshInterval, useTypedSelector} from '../../../utils/hooks';
9-
import {
10-
STORAGE_GROUPS_COLUMNS_WIDTH_LS_KEY,
11-
getDiskPageStorageColumns,
12-
} from '../../Storage/StorageGroups/getStorageGroupsColumns';
5+
import {useAutoRefreshInterval} from '../../../utils/hooks';
6+
import {STORAGE_GROUPS_COLUMNS_WIDTH_LS_KEY} from '../../Storage/StorageGroups/columns/getStorageGroupsColumns';
7+
import {useGetDiskStorageColumns} from '../../Storage/StorageGroups/columns/hooks';
138

149
interface PDiskGroupsProps {
1510
nodeId: string | number;
1611
pDiskId: string | number;
1712
}
1813

1914
export function PDiskGroups({pDiskId, nodeId}: PDiskGroupsProps) {
20-
const nodesMap = useTypedSelector(selectNodesMap);
2115
const [autoRefreshInterval] = useAutoRefreshInterval();
2216

2317
const pDiskStorageQuery = pDiskApi.useGetStorageInfoQuery(
@@ -27,9 +21,7 @@ export function PDiskGroups({pDiskId, nodeId}: PDiskGroupsProps) {
2721
const loading = pDiskStorageQuery.isFetching && pDiskStorageQuery.currentData === undefined;
2822
const data = pDiskStorageQuery.currentData ?? [];
2923

30-
const pDiskStorageColumns = React.useMemo(() => {
31-
return getDiskPageStorageColumns(nodesMap);
32-
}, [nodesMap]);
24+
const pDiskStorageColumns = useGetDiskStorageColumns();
3325

3426
if (loading) {
3527
return <TableSkeleton />;

src/containers/PDiskPage/PDiskPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export function PDiskPage() {
137137
<EntityPageTitle
138138
entityName={pDiskPageKeyset('pdisk')}
139139
status={getSeverityColor(Severity)}
140-
id={pDiskParamsDefined ? getPDiskId(nodeId, pDiskId) : null}
140+
id={getPDiskId(nodeId, pDiskId)}
141141
className={pdiskPageCn('title')}
142142
/>
143143
);
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
.ydb-storage-disks {
2+
display: flex;
3+
flex-direction: row;
4+
align-items: center;
5+
gap: 20px;
6+
7+
width: max-content;
8+
9+
&__vdisks-wrapper {
10+
display: flex;
11+
flex-grow: 1;
12+
flex-direction: row;
13+
gap: 4px;
14+
15+
width: 300px;
16+
}
17+
18+
&__pdisks-wrapper {
19+
display: flex;
20+
flex-direction: row;
21+
justify-content: left;
22+
gap: 6px;
23+
24+
width: max-content;
25+
}
26+
27+
&__vdisk-item {
28+
flex-basis: 8px;
29+
flex-shrink: 0;
30+
}
31+
&__vdisk-progress-bar {
32+
--progress-bar-compact-height: 18px;
33+
34+
border-radius: 4px;
35+
}
36+
37+
&__pdisk-item {
38+
width: 80px;
39+
}
40+
&__pdisk-progress-bar {
41+
--progress-bar-full-height: 20px;
42+
padding-left: var(--g-spacing-2);
43+
44+
text-align: left;
45+
}
46+
}

0 commit comments

Comments
 (0)