import React from 'react'; import {Flex, useLayoutContext} from '@gravity-ui/uikit'; import {isNil} from 'lodash'; import {VDiskWithDonorsStack} from '../../../components/VDisk/VDiskWithDonorsStack'; import type {Erasure} from '../../../types/api/storage'; import {cn} from '../../../utils/cn'; import type { PDiskDisplayStateGetter, VDiskDisplayStateGetter, } from '../../../utils/disks/displayState'; import type {PreparedVDisk} from '../../../utils/disks/types'; import {PDisk} from '../PDisk'; import {DISKS_POPUP_DEBOUNCE_TIMEOUT} from '../shared'; import type {StorageViewContext} from '../types'; import {useStoragePDiskDisplayStateGetter} from '../useStoragePDiskDisplayStateGetter'; import {useStorageVDiskDisplayStateGetter} from '../useStorageVDiskDisplayStateGetter'; import {isPdiskActive, isVdiskActive, useVDisksWithDCMargins} from '../utils'; import {useVirtualizedDiskList} from '../utils/useVirtualizedDiskList'; import {calculateCompactVDiskWidths} from './calculateCompactVDiskWidths'; import { ALL_VDISK_WIDTH, EXPERT_MODE_PDISK_WIDTH, VDISKS_CONTAINER_WIDTH, getAllVDisksContainerWidth, } from './constants'; import './Disks.scss'; const b = cn('ydb-storage-disks'); interface DiskPopupState { id: string; vdisk: boolean; pdisk: boolean; } type DiskPopupChangeHandler = ( id: string | undefined, source: 'vdisk' | 'pdisk', open: boolean, closePair?: boolean, ) => void; interface DisksProps { vDisks?: PreparedVDisk[]; viewContext?: StorageViewContext; erasure?: Erasure; withIcon?: boolean; isAllVDisksLayout?: boolean; } interface DisksItemProps { vDisk: PreparedVDisk; viewContext?: StorageViewContext; inactive?: boolean; highlighted: boolean; onPopupChange: DiskPopupChangeHandler; compactVDiskWidth?: number; withDCMargin?: boolean; withIcon?: boolean; getDisplayState?: VDiskDisplayStateGetter; isAllVDisksLayout?: boolean; renderContent: boolean; placeholderProps?: React.HTMLAttributes; } const VDiskItem = React.memo(function VDiskItem({ vDisk, highlighted, inactive, onPopupChange, compactVDiskWidth, withIcon, getDisplayState, isAllVDisksLayout, renderContent, placeholderProps, }: DisksItemProps) { const vDiskId = vDisk.StringifiedId; const setHighlightedVDisk = React.useCallback( (id?: string) => onPopupChange(vDiskId, 'vdisk', Boolean(id)), [onPopupChange, vDiskId], ); const onClosePopup = React.useCallback( () => onPopupChange(vDiskId, 'vdisk', false, true), [onPopupChange, vDiskId], ); const style: React.CSSProperties = isAllVDisksLayout ? {width: ALL_VDISK_WIDTH, flexBasis: ALL_VDISK_WIDTH} : {width: compactVDiskWidth, flexBasis: compactVDiskWidth}; return (
{isAllVDisksLayout ? (
) : null}
); }); const PDiskItem = React.memo(function PDiskItem({ vDisk, viewContext, highlighted, onPopupChange, withDCMargin, withIcon, getDisplayState, renderContent, placeholderProps, }: Omit & {getDisplayState?: PDiskDisplayStateGetter}) { const vDiskId = vDisk.StringifiedId; const onShowPopup = React.useCallback( () => onPopupChange(vDiskId, 'pdisk', true), [onPopupChange, vDiskId], ); const onHidePopup = React.useCallback( () => onPopupChange(vDiskId, 'pdisk', false), [onPopupChange, vDiskId], ); const onClosePopup = React.useCallback( () => onPopupChange(vDiskId, 'pdisk', false, true), [onPopupChange, vDiskId], ); if (!vDisk.PDisk) { // Preserve disk indices for focus tracking while virtualization is disabled. return