Skip to content

Commit ab2c179

Browse files
committed
fix: do not hide pdisk and vdisk popups if mouse on popup content
1 parent fc12a38 commit ab2c179

File tree

4 files changed

+47
-12
lines changed

4 files changed

+47
-12
lines changed

src/components/PDiskPopup/PDiskPopup.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ export const PDiskPopup = ({data, ...props}: PDiskPopupProps) => {
7070
const nodeHost = valueIsDefined(data.NodeId) ? nodeHostsMap?.get(data.NodeId) : undefined;
7171
const info = React.useMemo(() => preparePDiskData(data, nodeHost), [data, nodeHost]);
7272

73+
const [isPopupOpen, setIsPopupOpen] = React.useState(props.open);
74+
const onMouseLeave = React.useCallback(() => {
75+
setIsPopupOpen(false);
76+
}, []);
77+
const onMouseEnter = React.useCallback(() => {
78+
setIsPopupOpen(true);
79+
}, []);
80+
7381
return (
7482
<Popup
7583
contentClassName={b()}
@@ -78,7 +86,10 @@ export const PDiskPopup = ({data, ...props}: PDiskPopupProps) => {
7886
// bigger offset for easier switching to neighbour nodes
7987
// matches the default offset for popup with arrow out of a sense of beauty
8088
offset={[0, 12]}
89+
onMouseLeave={onMouseLeave}
90+
onMouseEnter={onMouseEnter}
8191
{...props}
92+
open={isPopupOpen || props.open}
8293
>
8394
<InfoViewer title="PDisk" info={info} size="s" />
8495
</Popup>

src/components/VDisk/VDisk.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from 'react';
22

3+
import {debounce} from 'lodash';
4+
35
import {cn} from '../../utils/cn';
46
import type {PreparedVDisk} from '../../utils/disks/types';
57
import {DiskStateProgressBar} from '../DiskStateProgressBar/DiskStateProgressBar';
@@ -12,6 +14,8 @@ import './VDisk.scss';
1214

1315
const b = cn('ydb-vdisk-component');
1416

17+
const DEBOUNCE_TIMEOUT = 100;
18+
1519
export interface VDiskProps {
1620
data?: PreparedVDisk;
1721
compact?: boolean;
@@ -35,15 +39,15 @@ export const VDisk = ({
3539

3640
const anchor = React.useRef(null);
3741

38-
const handleShowPopup = () => {
42+
const debouncedHandleShowPopup = debounce(() => {
3943
setIsPopupVisible(true);
4044
onShowPopup?.();
41-
};
45+
}, DEBOUNCE_TIMEOUT);
4246

43-
const handleHidePopup = () => {
47+
const debouncedHandleHidePopup = debounce(() => {
4448
setIsPopupVisible(false);
4549
onHidePopup?.();
46-
};
50+
}, DEBOUNCE_TIMEOUT);
4751

4852
const vDiskPath = getVDiskLink(data);
4953

@@ -52,8 +56,11 @@ export const VDisk = ({
5256
<div
5357
className={b()}
5458
ref={anchor}
55-
onMouseEnter={handleShowPopup}
56-
onMouseLeave={handleHidePopup}
59+
onMouseEnter={debouncedHandleShowPopup}
60+
onMouseLeave={() => {
61+
debouncedHandleShowPopup.cancel();
62+
debouncedHandleHidePopup();
63+
}}
5764
>
5865
<InternalLink to={vDiskPath} className={b('content')}>
5966
<DiskStateProgressBar

src/components/VDiskPopup/VDiskPopup.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ interface VDiskPopupProps extends PopupProps {
136136

137137
export const VDiskPopup = ({data, ...props}: VDiskPopupProps) => {
138138
const isFullData = isFullVDiskData(data);
139+
const [isPopupOpen, setIsPopupOpen] = React.useState(props.open);
140+
const onMouseLeave = React.useCallback(() => {
141+
setIsPopupOpen(false);
142+
}, []);
143+
const onMouseEnter = React.useCallback(() => {
144+
setIsPopupOpen(true);
145+
}, []);
139146

140147
const vdiskInfo = React.useMemo(
141148
() => (isFullData ? prepareVDiskData(data) : prepareUnavailableVDiskData(data)),
@@ -181,7 +188,10 @@ export const VDiskPopup = ({data, ...props}: VDiskPopupProps) => {
181188
// bigger offset for easier switching to neighbour nodes
182189
// matches the default offset for popup with arrow out of a sense of beauty
183190
offset={[0, 12]}
191+
onMouseEnter={onMouseEnter}
192+
onMouseLeave={onMouseLeave}
184193
{...props}
194+
open={isPopupOpen || props.open}
185195
>
186196
{data.DonorMode && <Label className={b('donor-label')}>Donor</Label>}
187197
<InfoViewer title="VDisk" info={vdiskInfo} size="s" />

src/containers/Storage/PDisk/PDisk.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from 'react';
22

3+
import {debounce} from 'lodash';
4+
35
import {DiskStateProgressBar} from '../../../components/DiskStateProgressBar/DiskStateProgressBar';
46
import {InternalLink} from '../../../components/InternalLink';
57
import {PDiskPopup} from '../../../components/PDiskPopup/PDiskPopup';
@@ -16,6 +18,8 @@ import './PDisk.scss';
1618

1719
const b = cn('pdisk-storage');
1820

21+
const DEBOUNCE_TIMEOUT = 100;
22+
1923
interface PDiskProps {
2024
data?: PreparedPDisk;
2125
vDisks?: PreparedVDisk[];
@@ -44,15 +48,15 @@ export const PDisk = ({
4448
const {NodeId, PDiskId} = data;
4549
const pDiskIdsDefined = valueIsDefined(NodeId) && valueIsDefined(PDiskId);
4650

47-
const handleShowPopup = () => {
51+
const debouncedHandleShowPopup = debounce(() => {
4852
setIsPopupVisible(true);
4953
onShowPopup?.();
50-
};
54+
}, DEBOUNCE_TIMEOUT);
5155

52-
const handleHidePopup = () => {
56+
const debouncedHandleHidePopup = debounce(() => {
5357
setIsPopupVisible(false);
5458
onHidePopup?.();
55-
};
59+
}, DEBOUNCE_TIMEOUT);
5660

5761
const renderVDisks = () => {
5862
if (!vDisks?.length) {
@@ -101,8 +105,11 @@ export const PDisk = ({
101105
<InternalLink
102106
to={pDiskPath}
103107
className={b('content')}
104-
onMouseEnter={handleShowPopup}
105-
onMouseLeave={handleHidePopup}
108+
onMouseEnter={debouncedHandleShowPopup}
109+
onMouseLeave={() => {
110+
debouncedHandleShowPopup.cancel();
111+
debouncedHandleHidePopup();
112+
}}
106113
>
107114
<DiskStateProgressBar
108115
diskAllocatedPercent={data.AllocatedPercent}

0 commit comments

Comments
 (0)