Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Storage): group disks by DC #1823

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions src/components/PDiskPopup/PDiskPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';

import {selectIsUserAllowedToMakeChanges} from '../../store/reducers/authentication/authentication';
import {selectNodeHostsMap} from '../../store/reducers/nodesList';
import {selectNodesMap} from '../../store/reducers/nodesList';
import {EFlag} from '../../types/api/enums';
import {valueIsDefined} from '../../utils';
import {EMPTY_DATA_PLACEHOLDER} from '../../utils/constants';
Expand All @@ -17,7 +17,7 @@ const errorColors = [EFlag.Orange, EFlag.Red, EFlag.Yellow];

export const preparePDiskData = (
data: PreparedPDisk,
nodeHost?: string,
nodeData?: {Host?: string; DC?: string},
withDeveloperUILink?: boolean,
) => {
const {
Expand Down Expand Up @@ -46,8 +46,11 @@ export const preparePDiskData = (
pdiskData.push({label: 'Node Id', value: NodeId});
}

if (nodeHost) {
pdiskData.push({label: 'Host', value: nodeHost});
if (nodeData?.Host) {
pdiskData.push({label: 'Host', value: nodeData.Host});
}
if (nodeData?.DC) {
pdiskData.push({label: 'DC', value: nodeData.DC});
}

if (Path) {
Expand Down Expand Up @@ -90,11 +93,11 @@ interface PDiskPopupProps {

export const PDiskPopup = ({data}: PDiskPopupProps) => {
const isUserAllowedToMakeChanges = useTypedSelector(selectIsUserAllowedToMakeChanges);
const nodeHostsMap = useTypedSelector(selectNodeHostsMap);
const nodeHost = valueIsDefined(data.NodeId) ? nodeHostsMap?.get(data.NodeId) : undefined;
const nodesMap = useTypedSelector(selectNodesMap);
const nodeData = valueIsDefined(data.NodeId) ? nodesMap?.get(data.NodeId) : undefined;
const info = React.useMemo(
() => preparePDiskData(data, nodeHost, isUserAllowedToMakeChanges),
[data, nodeHost, isUserAllowedToMakeChanges],
() => preparePDiskData(data, nodeData, isUserAllowedToMakeChanges),
[data, nodeData, isUserAllowedToMakeChanges],
);

return <InfoViewer title="PDisk" info={info} size="s" />;
Expand Down
10 changes: 5 additions & 5 deletions src/components/VDiskPopup/VDiskPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import {Label} from '@gravity-ui/uikit';

import {selectIsUserAllowedToMakeChanges} from '../../store/reducers/authentication/authentication';
import {selectNodeHostsMap} from '../../store/reducers/nodesList';
import {selectNodesMap} from '../../store/reducers/nodesList';
import {EFlag} from '../../types/api/enums';
import {valueIsDefined} from '../../utils';
import {cn} from '../../utils/cn';
Expand Down Expand Up @@ -188,14 +188,14 @@ export const VDiskPopup = ({data}: VDiskPopupProps) => {
[data, isFullData, isUserAllowedToMakeChanges],
);

const nodeHostsMap = useTypedSelector(selectNodeHostsMap);
const nodeHost = valueIsDefined(data.NodeId) ? nodeHostsMap?.get(data.NodeId) : undefined;
const nodesMap = useTypedSelector(selectNodesMap);
const nodeData = valueIsDefined(data.NodeId) ? nodesMap?.get(data.NodeId) : undefined;
const pdiskInfo = React.useMemo(
() =>
isFullData &&
data.PDisk &&
preparePDiskData(data.PDisk, nodeHost, isUserAllowedToMakeChanges),
[data, nodeHost, isFullData, isUserAllowedToMakeChanges],
preparePDiskData(data.PDisk, nodeData, isUserAllowedToMakeChanges),
[data, nodeData, isFullData, isUserAllowedToMakeChanges],
);

const donorsInfo: InfoViewerItem[] = [];
Expand Down
20 changes: 19 additions & 1 deletion src/containers/Storage/Disks/Disks.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,23 @@
display: flex;
flex-direction: row;
justify-content: left;
gap: 6px;

width: max-content;
}

&__vdisk-item {
flex-basis: 8px;
flex-shrink: 0;

margin-right: 4px;

&_with-dc-margin {
margin-right: 16px;
}

&:last-child {
margin-right: 0;
}
}
&__vdisk-progress-bar {
--progress-bar-compact-height: 18px;
Expand All @@ -27,6 +36,15 @@

&__pdisk-item {
min-width: 80px;
margin-right: 6px;

&_with-dc-margin {
margin-right: 20px;
}

&:last-child {
margin-right: 0;
}
}
&__pdisk-progress-bar {
--progress-bar-full-height: 20px;
Expand Down
23 changes: 16 additions & 7 deletions src/containers/Storage/Disks/Disks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {cn} from '../../../utils/cn';
import type {PreparedVDisk} from '../../../utils/disks/types';
import {PDisk} from '../PDisk';
import type {StorageViewContext} from '../types';
import {isVdiskActive} from '../utils';
import {isVdiskActive, useVDisksWithDCMargins} from '../utils';

import './Disks.scss';

Expand All @@ -24,6 +24,8 @@ interface DisksProps {
export function Disks({vDisks = [], viewContext}: DisksProps) {
const [highlightedVDisk, setHighlightedVDisk] = React.useState<string | undefined>();

const vDisksWithDCMargins = useVDisksWithDCMargins(vDisks);

const {
theme: {spaceBaseSize},
} = useLayoutContext();
Expand All @@ -37,26 +39,28 @@ export function Disks({vDisks = [], viewContext}: DisksProps) {

return (
<div className={b(null)}>
<Flex direction={'row'} gap={1} grow style={{width: VDISKS_CONTAINER_WIDTH}}>
{vDisks?.map((vDisk) => (
<Flex direction={'row'} grow style={{width: VDISKS_CONTAINER_WIDTH}}>
{vDisks?.map((vDisk, index) => (
<VDiskItem
key={vDisk.StringifiedId}
vDisk={vDisk}
inactive={!isVdiskActive(vDisk, viewContext)}
highlightedVDisk={highlightedVDisk}
setHighlightedVDisk={setHighlightedVDisk}
unavailableVDiskWidth={unavailableVDiskWidth}
withDCMargin={vDisksWithDCMargins.includes(index)}
/>
))}
</Flex>

<div className={b('pdisks-wrapper')}>
{vDisks?.map((vDisk) => (
{vDisks?.map((vDisk, index) => (
<PDiskItem
key={vDisk?.PDisk?.StringifiedId}
vDisk={vDisk}
highlightedVDisk={highlightedVDisk}
setHighlightedVDisk={setHighlightedVDisk}
withDCMargin={vDisksWithDCMargins.includes(index)}
/>
))}
</div>
Expand All @@ -70,6 +74,7 @@ interface DisksItemProps {
highlightedVDisk: string | undefined;
setHighlightedVDisk: (id: string | undefined) => void;
unavailableVDiskWidth?: number;
withDCMargin?: boolean;
}

function VDiskItem({
Expand All @@ -78,6 +83,7 @@ function VDiskItem({
inactive,
setHighlightedVDisk,
unavailableVDiskWidth,
withDCMargin,
}: DisksItemProps) {
// Do not show PDisk popup for VDisk
const vDiskToShow = {...vDisk, PDisk: undefined};
Expand All @@ -89,7 +95,10 @@ function VDiskItem({
const flexGrow = Number(vDiskToShow.AllocatedSize) || 1;

return (
<div style={{flexGrow, minWidth}} className={b('vdisk-item')}>
<div
style={{flexGrow, minWidth}}
className={b('vdisk-item', {['with-dc-margin']: withDCMargin})}
>
<VDisk
data={vDiskToShow}
compact
Expand All @@ -103,7 +112,7 @@ function VDiskItem({
);
}

function PDiskItem({vDisk, highlightedVDisk, setHighlightedVDisk}: DisksItemProps) {
function PDiskItem({vDisk, highlightedVDisk, setHighlightedVDisk, withDCMargin}: DisksItemProps) {
const vDiskId = vDisk.StringifiedId;

if (!vDisk.PDisk) {
Expand All @@ -112,7 +121,7 @@ function PDiskItem({vDisk, highlightedVDisk, setHighlightedVDisk}: DisksItemProp

return (
<PDisk
className={b('pdisk-item')}
className={b('pdisk-item', {['with-dc-margin']: withDCMargin})}
progressBarClassName={b('pdisk-progress-bar')}
data={vDisk.PDisk}
showPopup={highlightedVDisk === vDiskId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,6 @@
overflow: visible; // to enable stacked disks overflow the row
}

&__vdisks-wrapper {
display: flex;
justify-content: center;
gap: 10px;

min-width: 500px;
}
&__vdisks-item {
flex-grow: 1;

max-width: 200px;

.stack__layer {
.data-table__row:hover & {
background: var(--ydb-data-table-color-hover);
}
}
}

&__pool-name-wrapper {
overflow: hidden;

Expand Down
17 changes: 3 additions & 14 deletions src/containers/Storage/StorageGroups/columns/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {CellWithPopover} from '../../../../components/CellWithPopover/CellWithPo
import {InternalLink} from '../../../../components/InternalLink';
import {StatusIcon} from '../../../../components/StatusIcon/StatusIcon';
import {UsageLabel} from '../../../../components/UsageLabel/UsageLabel';
import {VDiskWithDonorsStack} from '../../../../components/VDisk/VDiskWithDonorsStack';
import {getStorageGroupPath} from '../../../../routes';
import {valueIsDefined} from '../../../../utils';
import {cn} from '../../../../utils/cn';
Expand All @@ -18,7 +17,8 @@ import {getUsageSeverity} from '../../../../utils/generateEvaluator';
import {formatToMs} from '../../../../utils/timeParsers';
import {bytesToGB, bytesToSpeed} from '../../../../utils/utils';
import {Disks} from '../../Disks/Disks';
import {getDegradedSeverity, isVdiskActive} from '../../utils';
import {VDisks} from '../../VDisks/VDisks';
import {getDegradedSeverity} from '../../utils';
import i18n from '../i18n';

import {
Expand Down Expand Up @@ -230,18 +230,7 @@ const getVDisksColumn = (data?: GetStorageColumnsData): StorageGroupsColumn => (
name: STORAGE_GROUPS_COLUMNS_IDS.VDisks,
header: STORAGE_GROUPS_COLUMNS_TITLES.VDisks,
className: b('vdisks-column'),
render: ({row}) => (
<div className={b('vdisks-wrapper')}>
{row.VDisks?.map((vDisk) => (
<VDiskWithDonorsStack
key={vDisk.StringifiedId}
data={vDisk}
inactive={!isVdiskActive(vDisk, data?.viewContext)}
className={b('vdisks-item')}
/>
))}
</div>
),
render: ({row}) => <VDisks vDisks={row.VDisks} viewContext={data?.viewContext} />,
align: DataTable.CENTER,
width: 900,
resizeable: false,
Expand Down
29 changes: 29 additions & 0 deletions src/containers/Storage/VDisks/VDisks.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.ydb-storage-vdisks {
&__wrapper {
display: flex;
justify-content: center;

min-width: 500px;
}

&__item {
flex-grow: 1;

max-width: 200px;
margin-right: 10px;

&_with-dc-margin {
margin-right: 20px;
}

&:last-child {
margin-right: 0px;
}

.stack__layer {
.data-table__row:hover & {
background: var(--ydb-data-table-color-hover);
}
}
}
}
33 changes: 33 additions & 0 deletions src/containers/Storage/VDisks/VDisks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {VDiskWithDonorsStack} from '../../../components/VDisk/VDiskWithDonorsStack';
import {cn} from '../../../utils/cn';
import type {PreparedVDisk} from '../../../utils/disks/types';
import type {StorageViewContext} from '../types';
import {isVdiskActive, useVDisksWithDCMargins} from '../utils';

import './VDisks.scss';

const b = cn('ydb-storage-vdisks');

interface VDisksProps {
vDisks?: PreparedVDisk[];
viewContext?: StorageViewContext;
}

export function VDisks({vDisks, viewContext}: VDisksProps) {
const vDisksWithDCMargins = useVDisksWithDCMargins(vDisks);

return (
<div className={b('wrapper')}>
{vDisks?.map((vDisk, index) => (
<VDiskWithDonorsStack
key={vDisk.StringifiedId}
data={vDisk}
inactive={!isVdiskActive(vDisk, viewContext)}
className={b('item', {
'with-dc-margin': vDisksWithDCMargins.includes(index),
})}
/>
))}
</div>
);
}
24 changes: 24 additions & 0 deletions src/containers/Storage/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import React from 'react';

import {selectNodesMap} from '../../../store/reducers/nodesList';
import type {PreparedStorageGroup} from '../../../store/reducers/storage/types';
import {valueIsDefined} from '../../../utils';
import type {PreparedVDisk} from '../../../utils/disks/types';
import {generateEvaluator} from '../../../utils/generateEvaluator';
import {useTypedSelector} from '../../../utils/hooks';
import type {StorageViewContext} from '../types';

const defaultDegradationEvaluator = generateEvaluator(['success', 'warning', 'danger'], 1, 2);
Expand Down Expand Up @@ -79,3 +83,23 @@ export function getStorageGroupsInitialEntitiesCount(

return DEFAULT_ENTITIES_COUNT;
}

export function useVDisksWithDCMargins(vDisks: PreparedVDisk[] = []) {
const nodesMap = useTypedSelector(selectNodesMap);

return React.useMemo(() => {
const disksWithMargins: number[] = [];

// Backend returns disks sorted by DC, so we don't need to apply any additional sorting
vDisks.forEach((disk, index) => {
const dc1 = nodesMap?.get(Number(disk?.NodeId))?.DC;
const dc2 = nodesMap?.get(Number(vDisks[index + 1]?.NodeId))?.DC;

if (dc1 !== dc2) {
disksWithMargins.push(index);
}
});

return disksWithMargins;
}, [vDisks, nodesMap]);
}
4 changes: 2 additions & 2 deletions src/containers/Tenant/Diagnostics/Partitions/Partitions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {skipToken} from '@reduxjs/toolkit/query';
import {ResponseError} from '../../../../components/Errors/ResponseError';
import {ResizeableDataTable} from '../../../../components/ResizeableDataTable/ResizeableDataTable';
import {TableSkeleton} from '../../../../components/TableSkeleton/TableSkeleton';
import {nodesListApi, selectNodeHostsMap} from '../../../../store/reducers/nodesList';
import {nodesListApi, selectNodesMap} from '../../../../store/reducers/nodesList';
import {partitionsApi, setSelectedConsumer} from '../../../../store/reducers/partitions/partitions';
import {selectConsumersNames, topicApi} from '../../../../store/reducers/topic';
import {cn} from '../../../../utils/cn';
Expand Down Expand Up @@ -55,7 +55,7 @@ export const Partitions = ({path, database}: PartitionsProps) => {
error: nodesError,
} = nodesListApi.useGetNodesListQuery(undefined);
const nodesLoading = nodesIsFetching && nodesData === undefined;
const nodeHostsMap = useTypedSelector(selectNodeHostsMap);
const nodeHostsMap = useTypedSelector(selectNodesMap);

const [hiddenColumns, setHiddenColumns] = useSetting<string[]>(PARTITIONS_HIDDEN_COLUMNS_KEY);

Expand Down
Loading
Loading