diff --git a/config/webpack.common.js b/config/webpack.common.js index f702deb4..62803569 100644 --- a/config/webpack.common.js +++ b/config/webpack.common.js @@ -72,10 +72,7 @@ module.exports = { }, }, ], - include: [ - root('src/asset/image/logo-small.svg'), - root('src/asset/image/logo-extend.svg'), - ], + include: [root('src/asset/image/cloud-logo.svg')], }, { test: /\.(woff|woff2|ttf|eot|svg)$/, @@ -88,10 +85,7 @@ module.exports = { }, }, ], - exclude: [ - root('src/asset/image/logo-small.svg'), - root('src/asset/image/logo-extend.svg'), - ], + exclude: [root('src/asset/image/cloud-logo.svg')], }, ], }, diff --git a/src/asset/image/cloud-logo.svg b/src/asset/image/cloud-logo.svg new file mode 100644 index 00000000..b2024c36 --- /dev/null +++ b/src/asset/image/cloud-logo.svg @@ -0,0 +1,15 @@ + + + 编组 4 + + + + Cloud + + + + + + + + \ No newline at end of file diff --git a/src/asset/image/global-menu.png b/src/asset/image/global-menu.png new file mode 100644 index 00000000..6b90fc5c Binary files /dev/null and b/src/asset/image/global-menu.png differ diff --git a/src/asset/image/logo-extend.svg b/src/asset/image/logo-extend.svg deleted file mode 100644 index c6f6e49c..00000000 --- a/src/asset/image/logo-extend.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/src/asset/image/logo-small.svg b/src/asset/image/logo-small.svg deleted file mode 100644 index 763663ef..00000000 --- a/src/asset/image/logo-small.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - logo - - - - - - \ No newline at end of file diff --git a/src/components/Layout/GlobalHeader/index.jsx b/src/components/Layout/GlobalHeader/index.jsx index 41941b80..f293c135 100644 --- a/src/components/Layout/GlobalHeader/index.jsx +++ b/src/components/Layout/GlobalHeader/index.jsx @@ -13,14 +13,41 @@ // limitations under the License. import React from 'react'; -import RightContent from './RightContent'; +import { Link } from 'react-router-dom'; +import cloudLogo from 'asset/image/cloud-logo.svg'; +import { getPath } from 'utils/route-map'; +import classnames from 'classnames'; +import GlobalNav from '../GlobalNav'; import ProjectDropdown from './ProjectDropdown'; +import RightContent from './RightContent'; import styles from './index.less'; export default function HeaderContent(props) { - const { isAdminPage = false } = props; + const { isAdminPage = false, navItems = [] } = props; + + const getRouteName = (routeName) => + isAdminPage ? `${routeName}Admin` : routeName; + + const getRoutePath = (routeName, params = {}, query = {}) => { + const realName = getRouteName(routeName); + return getPath({ key: realName, params, query }); + }; + + const renderLogo = () => { + const homeUrl = getRoutePath('overview'); + return ( +
+ + logo + +
+ ); + }; + return (
+ + {renderLogo()} {!isAdminPage && }
diff --git a/src/components/Layout/GlobalHeader/index.less b/src/components/Layout/GlobalHeader/index.less index f9de405a..bf3cad42 100644 --- a/src/components/Layout/GlobalHeader/index.less +++ b/src/components/Layout/GlobalHeader/index.less @@ -108,7 +108,7 @@ z-index: 200; flex-grow: 1; height: 100%; - padding-left: 36px; + padding-left: 0; overflow: hidden; color: @title-color; background-color: #fff; @@ -175,3 +175,15 @@ border-radius: 3px; } } + +.logo { + // margin: @size-medium 38px; + float: left; + height: @header-height; + padding: 0 46px; + line-height: @header-height; + + img { + height: 30px; + } +} diff --git a/src/components/Layout/GlobalNav/Left/index.jsx b/src/components/Layout/GlobalNav/Left/index.jsx new file mode 100644 index 00000000..62144c87 --- /dev/null +++ b/src/components/Layout/GlobalNav/Left/index.jsx @@ -0,0 +1,50 @@ +// Copyright 2021 99cloud +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import React from 'react'; +import { Link } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import { navItemPropType, getFirstLevelNavItemLink } from '../common'; +// import { pickFixedParams } from 'utils'; +import styles from './index.less'; + +export default class Left extends React.Component { + static propTypes = { + items: PropTypes.arrayOf(navItemPropType), + onClose: PropTypes.func, + }; + + static defaultProps = { + items: [], + }; + + renderItem = (item) => { + return ( +
+ + {item.name} + +
+ ); + }; + + render() { + const { items } = this.props; + return ; + } +} diff --git a/src/components/Layout/GlobalNav/Left/index.less b/src/components/Layout/GlobalNav/Left/index.less new file mode 100644 index 00000000..e5fe8563 --- /dev/null +++ b/src/components/Layout/GlobalNav/Left/index.less @@ -0,0 +1,18 @@ +.item { + padding: 12px 24px; + cursor: pointer; + + &:hover { + background-color: rgba(0, 0, 0, 5%); + } +} + +.item-label { + display: block; + width: 100%; + color: #000; + + &:hover { + color: #000; + } +} diff --git a/src/components/Layout/GlobalNav/Right/index.jsx b/src/components/Layout/GlobalNav/Right/index.jsx new file mode 100644 index 00000000..05153421 --- /dev/null +++ b/src/components/Layout/GlobalNav/Right/index.jsx @@ -0,0 +1,74 @@ +// Copyright 2021 99cloud +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import React from 'react'; +import { Link } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import { navItemPropType } from '../common'; + +import styles from './index.less'; + +export default class Right extends React.Component { + static propTypes = { + items: PropTypes.arrayOf(navItemPropType), + onClose: PropTypes.func, + }; + + static defaultProps = { + items: [], + }; + + renderNavItemChildren = (item) => { + const { children = [] } = item; + const currentChildren = children.length ? children : [item]; + const { onClose } = this.props; + const items = currentChildren.map((it) => { + const { name, path } = it; + return ( +
+ + {name} + +
+ ); + }); + return items; + }; + + renderNavItem = (item) => { + const { name = '' } = item || {}; + + return ( +
+
{name}
+
+ {this.renderNavItemChildren(item)} +
+
+ ); + }; + + render() { + const { items } = this.props; + if (!items.length) { + return null; + } + + return ( + + ); + } +} diff --git a/src/components/Layout/GlobalNav/Right/index.less b/src/components/Layout/GlobalNav/Right/index.less new file mode 100644 index 00000000..e74be330 --- /dev/null +++ b/src/components/Layout/GlobalNav/Right/index.less @@ -0,0 +1,38 @@ +.right { + columns: 200px 3; + column-gap: 12px; +} + +.nav-item { + display: inline-block; + width: 100%; + margin-bottom: 20px; + break-inside: avoid; + + .title { + box-sizing: border-box; + height: 32px; + margin-bottom: 4px; + color: #000; + font-weight: 600; + font-size: 14px; + line-height: 22px; + transition: color 0.2s ease; + } +} + +.children-item { + position: relative; + height: 32px; + margin-right: 8px; + line-height: 32px; + cursor: pointer; + + &:hover { + background-color: rgba(0, 0, 0, 5%); + } + + .link-name { + color: #000; + } +} diff --git a/src/components/Layout/GlobalNav/common.jsx b/src/components/Layout/GlobalNav/common.jsx new file mode 100644 index 00000000..b27ca8f6 --- /dev/null +++ b/src/components/Layout/GlobalNav/common.jsx @@ -0,0 +1,29 @@ +// Copyright 2021 99cloud +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import PropTypes from 'prop-types'; + +export const navItemPropType = PropTypes.shape({ + name: PropTypes.string, + path: PropTypes.string, + children: PropTypes.arrayOf(navItemPropType), +}); + +export const getFirstLevelNavItemLink = (item) => { + const { children = [] } = item; + if (!children.length) { + return item.path; + } + return item.children[0].path; +}; diff --git a/src/components/Layout/GlobalNav/index.jsx b/src/components/Layout/GlobalNav/index.jsx new file mode 100644 index 00000000..b6f6e739 --- /dev/null +++ b/src/components/Layout/GlobalNav/index.jsx @@ -0,0 +1,111 @@ +// Copyright 2021 99cloud +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import React from 'react'; +import { observer } from 'mobx-react'; +import { CloseOutlined } from '@ant-design/icons'; +import PropTypes from 'prop-types'; +import { Drawer } from 'antd'; +import menuIcon from 'asset/image/global-menu.png'; +import { navItemPropType } from './common'; +import Left from './Left'; +import Right from './Right'; + +import styles from './index.less'; + +export class GlobalNav extends React.Component { + static propTypes = { + navItems: PropTypes.arrayOf(navItemPropType), + }; + + static defaultProps = { + navItems: [], + }; + + constructor(props) { + super(props); + this.state = { + visible: false, + }; + } + + onClose = () => { + this.setState({ visible: false }); + }; + + onToggleOpen = () => { + this.setState(({ visible }) => { + return { + visible: !visible, + }; + }); + }; + + render() { + const { visible } = this.state; + const { navItems = [] } = this.props; + + const drawerStyle = { + top: '40px', + height: 'calc(100% - 40px)', + }; + + return ( + <> +
+ menu-icon +
+ + + + } + > +
+ +
+
+ + ); + } +} + +export default observer(GlobalNav); diff --git a/src/components/Layout/GlobalNav/index.less b/src/components/Layout/GlobalNav/index.less new file mode 100644 index 00000000..9b3b6921 --- /dev/null +++ b/src/components/Layout/GlobalNav/index.less @@ -0,0 +1,22 @@ +@import '~styles/variables'; + +.global-nav-icon { + position: relative; + float: left; + width: @header-height; + height: @header-height; + color: #fff; + font-size: 16px; + line-height: @header-height; + text-align: center; + background-color: @primary-color; + cursor: pointer; +} + +.global-nav-icon-icon { + width: 20px; +} + +.main { + padding: 32px 32px 0; +} diff --git a/src/layouts/Base/Menu.jsx b/src/layouts/Base/Menu.jsx index 14f9262f..919d6caa 100644 --- a/src/layouts/Base/Menu.jsx +++ b/src/layouts/Base/Menu.jsx @@ -15,12 +15,9 @@ import React, { Component } from 'react'; import { Menu, Tooltip } from 'antd'; import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; -import { Link } from 'react-router-dom'; import { inject, observer } from 'mobx-react'; import { toJS } from 'mobx'; import classnames from 'classnames'; -import logoSmall from 'asset/image/logo-small.svg'; -import logoExtend from 'asset/image/logo-extend.svg'; import { getPath } from 'utils/route-map'; import styles from './index.less'; @@ -66,10 +63,6 @@ export class LayoutMenu extends Component { this.setState({ collapsed }); }; - getImage(isExtend) { - return !isExtend ? logoSmall : logoExtend; - } - changeCollapse = () => { const { collapsed } = this.state; this.setState({ @@ -235,25 +228,6 @@ export class LayoutMenu extends Component { ); } - renderLogo() { - const { collapsed, hover } = this.state; - const isExtend = !collapsed || hover; - const imageSvg = this.getImage(isExtend); - const homeUrl = this.getRoutePath('overview'); - return ( -
- - logo - -
- ); - } - render() { const { currentRoutes } = this.props; const selectedKeys = this.getSelectedKeys(currentRoutes); @@ -270,7 +244,6 @@ export class LayoutMenu extends Component { onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} > - {this.renderLogo()} {this.renderMenu(selectedKeys)} {trigger} diff --git a/src/layouts/Base/index.jsx b/src/layouts/Base/index.jsx index 4ce195fb..a671d51b 100644 --- a/src/layouts/Base/index.jsx +++ b/src/layouts/Base/index.jsx @@ -93,6 +93,10 @@ export class BaseLayout extends Component { return ret; } + get globalNav() { + return this.menu; + } + get menu() { const menu = this.filterMenuByHidden(this.originMenu); const newMenu = this.getMenuAllowed(menu); @@ -246,20 +250,18 @@ export class BaseLayout extends Component { ); render() { - const { collapsed } = this.state; const { pathname } = this.props.location; const currentRoutes = this.getCurrentMenu(pathname); return (
{this.renderNotice()} -
+
{/* {this.renderLogo()} */} {this.renderHeader()}
diff --git a/src/layouts/Base/index.less b/src/layouts/Base/index.less index 6b72aeb8..363fc190 100644 --- a/src/layouts/Base/index.less +++ b/src/layouts/Base/index.less @@ -7,12 +7,12 @@ .header { top: 0; left: 0; + z-index: 1000; display: flex; align-items: center; justify-content: space-between; height: @header-height; padding: 0; - padding-left: 230px; color: @white; } @@ -247,10 +247,10 @@ .base-layout-sider { position: absolute; - top: 0; + top: @header-height; bottom: 0; left: 0; - z-index: 999; + z-index: 1; width: 230px; background-color: @sider-background; transition: all 0.2s; diff --git a/src/locales/en.json b/src/locales/en.json index cd2c4a03..265ef097 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -2068,6 +2068,7 @@ "Server Status": "Server Status", "Server Type": "Server Type", "Service": "Service", + "Service List": "Service List", "Service Port ID": "Service Port ID", "Service State": "Service State", "Service Status": "Service Status", diff --git a/src/locales/zh.json b/src/locales/zh.json index 2bdee839..a6472084 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -2068,6 +2068,7 @@ "Server Status": "服务状态", "Server Type": "服务类型", "Service": "服务", + "Service List": "服务列表", "Service Port ID": "服务端口ID", "Service State": "服务状态", "Service Status": "管理状态",