From 35152610bc8266bde139110fc8d6cbdf10bcbcc5 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 5 Mar 2020 11:07:02 +0100 Subject: [PATCH] find active child to figure out if the section is collapsible --- .../ui-components/src/navigation/Section.tsx | 59 ++++++++++++++----- .../src/navigation/SubNavigation.tsx | 11 +--- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/scm-ui/ui-components/src/navigation/Section.tsx b/scm-ui/ui-components/src/navigation/Section.tsx index eb4e94be73..ee40edaf6d 100644 --- a/scm-ui/ui-components/src/navigation/Section.tsx +++ b/scm-ui/ui-components/src/navigation/Section.tsx @@ -1,6 +1,8 @@ -import React, { FC, ReactElement, useEffect, useState } from "react"; +import React, { FC, ReactElement, ReactNode, useEffect, useState } from "react"; import { Button } from "../buttons"; import styled from "styled-components"; +import SubNavigation from "./SubNavigation"; +import { useLocation, matchPath } from "react-router-dom"; type Props = { label: string; @@ -39,8 +41,39 @@ const MenuLabel = styled.p` justify-content: ${props => (props.collapsed ? "center" : "left")}; `; -const Section: FC = ({ label, children, collapsed, onCollapse, scrollTransitionAt }) => { +const createParentPath = (to: string) => { + const parents = to.split("/"); + parents.splice(-1, 1); + return parents.join("/"); +}; + +const isSubNavigationActive = (children: ReactNode, url: string): boolean => { + const childArray = React.Children.toArray(children); + const match = childArray + .filter(child => { + // what about extension points? + // @ts-ignore + return child.type.name === SubNavigation.name; + }) + .map(child => { + // @ts-ignore + return child.props; + }) + .find(props => { + const path = createParentPath(props.to); + const matches = matchPath(url, { + path, + exact: props.activeOnlyWhenExact as boolean + }); + return matches != null; + }); + + return match != null; +}; + +const Section: FC = ({ label, children, collapsed = false, onCollapse, scrollTransitionAt }) => { const [scrollPositionY, setScrollPositionY] = useState(0); + const location = useLocation(); useEffect(() => { window.addEventListener("scroll", () => setScrollPositionY(window.pageYOffset)); @@ -50,29 +83,27 @@ const Section: FC = ({ label, children, collapsed, onCollapse, scrollTran }; }, []); + const subNavActive = isSubNavigationActive(children, location.pathname); + const isCollapsed = collapsed && !subNavActive; + const childrenWithProps = React.Children.map(children, (child: ReactElement) => - React.cloneElement(child, { collapsed: collapsed }) + React.cloneElement(child, { collapsed: isCollapsed }) ); - const arrowIcon = collapsed ? : ; + const arrowIcon = isCollapsed ? : ; return ( - - {onCollapse && ( - onCollapse(!collapsed)} - collapsed={collapsed ? collapsed : false} - > + + {onCollapse && !subNavActive && ( + onCollapse(!isCollapsed)} collapsed={isCollapsed}> {arrowIcon} )} - {collapsed ? "" : label} + {isCollapsed ? "" : label}
    {childrenWithProps}
diff --git a/scm-ui/ui-components/src/navigation/SubNavigation.tsx b/scm-ui/ui-components/src/navigation/SubNavigation.tsx index 27cfa40a9d..769167a027 100644 --- a/scm-ui/ui-components/src/navigation/SubNavigation.tsx +++ b/scm-ui/ui-components/src/navigation/SubNavigation.tsx @@ -1,7 +1,6 @@ import React, { FC, ReactElement, useContext, useEffect } from "react"; import { Link, useRouteMatch } from "react-router-dom"; import classNames from "classnames"; -import { MenuContext } from "./MenuContext"; type Props = { to: string; @@ -24,21 +23,13 @@ const SubNavigation: FC = ({ to, activeOnlyWhenExact, icon, collapsed, ti exact: activeOnlyWhenExact }); - const menuContext = useContext(MenuContext); - - useEffect(() => { - if (menuContext.menuCollapsed) { - menuContext.setMenuCollapsed(false); - } - }, [match]); - let defaultIcon = "fas fa-cog"; if (icon) { defaultIcon = icon; } let childrenList = null; - if (match) { + if (match && !collapsed) { childrenList =
    {children}
; }