From b110309e37c87df78a92408614ee426e7ae4dd01 Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Fri, 28 Nov 2025 02:37:52 +0300 Subject: [PATCH 1/6] feat(ui): update Disk indicators visual design across console --- .../DiskStateProgressBar.scss | 28 +++++++--- .../DiskStateProgressBar.tsx | 3 + src/components/VDisk/VDisk.tsx | 1 + src/containers/Storage/Disks/Disks.scss | 10 ++-- src/containers/Storage/Disks/Disks.tsx | 2 +- src/containers/Storage/PDisk/PDisk.tsx | 1 + .../columns/columns.tsx | 4 +- src/containers/Storage/VDisks/VDisks.scss | 4 +- .../utils/useStorageColumnsSettings.ts | 2 +- src/styles/mixins.scss | 56 ++++++++++++++++--- 10 files changed, 85 insertions(+), 26 deletions(-) diff --git a/src/components/DiskStateProgressBar/DiskStateProgressBar.scss b/src/components/DiskStateProgressBar/DiskStateProgressBar.scss index e8ceb76438..6312fa8682 100644 --- a/src/components/DiskStateProgressBar/DiskStateProgressBar.scss +++ b/src/components/DiskStateProgressBar/DiskStateProgressBar.scss @@ -4,10 +4,12 @@ $block: &; $border-width: 1px; - $outer-border-radius: 4px; + $outer-border-radius: var(--g-border-radius-s); $inner-border-radius: $outer-border-radius - $border-width; + $outer-compact-border-radius: var(--g-border-radius-xs); + $inner-compact-border-radius: $outer-compact-border-radius - $border-width; - --progress-bar-full-height: var(--g-text-body-3-line-height); + --progress-bar-full-height: var(--g-text-subheader-2-line-height); --progress-bar-compact-height: 12px; --stripe-width: 4px; @@ -16,22 +18,31 @@ position: relative; z-index: 0; + overflow: hidden; + min-width: 50px; height: var(--progress-bar-full-height); text-align: center; + opacity: 0.7; color: var(--g-color-text-primary); border: $border-width solid var(--entity-state-border-color); border-radius: $outer-border-radius; background-color: var(--entity-state-background-color); - @include mixins.entity-state-colors(); + + @include mixins.entity-state-colors($block); + + &:hover, + &_highlighted { + opacity: 1; + } &_compact { min-width: 0; height: var(--progress-bar-compact-height); - border-radius: 2px; + border-radius: $outer-compact-border-radius; } &_faded { @@ -78,7 +89,7 @@ } &_compact { - border-radius: 1px; + border-radius: $inner-compact-border-radius; } &_inverted { @@ -93,9 +104,10 @@ position: relative; z-index: 2; - margin-right: var(--g-spacing-1); + margin-right: var(--g-spacing-half); - font-size: var(--g-text-body-1-font-size); + font-family: var(--g-text-caption-font-family); + font-size: var(--g-text-caption-1-font-size); // bar height minus borders line-height: calc(var(--progress-bar-full-height) - #{$border-width * 2}); @@ -106,7 +118,7 @@ position: relative; z-index: 2; - margin-left: var(--g-spacing-1); + margin-left: calc(var(--g-spacing-1) - $border-width); color: var(--entity-state-border-color); } diff --git a/src/components/DiskStateProgressBar/DiskStateProgressBar.tsx b/src/components/DiskStateProgressBar/DiskStateProgressBar.tsx index ac93c6ab82..c8c73c3827 100644 --- a/src/components/DiskStateProgressBar/DiskStateProgressBar.tsx +++ b/src/components/DiskStateProgressBar/DiskStateProgressBar.tsx @@ -24,6 +24,7 @@ interface DiskStateProgressBarProps { className?: string; isDonor?: boolean; withIcon?: boolean; + highlighted?: boolean; } export function DiskStateProgressBar({ @@ -38,6 +39,7 @@ export function DiskStateProgressBar({ className, isDonor, withIcon, + highlighted, }: DiskStateProgressBarProps) { const [inverted] = useSetting(SETTING_KEYS.INVERTED_DISKS); @@ -48,6 +50,7 @@ export function DiskStateProgressBar({ empty, inactive, striped, + highlighted, }; if (isDonor) { diff --git a/src/components/VDisk/VDisk.tsx b/src/components/VDisk/VDisk.tsx index 76eb71ce2e..d3765517ae 100644 --- a/src/components/VDisk/VDisk.tsx +++ b/src/components/VDisk/VDisk.tsx @@ -64,6 +64,7 @@ export const VDisk = ({ isDonor={isHealthyDonor} className={progressBarClassName} withIcon={withIcon} + highlighted={showPopup} /> diff --git a/src/containers/Storage/Disks/Disks.scss b/src/containers/Storage/Disks/Disks.scss index 4bb544e9df..3aee924175 100644 --- a/src/containers/Storage/Disks/Disks.scss +++ b/src/containers/Storage/Disks/Disks.scss @@ -2,7 +2,7 @@ display: flex; flex-direction: row; align-items: center; - gap: 20px; + gap: var(--g-spacing-4); width: max-content; @@ -19,13 +19,13 @@ flex-shrink: 0; } &__vdisk-progress-bar { - --progress-bar-compact-height: 18px; + --progress-bar-compact-height: 20px; - border-radius: 4px; + border-radius: var(--g-border-radius-m); } &__pdisk-item { - min-width: 80px; + min-width: 55px; margin-right: 4px; &_with-dc-margin { @@ -39,6 +39,6 @@ &__pdisk-progress-bar { --progress-bar-full-height: 20px; - text-align: left; + border-radius: var(--g-border-radius-m); } } diff --git a/src/containers/Storage/Disks/Disks.tsx b/src/containers/Storage/Disks/Disks.tsx index 66c2243c07..ce5244b916 100644 --- a/src/containers/Storage/Disks/Disks.tsx +++ b/src/containers/Storage/Disks/Disks.tsx @@ -16,7 +16,7 @@ import './Disks.scss'; const b = cn('ydb-storage-disks'); -const VDISKS_CONTAINER_WIDTH = 300; +const VDISKS_CONTAINER_WIDTH = 316; interface DisksProps { vDisks?: PreparedVDisk[]; diff --git a/src/containers/Storage/PDisk/PDisk.tsx b/src/containers/Storage/PDisk/PDisk.tsx index b79e72095a..777925006a 100644 --- a/src/containers/Storage/PDisk/PDisk.tsx +++ b/src/containers/Storage/PDisk/PDisk.tsx @@ -107,6 +107,7 @@ export const PDisk = ({ diskAllocatedPercent={data.AllocatedPercent} severity={data.Severity} className={progressBarClassName} + highlighted={showPopup} /> diff --git a/src/containers/Storage/PaginatedStorageGroupsTable/columns/columns.tsx b/src/containers/Storage/PaginatedStorageGroupsTable/columns/columns.tsx index 1a4c932c58..79e8bd20a5 100644 --- a/src/containers/Storage/PaginatedStorageGroupsTable/columns/columns.tsx +++ b/src/containers/Storage/PaginatedStorageGroupsTable/columns/columns.tsx @@ -247,7 +247,7 @@ const getVDisksColumn = (data?: GetStorageColumnsData): StorageGroupsColumn => ( /> ), align: DataTable.CENTER, - width: 780, // usually 8-9 vdisks, this width corresponds to 8 vdisks, column is expanded if more + width: 475, // usually 8-9 vdisks, this width corresponds to 8 vdisks, column is expanded if more resizeable: false, sortable: false, }); @@ -267,7 +267,7 @@ const getDisksColumn = (data?: GetStorageColumnsData): StorageGroupsColumn => ({ ); }, align: DataTable.CENTER, - width: 900, + width: 800, resizeable: false, sortable: false, }); diff --git a/src/containers/Storage/VDisks/VDisks.scss b/src/containers/Storage/VDisks/VDisks.scss index a8927d4afe..325a8952dc 100644 --- a/src/containers/Storage/VDisks/VDisks.scss +++ b/src/containers/Storage/VDisks/VDisks.scss @@ -4,8 +4,8 @@ } &__item { - width: 90px; - margin-right: 6px; + width: 55px; + margin-right: var(--g-spacing-1); &_with-dc-margin { margin-right: 12px; diff --git a/src/containers/Storage/utils/useStorageColumnsSettings.ts b/src/containers/Storage/utils/useStorageColumnsSettings.ts index d166fee074..b3049f2544 100644 --- a/src/containers/Storage/utils/useStorageColumnsSettings.ts +++ b/src/containers/Storage/utils/useStorageColumnsSettings.ts @@ -5,7 +5,7 @@ import type {StorageNodesPaginatedTableData} from '../types'; const PDISK_VDISK_WIDTH = 3; const PDISK_GAP_WIDTH = 2; -const PDISK_MIN_WIDTH = 120; +const PDISK_MIN_WIDTH = 165; const PDISK_MARGIN = 10; const MAX_SLOTS_DEFAULT = 1; const PAGNATED_TABLE_CELL_HORIZONTAL_PADDING = 10; diff --git a/src/styles/mixins.scss b/src/styles/mixins.scss index 2d1f18a825..2837f92b40 100644 --- a/src/styles/mixins.scss +++ b/src/styles/mixins.scss @@ -240,7 +240,7 @@ } } -@mixin entity-state-colors { +@mixin entity-state-colors($block: null) { --entity-state-border-color: var(--g-color-base-misc-heavy); --entity-state-background-color: var(--g-color-base-misc-light); --entity-state-fill-color: var(--g-color-base-misc-medium); @@ -248,24 +248,46 @@ &_green { --entity-state-font-color: var(--g-color-text-positive); - --entity-state-border-color: var(--g-color-base-positive-heavy); + --entity-state-border-color: var(--g-color-base-positive-medium); --entity-state-background-color: var(--g-color-base-positive-light); --entity-state-fill-color: var(--g-color-base-positive-medium); + + &:hover, + &#{$block}_highlighted { + --entity-state-border-color: var(--g-color-base-positive-medium-hover); + --entity-state-background-color: var(--g-color-base-positive-light-hover); + --entity-state-fill-color: var(--g-color-base-positive-heavy); + } } &_blue { --entity-state-font-color: var(--g-color-text-info); --entity-state-border-color: var(--g-color-base-info-heavy); - --entity-state-shadow-color: var(--g-color-base-info-light); + --entity-state-shadow-color: var(--g-color-base-info-medium); --entity-state-background-color: var(--g-color-base-info-light); --entity-state-fill-color: var(--g-color-base-info-medium); + + &:hover, + &#{$block}_highlighted { + --entity-state-border-color: var(--g-color-base-info-heavy-hover); + --entity-state-shadow-color: var(--g-color-base-info-heavy); + --entity-state-background-color: var(--g-color-base-info-light-hover); + --entity-state-fill-color: var(--g-color-base-info-medium-hover); + } } &_yellow { --entity-state-font-color: var(--g-color-text-warning); - --entity-state-border-color: var(--g-color-base-warning-heavy); - --entity-state-background-color: var(--g-color-base-yellow-light); - --entity-state-fill-color: var(--g-color-base-yellow-medium); + --entity-state-border-color: var(--g-color-base-warning-medium); + --entity-state-background-color: var(--g-color-base-warning-light); + --entity-state-fill-color: var(--g-color-base-warning-medium); + + &:hover, + &#{$block}_highlighted { + --entity-state-border-color: var(--g-color-base-warning-medium-hover); + --entity-state-background-color: var(--g-color-base-warning-light-hover); + --entity-state-fill-color: var(--g-color-base-warning-medium-hover); + } } &_red { @@ -273,6 +295,13 @@ --entity-state-border-color: var(--g-color-base-danger-heavy); --entity-state-background-color: var(--g-color-base-danger-light); --entity-state-fill-color: var(--g-color-base-danger-medium); + + &:hover, + &#{$block}_highlighted { + --entity-state-border-color: var(--g-color-base-danger-heavy-hover); + --entity-state-background-color: var(--g-color-base-danger-light); + --entity-state-fill-color: var(--g-color-base-danger-medium-hover); + } } &_darkgrey { @@ -281,10 +310,23 @@ --entity-state-shadow-color: var(--g-color-base-neutral-light); --entity-state-fill-color: var(--g-color-base-neutral-light); --entity-state-background-color: transparent; + + &:hover, + &#{$block}_highlighted { + --entity-state-border-color: var(--g-color-base-neutral-heavy-hover); + --entity-state-shadow-color: var(--g-color-base-neutral-light-hover); + --entity-state-fill-color: var(--g-color-base-neutral-light-hover); + --entity-state-background-color: transparent; + } } &__grey { --entity-state-font-color: var(--g-color-text-secondary); - --entity-state-border-color: var(--g-color-line-generic-hover); + --entity-state-background-color: var(--g-color-base-neutral-light-hover); + + &:hover, + &#{$block}_highlighted { + --entity-state-background-color: var(--g-color-base-neutral-medium); + } } } From af93b34ae25a5e36196998111874a4c034fafde9 Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Fri, 28 Nov 2025 12:52:02 +0300 Subject: [PATCH 2/6] Fix bugs --- src/components/VDisk/VDisk.tsx | 6 ++--- src/components/VDiskPopup/VDiskPopup.tsx | 22 +++++++------------ .../YDBDefinitionList/YDBDefinitionList.scss | 4 ---- src/utils/disks/helpers.ts | 3 +-- 4 files changed, 12 insertions(+), 23 deletions(-) diff --git a/src/components/VDisk/VDisk.tsx b/src/components/VDisk/VDisk.tsx index d3765517ae..0c31ff6a9a 100644 --- a/src/components/VDisk/VDisk.tsx +++ b/src/components/VDisk/VDisk.tsx @@ -41,7 +41,7 @@ export const VDisk = ({ const severity = data.Severity; const isReplicatingColor = severity === DISK_COLOR_STATE_TO_NUMERIC_SEVERITY.Blue; - const isHealthyDonor = data.DonorMode && isReplicatingColor; + const isDonor = data.DonorMode; return ( Date: Fri, 5 Dec 2025 18:50:35 +0300 Subject: [PATCH 3/6] Implement new highlighting --- .../DiskStateProgressBar.scss | 10 +- .../DiskStateProgressBar.tsx | 3 + src/components/HoverPopup/HoverPopup.tsx | 49 ++++++--- src/components/VDisk/VDisk.tsx | 7 +- src/components/VDisk/VDiskWithDonorsStack.tsx | 37 ++++++- src/containers/Storage/Disks/Disks.tsx | 41 ++++--- src/containers/Storage/PDisk/PDisk.tsx | 62 +++++++---- .../columns/StorageGroupsColumns.scss | 3 + .../columns/columns.tsx | 100 ++++++++++-------- .../columns/hooks.ts | 25 ++++- .../columns/types.ts | 6 ++ .../columns/StorageNodesColumns.scss | 2 + .../columns/columns.tsx | 25 ++++- .../columns/hooks.ts | 13 ++- .../columns/types.ts | 3 + src/containers/Storage/VDisks/VDisks.scss | 4 + src/containers/Storage/VDisks/VDisks.tsx | 14 ++- src/containers/Storage/utils/index.ts | 26 ++--- src/styles/mixins.scss | 14 +-- 19 files changed, 319 insertions(+), 125 deletions(-) diff --git a/src/components/DiskStateProgressBar/DiskStateProgressBar.scss b/src/components/DiskStateProgressBar/DiskStateProgressBar.scss index 6312fa8682..9a56776f8b 100644 --- a/src/components/DiskStateProgressBar/DiskStateProgressBar.scss +++ b/src/components/DiskStateProgressBar/DiskStateProgressBar.scss @@ -25,7 +25,6 @@ text-align: center; - opacity: 0.7; color: var(--g-color-text-primary); border: $border-width solid var(--entity-state-border-color); border-radius: $outer-border-radius; @@ -33,11 +32,6 @@ @include mixins.entity-state-colors($block); - &:hover, - &_highlighted { - opacity: 1; - } - &_compact { min-width: 0; height: var(--progress-bar-compact-height); @@ -53,6 +47,10 @@ opacity: 0.5; } + &_darkened { + opacity: 0.7; + } + &_empty { color: var(--g-color-text-hint); border-style: dashed; diff --git a/src/components/DiskStateProgressBar/DiskStateProgressBar.tsx b/src/components/DiskStateProgressBar/DiskStateProgressBar.tsx index c8c73c3827..6a6e81b8f6 100644 --- a/src/components/DiskStateProgressBar/DiskStateProgressBar.tsx +++ b/src/components/DiskStateProgressBar/DiskStateProgressBar.tsx @@ -25,6 +25,7 @@ interface DiskStateProgressBarProps { isDonor?: boolean; withIcon?: boolean; highlighted?: boolean; + darkened?: boolean; } export function DiskStateProgressBar({ @@ -40,6 +41,7 @@ export function DiskStateProgressBar({ isDonor, withIcon, highlighted, + darkened, }: DiskStateProgressBarProps) { const [inverted] = useSetting(SETTING_KEYS.INVERTED_DISKS); @@ -51,6 +53,7 @@ export function DiskStateProgressBar({ inactive, striped, highlighted, + darkened, }; if (isDonor) { diff --git a/src/components/HoverPopup/HoverPopup.tsx b/src/components/HoverPopup/HoverPopup.tsx index ac902e9a52..30e6b64ee3 100644 --- a/src/components/HoverPopup/HoverPopup.tsx +++ b/src/components/HoverPopup/HoverPopup.tsx @@ -34,44 +34,50 @@ export const HoverPopup = ({ delayOpen = DEBOUNCE_TIMEOUT, }: HoverPopupProps) => { const [isPopupVisible, setIsPopupVisible] = React.useState(false); + const [isPopupContentHovered, setIsPopupContentHovered] = React.useState(false); + const [isFocused, setIsFocused] = React.useState(false); + const anchor = React.useRef(null); const debouncedHandleShowPopup = React.useMemo( () => debounce(() => { setIsPopupVisible(true); - onShowPopup?.(); }, delayOpen), - [onShowPopup, delayOpen], + [delayOpen], ); const hidePopup = React.useCallback(() => { setIsPopupVisible(false); - onHidePopup?.(); - }, [onHidePopup]); + }, []); const debouncedHandleHidePopup = React.useMemo( - () => debounce(hidePopup, delayClose), + () => + debounce(() => { + hidePopup(); + }, delayClose), [hidePopup, delayClose], ); - const onMouseEnter = debouncedHandleShowPopup; + const onMouseEnter = () => { + debouncedHandleHidePopup.cancel(); + debouncedHandleShowPopup(); + }; const onMouseLeave = () => { debouncedHandleShowPopup.cancel(); debouncedHandleHidePopup(); }; - const [isPopupContentHovered, setIsPopupContentHovered] = React.useState(false); - const [isFocused, setIsFocused] = React.useState(false); - const onPopupMouseEnter = React.useCallback(() => { setIsPopupContentHovered(true); - }, []); + debouncedHandleHidePopup.cancel(); + }, [debouncedHandleHidePopup]); const onPopupMouseLeave = React.useCallback(() => { setIsPopupContentHovered(false); - }, []); + debouncedHandleHidePopup(); + }, [debouncedHandleHidePopup]); const onPopupContextMenu = React.useCallback(() => { setIsFocused(true); @@ -87,7 +93,26 @@ export const HoverPopup = ({ hidePopup(); }, [hidePopup]); - const open = isPopupVisible || showPopup || isPopupContentHovered || isFocused; + const internalOpen = isPopupVisible || isPopupContentHovered || isFocused; + const open = internalOpen || showPopup; + + const prevInternalOpenRef = React.useRef(internalOpen); + + React.useEffect(() => { + const prev = prevInternalOpenRef.current; + + if (prev === internalOpen) { + return; + } + + if (internalOpen) { + onShowPopup?.(); + } else { + onHidePopup?.(); + } + + prevInternalOpenRef.current = internalOpen; + }, [internalOpen, onShowPopup, onHidePopup]); return ( diff --git a/src/components/VDisk/VDisk.tsx b/src/components/VDisk/VDisk.tsx index 0c31ff6a9a..ddcd7ac8c7 100644 --- a/src/components/VDisk/VDisk.tsx +++ b/src/components/VDisk/VDisk.tsx @@ -22,6 +22,8 @@ export interface VDiskProps { delayOpen?: number; delayClose?: number; withIcon?: boolean; + highlighted?: boolean; + darkened?: boolean; } export const VDisk = ({ @@ -35,6 +37,8 @@ export const VDisk = ({ delayClose, delayOpen, withIcon, + highlighted, + darkened, }: VDiskProps) => { const getVDiskLink = useVDiskPagePath(); const vDiskPath = getVDiskLink({nodeId: data.NodeId, vDiskId: data.StringifiedId}); @@ -64,7 +68,8 @@ export const VDisk = ({ isDonor={isDonor} className={progressBarClassName} withIcon={withIcon} - highlighted={showPopup} + highlighted={highlighted} + darkened={darkened} /> diff --git a/src/components/VDisk/VDiskWithDonorsStack.tsx b/src/components/VDisk/VDiskWithDonorsStack.tsx index e1411310d8..ee2374a060 100644 --- a/src/components/VDisk/VDiskWithDonorsStack.tsx +++ b/src/components/VDisk/VDiskWithDonorsStack.tsx @@ -10,6 +10,9 @@ interface VDiskWithDonorsStackProps extends VDiskProps { data?: PreparedVDisk; className?: string; stackClassName?: string; + highlightedVDisk?: string; + setHighlightedVDisk?: (id?: string) => void; + progressBarClassName?: string; } export function VDiskWithDonorsStack({ @@ -17,30 +20,54 @@ export function VDiskWithDonorsStack({ className, stackClassName, withIcon, + highlightedVDisk, + setHighlightedVDisk, ...restProps }: VDiskWithDonorsStackProps) { const {Donors: donors, ...restData} = data || {}; + const stackId = data?.StringifiedId; + const isHighlighted = Boolean(stackId && highlightedVDisk === stackId); + const isDarkened = Boolean(highlightedVDisk && highlightedVDisk !== stackId); + + const handleShowPopup = () => { + if (stackId) { + setHighlightedVDisk?.(stackId); + } + }; + + const handleHidePopup = () => { + setHighlightedVDisk?.(undefined); + }; + + const commonVDiskProps: Partial = { + withIcon, + showPopup: isHighlighted, + highlighted: isHighlighted, + darkened: isDarkened, + onShowPopup: handleShowPopup, + onHidePopup: handleHidePopup, + ...restProps, + }; + const content = donors && donors.length > 0 ? ( - + {donors.map((donor) => { const isFullData = isFullVDiskData(donor); - // donor and acceptor are always in the same group return ( ); })} ) : ( - + ); return
{content}
; diff --git a/src/containers/Storage/Disks/Disks.tsx b/src/containers/Storage/Disks/Disks.tsx index ce5244b916..138bc929c6 100644 --- a/src/containers/Storage/Disks/Disks.tsx +++ b/src/containers/Storage/Disks/Disks.tsx @@ -1,5 +1,3 @@ -import React from 'react'; - import {Flex, useLayoutContext} from '@gravity-ui/uikit'; import {VDisk} from '../../../components/VDisk/VDisk'; @@ -23,11 +21,18 @@ interface DisksProps { viewContext?: StorageViewContext; erasure?: Erasure; withIcon?: boolean; + highlightedVDisk?: string; + setHighlightedVDisk?: (id?: string) => void; } -export function Disks({vDisks = [], viewContext, erasure, withIcon}: DisksProps) { - const [highlightedVDisk, setHighlightedVDisk] = React.useState(); - +export function Disks({ + vDisks = [], + viewContext, + erasure, + withIcon, + highlightedVDisk, + setHighlightedVDisk, +}: DisksProps) { const vDisksWithDCMargins = useVDisksWithDCMargins(vDisks, erasure); const { @@ -76,8 +81,8 @@ export function Disks({vDisks = [], viewContext, erasure, withIcon}: DisksProps) interface DisksItemProps { vDisk: PreparedVDisk; inactive?: boolean; - highlightedVDisk: string | undefined; - setHighlightedVDisk: (id: string | undefined) => void; + highlightedVDisk?: string; + setHighlightedVDisk?: (id?: string) => void; unavailableVDiskWidth?: number; withDCMargin?: boolean; withIcon?: boolean; @@ -100,6 +105,9 @@ function VDiskItem({ const minWidth = isNumeric(vDiskToShow.AllocatedSize) ? undefined : unavailableVDiskWidth; const flexGrow = Number(vDiskToShow.AllocatedSize) || 1; + const isHighlighted = highlightedVDisk === vDiskId; + const darkened = Boolean(highlightedVDisk && highlightedVDisk !== vDiskId); + return (
setHighlightedVDisk(vDiskId)} - onHidePopup={() => setHighlightedVDisk(undefined)} + onShowPopup={() => setHighlightedVDisk?.(vDiskId)} + onHidePopup={() => setHighlightedVDisk?.(undefined)} progressBarClassName={b('vdisk-progress-bar')} + highlighted={isHighlighted} + darkened={darkened} />
); @@ -127,6 +137,9 @@ function PDiskItem({ }: DisksItemProps) { const vDiskId = vDisk.StringifiedId; + const isHighlighted = highlightedVDisk === vDiskId; + const darkened = Boolean(highlightedVDisk && highlightedVDisk !== vDiskId); + if (!vDisk.PDisk) { return null; } @@ -136,12 +149,14 @@ function PDiskItem({ className={b('pdisk-item', {['with-dc-margin']: withDCMargin})} progressBarClassName={b('pdisk-progress-bar')} data={vDisk.PDisk} - showPopup={highlightedVDisk === vDiskId} + showPopup={isHighlighted} delayOpen={DISKS_POPUP_DEBOUNCE_TIMEOUT} delayClose={DISKS_POPUP_DEBOUNCE_TIMEOUT} - onShowPopup={() => setHighlightedVDisk(vDiskId)} - onHidePopup={() => setHighlightedVDisk(undefined)} + onShowPopup={() => setHighlightedVDisk?.(vDiskId)} + onHidePopup={() => setHighlightedVDisk?.(undefined)} withIcon={withIcon} + highlighted={isHighlighted} + darkened={darkened} /> ); } diff --git a/src/containers/Storage/PDisk/PDisk.tsx b/src/containers/Storage/PDisk/PDisk.tsx index 777925006a..631cbfa654 100644 --- a/src/containers/Storage/PDisk/PDisk.tsx +++ b/src/containers/Storage/PDisk/PDisk.tsx @@ -31,6 +31,10 @@ interface PDiskProps { delayOpen?: number; delayClose?: number; withIcon?: boolean; + highlighted?: boolean; + darkened?: boolean; + highlightedPDisk?: string; + setHighlightedPDisk?: (id?: string) => void; } export const PDisk = ({ @@ -46,6 +50,10 @@ export const PDisk = ({ delayOpen = DISKS_POPUP_DEBOUNCE_TIMEOUT, delayClose = DISKS_POPUP_DEBOUNCE_TIMEOUT, withIcon, + highlighted, + darkened, + highlightedPDisk, + setHighlightedPDisk, }: PDiskProps) => { const {NodeId, PDiskId} = data; const pDiskIdsDefined = !isNil(NodeId) && !isNil(PDiskId); @@ -58,26 +66,37 @@ export const PDisk = ({ return (
- {vDisks.map((vdisk) => ( -
- -
- ))} + {vDisks.map((vdisk) => { + const vDiskId = vdisk.StringifiedId; + const vDiskHighlighted = highlightedPDisk === vDiskId; + const vDiskDarkened = Boolean(highlightedPDisk && highlightedPDisk !== vDiskId); + + return ( +
+ setHighlightedPDisk?.(vDiskId)} + onHidePopup={() => setHighlightedPDisk?.(undefined)} + highlighted={vDiskHighlighted} + darkened={vDiskDarkened} + /> +
+ ); + })}
); }; @@ -107,7 +126,8 @@ export const PDisk = ({ diskAllocatedPercent={data.AllocatedPercent} severity={data.Severity} className={progressBarClassName} - highlighted={showPopup} + highlighted={highlighted} + darkened={darkened} />
diff --git a/src/containers/Storage/PaginatedStorageGroupsTable/columns/StorageGroupsColumns.scss b/src/containers/Storage/PaginatedStorageGroupsTable/columns/StorageGroupsColumns.scss index b4c4a9a1a6..05b0f1d687 100644 --- a/src/containers/Storage/PaginatedStorageGroupsTable/columns/StorageGroupsColumns.scss +++ b/src/containers/Storage/PaginatedStorageGroupsTable/columns/StorageGroupsColumns.scss @@ -20,3 +20,6 @@ font-weight: 500; } } + +@include mixins.hover-dim-column-class('ydb-storage-groups-columns__disks-column'); +@include mixins.hover-dim-column-class('ydb-storage-groups-columns__vdisks-column'); diff --git a/src/containers/Storage/PaginatedStorageGroupsTable/columns/columns.tsx b/src/containers/Storage/PaginatedStorageGroupsTable/columns/columns.tsx index 79e8bd20a5..5378860d9a 100644 --- a/src/containers/Storage/PaginatedStorageGroupsTable/columns/columns.tsx +++ b/src/containers/Storage/PaginatedStorageGroupsTable/columns/columns.tsx @@ -16,7 +16,7 @@ import {formatToMs} from '../../../../utils/timeParsers'; import {bytesToGB, bytesToSpeed} from '../../../../utils/utils'; import {Disks} from '../../Disks/Disks'; import {VDisks} from '../../VDisks/VDisks'; -import {getDegradedSeverity} from '../../utils'; +import {getDegradedSeverity, isTopLevelStorageContext} from '../../utils'; import i18n from '../i18n'; import { @@ -123,10 +123,10 @@ const usageColumn: StorageGroupsColumn = { width: 85, resizeMinWidth: 75, render: ({row}) => { - return !isNil(row.Usage) ? ( - - ) : ( + return isNil(row.Usage) ? ( EMPTY_DATA_PLACEHOLDER + ) : ( + ); }, align: DataTable.LEFT, @@ -137,13 +137,13 @@ const diskSpaceUsageColumn: StorageGroupsColumn = { width: 115, resizeMinWidth: 75, render: ({row}) => { - return !isNil(row.DiskSpaceUsage) ? ( + return isNil(row.DiskSpaceUsage) ? ( + EMPTY_DATA_PLACEHOLDER + ) : ( - ) : ( - EMPTY_DATA_PLACEHOLDER ); }, align: DataTable.LEFT, @@ -215,9 +215,9 @@ const latencyColumn: StorageGroupsColumn = { header: STORAGE_GROUPS_COLUMNS_TITLES.Latency, width: 100, render: ({row}) => { - return !isNil(row.LatencyPutTabletLogMs) - ? formatToMs(row.LatencyPutTabletLogMs) - : EMPTY_DATA_PLACEHOLDER; + return isNil(row.LatencyPutTabletLogMs) + ? EMPTY_DATA_PLACEHOLDER + : formatToMs(row.LatencyPutTabletLogMs); }, align: DataTable.RIGHT, }; @@ -227,50 +227,64 @@ const allocationUnitsColumn: StorageGroupsColumn = { header: STORAGE_GROUPS_COLUMNS_TITLES.AllocationUnits, width: 150, render: ({row}) => { - return !isNil(row.AllocationUnits) - ? formatNumber(row.AllocationUnits) - : EMPTY_DATA_PLACEHOLDER; + return isNil(row.AllocationUnits) + ? EMPTY_DATA_PLACEHOLDER + : formatNumber(row.AllocationUnits); }, align: DataTable.RIGHT, }; -const getVDisksColumn = (data?: GetStorageColumnsData): StorageGroupsColumn => ({ - name: STORAGE_GROUPS_COLUMNS_IDS.VDisks, - header: STORAGE_GROUPS_COLUMNS_TITLES.VDisks, - className: b('vdisks-column'), - render: ({row}) => ( - - ), - align: DataTable.CENTER, - width: 475, // usually 8-9 vdisks, this width corresponds to 8 vdisks, column is expanded if more - resizeable: false, - sortable: false, -}); +const getVDisksColumn = (data?: GetStorageColumnsData): StorageGroupsColumn => { + const highlightEnabled = isTopLevelStorageContext(data?.viewContext); + const highlightedVDisk = highlightEnabled ? data?.highlightedVDisksVDisk : undefined; + const setHighlightedVDisk = highlightEnabled ? data?.setHighlightedVDisksVDisk : undefined; -const getDisksColumn = (data?: GetStorageColumnsData): StorageGroupsColumn => ({ - name: STORAGE_GROUPS_COLUMNS_IDS.VDisksPDisks, - header: STORAGE_GROUPS_COLUMNS_TITLES.VDisksPDisks, - className: b('disks-column'), - render: ({row}) => { - return ( + return { + name: STORAGE_GROUPS_COLUMNS_IDS.VDisks, + header: STORAGE_GROUPS_COLUMNS_TITLES.VDisks, + className: b('vdisks-column', {highlighted: highlightEnabled}), + render: ({row}) => ( + + ), + align: DataTable.CENTER, + width: 475, // usually 8-9 vdisks, this width corresponds to 8 vdisks, column is expanded if more + resizeable: false, + sortable: false, + }; +}; + +const getDisksColumn = (data?: GetStorageColumnsData): StorageGroupsColumn => { + const highlightEnabled = isTopLevelStorageContext(data?.viewContext); + const highlightedVDisk = highlightEnabled ? data?.highlightedVDisk : undefined; + const setHighlightedVDisk = highlightEnabled ? data?.setHighlightedVDisk : undefined; + + return { + name: STORAGE_GROUPS_COLUMNS_IDS.VDisksPDisks, + header: STORAGE_GROUPS_COLUMNS_TITLES.VDisksPDisks, + className: b('disks-column', {highlighted: highlightEnabled}), + render: ({row}) => ( - ); - }, - align: DataTable.CENTER, - width: 800, - resizeable: false, - sortable: false, -}); + ), + align: DataTable.CENTER, + width: 800, + resizeable: false, + sortable: false, + }; +}; export const getStorageTopGroupsColumns: StorageColumnsGetter = () => { return [groupIdColumn, typeColumn, erasureColumn, usageColumn, usedColumn, limitColumn]; diff --git a/src/containers/Storage/PaginatedStorageGroupsTable/columns/hooks.ts b/src/containers/Storage/PaginatedStorageGroupsTable/columns/hooks.ts index eaffdf2711..5aa75f7790 100644 --- a/src/containers/Storage/PaginatedStorageGroupsTable/columns/hooks.ts +++ b/src/containers/Storage/PaginatedStorageGroupsTable/columns/hooks.ts @@ -28,8 +28,20 @@ export function useStorageGroupsSelectedColumns({ const isViewerUser = useIsViewerUser(); const bridgeModeEnabled = useBridgeModeEnabled(); + const [highlightedVDisk, setHighlightedVDisk] = React.useState(); + + const [highlightedVDisksVDisk, setHighlightedVDisksVDisk] = React.useState< + string | undefined + >(); + const columns = React.useMemo(() => { - const allColumns = getStorageGroupsColumns({viewContext}); + const allColumns = getStorageGroupsColumns({ + viewContext, + highlightedVDisk, + setHighlightedVDisk, + highlightedVDisksVDisk, + setHighlightedVDisksVDisk, + }); const filteredByBridge = bridgeModeEnabled ? allColumns : allColumns.filter((c) => c.name !== STORAGE_GROUPS_COLUMNS_IDS.PileName); @@ -44,7 +56,16 @@ export function useStorageGroupsSelectedColumns({ return filteredColumns; } return filteredColumns.filter((column) => !isViewerGroupsColumn(column.name)); - }, [isUserAllowedToMakeChanges, viewContext, isViewerUser, bridgeModeEnabled]); + }, [ + isUserAllowedToMakeChanges, + viewContext, + isViewerUser, + bridgeModeEnabled, + highlightedVDisk, + setHighlightedVDisk, + highlightedVDisksVDisk, + setHighlightedVDisksVDisk, + ]); const requiredColumns = React.useMemo(() => { if (visibleEntities === VISIBLE_ENTITIES.missing) { diff --git a/src/containers/Storage/PaginatedStorageGroupsTable/columns/types.ts b/src/containers/Storage/PaginatedStorageGroupsTable/columns/types.ts index a7d30a47ad..3c8225d213 100644 --- a/src/containers/Storage/PaginatedStorageGroupsTable/columns/types.ts +++ b/src/containers/Storage/PaginatedStorageGroupsTable/columns/types.ts @@ -6,6 +6,12 @@ export type StorageGroupsColumn = Column; export interface GetStorageColumnsData { viewContext?: StorageViewContext; + + highlightedVDisk?: string; + setHighlightedVDisk?: (id: string | undefined) => void; + + highlightedVDisksVDisk?: string; + setHighlightedVDisksVDisk?: (id: string | undefined) => void; } export interface GetStorageGroupsColumnsParams { diff --git a/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss b/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss index 16e429a71b..272579859c 100644 --- a/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss +++ b/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss @@ -17,3 +17,5 @@ flex-shrink: 0; } } + +@include hover-dim-column-class('ydb-storage-nodes-columns__pdisks-column') diff --git a/src/containers/Storage/PaginatedStorageNodesTable/columns/columns.tsx b/src/containers/Storage/PaginatedStorageNodesTable/columns/columns.tsx index ad06d62944..0b73e683d1 100644 --- a/src/containers/Storage/PaginatedStorageNodesTable/columns/columns.tsx +++ b/src/containers/Storage/PaginatedStorageNodesTable/columns/columns.tsx @@ -25,6 +25,7 @@ import { import type {NodesColumn} from '../../../../components/nodesColumns/types'; import {cn} from '../../../../utils/cn'; import {PDisk} from '../../PDisk/PDisk'; +import {isTopLevelStorageContext} from '../../utils'; import type {GetStorageNodesColumnsParams} from './types'; @@ -35,11 +36,17 @@ const b = cn('ydb-storage-nodes-columns'); export const getPDisksColumn = ({ viewContext, columnsSettings, + highlightedPDisk, + setHighlightedPDisk, }: GetStorageNodesColumnsParams): NodesColumn => { + const highlightEnabled = isTopLevelStorageContext(viewContext); + const coloredPDisk = highlightEnabled ? highlightedPDisk : undefined; + const setColoredPDisk = highlightEnabled ? setHighlightedPDisk : undefined; + return { name: NODES_COLUMNS_IDS.PDisks, header: NODES_COLUMNS_TITLES.PDisks, - className: b('pdisks-column'), + className: b('pdisks-column', {highlighted: highlightEnabled}), width: columnsSettings?.pDiskContainerWidth, render: ({row}) => { return ( @@ -49,6 +56,11 @@ export const getPDisksColumn = ({ (vdisk) => vdisk.PDiskId === pDisk.PDiskId, ); + const id = `${row.NodeId}-${pDisk.PDiskId}`; + + const highlighted = highlightedPDisk === id; + const darkened = Boolean(highlightedPDisk && highlightedPDisk !== id); + return (
setColoredPDisk?.(id)} + onHidePopup={() => setColoredPDisk?.(undefined)} + highlighted={highlighted} + darkened={darkened} + highlightedPDisk={coloredPDisk} + setHighlightedPDisk={setColoredPDisk} />
); @@ -73,6 +92,8 @@ export const getStorageNodesColumns = ({ database, viewContext, columnsSettings, + highlightedPDisk, + setHighlightedPDisk, }: GetStorageNodesColumnsParams): NodesColumn[] => { const columns: NodesColumn[] = [ getNodeIdColumn(), @@ -89,7 +110,7 @@ export const getStorageNodesColumns = ({ getDiskSpaceUsageColumn(), getVersionColumn(), getMissingDisksColumn(), - getPDisksColumn({viewContext, columnsSettings}), + getPDisksColumn({viewContext, columnsSettings, highlightedPDisk, setHighlightedPDisk}), getTabletsColumn({database}), ]; diff --git a/src/containers/Storage/PaginatedStorageNodesTable/columns/hooks.ts b/src/containers/Storage/PaginatedStorageNodesTable/columns/hooks.ts index cba6c1b783..aa1b4faa72 100644 --- a/src/containers/Storage/PaginatedStorageNodesTable/columns/hooks.ts +++ b/src/containers/Storage/PaginatedStorageNodesTable/columns/hooks.ts @@ -24,14 +24,25 @@ export function useStorageNodesSelectedColumns({ }: GetStorageNodesColumnsParams) { const bridgeModeEnabled = useBridgeModeEnabled(); + const [highlightedPDisk, setHighlightedPDisk] = React.useState(); + const columns = React.useMemo(() => { const all = getStorageNodesColumns({ database, viewContext, columnsSettings, + highlightedPDisk, + setHighlightedPDisk, }); return bridgeModeEnabled ? all : all.filter((c) => c.name !== NODES_COLUMNS_IDS.PileName); - }, [database, viewContext, columnsSettings, bridgeModeEnabled]); + }, [ + database, + viewContext, + columnsSettings, + bridgeModeEnabled, + highlightedPDisk, + setHighlightedPDisk, + ]); const requiredColumns = React.useMemo(() => { if (visibleEntities === VISIBLE_ENTITIES.missing) { diff --git a/src/containers/Storage/PaginatedStorageNodesTable/columns/types.ts b/src/containers/Storage/PaginatedStorageNodesTable/columns/types.ts index 4f559144a6..e65f3f0544 100644 --- a/src/containers/Storage/PaginatedStorageNodesTable/columns/types.ts +++ b/src/containers/Storage/PaginatedStorageNodesTable/columns/types.ts @@ -11,4 +11,7 @@ export interface GetStorageNodesColumnsParams { database?: string; viewContext?: StorageViewContext; columnsSettings?: StorageNodesColumnsSettings; + + highlightedPDisk?: string; + setHighlightedPDisk?: (id: string | undefined) => void; } diff --git a/src/containers/Storage/VDisks/VDisks.scss b/src/containers/Storage/VDisks/VDisks.scss index 325a8952dc..5b9a10224e 100644 --- a/src/containers/Storage/VDisks/VDisks.scss +++ b/src/containers/Storage/VDisks/VDisks.scss @@ -21,4 +21,8 @@ } } } + + &__vdisks-progress-bar { + border-radius: var(--g-border-radius-m); + } } diff --git a/src/containers/Storage/VDisks/VDisks.tsx b/src/containers/Storage/VDisks/VDisks.tsx index b268cbd598..296c7d61df 100644 --- a/src/containers/Storage/VDisks/VDisks.tsx +++ b/src/containers/Storage/VDisks/VDisks.tsx @@ -15,9 +15,18 @@ interface VDisksProps { viewContext?: StorageViewContext; erasure?: Erasure; withIcon?: boolean; + highlightedVDisk?: string; + setHighlightedVDisk?: (id: string | undefined) => void; } -export function VDisks({vDisks, viewContext, erasure, withIcon}: VDisksProps) { +export function VDisks({ + vDisks, + viewContext, + erasure, + withIcon, + highlightedVDisk, + setHighlightedVDisk, +}: VDisksProps) { const vDisksWithDCMargins = useVDisksWithDCMargins(vDisks, erasure); return ( @@ -33,6 +42,9 @@ export function VDisks({vDisks, viewContext, erasure, withIcon}: VDisksProps) { className={b('item', { 'with-dc-margin': vDisksWithDCMargins.includes(index), })} + highlightedVDisk={highlightedVDisk} + setHighlightedVDisk={setHighlightedVDisk} + progressBarClassName={b('vdisks-progress-bar')} /> ))} diff --git a/src/containers/Storage/utils/index.ts b/src/containers/Storage/utils/index.ts index 8d7b7fea78..a929b8cf06 100644 --- a/src/containers/Storage/utils/index.ts +++ b/src/containers/Storage/utils/index.ts @@ -1,9 +1,10 @@ import React from 'react'; +import {isNil} from 'lodash'; + import {selectNodesMap} from '../../../store/reducers/nodesList'; import type {PreparedStorageGroup} from '../../../store/reducers/storage/types'; import type {Erasure} from '../../../types/api/storage'; -import {valueIsDefined} from '../../../utils'; import type {PreparedVDisk} from '../../../utils/disks/types'; import {generateEvaluator} from '../../../utils/generateEvaluator'; import {useTypedSelector} from '../../../utils/hooks'; @@ -30,25 +31,30 @@ export const getDegradedSeverity = (group: PreparedStorageGroup) => { export function isVdiskActive(vDisk: PreparedVDisk, viewContext?: StorageViewContext) { let isActive = true; - if (valueIsDefined(vDisk.VDiskId?.GroupID) && viewContext?.groupId) { + if (!isNil(vDisk.VDiskId?.GroupID) && viewContext?.groupId) { isActive &&= String(vDisk.VDiskId.GroupID) === viewContext.groupId; } - if (valueIsDefined(vDisk.NodeId) && viewContext?.nodeId) { + if (!isNil(vDisk.NodeId) && viewContext?.nodeId) { isActive &&= String(vDisk.NodeId) === viewContext.nodeId; } - if (valueIsDefined(vDisk.PDiskId) && viewContext?.pDiskId) { + if (!isNil(vDisk.PDiskId) && viewContext?.pDiskId) { isActive &&= String(vDisk.PDiskId) === viewContext.pDiskId; } - if (valueIsDefined(vDisk.VDiskSlotId) && viewContext?.vDiskSlotId) { + if (!isNil(vDisk.VDiskSlotId) && viewContext?.vDiskSlotId) { isActive &&= String(vDisk.VDiskSlotId) === viewContext.vDiskSlotId; } return isActive; } +export function isTopLevelStorageContext(context?: StorageViewContext): boolean { + // highlight the disk only where we are not committed to a specific node / p-disk / v-disk slot + return isNil(context?.nodeId) && isNil(context?.pDiskId) && isNil(context?.vDiskSlotId); +} + const DEFAULT_ENTITIES_COUNT = 10; // NodePage - 1 node @@ -58,11 +64,7 @@ const DEFAULT_ENTITIES_COUNT = 10; export function getStorageNodesInitialEntitiesCount( context?: StorageViewContext, ): number | undefined { - if ( - valueIsDefined(context?.nodeId) || - valueIsDefined(context?.pDiskId) || - valueIsDefined(context?.vDiskSlotId) - ) { + if (!isNil(context?.nodeId) || !isNil(context?.pDiskId) || !isNil(context?.vDiskSlotId)) { return 1; } @@ -76,10 +78,10 @@ export function getStorageNodesInitialEntitiesCount( export function getStorageGroupsInitialEntitiesCount( context?: StorageViewContext, ): number | undefined { - if (valueIsDefined(context?.groupId)) { + if (!isNil(context?.groupId)) { return 1; } - if (valueIsDefined(context?.vDiskSlotId)) { + if (!isNil(context?.vDiskSlotId)) { return 1; } diff --git a/src/styles/mixins.scss b/src/styles/mixins.scss index 2837f92b40..569b02cf60 100644 --- a/src/styles/mixins.scss +++ b/src/styles/mixins.scss @@ -252,7 +252,6 @@ --entity-state-background-color: var(--g-color-base-positive-light); --entity-state-fill-color: var(--g-color-base-positive-medium); - &:hover, &#{$block}_highlighted { --entity-state-border-color: var(--g-color-base-positive-medium-hover); --entity-state-background-color: var(--g-color-base-positive-light-hover); @@ -267,7 +266,6 @@ --entity-state-background-color: var(--g-color-base-info-light); --entity-state-fill-color: var(--g-color-base-info-medium); - &:hover, &#{$block}_highlighted { --entity-state-border-color: var(--g-color-base-info-heavy-hover); --entity-state-shadow-color: var(--g-color-base-info-heavy); @@ -282,7 +280,6 @@ --entity-state-background-color: var(--g-color-base-warning-light); --entity-state-fill-color: var(--g-color-base-warning-medium); - &:hover, &#{$block}_highlighted { --entity-state-border-color: var(--g-color-base-warning-medium-hover); --entity-state-background-color: var(--g-color-base-warning-light-hover); @@ -296,7 +293,6 @@ --entity-state-background-color: var(--g-color-base-danger-light); --entity-state-fill-color: var(--g-color-base-danger-medium); - &:hover, &#{$block}_highlighted { --entity-state-border-color: var(--g-color-base-danger-heavy-hover); --entity-state-background-color: var(--g-color-base-danger-light); @@ -311,7 +307,6 @@ --entity-state-fill-color: var(--g-color-base-neutral-light); --entity-state-background-color: transparent; - &:hover, &#{$block}_highlighted { --entity-state-border-color: var(--g-color-base-neutral-heavy-hover); --entity-state-shadow-color: var(--g-color-base-neutral-light-hover); @@ -324,9 +319,16 @@ --entity-state-font-color: var(--g-color-text-secondary); --entity-state-background-color: var(--g-color-base-neutral-light-hover); - &:hover, &#{$block}_highlighted { --entity-state-background-color: var(--g-color-base-neutral-medium); } } } + +@mixin hover-dim-column-class($column-class) { + .ydb-paginated-table__table:has(.#{$column-class}:hover) + .#{$column-class}_highlighted + .storage-disk-progress-bar:not(.storage-disk-progress-bar_highlighted) { + opacity: 0.7; + } +} From f57b4096a5645fa58a8c387e35010338f1efe4d9 Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Fri, 5 Dec 2025 18:53:26 +0300 Subject: [PATCH 4/6] Fix bugs --- src/containers/Storage/Disks/Disks.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/containers/Storage/Disks/Disks.scss b/src/containers/Storage/Disks/Disks.scss index 3aee924175..165ad76057 100644 --- a/src/containers/Storage/Disks/Disks.scss +++ b/src/containers/Storage/Disks/Disks.scss @@ -26,10 +26,10 @@ &__pdisk-item { min-width: 55px; - margin-right: 4px; + margin-right: var(--g-spacing-1); &_with-dc-margin { - margin-right: 12px; + margin-right: var(--g-spacing-3); } &:last-child { From 329c752a284800f3c2e53c48fe1a1558cf803c0a Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Fri, 5 Dec 2025 18:58:54 +0300 Subject: [PATCH 5/6] Fix bugs --- .../Storage/PaginatedStorageGroupsTable/columns/hooks.ts | 2 -- .../columns/StorageNodesColumns.scss | 2 +- .../Storage/PaginatedStorageNodesTable/columns/hooks.ts | 9 +-------- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/containers/Storage/PaginatedStorageGroupsTable/columns/hooks.ts b/src/containers/Storage/PaginatedStorageGroupsTable/columns/hooks.ts index 5aa75f7790..c1f72f350a 100644 --- a/src/containers/Storage/PaginatedStorageGroupsTable/columns/hooks.ts +++ b/src/containers/Storage/PaginatedStorageGroupsTable/columns/hooks.ts @@ -62,9 +62,7 @@ export function useStorageGroupsSelectedColumns({ isViewerUser, bridgeModeEnabled, highlightedVDisk, - setHighlightedVDisk, highlightedVDisksVDisk, - setHighlightedVDisksVDisk, ]); const requiredColumns = React.useMemo(() => { diff --git a/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss b/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss index 272579859c..f18e489ec8 100644 --- a/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss +++ b/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss @@ -18,4 +18,4 @@ } } -@include hover-dim-column-class('ydb-storage-nodes-columns__pdisks-column') +@include hover-dim-column-class('ydb-storage-nodes-columns__pdisks-column'); diff --git a/src/containers/Storage/PaginatedStorageNodesTable/columns/hooks.ts b/src/containers/Storage/PaginatedStorageNodesTable/columns/hooks.ts index aa1b4faa72..bddaf4e5de 100644 --- a/src/containers/Storage/PaginatedStorageNodesTable/columns/hooks.ts +++ b/src/containers/Storage/PaginatedStorageNodesTable/columns/hooks.ts @@ -35,14 +35,7 @@ export function useStorageNodesSelectedColumns({ setHighlightedPDisk, }); return bridgeModeEnabled ? all : all.filter((c) => c.name !== NODES_COLUMNS_IDS.PileName); - }, [ - database, - viewContext, - columnsSettings, - bridgeModeEnabled, - highlightedPDisk, - setHighlightedPDisk, - ]); + }, [database, viewContext, columnsSettings, bridgeModeEnabled, highlightedPDisk]); const requiredColumns = React.useMemo(() => { if (visibleEntities === VISIBLE_ENTITIES.missing) { From 94866fec4836dc60403ccbfd18d6babc69dcda27 Mon Sep 17 00:00:00 2001 From: Daria Vorontsova Date: Fri, 5 Dec 2025 19:00:38 +0300 Subject: [PATCH 6/6] Fix bugs --- .../columns/StorageNodesColumns.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss b/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss index f18e489ec8..7c7424f64f 100644 --- a/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss +++ b/src/containers/Storage/PaginatedStorageNodesTable/columns/StorageNodesColumns.scss @@ -1,4 +1,4 @@ -@import '../../../../styles/mixins.scss'; +@use '../../../../styles/mixins.scss'; .ydb-storage-nodes-columns { &__pdisks-column { @@ -18,4 +18,4 @@ } } -@include hover-dim-column-class('ydb-storage-nodes-columns__pdisks-column'); +@include mixins.hover-dim-column-class('ydb-storage-nodes-columns__pdisks-column');