Skip to content

Commit

Permalink
EPMRPP-90127 || Popover is not collapsed when clicking on the same op… (
Browse files Browse the repository at this point in the history
#3802)

* 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
  • Loading branch information
BlazarQSO authored Apr 15, 2024
1 parent 09242e9 commit c241e3d
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 53 deletions.
2 changes: 1 addition & 1 deletion app/src/componentLibrary/popover/popover.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
46 changes: 23 additions & 23 deletions app/src/componentLibrary/popover/withPopover/withPopover.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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 (
<>
<div className={cx('with-popover-wrapper')} ref={parentRef}>
<button
ref={parentRef}
className={cx('with-popover', popoverWrapperClassName)}
onClick={() => {
setOpened(true);
setIsOpenPopover?.(true);
}}
onClick={onClickHandle}
tabIndex={tabIndex ?? -1}
>
<WrappedComponent isPopoverOpen={isOpened} {...props} />
<WrappedComponent isPopoverOpen={isPopoverOpened} {...props} />
</button>
{isOpened && (
{isPopoverOpened && (
<Popover onClose={onClose} parentRef={parentRef} {...popoverConfig}>
<ContentComponent closePopover={onClose} {...props} />
</Popover>
)}
</>
</div>
);
};
4 changes: 4 additions & 0 deletions app/src/componentLibrary/popover/withPopover/withPopover.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
* limitations under the License.
*/

.with-popover-wrapper {
display: inline-block;
}

.with-popover {
display: block;
width: fit-content;
Expand Down
11 changes: 2 additions & 9 deletions app/src/componentLibrary/sidebar/navbar/navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export const Navbar = ({
topSidebarControlItems,
bottomSidebarControlItems,
createFooterControlBlock,
setIsOpenPopover,
getClassName,
setHoverType,
clearActionButton,
Expand All @@ -42,9 +41,7 @@ export const Navbar = ({
<i className={cx('logo')}>{Parser(logoControlIcon)}</i>
</div>
)}
<div className={cx('main-block')}>
{createMainControlBlock(onCloseNavbar, setIsOpenPopover)}
</div>
<div className={cx('main-block')}>{createMainControlBlock(onCloseNavbar)}</div>
{topSidebarControlItems.length > 0 && (
<div className={cx('top-block')}>
{topSidebarControlItems.map(({ sidebarBlockItem, key, onClick }) => (
Expand Down Expand Up @@ -83,9 +80,7 @@ export const Navbar = ({
))}
</div>
)}
<div className={cx('bottom-block')}>
{createFooterControlBlock(onCloseNavbar, setIsOpenPopover)}
</div>
<div className={cx('bottom-block')}>{createFooterControlBlock(onCloseNavbar)}</div>
</div>
);

Expand All @@ -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,
Expand All @@ -110,5 +104,4 @@ Navbar.defaultProps = {
bottomSidebarControlItems: [],
createMainControlBlock: () => {},
createFooterControlBlock: () => {},
setIsOpenPopover: () => {},
};
35 changes: 24 additions & 11 deletions app/src/componentLibrary/sidebar/sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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) => {
Expand Down Expand Up @@ -85,9 +96,10 @@ export const Sidebar = ({

return (
<div
ref={sidebarRef}
className={cx('sidebar-container')}
onMouseEnter={onOpenNavbar}
onMouseLeave={onCloseSidebar}
onMouseLeave={onLeaveNavbar}
>
<aside className={cx('sidebar')}>
<div className={cx('logo')}>
Expand Down Expand Up @@ -131,7 +143,6 @@ export const Sidebar = ({
<Navbar
active={isOpenNavbar}
onCloseNavbar={onCloseNavbar}
setIsOpenPopover={setIsOpenNavbarPopover}
getClassName={getClassName}
setHoverType={setHoverType}
clearActionButton={clearActionButton}
Expand All @@ -148,12 +159,14 @@ Sidebar.propTypes = {
logoBlockIcon: PropTypes.element,
createMainBlock: PropTypes.element,
createFooterBlock: PropTypes.func,
shouldBeCollapsedOnLeave: PropTypes.bool,
};

Sidebar.defaultProps = {
logoBlockIcon: null,
createMainBlock: null,
topSidebarItems: [],
bottomSidebarItems: [],
shouldBeCollapsedOnLeave: false,
createFooterBlock: () => {},
};
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@

.popover {
max-height: calc(100% - 112px);
margin-left: 4px;
margin-left: -4px;
padding: 8px 0;

&::after {
Expand Down
8 changes: 4 additions & 4 deletions app/src/layouts/appLayout/projectSidebar/projectSidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,16 @@ export const ProjectSidebar = ({ onClickNavBtn }) => {
isHoveredOrganization={isHoveredOrganization}
onClick={() => {
openNavbar();
setIsOpenOrganizationPopover(true);
setIsOpenOrganizationPopover(!isOpenOrganizationPopover);
}}
/>
);

const createMainControlBlock = (closeNavbar, setIsOpenPopover) => (
const createMainControlBlock = (closeNavbar) => (
<OrganizationsControlWithPopover
closeNavbar={closeNavbar}
isOpenPopover={isOpenOrganizationPopover}
closePopover={() => setIsOpenOrganizationPopover(false)}
setIsOpenPopover={setIsOpenPopover}
togglePopover={setIsOpenOrganizationPopover}
onHoverOrganization={onHoverOrganization}
onClearOrganization={onClearOrganization}
isHoveredOrganization={isHoveredOrganization}
Expand All @@ -196,6 +195,7 @@ export const ProjectSidebar = ({ onClickNavBtn }) => {
createMainControlBlock={createMainControlBlock}
topSidebarItems={topSidebarItems}
topSidebarControlItems={topSidebarControlItems}
isOpenOrganizationPopover={isOpenOrganizationPopover}
/>
);
};
Expand Down
11 changes: 7 additions & 4 deletions app/src/layouts/common/appSidebar/appSidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const AppSidebar = ({
bottomSidebarItems,
topSidebarControlItems,
bottomSidebarControlItems,
isOpenOrganizationPopover,
}) => {
const { formatMessage } = useIntl();
const [isOpenAvatarPopover, setIsOpenAvatarPopover] = useState(false);
Expand All @@ -61,7 +62,7 @@ export const AppSidebar = ({
<UserAvatar
onClick={() => {
openNavbar();
setIsOpenAvatarPopover(true);
setIsOpenAvatarPopover(!isOpenAvatarPopover);
}}
onHoverUser={onHoverUser}
onClearUser={onClearUser}
Expand All @@ -70,7 +71,7 @@ export const AppSidebar = ({
</>
);

const createFooterControlBlock = (onCloseNavbar, setIsOpenPopover) => (
const createFooterControlBlock = (onCloseNavbar) => (
<>
<div className={cx('policy-control')}>
<a href={referenceDictionary.rpEpamPolicy} target="_blank">
Expand All @@ -80,9 +81,8 @@ export const AppSidebar = ({
<div className={cx('user-control', { hover: isHoveredUser })}>
<UserControlWithPopover
closeNavbar={onCloseNavbar}
setIsOpenPopover={setIsOpenPopover}
isOpenPopover={isOpenAvatarPopover}
closePopover={() => setIsOpenAvatarPopover(false)}
togglePopover={setIsOpenAvatarPopover}
/>
</div>
</>
Expand All @@ -100,6 +100,7 @@ export const AppSidebar = ({
bottomSidebarControlItems={bottomSidebarControlItems}
createFooterControlBlock={createFooterControlBlock}
createFooterBlock={createFooterBlock}
shouldBeCollapsedOnLeave={!(isOpenAvatarPopover || isOpenOrganizationPopover)}
/>
);
};
Expand All @@ -111,13 +112,15 @@ AppSidebar.propTypes = {
bottomSidebarControlItems: PropTypes.array,
createMainControlBlock: PropTypes.func,
createMainBlock: PropTypes.func,
isOpenOrganizationPopover: PropTypes.bool,
};

AppSidebar.defaultProps = {
topSidebarItems: [],
bottomSidebarItems: [],
topSidebarControlItems: [],
bottomSidebarControlItems: [],
isOpenOrganizationPopover: false,
createMainControlBlock: () => {},
createMainBlock: () => {},
};

0 comments on commit c241e3d

Please sign in to comment.