Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
ant-design-pro
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
duanledexianxianxian
ant-design-pro
Commits
f67bff39
Unverified
Commit
f67bff39
authored
Dec 12, 2017
by
偏右
Committed by
GitHub
Dec 12, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
GlobalHeader & SiderMenu (#411)
* GlobalHeader & SiderMenu * Fix login and logout * Fix test case
parent
3e1ad8fb
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
367 additions
and
322 deletions
+367
-322
src/components/GlobalHeader/index.js
src/components/GlobalHeader/index.js
+157
-0
src/components/GlobalHeader/index.less
src/components/GlobalHeader/index.less
+11
-42
src/components/SiderMenu/index.js
src/components/SiderMenu/index.js
+139
-0
src/components/SiderMenu/index.less
src/components/SiderMenu/index.less
+32
-0
src/e2e/home.e2e.js
src/e2e/home.e2e.js
+1
-1
src/layouts/BasicLayout.js
src/layouts/BasicLayout.js
+27
-279
No files found.
src/components/GlobalHeader/index.js
0 → 100644
View file @
f67bff39
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
Layout
,
Menu
,
Icon
,
Spin
,
Tag
,
Dropdown
,
Avatar
,
message
}
from
'
antd
'
;
import
moment
from
'
moment
'
;
import
groupBy
from
'
lodash/groupBy
'
;
import
Debounce
from
'
lodash-decorators/debounce
'
;
import
NoticeIcon
from
'
../../components/NoticeIcon
'
;
import
HeaderSearch
from
'
../../components/HeaderSearch
'
;
import
styles
from
'
./index.less
'
;
const
{
Header
}
=
Layout
;
export
default
class
GlobalHeader
extends
PureComponent
{
componentDidMount
()
{
this
.
props
.
dispatch
({
type
:
'
user/fetchCurrent
'
,
});
}
componentWillUnmount
()
{
this
.
triggerResizeEvent
.
cancel
();
}
getNoticeData
()
{
const
{
notices
=
[]
}
=
this
.
props
;
if
(
notices
.
length
===
0
)
{
return
{};
}
const
newNotices
=
notices
.
map
((
notice
)
=>
{
const
newNotice
=
{
...
notice
};
if
(
newNotice
.
datetime
)
{
newNotice
.
datetime
=
moment
(
notice
.
datetime
).
fromNow
();
}
// transform id to item key
if
(
newNotice
.
id
)
{
newNotice
.
key
=
newNotice
.
id
;
}
if
(
newNotice
.
extra
&&
newNotice
.
status
)
{
const
color
=
({
todo
:
''
,
processing
:
'
blue
'
,
urgent
:
'
red
'
,
doing
:
'
gold
'
,
})[
newNotice
.
status
];
newNotice
.
extra
=
<
Tag
color
=
{
color
}
style
=
{{
marginRight
:
0
}}
>
{
newNotice
.
extra
}
<
/Tag>
;
}
return
newNotice
;
});
return
groupBy
(
newNotices
,
'
type
'
);
}
handleNoticeClear
=
(
type
)
=>
{
message
.
success
(
`清空了
${
type
}
`
);
this
.
props
.
dispatch
({
type
:
'
global/clearNotices
'
,
payload
:
type
,
});
}
handleNoticeVisibleChange
=
(
visible
)
=>
{
if
(
visible
)
{
this
.
props
.
dispatch
({
type
:
'
global/fetchNotices
'
,
});
}
}
handleMenuClick
=
({
key
})
=>
{
if
(
key
===
'
logout
'
)
{
this
.
props
.
dispatch
({
type
:
'
login/logout
'
,
});
}
}
toggle
=
()
=>
{
const
{
collapsed
}
=
this
.
props
;
this
.
props
.
dispatch
({
type
:
'
global/changeLayoutCollapsed
'
,
payload
:
!
collapsed
,
});
this
.
triggerResizeEvent
();
}
@
Debounce
(
600
)
triggerResizeEvent
()
{
// eslint-disable-line
const
event
=
document
.
createEvent
(
'
HTMLEvents
'
);
event
.
initEvent
(
'
resize
'
,
true
,
false
);
window
.
dispatchEvent
(
event
);
}
render
()
{
const
{
currentUser
,
collapsed
,
fetchingNotices
,
}
=
this
.
props
;
const
menu
=
(
<
Menu
className
=
{
styles
.
menu
}
selectedKeys
=
{[]}
onClick
=
{
this
.
handleMenuClick
}
>
<
Menu
.
Item
disabled
><
Icon
type
=
"
user
"
/>
个人中心
<
/Menu.Item
>
<
Menu
.
Item
disabled
><
Icon
type
=
"
setting
"
/>
设置
<
/Menu.Item
>
<
Menu
.
Divider
/>
<
Menu
.
Item
key
=
"
logout
"
><
Icon
type
=
"
logout
"
/>
退出登录
<
/Menu.Item
>
<
/Menu
>
);
const
noticeData
=
this
.
getNoticeData
();
return
(
<
Header
className
=
{
styles
.
header
}
>
<
Icon
className
=
{
styles
.
trigger
}
type
=
{
collapsed
?
'
menu-unfold
'
:
'
menu-fold
'
}
onClick
=
{
this
.
toggle
}
/
>
<
div
className
=
{
styles
.
right
}
>
<
HeaderSearch
className
=
{
`
${
styles
.
action
}
${
styles
.
search
}
`
}
placeholder
=
"
站内搜索
"
dataSource
=
{[
'
搜索提示一
'
,
'
搜索提示二
'
,
'
搜索提示三
'
]}
onSearch
=
{(
value
)
=>
{
console
.
log
(
'
input
'
,
value
);
// eslint-disable-line
}}
onPressEnter
=
{(
value
)
=>
{
console
.
log
(
'
enter
'
,
value
);
// eslint-disable-line
}}
/
>
<
NoticeIcon
className
=
{
styles
.
action
}
count
=
{
currentUser
.
notifyCount
}
onItemClick
=
{(
item
,
tabProps
)
=>
{
console
.
log
(
item
,
tabProps
);
// eslint-disable-line
}}
onClear
=
{
this
.
handleNoticeClear
}
onPopupVisibleChange
=
{
this
.
handleNoticeVisibleChange
}
loading
=
{
fetchingNotices
}
popupAlign
=
{{
offset
:
[
20
,
-
16
]
}}
>
<
NoticeIcon
.
Tab
list
=
{
noticeData
[
'
通知
'
]}
title
=
"
通知
"
emptyText
=
"
你已查看所有通知
"
emptyImage
=
"
https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg
"
/>
<
NoticeIcon
.
Tab
list
=
{
noticeData
[
'
消息
'
]}
title
=
"
消息
"
emptyText
=
"
您已读完所有消息
"
emptyImage
=
"
https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg
"
/>
<
NoticeIcon
.
Tab
list
=
{
noticeData
[
'
待办
'
]}
title
=
"
待办
"
emptyText
=
"
你已完成所有待办
"
emptyImage
=
"
https://gw.alipayobjects.com/zos/rmsportal/HsIsxMZiWKrNUavQUXqx.svg
"
/>
<
/NoticeIcon
>
{
currentUser
.
name
?
(
<
Dropdown
overlay
=
{
menu
}
>
<
span
className
=
{
`
${
styles
.
action
}
${
styles
.
account
}
`
}
>
<
Avatar
size
=
"
small
"
className
=
{
styles
.
avatar
}
src
=
{
currentUser
.
avatar
}
/
>
{
currentUser
.
name
}
<
/span
>
<
/Dropdown
>
)
:
<
Spin
size
=
"
small
"
style
=
{{
marginLeft
:
8
}}
/>
}
<
/div
>
<
/Header
>
);
}
}
src/
layouts/BasicLayout
.less
→
src/
components/GlobalHeader/index
.less
View file @
f67bff39
...
...
@@ -7,27 +7,18 @@
position: relative;
}
.logo {
height: 64px;
position: relative;
line-height: 64px;
padding-left: (@menu-collapsed-width - 32px) / 2;
transition: all .3s;
background: #002140;
overflow: hidden;
img {
display: inline-block;
vertical-align: middle;
height: 32px;
:global {
.ant-layout {
overflow-x: hidden;
}
h1 {
color: #fff;
display: inline-block;
vertical-align: middle;
font-size: 20
px;
margin: 0 0 0 12px;
font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif;
font-weight: 600
;
}
.menu {
:global(.anticon) {
margin-right: 8
px;
}
:global(.ant-dropdown-menu-item) {
width: 160px
;
}
}
...
...
@@ -82,25 +73,3 @@ i.trigger {
}
}
}
.menu {
:global(.anticon) {
margin-right: 8px;
}
:global(.ant-dropdown-menu-item) {
width: 160px;
}
}
:global {
.ant-layout {
overflow-x: hidden;
}
}
.sider {
min-height: 100vh;
box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
position: relative;
z-index: 10;
}
src/components/SiderMenu/index.js
0 → 100644
View file @
f67bff39
import
React
,
{
PureComponent
}
from
'
react
'
;
import
{
Layout
,
Menu
,
Icon
}
from
'
antd
'
;
import
{
Link
}
from
'
dva/router
'
;
import
logo
from
'
../../assets/logo.svg
'
;
import
styles
from
'
./index.less
'
;
const
{
Sider
}
=
Layout
;
const
{
SubMenu
}
=
Menu
;
export
default
class
SiderMenu
extends
PureComponent
{
constructor
(
props
)
{
super
(
props
);
// 把一级 Layout 的 children 作为菜单项
this
.
menus
=
props
.
navData
.
reduce
((
arr
,
current
)
=>
arr
.
concat
(
current
.
children
),
[]);
this
.
state
=
{
openKeys
:
this
.
getDefaultCollapsedSubMenus
(
props
),
};
}
onCollapse
=
(
collapsed
)
=>
{
this
.
props
.
dispatch
({
type
:
'
global/changeLayoutCollapsed
'
,
payload
:
collapsed
,
});
}
getDefaultCollapsedSubMenus
(
props
)
{
const
currentMenuSelectedKeys
=
[...
this
.
getCurrentMenuSelectedKeys
(
props
)];
currentMenuSelectedKeys
.
splice
(
-
1
,
1
);
if
(
currentMenuSelectedKeys
.
length
===
0
)
{
return
[
'
dashboard
'
];
}
return
currentMenuSelectedKeys
;
}
getCurrentMenuSelectedKeys
(
props
)
{
const
{
location
:
{
pathname
}
}
=
props
||
this
.
props
;
const
keys
=
pathname
.
split
(
'
/
'
).
slice
(
1
);
if
(
keys
.
length
===
1
&&
keys
[
0
]
===
''
)
{
return
[
this
.
menus
[
0
].
key
];
}
return
keys
;
}
getNavMenuItems
(
menusData
,
parentPath
=
''
)
{
if
(
!
menusData
)
{
return
[];
}
return
menusData
.
map
((
item
)
=>
{
if
(
!
item
.
name
)
{
return
null
;
}
let
itemPath
;
if
(
item
.
path
.
indexOf
(
'
http
'
)
===
0
)
{
itemPath
=
item
.
path
;
}
else
{
itemPath
=
`
${
parentPath
}
/
${
item
.
path
||
''
}
`
.
replace
(
/
\/
+/g
,
'
/
'
);
}
if
(
item
.
children
&&
item
.
children
.
some
(
child
=>
child
.
name
))
{
return
(
<
SubMenu
title
=
{
item
.
icon
?
(
<
span
>
<
Icon
type
=
{
item
.
icon
}
/
>
<
span
>
{
item
.
name
}
<
/span
>
<
/span
>
)
:
item
.
name
}
key
=
{
item
.
key
||
item
.
path
}
>
{
this
.
getNavMenuItems
(
item
.
children
,
itemPath
)}
<
/SubMenu
>
);
}
const
icon
=
item
.
icon
&&
<
Icon
type
=
{
item
.
icon
}
/>
;
return
(
<
Menu
.
Item
key
=
{
item
.
key
||
item
.
path
}
>
{
/^
https
?:
\
/
\
//.test(itemPath) ? (
<
a
href
=
{
itemPath
}
target
=
{
item
.
target
}
>
{
icon
}
<
span
>
{
item
.
name
}
<
/span
>
<
/a
>
)
:
(
<
Link
to
=
{
itemPath
}
target
=
{
item
.
target
}
replace
=
{
itemPath
===
this
.
props
.
location
.
pathname
}
>
{
icon
}
<
span
>
{
item
.
name
}
<
/span
>
<
/Link
>
)
}
<
/Menu.Item
>
);
});
}
handleOpenChange
=
(
openKeys
)
=>
{
const
lastOpenKey
=
openKeys
[
openKeys
.
length
-
1
];
const
isMainMenu
=
this
.
menus
.
some
(
item
=>
lastOpenKey
&&
(
item
.
key
===
lastOpenKey
||
item
.
path
===
lastOpenKey
)
);
this
.
setState
({
openKeys
:
isMainMenu
?
[
lastOpenKey
]
:
[...
openKeys
],
});
}
render
()
{
const
{
collapsed
}
=
this
.
props
;
// Don't show popup menu when it is been collapsed
const
menuProps
=
collapsed
?
{}
:
{
openKeys
:
this
.
state
.
openKeys
,
};
return
(
<
Sider
trigger
=
{
null
}
collapsible
collapsed
=
{
collapsed
}
breakpoint
=
"
md
"
onCollapse
=
{
this
.
onCollapse
}
width
=
{
256
}
className
=
{
styles
.
sider
}
>
<
div
className
=
{
styles
.
logo
}
>
<
Link
to
=
"
/
"
>
<
img
src
=
{
logo
}
alt
=
"
logo
"
/>
<
h1
>
Ant
Design
Pro
<
/h1
>
<
/Link
>
<
/div
>
<
Menu
theme
=
"
dark
"
mode
=
"
inline
"
{...
menuProps
}
onOpenChange
=
{
this
.
handleOpenChange
}
selectedKeys
=
{
this
.
getCurrentMenuSelectedKeys
()}
style
=
{{
margin
:
'
16px 0
'
,
width
:
'
100%
'
}}
>
{
this
.
getNavMenuItems
(
this
.
menus
)}
<
/Menu
>
<
/Sider
>
);
}
}
src/components/SiderMenu/index.less
0 → 100644
View file @
f67bff39
@import "~antd/lib/style/themes/default.less";
.logo {
height: 64px;
position: relative;
line-height: 64px;
padding-left: (@menu-collapsed-width - 32px) / 2;
transition: all .3s;
background: #002140;
overflow: hidden;
img {
display: inline-block;
vertical-align: middle;
height: 32px;
}
h1 {
color: #fff;
display: inline-block;
vertical-align: middle;
font-size: 20px;
margin: 0 0 0 12px;
font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif;
font-weight: 600;
}
}
.sider {
min-height: 100vh;
box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
position: relative;
z-index: 10;
}
src/e2e/home.e2e.js
View file @
f67bff39
...
...
@@ -3,7 +3,7 @@ import Nightmare from 'nightmare';
describe
(
'
Homepage
'
,
()
=>
{
it
(
'
it should have logo text
'
,
async
()
=>
{
const
page
=
Nightmare
().
goto
(
'
http://localhost:8000
'
);
const
text
=
await
page
.
evaluate
(()
=>
document
.
body
.
innerHTML
).
end
();
const
text
=
await
page
.
wait
(
'
h1
'
).
evaluate
(()
=>
document
.
body
.
innerHTML
).
end
();
expect
(
text
).
toContain
(
'
<h1>Ant Design Pro</h1>
'
);
});
});
src/layouts/BasicLayout.js
View file @
f67bff39
import
React
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
{
Layout
,
Menu
,
Icon
,
Avatar
,
Dropdown
,
Tag
,
message
,
Spi
n
}
from
'
antd
'
;
import
{
Layout
,
Ico
n
}
from
'
antd
'
;
import
DocumentTitle
from
'
react-document-title
'
;
import
{
connect
}
from
'
dva
'
;
import
{
Link
,
Route
,
Redirect
,
Switch
}
from
'
dva/router
'
;
import
moment
from
'
moment
'
;
import
groupBy
from
'
lodash/groupBy
'
;
import
{
Route
,
Redirect
,
Switch
}
from
'
dva/router
'
;
import
{
ContainerQuery
}
from
'
react-container-query
'
;
import
classNames
from
'
classnames
'
;
import
Debounce
from
'
lodash-decorators/debounce
'
;
import
HeaderSearch
from
'
../components/HeaderSearch
'
;
import
NoticeIcon
from
'
../components/NoticeIcon
'
;
import
GlobalHeader
from
'
../components/GlobalHeader
'
;
import
GlobalFooter
from
'
../components/GlobalFooter
'
;
import
SiderMenu
from
'
../components/SiderMenu
'
;
import
NotFound
from
'
../routes/Exception/404
'
;
import
styles
from
'
./BasicLayout.less
'
;
import
logo
from
'
../assets/logo.svg
'
;
const
{
Header
,
Sider
,
Content
}
=
Layout
;
const
{
SubMenu
}
=
Menu
;
const
{
Content
}
=
Layout
;
const
query
=
{
'
screen-xs
'
:
{
...
...
@@ -45,14 +39,6 @@ class BasicLayout extends React.PureComponent {
location
:
PropTypes
.
object
,
breadcrumbNameMap
:
PropTypes
.
object
,
}
constructor
(
props
)
{
super
(
props
);
// 把一级 Layout 的 children 作为菜单项
this
.
menus
=
props
.
navData
.
reduce
((
arr
,
current
)
=>
arr
.
concat
(
current
.
children
),
[]);
this
.
state
=
{
openKeys
:
this
.
getDefaultCollapsedSubMenus
(
props
),
};
}
getChildContext
()
{
const
{
location
,
navData
,
getRouteData
}
=
this
.
props
;
const
routeData
=
getRouteData
(
'
BasicLayout
'
);
...
...
@@ -68,106 +54,6 @@ class BasicLayout extends React.PureComponent {
});
return
{
location
,
breadcrumbNameMap
};
}
componentDidMount
()
{
this
.
props
.
dispatch
({
type
:
'
user/fetchCurrent
'
,
});
}
componentWillUnmount
()
{
this
.
triggerResizeEvent
.
cancel
();
}
onCollapse
=
(
collapsed
)
=>
{
this
.
props
.
dispatch
({
type
:
'
global/changeLayoutCollapsed
'
,
payload
:
collapsed
,
});
}
onMenuClick
=
({
key
})
=>
{
if
(
key
===
'
logout
'
)
{
this
.
props
.
dispatch
({
type
:
'
login/logout
'
,
});
}
}
getMenuData
=
(
data
,
parentPath
)
=>
{
let
arr
=
[];
data
.
forEach
((
item
)
=>
{
if
(
item
.
children
)
{
arr
.
push
({
path
:
`
${
parentPath
}
/
${
item
.
path
}
`
,
name
:
item
.
name
});
arr
=
arr
.
concat
(
this
.
getMenuData
(
item
.
children
,
`
${
parentPath
}
/
${
item
.
path
}
`
));
}
});
return
arr
;
}
getDefaultCollapsedSubMenus
(
props
)
{
const
currentMenuSelectedKeys
=
[...
this
.
getCurrentMenuSelectedKeys
(
props
)];
currentMenuSelectedKeys
.
splice
(
-
1
,
1
);
if
(
currentMenuSelectedKeys
.
length
===
0
)
{
return
[
'
dashboard
'
];
}
return
currentMenuSelectedKeys
;
}
getCurrentMenuSelectedKeys
(
props
)
{
const
{
location
:
{
pathname
}
}
=
props
||
this
.
props
;
const
keys
=
pathname
.
split
(
'
/
'
).
slice
(
1
);
if
(
keys
.
length
===
1
&&
keys
[
0
]
===
''
)
{
return
[
this
.
menus
[
0
].
key
];
}
return
keys
;
}
getNavMenuItems
(
menusData
,
parentPath
=
''
)
{
if
(
!
menusData
)
{
return
[];
}
return
menusData
.
map
((
item
)
=>
{
if
(
!
item
.
name
)
{
return
null
;
}
let
itemPath
;
if
(
item
.
path
.
indexOf
(
'
http
'
)
===
0
)
{
itemPath
=
item
.
path
;
}
else
{
itemPath
=
`
${
parentPath
}
/
${
item
.
path
||
''
}
`
.
replace
(
/
\/
+/g
,
'
/
'
);
}
if
(
item
.
children
&&
item
.
children
.
some
(
child
=>
child
.
name
))
{
return
(
<
SubMenu
title
=
{
item
.
icon
?
(
<
span
>
<
Icon
type
=
{
item
.
icon
}
/
>
<
span
>
{
item
.
name
}
<
/span
>
<
/span
>
)
:
item
.
name
}
key
=
{
item
.
key
||
item
.
path
}
>
{
this
.
getNavMenuItems
(
item
.
children
,
itemPath
)}
<
/SubMenu
>
);
}
const
icon
=
item
.
icon
&&
<
Icon
type
=
{
item
.
icon
}
/>
;
return
(
<
Menu
.
Item
key
=
{
item
.
key
||
item
.
path
}
>
{
/^
https
?:
\
/
\
//.test(itemPath) ? (
<
a
href
=
{
itemPath
}
target
=
{
item
.
target
}
>
{
icon
}
<
span
>
{
item
.
name
}
<
/span
>
<
/a
>
)
:
(
<
Link
to
=
{
itemPath
}
target
=
{
item
.
target
}
replace
=
{
itemPath
===
this
.
props
.
location
.
pathname
}
>
{
icon
}
<
span
>
{
item
.
name
}
<
/span
>
<
/Link
>
)
}
<
/Menu.Item
>
);
});
}
getPageTitle
()
{
const
{
location
,
getRouteData
}
=
this
.
props
;
const
{
pathname
}
=
location
;
...
...
@@ -179,175 +65,37 @@ class BasicLayout extends React.PureComponent {
});
return
title
;
}
getNoticeData
()
{
const
{
notices
=
[]
}
=
this
.
props
;
if
(
notices
.
length
===
0
)
{
return
{};
}
const
newNotices
=
notices
.
map
((
notice
)
=>
{
const
newNotice
=
{
...
notice
};
if
(
newNotice
.
datetime
)
{
newNotice
.
datetime
=
moment
(
notice
.
datetime
).
fromNow
();
}
// transform id to item key
if
(
newNotice
.
id
)
{
newNotice
.
key
=
newNotice
.
id
;
}
if
(
newNotice
.
extra
&&
newNotice
.
status
)
{
const
color
=
({
todo
:
''
,
processing
:
'
blue
'
,
urgent
:
'
red
'
,
doing
:
'
gold
'
,
})[
newNotice
.
status
];
newNotice
.
extra
=
<
Tag
color
=
{
color
}
style
=
{{
marginRight
:
0
}}
>
{
newNotice
.
extra
}
<
/Tag>
;
getMenuData
=
(
data
,
parentPath
)
=>
{
let
arr
=
[];
data
.
forEach
((
item
)
=>
{
if
(
item
.
children
)
{
arr
.
push
({
path
:
`
${
parentPath
}
/
${
item
.
path
}
`
,
name
:
item
.
name
});
arr
=
arr
.
concat
(
this
.
getMenuData
(
item
.
children
,
`
${
parentPath
}
/
${
item
.
path
}
`
));
}
return
newNotice
;
});
return
groupBy
(
newNotices
,
'
type
'
);
}
handleOpenChange
=
(
openKeys
)
=>
{
const
lastOpenKey
=
openKeys
[
openKeys
.
length
-
1
];
const
isMainMenu
=
this
.
menus
.
some
(
item
=>
lastOpenKey
&&
(
item
.
key
===
lastOpenKey
||
item
.
path
===
lastOpenKey
)
);
this
.
setState
({
openKeys
:
isMainMenu
?
[
lastOpenKey
]
:
[...
openKeys
],
});
}
toggle
=
()
=>
{
const
{
collapsed
}
=
this
.
props
;
this
.
props
.
dispatch
({
type
:
'
global/changeLayoutCollapsed
'
,
payload
:
!
collapsed
,
});
this
.
triggerResizeEvent
();
}
@
Debounce
(
600
)
triggerResizeEvent
()
{
// eslint-disable-line
const
event
=
document
.
createEvent
(
'
HTMLEvents
'
);
event
.
initEvent
(
'
resize
'
,
true
,
false
);
window
.
dispatchEvent
(
event
);
}
handleNoticeClear
=
(
type
)
=>
{
message
.
success
(
`清空了
${
type
}
`
);
this
.
props
.
dispatch
({
type
:
'
global/clearNotices
'
,
payload
:
type
,
});
}
handleNoticeVisibleChange
=
(
visible
)
=>
{
if
(
visible
)
{
this
.
props
.
dispatch
({
type
:
'
global/fetchNotices
'
,
});
}
return
arr
;
}
render
()
{
const
{
currentUser
,
collapsed
,
fetchingNotices
,
getRouteData
}
=
this
.
props
;
const
menu
=
(
<
Menu
className
=
{
styles
.
menu
}
selectedKeys
=
{[]}
onClick
=
{
this
.
onMenuClick
}
>
<
Menu
.
Item
disabled
><
Icon
type
=
"
user
"
/>
个人中心
<
/Menu.Item
>
<
Menu
.
Item
disabled
><
Icon
type
=
"
setting
"
/>
设置
<
/Menu.Item
>
<
Menu
.
Divider
/>
<
Menu
.
Item
key
=
"
logout
"
><
Icon
type
=
"
logout
"
/>
退出登录
<
/Menu.Item
>
<
/Menu
>
);
const
noticeData
=
this
.
getNoticeData
();
// Don't show popup menu when it is been collapsed
const
menuProps
=
collapsed
?
{}
:
{
openKeys
:
this
.
state
.
openKeys
,
};
const
{
currentUser
,
collapsed
,
fetchingNotices
,
notices
,
getRouteData
,
navData
,
location
,
dispatch
,
}
=
this
.
props
;
const
layout
=
(
<
Layout
>
<
Sider
trigger
=
{
null
}
collapsible
<
SiderMenu
collapsed
=
{
collapsed
}
breakpoint
=
"
md
"
onCollapse
=
{
this
.
onCollapse
}
width
=
{
256
}
className
=
{
styles
.
sider
}
>
<
div
className
=
{
styles
.
logo
}
>
<
Link
to
=
"
/
"
>
<
img
src
=
{
logo
}
alt
=
"
logo
"
/>
<
h1
>
Ant
Design
Pro
<
/h1
>
<
/Link
>
<
/div
>
<
Menu
theme
=
"
dark
"
mode
=
"
inline
"
{...
menuProps
}
onOpenChange
=
{
this
.
handleOpenChange
}
selectedKeys
=
{
this
.
getCurrentMenuSelectedKeys
()}
style
=
{{
margin
:
'
16px 0
'
,
width
:
'
100%
'
}}
>
{
this
.
getNavMenuItems
(
this
.
menus
)}
<
/Menu
>
<
/Sider
>
navData
=
{
navData
}
location
=
{
location
}
dispatch
=
{
dispatch
}
/
>
<
Layout
>
<
Header
className
=
{
styles
.
header
}
>
<
Icon
className
=
{
styles
.
trigger
}
type
=
{
collapsed
?
'
menu-unfold
'
:
'
menu-fold
'
}
onClick
=
{
this
.
toggle
}
/
>
<
div
className
=
{
styles
.
right
}
>
<
HeaderSearch
className
=
{
`
${
styles
.
action
}
${
styles
.
search
}
`
}
placeholder
=
"
站内搜索
"
dataSource
=
{[
'
搜索提示一
'
,
'
搜索提示二
'
,
'
搜索提示三
'
]}
onSearch
=
{(
value
)
=>
{
console
.
log
(
'
input
'
,
value
);
// eslint-disable-line
}}
onPressEnter
=
{(
value
)
=>
{
console
.
log
(
'
enter
'
,
value
);
// eslint-disable-line
}}
/
>
<
NoticeIcon
className
=
{
styles
.
action
}
count
=
{
currentUser
.
notifyCount
}
onItemClick
=
{(
item
,
tabProps
)
=>
{
console
.
log
(
item
,
tabProps
);
// eslint-disable-line
}}
onClear
=
{
this
.
handleNoticeClear
}
onPopupVisibleChange
=
{
this
.
handleNoticeVisibleChange
}
loading
=
{
fetchingNotices
}
popupAlign
=
{{
offset
:
[
20
,
-
16
]
}}
>
<
NoticeIcon
.
Tab
list
=
{
noticeData
[
'
通知
'
]}
title
=
"
通知
"
emptyText
=
"
你已查看所有通知
"
emptyImage
=
"
https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg
"
/>
<
NoticeIcon
.
Tab
list
=
{
noticeData
[
'
消息
'
]}
title
=
"
消息
"
emptyText
=
"
您已读完所有消息
"
emptyImage
=
"
https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg
"
/>
<
NoticeIcon
.
Tab
list
=
{
noticeData
[
'
待办
'
]}
title
=
"
待办
"
emptyText
=
"
你已完成所有待办
"
emptyImage
=
"
https://gw.alipayobjects.com/zos/rmsportal/HsIsxMZiWKrNUavQUXqx.svg
"
/>
<
/NoticeIcon
>
{
currentUser
.
name
?
(
<
Dropdown
overlay
=
{
menu
}
>
<
span
className
=
{
`
${
styles
.
action
}
${
styles
.
account
}
`
}
>
<
Avatar
size
=
"
small
"
className
=
{
styles
.
avatar
}
src
=
{
currentUser
.
avatar
}
/
>
{
currentUser
.
name
}
<
/span
>
<
/Dropdown
>
)
:
<
Spin
size
=
"
small
"
style
=
{{
marginLeft
:
8
}}
/>
}
<
/div
>
<
/Header
>
<
GlobalHeader
currentUser
=
{
currentUser
}
fetchingNotices
=
{
fetchingNotices
}
notices
=
{
notices
}
collapsed
=
{
collapsed
}
dispatch
=
{
dispatch
}
/
>
<
Content
style
=
{{
margin
:
'
24px 24px 0
'
,
height
:
'
100%
'
}}
>
<
div
style
=
{{
minHeight
:
'
calc(100vh - 260px)
'
}}
>
<
Switch
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment