You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
4.7 KiB
153 lines
4.7 KiB
import { ConnectProps, ConnectState } from '@/models/connect';
|
|
import { NoticeItem } from '@/models/global';
|
|
import { CurrentUser } from '@/models/user';
|
|
import React, { Component } from 'react';
|
|
import { Tag, message } from 'antd';
|
|
import { formatMessage } from 'umi-plugin-react/locale';
|
|
import moment from 'moment';
|
|
import groupBy from 'lodash/groupBy';
|
|
import NoticeIcon from '../NoticeIcon';
|
|
import styles from './index.less';
|
|
import { connect } from 'dva';
|
|
|
|
export interface GlobalHeaderRightProps extends 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(`${formatMessage({ id: 'component.noticeIcon.cleared' })} ${title}`);
|
|
if (dispatch) {
|
|
dispatch({
|
|
type: 'global/clearNotices',
|
|
payload: key,
|
|
});
|
|
}
|
|
};
|
|
|
|
getNoticeData = (): { [key: string]: NoticeItem[] } => {
|
|
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 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={formatMessage({ id: 'component.noticeIcon.clear' })}
|
|
viewMoreText={formatMessage({ id: 'component.noticeIcon.view-more' })}
|
|
onClear={this.handleNoticeClear}
|
|
onPopupVisibleChange={onNoticeVisibleChange}
|
|
onViewMore={() => message.info('Click on view more')}
|
|
clearClose
|
|
>
|
|
<NoticeIcon.Tab
|
|
tabKey="notification"
|
|
count={unreadMsg.notification}
|
|
list={noticeData.notification}
|
|
title={formatMessage({ id: 'component.globalHeader.notification' })}
|
|
emptyText={formatMessage({ id: 'component.globalHeader.notification.empty' })}
|
|
showViewMore
|
|
/>
|
|
<NoticeIcon.Tab
|
|
tabKey="message"
|
|
count={unreadMsg.message}
|
|
list={noticeData.message}
|
|
title={formatMessage({ id: 'component.globalHeader.message' })}
|
|
emptyText={formatMessage({ id: 'component.globalHeader.message.empty' })}
|
|
showViewMore
|
|
/>
|
|
<NoticeIcon.Tab
|
|
tabKey="event"
|
|
title={formatMessage({ id: 'component.globalHeader.event' })}
|
|
emptyText={formatMessage({ id: 'component.globalHeader.event.empty' })}
|
|
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);
|
|
|