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.
168 lines
4.4 KiB
168 lines
4.4 KiB
import { Component } from 'react';
|
|
import type { ConnectProps } from 'umi';
|
|
import { connect } from 'umi';
|
|
import { Tag, message } from 'antd';
|
|
import groupBy from 'lodash/groupBy';
|
|
import moment from 'moment';
|
|
import type { NoticeItem } from '@/models/global';
|
|
import type { CurrentUser } from '@/models/user';
|
|
import type { ConnectState } from '@/models/connect';
|
|
import NoticeIcon from '../NoticeIcon';
|
|
import styles from './index.less';
|
|
|
|
export type GlobalHeaderRightProps = {
|
|
notices?: NoticeItem[];
|
|
currentUser?: CurrentUser;
|
|
fetchingNotices?: boolean;
|
|
onNoticeVisibleChange?: (visible: boolean) => void;
|
|
onNoticeClear?: (tabName?: string) => void;
|
|
} & Partial<ConnectProps>;
|
|
|
|
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(`${'Emptied'} ${title}`);
|
|
|
|
if (dispatch) {
|
|
dispatch({
|
|
type: 'global/clearNotices',
|
|
payload: key,
|
|
});
|
|
}
|
|
};
|
|
|
|
getNoticeData = (): Record<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: Record<string, NoticeItem[]>) => {
|
|
const unreadMsg: Record<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="Empty"
|
|
viewMoreText="See 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="Notification"
|
|
emptyText="You have viewed all notifications"
|
|
showViewMore
|
|
/>
|
|
<NoticeIcon.Tab
|
|
tabKey="message"
|
|
count={unreadMsg.message}
|
|
list={noticeData.message}
|
|
title="Message"
|
|
emptyText="You have read all messages"
|
|
showViewMore
|
|
/>
|
|
<NoticeIcon.Tab
|
|
tabKey="event"
|
|
title="To do"
|
|
emptyText="You have completed all to-dos"
|
|
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);
|
|
|