From e3543ed1b50f7f9661e29ce2f5882b1c55fe71a4 Mon Sep 17 00:00:00 2001 From: "Jingwei.Zhang" Date: Wed, 9 Nov 2022 12:30:28 +0800 Subject: [PATCH] feat: update menu in the layout 1. Update the menu style to adjust the global nav display 2. Update the menu open keys when the url change: the menu will auto open the current url's father menu Change-Id: I567db87e369264d9b1d1372332868267b478cf46 --- src/components/Layout/GlobalHeader/index.less | 4 +- src/layouts/Base/Menu.jsx | 94 ++++++++++++++++--- src/layouts/Base/index.less | 30 ++++-- 3 files changed, 108 insertions(+), 20 deletions(-) diff --git a/src/components/Layout/GlobalHeader/index.less b/src/components/Layout/GlobalHeader/index.less index bf3cad42..4f32c390 100644 --- a/src/components/Layout/GlobalHeader/index.less +++ b/src/components/Layout/GlobalHeader/index.less @@ -177,11 +177,11 @@ } .logo { - // margin: @size-medium 38px; float: left; + width: 190px; height: @header-height; - padding: 0 46px; line-height: @header-height; + text-align: center; img { height: 30px; diff --git a/src/layouts/Base/Menu.jsx b/src/layouts/Base/Menu.jsx index 919d6caa..73cfe350 100644 --- a/src/layouts/Base/Menu.jsx +++ b/src/layouts/Base/Menu.jsx @@ -17,6 +17,7 @@ import { Menu, Tooltip } from 'antd'; import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; import { inject, observer } from 'mobx-react'; import { toJS } from 'mobx'; +import { isString, isEqual } from 'lodash'; import classnames from 'classnames'; import { getPath } from 'utils/route-map'; import styles from './index.less'; @@ -34,6 +35,18 @@ export class LayoutMenu extends Component { this.maxTitleLength = 17; } + componentDidMount() { + this.init(); + } + + componentDidUpdate(prevProps) { + const { pathname } = this.props; + const { pathname: prevPathname } = prevProps; + if (prevPathname && pathname !== prevPathname) { + this.updateOpenKeysByRoute(); + } + } + get menu() { return this.props.menu || []; } @@ -51,6 +64,13 @@ export class LayoutMenu extends Component { return getPath({ key: realName, params, query }); } + getOpenKeysByRoute() { + const { currentRoutes } = this.props; + const selectedKeys = this.getSelectedKeys(currentRoutes); + const currentOpenKeys = this.getCurrentOpenKeys(selectedKeys); + return currentOpenKeys; + } + get rootStore() { return this.props.rootStore; } @@ -78,7 +98,7 @@ export class LayoutMenu extends Component { if (collapsed) { const target = (e && e.target) || null; const className = target ? target.className || '' : ''; - if (className.indexOf('trigger') < 0) { + if (isString(className) && !className.includes('trigger')) { this.setState({ hover: true, }); @@ -107,7 +127,7 @@ export class LayoutMenu extends Component { const { collapsed, hover } = this.state; if (collapsed && !hover) { return ( - + {item.icon} ); @@ -160,23 +180,56 @@ export class LayoutMenu extends Component { ); }; + getFirstLevelKeys = (selectedKeys) => { + const fathers = this.menu.filter((it) => { + const { children = [] } = it; + if (!children.length) { + return selectedKeys.includes(it.key); + } + let hasFather = children.find((c) => selectedKeys.includes(c.key)); + if (hasFather) { + return true; + } + children.forEach((c) => { + const { children: cc = [] } = c; + const child = cc.find((ccc) => selectedKeys.includes(ccc.key)); + if (child) { + hasFather = true; + } + }); + return hasFather; + }); + return fathers.map((f) => f.key); + }; + + getSelectedKeysForMenu = (selectedKeys) => { + const { collapsed, hover } = this.state; + if (!collapsed || hover) { + return selectedKeys; + } + return this.getFirstLevelKeys(selectedKeys); + }; + + getCurrentOpenKeys = (selectedKeys) => { + return this.getFirstLevelKeys(selectedKeys); + }; + renderMenu = (selectedKeys = []) => { - const { openKeys } = this.state; - const { openKeys: defaultOpenKeys } = this.rootStore; - const newOpenKeys = - openKeys.length === 0 ? toJS(defaultOpenKeys) : openKeys; + const { collapsed } = this.state; + const { openKeys } = this.rootStore; const menuItems = this.menu .map((item) => this.renderMenuItem(item)) .filter((it) => it !== null); + const newSelectedKeys = this.getSelectedKeysForMenu(selectedKeys); return ( {menuItems} @@ -192,9 +245,13 @@ export class LayoutMenu extends Component { ); const latestOpenKey = openKeys.find((key) => oldKeys.indexOf(key) === -1); const newKeys = latestOpenKey ? [latestOpenKey] : []; - this.rootStore.updateOpenKeys(newKeys); + this.updateOpenKeys(newKeys); + }; + + updateOpenKeys = (keys) => { + this.rootStore.updateOpenKeys(keys); this.setState({ - openKeys: newKeys, + openKeys: keys, }); }; @@ -211,6 +268,19 @@ export class LayoutMenu extends Component { return []; }; + updateOpenKeysByRoute() { + const currentOpenKeys = this.getOpenKeysByRoute(); + const { openKeys: defaultOpenKeys } = this.rootStore; + if (!isEqual(currentOpenKeys, toJS(defaultOpenKeys))) { + this.init(); + } + } + + init() { + const currentOpenKeys = this.getOpenKeysByRoute(); + this.updateOpenKeys(currentOpenKeys); + } + renderTrigger() { const { collapsed } = this.state; // const triggerIcon = ; diff --git a/src/layouts/Base/index.less b/src/layouts/Base/index.less index 363fc190..80b8a5e1 100644 --- a/src/layouts/Base/index.less +++ b/src/layouts/Base/index.less @@ -19,7 +19,7 @@ .header-collapsed { &:extend(.header); - padding-left: 88px; + padding-left: 40px; } .logo { @@ -252,16 +252,24 @@ left: 0; z-index: 1; width: 230px; + padding-top: 10px; background-color: @sider-background; transition: all 0.2s; } .base-layout-sider-collapsed { - width: 88px; + width: 40px; transition: all 0.2s; - // &:hover { - // width: 220px; - // } + + .menu-collapsed { + padding-right: 0; + padding-left: 0; + + .menu-item-collapsed { + padding-left: 12px !important; + text-overflow: inherit; + } + } } .base-layout-right { @@ -273,12 +281,22 @@ } .base-layout-right-collapsed { - left: 88px; + left: 40px; } .base-layout-sider-hover { width: 230px; transition: all 0.2s; + + .menu-collapsed { + padding-right: 14px; + padding-left: 14px; + + .menu-item-collapsed { + padding-left: 48px !important; + text-overflow: ellipsis; + } + } } .notice {