From 87d71e4b9e192416e33346b47f867aa8bc1b1911 Mon Sep 17 00:00:00 2001 From: Ross Mabbett <92495987+rtexelm@users.noreply.github.com> Date: Thu, 4 Apr 2024 19:31:07 -0400 Subject: [PATCH] fix(Dashboard): Add border to row when hovering HoverMenu in edit mode (#27593) --- .../DashboardBuilder/DashboardBuilder.tsx | 5 +++++ .../components/gridComponents/Row.jsx | 16 ++++++++++++++-- .../components/menu/HoverMenu.test.tsx | 16 +++++++++++++++- .../dashboard/components/menu/HoverMenu.tsx | 19 +++++++++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx index e86d924b2104f..ba21420394b2e 100644 --- a/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx +++ b/superset-frontend/src/dashboard/components/DashboardBuilder/DashboardBuilder.tsx @@ -186,6 +186,11 @@ const DashboardContentWrapper = styled.div` pointer-events: none; } + .grid-row.grid-row--hovered:after, + .dashboard-component-tabs > .grid-row--hovered:after { + border: 2px dashed ${theme.colors.primary.base}; + } + .resizable-container { & .dashboard-component-chart-holder { .dashboard-chart { diff --git a/superset-frontend/src/dashboard/components/gridComponents/Row.jsx b/superset-frontend/src/dashboard/components/gridComponents/Row.jsx index 95560e3b5900b..b6dc042a2b094 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Row.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Row.jsx @@ -135,6 +135,7 @@ class Row extends React.PureComponent { this.state = { isFocused: false, isInView: false, + hoverMenuHovered: false, }; this.handleDeleteComponent = this.handleDeleteComponent.bind(this); this.handleUpdateMeta = this.handleUpdateMeta.bind(this); @@ -143,6 +144,7 @@ class Row extends React.PureComponent { 'background', ); this.handleChangeFocus = this.handleChangeFocus.bind(this); + this.handleMenuHover = this.handleMenuHover.bind(this); this.setVerticalEmptyContainerHeight = debounce( this.setVerticalEmptyContainerHeight.bind(this), FAST_DEBOUNCE, @@ -235,6 +237,11 @@ class Row extends React.PureComponent { deleteComponent(component.id, parentId); } + handleMenuHover = hovered => { + const { isHovered } = hovered; + this.setState(() => ({ hoverMenuHovered: isHovered })); + }; + render() { const { component: rowComponent, @@ -252,7 +259,7 @@ class Row extends React.PureComponent { onChangeTab, isComponentVisible, } = this.props; - const { containerHeight } = this.state; + const { containerHeight, hoverMenuHovered } = this.state; const rowItems = rowComponent.children || []; @@ -287,7 +294,11 @@ class Row extends React.PureComponent { editMode={editMode} > {editMode && ( - + { const { container } = render(); expect(container.querySelector('.hover-menu')).toBeInTheDocument(); }); + +test('should call onHover when mouse enters and leaves', () => { + const onHover = jest.fn(); + render(); + + const hoverMenu = screen.getByTestId('hover-menu'); + + userEvent.hover(hoverMenu); + expect(onHover).toBeCalledWith({ isHovered: true }); + + userEvent.unhover(hoverMenu); + expect(onHover).toBeCalledWith({ isHovered: false }); +}); diff --git a/superset-frontend/src/dashboard/components/menu/HoverMenu.tsx b/superset-frontend/src/dashboard/components/menu/HoverMenu.tsx index 5fbc37cbbfd58..43d7683ce370e 100644 --- a/superset-frontend/src/dashboard/components/menu/HoverMenu.tsx +++ b/superset-frontend/src/dashboard/components/menu/HoverMenu.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/no-unused-state */ /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -24,6 +25,7 @@ interface HoverMenuProps { position: 'left' | 'top'; innerRef: RefObject; children: React.ReactNode; + onHover?: (data: { isHovered: boolean }) => void; } const HoverStyleOverrides = styled.div` @@ -70,6 +72,20 @@ export default class HoverMenu extends React.PureComponent { children: null, }; + handleMouseEnter = () => { + const { onHover } = this.props; + if (onHover) { + onHover({ isHovered: true }); + } + }; + + handleMouseLeave = () => { + const { onHover } = this.props; + if (onHover) { + onHover({ isHovered: false }); + } + }; + render() { const { innerRef, position, children } = this.props; return ( @@ -81,6 +97,9 @@ export default class HoverMenu extends React.PureComponent { position === 'left' && 'hover-menu--left', position === 'top' && 'hover-menu--top', )} + onMouseEnter={this.handleMouseEnter} + onMouseLeave={this.handleMouseLeave} + data-test="hover-menu" > {children}