172 lines
4.4 KiB
TypeScript
172 lines
4.4 KiB
TypeScript
import React, { Component } from 'react';
|
|
import { connect, ConnectProps } from 'umi';
|
|
import { Tag, message } from 'antd';
|
|
import groupBy from 'lodash/groupBy';
|
|
import moment from 'moment';
|
|
import { NoticeItem } from '@/models/global';
|
|
import { CurrentUser } from '@/models/user';
|
|
import { ConnectState } from '@/models/connect';
|
|
import NoticeIcon from '../NoticeIcon';
|
|
import styles from './index.less';
|
|
|
|
export interface GlobalHeaderRightProps extends Partial<ConnectProps> {
|
|
notices?: NoticeItem[];
|
|
currentUser?: CurrentUser;
|
|
fetchingNotices?: boolean;
|
|
onNoticeVisibleChange?: (visible: boolean) => void;
|
|
onNoticeClear?: (tabName?: string) => void;
|
|
}
|
|
|
|
class GlobalHeaderRight extends Component<GlobalHeaderRightProps> {
|
|
componentDidMount() {
|
|
const { dispatch } = this.props;
|
|
|
|
if (dispatch) {
|
|
dispatch({
|
|
type: 'global/fetchNotices',
|
|
});
|
|
}
|
|
}
|
|
|
|
changeReadState = (clickedItem: NoticeItem): void => {
|
|
const { id } = clickedItem;
|
|
const { dispatch } = this.props;
|
|
|
|
if (dispatch) {
|
|
dispatch({
|
|
type: 'global/changeNoticeReadState',
|
|
payload: id,
|
|
});
|
|
}
|
|
};
|
|
|
|
handleNoticeClear = (title: string, key: string) => {
|
|
const { dispatch } = this.props;
|
|
message.success(`${'清空了'} ${title}`);
|
|
|
|
if (dispatch) {
|
|
dispatch({
|
|
type: 'global/clearNotices',
|
|
payload: key,
|
|
});
|
|
}
|
|
};
|
|
|
|
getNoticeData = (): {
|
|
[key: string]: NoticeItem[];
|
|
} => {
|
|
const { notices = [] } = this.props;
|
|
|
|
if (!notices || notices.length === 0 || !Array.isArray(notices)) {
|
|
return {};
|
|
}
|
|
|
|
const newNotices = notices.map((notice) => {
|
|
const newNotice = { ...notice };
|
|
|
|
if (newNotice.datetime) {
|
|
newNotice.datetime = moment(notice.datetime as string).fromNow();
|
|
}
|
|
|
|
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');
|
|
};
|
|
|
|
getUnreadData = (noticeData: { [key: string]: NoticeItem[] }) => {
|
|
const unreadMsg: {
|
|
[key: string]: number;
|
|
} = {};
|
|
Object.keys(noticeData).forEach((key) => {
|
|
const value = noticeData[key];
|
|
|
|
if (!unreadMsg[key]) {
|
|
unreadMsg[key] = 0;
|
|
}
|
|
|
|
if (Array.isArray(value)) {
|
|
unreadMsg[key] = value.filter((item) => !item.read).length;
|
|
}
|
|
});
|
|
return unreadMsg;
|
|
};
|
|
|
|
render() {
|
|
const { currentUser, fetchingNotices, onNoticeVisibleChange } = this.props;
|
|
const noticeData = this.getNoticeData();
|
|
const unreadMsg = this.getUnreadData(noticeData);
|
|
return (
|
|
<NoticeIcon
|
|
className={styles.action}
|
|
count={currentUser && currentUser.unreadCount}
|
|
onItemClick={(item) => {
|
|
this.changeReadState(item as NoticeItem);
|
|
}}
|
|
loading={fetchingNotices}
|
|
clearText="清空"
|
|
viewMoreText="查看更多"
|
|
onClear={this.handleNoticeClear}
|
|
onPopupVisibleChange={onNoticeVisibleChange}
|
|
onViewMore={() => message.info('Click on view more')}
|
|
clearClose
|
|
>
|
|
<NoticeIcon.Tab
|
|
tabKey="notification"
|
|
count={unreadMsg.notification}
|
|
list={noticeData.notification}
|
|
title="通知"
|
|
emptyText="你已查看所有通知"
|
|
showViewMore
|
|
/>
|
|
<NoticeIcon.Tab
|
|
tabKey="message"
|
|
count={unreadMsg.message}
|
|
list={noticeData.message}
|
|
title="消息"
|
|
emptyText="您已读完所有消息"
|
|
showViewMore
|
|
/>
|
|
<NoticeIcon.Tab
|
|
tabKey="event"
|
|
title="待办"
|
|
emptyText="你已完成所有待办"
|
|
count={unreadMsg.event}
|
|
list={noticeData.event}
|
|
showViewMore
|
|
/>
|
|
</NoticeIcon>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default connect(({ user, global, loading }: ConnectState) => ({
|
|
currentUser: user.currentUser,
|
|
collapsed: global.collapsed,
|
|
fetchingMoreNotices: loading.effects['global/fetchMoreNotices'],
|
|
fetchingNotices: loading.effects['global/fetchNotices'],
|
|
notices: global.notices,
|
|
}))(GlobalHeaderRight);
|