update 用户菜单重做

This commit is contained in:
2021-06-23 13:43:48 +08:00
parent bf18f21a24
commit 621e1ec061
7 changed files with 120 additions and 125 deletions

View File

@@ -21,6 +21,29 @@
box-shadow: @btn-primary-shadow; box-shadow: @btn-primary-shadow;
text-shadow: @btn-text-shadow; text-shadow: @btn-text-shadow;
} }
.ant-btn-danger-disabled,
.ant-btn-danger.disabled,
.ant-btn-danger[disabled],
.ant-btn-danger-disabled:hover,
.ant-btn-danger.disabled:hover,
.ant-btn-danger[disabled]:hover,
.ant-btn-danger-disabled:focus,
.ant-btn-danger.disabled:focus,
.ant-btn-danger[disabled]:focus,
.ant-btn-danger-disabled:active,
.ant-btn-danger.disabled:active,
.ant-btn-danger[disabled]:active,
.ant-btn-danger-disabled.active,
.ant-btn-danger.disabled.active,
.ant-btn-danger[disabled].active {
opacity: .5;
color: @btn-danger-color;
border-color: @btn-danger-border;
background-color: @btn-danger-bg;
box-shadow: @btn-primary-shadow;
text-shadow: @btn-text-shadow;
}
.ant-radio-button-wrapper-disabled,
.ant-radio-button-wrapper-disabled:first-child, .ant-radio-button-wrapper-disabled:first-child,
.ant-radio-button-wrapper-disabled:hover { .ant-radio-button-wrapper-disabled:hover {
opacity: .5; opacity: .5;

View File

@@ -333,6 +333,9 @@
margin-bottom: @padding-xs; margin-bottom: @padding-xs;
border-left: @border-width-base @border-style-base @normal-color; border-left: @border-width-base @border-style-base @normal-color;
&.ant-radio-button-wrapper-checked {
border-left-color: @primary-color;
}
&:not(:first-child) { &:not(:first-child) {
&::before { &::before {
content: none; content: none;

View File

@@ -163,49 +163,6 @@
&--avatar { &--avatar {
box-shadow: 0 0 0 2px @white; box-shadow: 0 0 0 2px @white;
} }
&--name {
font-weight: bolder;
position: absolute;
left: 32px + @padding-sm * 2;
transition: @animation-duration-slow;
opacity: 0;
}
&--dropdown {
width: 200px;
transition: @animation-duration-base;
transform: scaleY(0);
transform-origin: top;
opacity: 0;
.ant-dropdown-menu {
box-shadow: none;
}
}
}
&.open {
width: 200px;
.user-container-inner {
background-color: @white;
box-shadow: @box-shadow-base;
}
.user {
&--name {
opacity: 1;
}
}
}
&.drop {
.user {
&--dropdown {
transform: scaleY(1);
opacity: 1;
}
}
} }
} }
} }
@@ -652,3 +609,13 @@
} }
} }
} }
.yo-user-popover {
width: 280px;
padding-top: 0;
.ant-popover-arrow {
display: none;
}
.ant-popover-inner-content {
padding: 0;
}
}

View File

@@ -2,20 +2,27 @@ import React, { Component } from 'react'
import * as Icon from '@ant-design/icons' import * as Icon from '@ant-design/icons'
export default class AntIcon extends Component { export default class AntIcon extends Component {
render() { render() {
const type = (this.props.type || '').toUpperCase() const type = (this.props.type || '').toUpperCase()
if (type) { if (type) {
if (type.indexOf('OUTLINED') >= 0 || type.indexOf('FILLED') >= 0 || type.indexOf('TWOTONE') >= 0) { if (
type.indexOf('OUTLINED') >= 0 ||
type.indexOf('FILLED') >= 0 ||
type.indexOf('TWOTONE') >= 0
) {
const I = Icon[this.props.type] const I = Icon[this.props.type]
return <I {...this.props} /> return I ? <I {...this.props} /> : false
} else { } else {
const t = type.split('-').map(p => { const t =
return p[0] + p.slice(1).toLowerCase() type
}).join('') + 'Outlined' .split('-')
.map(p => {
return p[0] + p.slice(1).toLowerCase()
})
.join('') + 'Outlined'
const I = Icon[t] const I = Icon[t]
return <I {...this.props} /> return I ? <I {...this.props} /> : false
} }
} }
return <></> return <></>

View File

@@ -79,7 +79,6 @@ export default class building extends Component {
const { houseInfo } = this.record const { houseInfo } = this.record
if (houseInfo.completedDate) { if (houseInfo.completedDate) {
houseInfo.completedDate = moment(houseInfo.completedDate) houseInfo.completedDate = moment(houseInfo.completedDate)
debugger
dispatch({ dispatch({
type: 'PATROL_INIT_GRADE_BY_COMPLETED_DATE', type: 'PATROL_INIT_GRADE_BY_COMPLETED_DATE',
value: +houseInfo.completedDate.format('YYYY'), value: +houseInfo.completedDate.format('YYYY'),

View File

@@ -45,7 +45,7 @@ export default class index extends Component {
const { userId } = this.state const { userId } = this.state
return ( return (
<Tabs> <Tabs tabBarStyle={{ padding: '0 24px' }}>
<Tabs.TabPane key="1" tab="选房"> <Tabs.TabPane key="1" tab="选房">
<SelectorList <SelectorList
userId={userId} userId={userId}

View File

@@ -1,6 +1,6 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { withRouter } from 'react-router-dom' import { withRouter } from 'react-router-dom'
import { Modal, message as Message } from 'antd' import { Modal, message as Message, Dropdown, Button, Menu, Popover, Tag, Row, Col } from 'antd'
import { isEqual } from 'lodash' import { isEqual } from 'lodash'
import store from 'store' import store from 'store'
import { api } from 'common/api' import { api } from 'common/api'
@@ -11,12 +11,8 @@ const { getState, dispatch, subscribe } = store
const storePath = 'user' const storePath = 'user'
let userOpenTimer, userCloseTimer
let initDropdownHeight
class User extends Component { class User extends Component {
state = { state = {
dropdownHeight: 0,
user: getState(storePath), user: getState(storePath),
} }
@@ -30,40 +26,14 @@ class User extends Component {
}) })
} }
// shouldComponentUpdate(props, state) { shouldComponentUpdate(props, state) {
// return !isEqual(this.state, state) return !isEqual(this.state, state)
// }
componentDidMount() {
initDropdownHeight = this.refs.dropdown.scrollHeight
} }
componentWillUnmount() { componentWillUnmount() {
this.unsubscribe() this.unsubscribe()
} }
onOpen = e => {
clearTimeout(userCloseTimer)
this.refs.container.classList.add('open')
userOpenTimer = setTimeout(() => {
this.refs.container.classList.add('drop')
this.setState({
dropdownHeight: initDropdownHeight,
})
}, 300)
}
onClose = e => {
clearTimeout(userOpenTimer)
this.refs.container.classList.remove('drop')
this.setState({
dropdownHeight: 0,
})
userCloseTimer = setTimeout(() => {
this.refs.container.classList.remove('open')
}, 300)
}
onAccountSetting = () => {} onAccountSetting = () => {}
onLogout = () => { onLogout = () => {
@@ -84,48 +54,74 @@ class User extends Component {
}) })
} }
render() { renderMenu() {
const { user } = this.state
return ( return (
<div <>
className="user-container" <div className="p-md pb-xs">
onMouseEnter={e => { <Row align="bottom" justify="space-between">
this.onOpen(e) <Col>
}} <b className="h5">{user.nickName || user.name}</b>
onMouseLeave={e => { </Col>
this.onClose(e) <Col>
}} <span className="text-gray">{user.account}</span>
ref="container" </Col>
> </Row>
<p className="text-gray">上次登录时间{user.lastLoginTime}</p>
{user.adminType === 1 && (
<Tag color="pink" className="mb-xs">
超级管理员
</Tag>
)}
{user.roles &&
user.roles.map(role => (
<Tag color="purple" className="mb-xs">
{role.name}
</Tag>
))}
</div>
<Menu selectable={false}>
<Menu.Divider />
<Menu.Item key="1">
<AntIcon type="user" className="mr-sm" />
个人中心
</Menu.Item>
<Menu.Item key="2">其他菜单</Menu.Item>
<Menu.Item key="3">其他菜单</Menu.Item>
<Menu.Item key="4">其他菜单</Menu.Item>
<Menu.Divider />
<Menu.Item key="-1" onClick={() => this.onLogout()}>
<AntIcon type="logout" className="mr-sm" />
退出登录
</Menu.Item>
</Menu>
</>
)
}
render() {
const { user } = this.state
return (
<div className="user-container">
<div className="user-container-inner"> <div className="user-container-inner">
<div className="user--base"> <Popover
<Image arrowPointAtCenter={true}
width="32" overlayClassName="yo-user-popover"
type="avatar" placement="bottomRight"
className="user--avatar" content={this.renderMenu()}
icon={<AntIcon type="user" />}
id={this.state.user.avatar}
/>
<span className="user--name">
{this.state.user.nickName || this.state.user.name}
</span>
</div>
<div
className="user--dropdown"
ref="dropdown"
style={{ height: `${this.state.dropdownHeight}px` }}
> >
<ul className="ant-dropdown-menu ant-dropdown-menu-vertical"> <div className="user--base">
<li className="ant-dropdown-menu-item" onClick={this.onAccountSetting}> <Image
<AntIcon type="user" /> width="32"
个人中心 type="avatar"
</li> className="user--avatar"
<li className="ant-dropdown-menu-item-divider"></li> icon={<AntIcon type="user" />}
<li className="ant-dropdown-menu-item" onClick={this.onLogout}> id={user.avatar}
<AntIcon type="logout" /> />
退出登录 </div>
</li> </Popover>
</ul>
</div>
</div> </div>
</div> </div>
) )