From c241e3da6bd3fd81017c186b32a41e2f71f5416c Mon Sep 17 00:00:00 2001 From: Iukou Siarhei <45054016+BlazarQSO@users.noreply.github.com> Date: Mon, 15 Apr 2024 18:06:33 +0300 Subject: [PATCH] =?UTF-8?q?EPMRPP-90127=20||=20Popover=20is=20not=20collap?= =?UTF-8?q?sed=20when=20clicking=20on=20the=20same=20op=E2=80=A6=20(#3802)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * EPMRPP-90207 || Sidebar should be expanded on hovering and collapsed on unhovering * EPMRPP-90207 || Code Review fix - 1 * EPMRPP-90128 || The sidebar with expanded popover should be closed in one click * EPMRPP-90127 || Popover is not collapsed when clicking on the same option * EPMRPP-90127 || delete an unnecessary property * EPMRPP-90128 || Code Review fix - 1 * EPMRPP-90128 || delete unnecessary property * EPMRPP-90127 || Code Review fix - 2 * EPMRPP-90127 || Code Review fix - 3 * EPMRPP-90127 || Code Review fix - 4 * EPMRPP-90127 || Code Review fix - 5 * EPMRPP-90127 || Code Review fix - 6 * EPMRPP-90127 || Code Review fix - 6 --- app/src/componentLibrary/popover/popover.jsx | 2 +- .../popover/withPopover/withPopover.jsx | 46 +++++++++---------- .../popover/withPopover/withPopover.scss | 4 ++ .../sidebar/navbar/navbar.jsx | 11 +---- app/src/componentLibrary/sidebar/sidebar.jsx | 35 +++++++++----- .../organizationsControl.scss | 2 +- .../projectSidebar/projectSidebar.jsx | 8 ++-- .../layouts/common/appSidebar/appSidebar.jsx | 11 +++-- 8 files changed, 66 insertions(+), 53 deletions(-) diff --git a/app/src/componentLibrary/popover/popover.jsx b/app/src/componentLibrary/popover/popover.jsx index 6aad47bb5d..bb11c96722 100644 --- a/app/src/componentLibrary/popover/popover.jsx +++ b/app/src/componentLibrary/popover/popover.jsx @@ -42,7 +42,7 @@ export const Popover = ({ const [left, setLeft] = useState(0); const isNotDefaultTopPosition = !topPosition; - useOnClickOutside(popoverRef, onClose); + useOnClickOutside(parentRef, onClose); useLayoutEffect(() => { const { current: parent } = parentRef; diff --git a/app/src/componentLibrary/popover/withPopover/withPopover.jsx b/app/src/componentLibrary/popover/withPopover/withPopover.jsx index 4fda44c67d..ff0531b081 100644 --- a/app/src/componentLibrary/popover/withPopover/withPopover.jsx +++ b/app/src/componentLibrary/popover/withPopover/withPopover.jsx @@ -14,7 +14,9 @@ * limitations under the License. */ -import React, { useEffect, useRef, useState } from 'react'; +/* eslint-disable react/prop-types */ + +import React, { useRef, useState, useCallback } from 'react'; import classNames from 'classnames/bind'; import { Popover } from '../popover'; import styles from './withPopover.scss'; @@ -26,44 +28,42 @@ export const withPopover = ({ popoverWrapperClassName, tabIndex, ...popoverConfig -}) => ( - WrappedComponent, - // eslint-disable-next-line react/prop-types -) => ({ isOpenPopover, closePopover, setIsOpenPopover, ...props }) => { +}) => (WrappedComponent) => ({ isOpenPopover, togglePopover, ...props }) => { const parentRef = useRef(); const [isOpened, setOpened] = useState(false); - useEffect(() => { - if (isOpenPopover) { - setOpened(true); - setIsOpenPopover?.(true); + const onClose = useCallback(() => { + if (togglePopover) { + togglePopover(false); + } else { + setOpened(false); } - }, [isOpenPopover, setIsOpenPopover]); + }, [togglePopover, setOpened]); - const onClose = () => { - closePopover?.(); - setIsOpenPopover?.(false); - setOpened(false); + const onClickHandle = () => { + if (togglePopover) { + togglePopover(!isOpenPopover); + } else { + setOpened(true); + } }; + const isPopoverOpened = togglePopover ? isOpenPopover : isOpened; + return ( - <> +
- {isOpened && ( + {isPopoverOpened && ( )} - +
); }; diff --git a/app/src/componentLibrary/popover/withPopover/withPopover.scss b/app/src/componentLibrary/popover/withPopover/withPopover.scss index 9513ba6c17..6448cde765 100644 --- a/app/src/componentLibrary/popover/withPopover/withPopover.scss +++ b/app/src/componentLibrary/popover/withPopover/withPopover.scss @@ -14,6 +14,10 @@ * limitations under the License. */ +.with-popover-wrapper { + display: inline-block; +} + .with-popover { display: block; width: fit-content; diff --git a/app/src/componentLibrary/sidebar/navbar/navbar.jsx b/app/src/componentLibrary/sidebar/navbar/navbar.jsx index 090c695e9d..534dc8acb4 100644 --- a/app/src/componentLibrary/sidebar/navbar/navbar.jsx +++ b/app/src/componentLibrary/sidebar/navbar/navbar.jsx @@ -30,7 +30,6 @@ export const Navbar = ({ topSidebarControlItems, bottomSidebarControlItems, createFooterControlBlock, - setIsOpenPopover, getClassName, setHoverType, clearActionButton, @@ -42,9 +41,7 @@ export const Navbar = ({ {Parser(logoControlIcon)} )} -
- {createMainControlBlock(onCloseNavbar, setIsOpenPopover)} -
+
{createMainControlBlock(onCloseNavbar)}
{topSidebarControlItems.length > 0 && (
{topSidebarControlItems.map(({ sidebarBlockItem, key, onClick }) => ( @@ -83,9 +80,7 @@ export const Navbar = ({ ))}
)} -
- {createFooterControlBlock(onCloseNavbar, setIsOpenPopover)} -
+
{createFooterControlBlock(onCloseNavbar)}
); @@ -97,7 +92,6 @@ Navbar.propTypes = { logoControlIcon: PropTypes.element, createMainControlBlock: PropTypes.func, createFooterControlBlock: PropTypes.func, - setIsOpenPopover: PropTypes.func, getClassName: PropTypes.object.isRequired, setHoverType: PropTypes.func.isRequired, clearActionButton: PropTypes.func.isRequired, @@ -110,5 +104,4 @@ Navbar.defaultProps = { bottomSidebarControlItems: [], createMainControlBlock: () => {}, createFooterControlBlock: () => {}, - setIsOpenPopover: () => {}, }; diff --git a/app/src/componentLibrary/sidebar/sidebar.jsx b/app/src/componentLibrary/sidebar/sidebar.jsx index 941d5b224c..1f45f69658 100644 --- a/app/src/componentLibrary/sidebar/sidebar.jsx +++ b/app/src/componentLibrary/sidebar/sidebar.jsx @@ -14,10 +14,11 @@ * limitations under the License. */ -import React, { useState } from 'react'; +import React, { useRef, useState, useCallback } from 'react'; import PropTypes from 'prop-types'; import Parser from 'html-react-parser'; import classNames from 'classnames/bind'; +import { useOnClickOutside } from 'common/hooks'; import { Navbar } from './navbar'; import { SidebarButton } from './sidebarButton'; import styles from './sidebar.scss'; @@ -32,26 +33,36 @@ export const Sidebar = ({ topSidebarItems, bottomSidebarItems, createFooterBlock, + shouldBeCollapsedOnLeave, ...navbarProps }) => { - const [isOpenNavbarPopover, setIsOpenNavbarPopover] = useState(false); const [isOpenNavbar, setIsOpenNavbar] = useState(false); const [actionButtonKey, setActionButtonKey] = useState(null); const [actionButtonType, setActionButtonType] = useState(null); - const onOpenNavbar = () => { - setIsOpenNavbar(true); + const sidebarRef = useRef(null); + + const onCloseNavbar = () => { + setIsOpenNavbar(false); }; - const onCloseSidebar = () => { - if (!isOpenNavbarPopover) { - setIsOpenNavbar(false); + const handleClickOutside = useCallback(() => { + if (isOpenNavbar) { + onCloseNavbar(); } + }, [isOpenNavbar]); + + useOnClickOutside(sidebarRef, handleClickOutside); + + const onOpenNavbar = () => { + setIsOpenNavbar(true); }; - const onCloseNavbar = () => { - setIsOpenNavbar(false); + const onLeaveNavbar = () => { + if (shouldBeCollapsedOnLeave) { + onCloseNavbar(); + } }; const onButtonClick = (onClick) => { @@ -85,9 +96,10 @@ export const Sidebar = ({ return (