diff --git a/mock/notices.js b/mock/notices.js index e07565dfe603c73b348c908a201d20422da3bf52..505088e0da17ba556961e2d1f3ed1159d561cae2 100644 --- a/mock/notices.js +++ b/mock/notices.js @@ -1,114 +1,101 @@ -const fakeNotices = [ - { - id: '000000001', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', - title: '你收到了 14 份新周报', - datetime: '2017-08-09', - type: 'notification', - }, - { - id: '000000002', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', - title: '你推荐的 曲妮妮 已通过第三轮面试', - datetime: '2017-08-08', - type: 'notification', - }, - { - id: '000000003', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', - title: '这种模板可以区分多种通知类型', - datetime: '2017-08-07', - read: true, - type: 'notification', - }, - { - id: '000000004', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', - title: '左侧图标用于区分不同的类型', - datetime: '2017-08-07', - type: 'notification', - }, - { - id: '000000005', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', - title: '内容不要超过两行字,超出时自动截断', - datetime: '2017-08-07', - type: 'notification', - }, - { - id: '000000006', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '曲丽丽 评论了你', - description: '描述信息描述信息描述信息', - datetime: '2017-08-07', - type: 'message', - clickClose: true, - }, - { - id: '000000007', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '朱偏右 回复了你', - description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', - datetime: '2017-08-07', - type: 'message', - clickClose: true, - }, - { - id: '000000008', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '标题', - description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', - datetime: '2017-08-07', - type: 'message', - clickClose: true, - }, - { - id: '000000009', - title: '任务名称', - description: '任务需要在 2017-01-12 20:00 前启动', - extra: '未开始', - status: 'todo', - type: 'event', - }, - { - id: '000000010', - title: '第三方紧急代码变更', - description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', - extra: '马上到期', - status: 'urgent', - type: 'event', - }, - { - id: '000000011', - title: '信息安全考试', - description: '指派竹尔于 2017-01-09 前完成更新并发布', - extra: '已耗时 8 天', - status: 'doing', - type: 'event', - }, - { - id: '000000012', - title: 'ABCD 版本发布', - description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', - extra: '进行中', - status: 'processing', - type: 'event', - }, -]; - -const getNotices = (req, res) => { - if (req.query && req.query.type) { - const startFrom = parseInt(req.query.lastItemId, 10) + 1; - const result = fakeNotices - .filter(({ type }) => type === req.query.type) - .map((notice, index) => ({ - ...notice, - id: `0000000${startFrom + index}`, - })); - return res.json(startFrom > 24 ? result.concat(null) : result); - } - return res.json(fakeNotices); -}; +const getNotices = (req, res) => + res.json([ + { + id: '000000001', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', + title: '你收到了 14 份新周报', + datetime: '2017-08-09', + type: 'notification', + }, + { + id: '000000002', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', + title: '你推荐的 曲妮妮 已通过第三轮面试', + datetime: '2017-08-08', + type: 'notification', + }, + { + id: '000000003', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', + title: '这种模板可以区分多种通知类型', + datetime: '2017-08-07', + read: true, + type: 'notification', + }, + { + id: '000000004', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + datetime: '2017-08-07', + type: 'notification', + }, + { + id: '000000005', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', + title: '内容不要超过两行字,超出时自动截断', + datetime: '2017-08-07', + type: 'notification', + }, + { + id: '000000006', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '曲丽丽 评论了你', + description: '描述信息描述信息描述信息', + datetime: '2017-08-07', + type: 'message', + clickClose: true, + }, + { + id: '000000007', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '朱偏右 回复了你', + description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', + datetime: '2017-08-07', + type: 'message', + clickClose: true, + }, + { + id: '000000008', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '标题', + description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', + datetime: '2017-08-07', + type: 'message', + clickClose: true, + }, + { + id: '000000009', + title: '任务名称', + description: '任务需要在 2017-01-12 20:00 前启动', + extra: '未开始', + status: 'todo', + type: 'event', + }, + { + id: '000000010', + title: '第三方紧急代码变更', + description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', + extra: '马上到期', + status: 'urgent', + type: 'event', + }, + { + id: '000000011', + title: '信息安全考试', + description: '指派竹尔于 2017-01-09 前完成更新并发布', + extra: '已耗时 8 天', + status: 'doing', + type: 'event', + }, + { + id: '000000012', + title: 'ABCD 版本发布', + description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', + extra: '进行中', + status: 'processing', + type: 'event', + }, + ]); export default { 'GET /api/notices': getNotices, diff --git a/src/components/Charts/index.js b/src/components/Charts/index.js index 56a1c565f4a162f4ef0cee14b39116596ed9a9f0..6fbcb743648d6738afbcbcad26f988b2dae37d89 100644 --- a/src/components/Charts/index.js +++ b/src/components/Charts/index.js @@ -3,15 +3,11 @@ import numeral from 'numeral'; import ChartCard from './ChartCard'; import Field from './Field'; -const getComponent = Component => { - return props => { - return ( - - - - ); - }; -}; +const getComponent = Component => props => ( + + + +); const Bar = getComponent(React.lazy(() => import('./Bar'))); const Pie = getComponent(React.lazy(() => import('./Pie'))); diff --git a/src/components/DescriptionList/index.less b/src/components/DescriptionList/index.less index 4048a128ee949cfd5c8ab94ea5b5c331cd1bb22b..c3cf8e69e7cd0269f359b20fa73e868a7e87182b 100644 --- a/src/components/DescriptionList/index.less +++ b/src/components/DescriptionList/index.less @@ -8,6 +8,14 @@ overflow: hidden; } } + // fix margin top error of following descriptionList + & + & { + :global { + .ant-row { + margin-top: 16px; + } + } + } .title { margin-bottom: 16px; @@ -47,6 +55,14 @@ margin-bottom: -8px; } } + // fix margin top error of following descriptionList + & + .descriptionList { + :global { + .ant-row { + margin-top: 8px; + } + } + } .title { margin-bottom: 12px; color: @text-color; diff --git a/src/components/GlobalHeader/RightContent.js b/src/components/GlobalHeader/RightContent.js index dad360ff08299518c7d3fdc7026c2b3b289b883f..3b07c3e6ba421f4f842901f97b715f6dd6f825fc 100644 --- a/src/components/GlobalHeader/RightContent.js +++ b/src/components/GlobalHeader/RightContent.js @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; import { FormattedMessage, formatMessage } from 'umi/locale'; -import { Spin, Tag, Menu, Icon, Avatar, Tooltip } from 'antd'; +import { Spin, Tag, Menu, Icon, Avatar, Tooltip, message } from 'antd'; import moment from 'moment'; import groupBy from 'lodash/groupBy'; import NoticeIcon from '../NoticeIcon'; @@ -63,30 +63,13 @@ export default class GlobalHeaderRight extends PureComponent { }); }; - fetchMoreNotices = tabProps => { - const { list, name } = tabProps; - const { dispatch, notices = [] } = this.props; - const lastItemId = notices[notices.length - 1].id; - dispatch({ - type: 'global/fetchMoreNotices', - payload: { - lastItemId, - type: name, - offset: list.length, - }, - }); - }; - render() { const { currentUser, - fetchingMoreNotices, fetchingNotices, - loadedAllNotices, onNoticeVisibleChange, onMenuClick, onNoticeClear, - skeletonCount, theme, } = this.props; const menu = ( @@ -110,11 +93,6 @@ export default class GlobalHeaderRight extends PureComponent { ); - const loadMoreProps = { - skeletonCount, - loadedAll: loadedAllNotices, - loading: fetchingMoreNotices, - }; const noticeData = this.getNoticeData(); const unreadMsg = this.getUnreadData(noticeData); let className = styles.right; @@ -155,44 +133,43 @@ export default class GlobalHeaderRight extends PureComponent { console.log(item, tabProps); // eslint-disable-line this.changeReadState(item, tabProps); }} + loading={fetchingNotices} locale={{ emptyText: formatMessage({ id: 'component.noticeIcon.empty' }), clear: formatMessage({ id: 'component.noticeIcon.clear' }), - loadedAll: formatMessage({ id: 'component.noticeIcon.loaded' }), - loadMore: formatMessage({ id: 'component.noticeIcon.loading-more' }), + viewMore: formatMessage({ id: 'component.noticeIcon.view-more' }), + notification: formatMessage({ id: 'component.globalHeader.notification' }), + message: formatMessage({ id: 'component.globalHeader.message' }), + event: formatMessage({ id: 'component.globalHeader.event' }), }} onClear={onNoticeClear} - onLoadMore={this.fetchMoreNotices} onPopupVisibleChange={onNoticeVisibleChange} - loading={fetchingNotices} + onViewMore={() => message.info('Click on view more')} clearClose > {currentUser.name ? ( diff --git a/src/components/NoticeIcon/NoticeIconTab.d.ts b/src/components/NoticeIcon/NoticeIconTab.d.ts index 6ffaf032159f3cb909fde4bcda2ce57549bd9166..869dbbf08af2278a6bcb9a763bd91101089ce54f 100644 --- a/src/components/NoticeIcon/NoticeIconTab.d.ts +++ b/src/components/NoticeIcon/NoticeIconTab.d.ts @@ -15,12 +15,9 @@ export interface INoticeIconTabProps { emptyText?: React.ReactNode; emptyImage?: string; list?: INoticeIconData[]; - loadedAll?: boolean; - loading?: boolean; name?: string; showClear?: boolean; - skeletonCount?: number; - skeletonProps?: SkeletonProps; + showViewMore?: boolean; style?: React.CSSProperties; title?: string; } diff --git a/src/components/NoticeIcon/NoticeList.js b/src/components/NoticeIcon/NoticeList.js index 6b73e6e0de9987fcc11a8df296b43e5cda5822bf..63985abd5b2871b3f0640b21f283c601354b86b2 100644 --- a/src/components/NoticeIcon/NoticeList.js +++ b/src/components/NoticeIcon/NoticeList.js @@ -1,10 +1,8 @@ import React from 'react'; -import { Avatar, List, Skeleton } from 'antd'; +import { Avatar, List } from 'antd'; import classNames from 'classnames'; import styles from './NoticeList.less'; -let ListElement = null; - export default function NoticeList({ data = [], onClick, @@ -13,14 +11,9 @@ export default function NoticeList({ locale, emptyText, emptyImage, - loading, - onLoadMore, - visible, - loadedAll = true, - scrollToLoad = true, + onViewMore = null, showClear = true, - skeletonCount = 5, - skeletonProps = {}, + showViewMore = false, }) { if (data.length === 0) { return ( @@ -30,36 +23,10 @@ export default function NoticeList({ ); } - const loadingList = Array.from({ length: loading ? skeletonCount : 0 }).map(() => ({ loading })); - const LoadMore = loadedAll ? ( -
- {locale.loadedAll} -
- ) : ( -
- {locale.loadMore} -
- ); - const onScroll = event => { - if (!scrollToLoad || loading || loadedAll) return; - if (typeof onLoadMore !== 'function') return; - const { currentTarget: t } = event; - if (t.scrollHeight - t.scrollTop - t.clientHeight <= 40) { - onLoadMore(event); - ListElement = t; - } - }; - if (!visible && ListElement) { - try { - ListElement.scrollTo(null, 0); - } catch (err) { - ListElement = null; - } - } return (
- - {[...data, ...loadingList].map((item, i) => { + + {data.map((item, i) => { const itemCls = classNames(styles.item, { [styles.read]: item.read, }); @@ -74,35 +41,36 @@ export default function NoticeList({ return ( onClick(item)}> - - - {item.title} -
{item.extra}
-
- } - description={ -
-
- {item.description} -
-
{item.datetime}
+ + {item.title} +
{item.extra}
+
+ } + description={ +
+
+ {item.description}
- } - /> - +
{item.datetime}
+
+ } + /> ); })} - {showClear ? ( -
- {locale.clear} {title} -
- ) : null} +
+ {showClear ? ( +
+ {locale.clear} {locale[title] || title} +
+ ) : null} + {showViewMore ?
{locale.viewMore}
: null} +
); } diff --git a/src/components/NoticeIcon/NoticeList.less b/src/components/NoticeIcon/NoticeList.less index fc566ad06d914d0332c5b30ddeb70043efa2efb9..efa686cb0e97c79726eee8e6d1631070b3e24ca7 100644 --- a/src/components/NoticeIcon/NoticeList.less +++ b/src/components/NoticeIcon/NoticeList.less @@ -78,17 +78,28 @@ } } -.clear { +.bottomBar { height: 46px; color: @text-color; line-height: 46px; text-align: center; border-top: 1px solid @border-color-split; border-radius: 0 0 @border-radius-base @border-radius-base; - cursor: pointer; transition: all 0.3s; - - &:hover { - color: @heading-color; + div { + display: inline-block; + width: 50%; + cursor: pointer; + transition: all 0.3s; + user-select: none; + &:hover { + color: @heading-color; + } + &:only-child { + width: 100%; + } + &:not(:only-child):last-child { + border-left: 1px solid @border-color-split; + } } } diff --git a/src/components/NoticeIcon/demo/popover.md b/src/components/NoticeIcon/demo/popover.md index 9515c5187ea2508cdabacba3af882be55d515fe2..9694c5efb6b58873e618b3c3393ef576546bc344 100644 --- a/src/components/NoticeIcon/demo/popover.md +++ b/src/components/NoticeIcon/demo/popover.md @@ -9,103 +9,90 @@ title: 带浮层卡片 import NoticeIcon from 'ant-design-pro/lib/NoticeIcon'; import { Tag } from 'antd'; -const data = [ - { - id: '000000001', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', - title: '你收到了 14 份新周报', - datetime: '2017-08-09', - type: '通知', - }, - { - id: '000000002', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', - title: '你推荐的 曲妮妮 已通过第三轮面试', - datetime: '2017-08-08', - type: '通知', - }, - { - id: '000000003', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', - title: '这种模板可以区分多种通知类型', - datetime: '2017-08-07', - read: true, - type: '通知', - }, - { - id: '000000004', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', - title: '左侧图标用于区分不同的类型', - datetime: '2017-08-07', - type: '通知', - }, - { - id: '000000005', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', - title: '内容不要超过两行字,超出时自动截断', - datetime: '2017-08-07', - type: '通知', - }, - { - id: '000000006', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '曲丽丽 评论了你', - description: '描述信息描述信息描述信息', - datetime: '2017-08-07', - type: '消息', - clickClose: true, - }, - { - id: '000000007', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '朱偏右 回复了你', - description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', - datetime: '2017-08-07', - type: '消息', - clickClose: true, - }, - { - id: '000000008', - avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', - title: '标题', - description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', - datetime: '2017-08-07', - type: '消息', - clickClose: true, - }, - { - id: '000000009', - title: '任务名称', - description: '任务需要在 2017-01-12 20:00 前启动', - extra: '未开始', - status: 'todo', - type: '待办', - }, - { - id: '000000010', - title: '第三方紧急代码变更', - description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', - extra: '马上到期', - status: 'urgent', - type: '待办', - }, - { - id: '000000011', - title: '信息安全考试', - description: '指派竹尔于 2017-01-09 前完成更新并发布', - extra: '已耗时 8 天', - status: 'doing', - type: '待办', - }, - { - id: '000000012', - title: 'ABCD 版本发布', - description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', - extra: '进行中', - status: 'processing', - type: '待办', - }, -]; +const data = [{ + id: '000000001', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', + title: '你收到了 14 份新周报', + datetime: '2017-08-09', + type: 'notification', +}, { + id: '000000002', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png', + title: '你推荐的 曲妮妮 已通过第三轮面试', + datetime: '2017-08-08', + type: 'notification', +}, { + id: '000000003', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png', + title: '这种模板可以区分多种通知类型', + datetime: '2017-08-07', + read: true, + type: 'notification', +}, { + id: '000000004', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png', + title: '左侧图标用于区分不同的类型', + datetime: '2017-08-07', + type: 'notification', +}, { + id: '000000005', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png', + title: '内容不要超过两行字,超出时自动截断', + datetime: '2017-08-07', + type: 'notification', +}, { + id: '000000006', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '曲丽丽 评论了你', + description: '描述信息描述信息描述信息', + datetime: '2017-08-07', + type: 'message', + clickClose: true, +}, { + id: '000000007', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '朱偏右 回复了你', + description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', + datetime: '2017-08-07', + type: 'message', + clickClose: true, +}, { + id: '000000008', + avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg', + title: '标题', + description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像', + datetime: '2017-08-07', + type: 'message', + clickClose: true, +}, { + id: '000000009', + title: '任务名称', + description: '任务需要在 2017-01-12 20:00 前启动', + extra: '未开始', + status: 'todo', + type: 'event', +}, { + id: '000000010', + title: '第三方紧急代码变更', + description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', + extra: '马上到期', + status: 'urgent', + type: 'event', +}, { + id: '000000011', + title: '信息安全考试', + description: '指派竹尔于 2017-01-09 前完成更新并发布', + extra: '已耗时 8 天', + status: 'doing', + type: 'event', +}, { + id: '000000012', + title: 'ABCD 版本发布', + description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务', + extra: '进行中', + status: 'processing', + type: 'event', +}]; function onItemClick(item, tabProps) { console.log(item, tabProps); @@ -163,23 +150,20 @@ const Demo = () => ( > diff --git a/src/components/NoticeIcon/index.d.ts b/src/components/NoticeIcon/index.d.ts index f7d6479aa89d8584d37e0f7360b1ddc705a71ca8..d32586d6876b453a5184f222001b9e9a7968f8bb 100644 --- a/src/components/NoticeIcon/index.d.ts +++ b/src/components/NoticeIcon/index.d.ts @@ -8,7 +8,7 @@ export interface INoticeIconProps { loading?: boolean; onClear?: (tabName: string) => void; onItemClick?: (item: INoticeIconData, tabProps: INoticeIconProps) => void; - onLoadMore?: (tabProps: INoticeIconProps) => void; + onViewMore?: (tabProps: INoticeIconProps) => void; onTabChange?: (tabTile: string) => void; style?: React.CSSProperties; onPopupVisibleChange?: (visible: boolean) => void; @@ -16,8 +16,8 @@ export interface INoticeIconProps { locale?: { emptyText: string; clear: string; - loadedAll: string; - loadMore: string; + viewMore: string; + [key: string]: string; }; clearClose?: boolean; } diff --git a/src/components/NoticeIcon/index.en-US.md b/src/components/NoticeIcon/index.en-US.md index c6472780611431720999731b964e9ad52659bda2..677fa216324a97c0f6656d06307d449409d421d0 100644 --- a/src/components/NoticeIcon/index.en-US.md +++ b/src/components/NoticeIcon/index.en-US.md @@ -5,7 +5,7 @@ cols: 1 order: 9 --- -用在导航工具栏上,作为整个产品统一的通知中心。 +Used in navigation toolbar as a unified notification center for the entire product. ## API @@ -16,11 +16,11 @@ bell | Change the bell Icon | ReactNode | `` loading | Popup card loading status | boolean | `false` onClear | Click to clear button the callback | function(tabName) | - onItemClick | Click on the list item's callback | function(item, tabProps) | - -onLoadMore | Callback of click for loading more | function(tabProps, event) | - onPopupVisibleChange | Popup Card Showing or Hiding Callbacks | function(visible) | - onTabChange | Switching callbacks for tabs | function(tabTitle) | - +onViewMore | Callback of click for view more | function(tabProps, event) | - popupVisible | Popup card display state | boolean | - -locale | Default message text | Object | `{ emptyText: 'No notifications', clear: 'Clear', loadedAll: 'Loaded', loadMore: 'Loading more' }` +locale | Default message text | Object | `{ emptyText: 'No notifications', clear: 'Clear', viewMore: 'Loading more' }` clearClose | Close menu after clear | boolean | `false` ### NoticeIcon.Tab @@ -31,14 +31,9 @@ count | Unread messages count of this tab | number | list.length emptyText | Message text when list is empty | ReactNode | - emptyImage | Image when list is empty | string | - list | List data, format refer to the following table | Array | `[]` -loadedAll | All messages have been loaded | boolean | `true` -loading | Loading status of this tab | boolean | `false` -name | identifier for message Tab | string | - -scrollToLoad | Scroll to load | boolean | `true` -skeletonCount | Number of skeleton when tab is loading | number | `5` -skeletonProps | Props of skeleton | SkeletonProps | `{}` showClear | Clear button display status | boolean | `true` -title | header for message Tab | string | - +showViewMore | View more button display status | boolean | `false` +title | header for message Tab, the actual text is `locale[title] || title` | string | - ### Tab data diff --git a/src/components/NoticeIcon/index.js b/src/components/NoticeIcon/index.js index 133819bb1e580f88020b5609c6d4afd3aae35883..5ba4a70e1e9a4c684dab3a70ba55fe94da6d38c6 100644 --- a/src/components/NoticeIcon/index.js +++ b/src/components/NoticeIcon/index.js @@ -16,13 +16,13 @@ export default class NoticeIcon extends PureComponent { onPopupVisibleChange: () => {}, onTabChange: () => {}, onClear: () => {}, + onViewMore: () => {}, loading: false, clearClose: false, locale: { emptyText: 'No notifications', clear: 'Clear', - loadedAll: 'Loaded', - loadMore: 'Loading more', + viewMore: 'More', }, emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg', }; @@ -53,53 +53,35 @@ export default class NoticeIcon extends PureComponent { onTabChange(tabType); }; - onLoadMore = (tabProps, event) => { - const { onLoadMore } = this.props; - onLoadMore(tabProps, event); + onViewMore = (tabProps, event) => { + const { onViewMore } = this.props; + onViewMore(tabProps, event); }; getNotificationBox() { - const { visible } = this.state; const { children, loading, locale } = this.props; if (!children) { return null; } const panes = React.Children.map(children, child => { - const { - list, - title, - name, - count, - emptyText, - emptyImage, - showClear, - loadedAll, - scrollToLoad, - skeletonCount, - skeletonProps, - loading: tabLoading, - } = child.props; + const { list, title, count, emptyText, emptyImage, showClear, showViewMore } = child.props; const len = list && list.length ? list.length : 0; const msgCount = count || count === 0 ? count : len; - const tabTitle = msgCount > 0 ? `${title} (${msgCount})` : title; + const localeTitle = locale[title] || title; + const tabTitle = msgCount > 0 ? `${localeTitle} (${msgCount})` : localeTitle; return ( - + this.onClear(name)} + onClear={() => this.onClear(title)} onClick={item => this.onItemClick(item, child.props)} - onLoadMore={event => this.onLoadMore(child.props, event)} - scrollToLoad={scrollToLoad} + onViewMore={event => this.onViewMore(child.props, event)} showClear={showClear} - skeletonCount={skeletonCount} - skeletonProps={skeletonProps} + showViewMore={showViewMore} title={title} - visible={visible} /> ); diff --git a/src/components/NoticeIcon/index.zh-CN.md b/src/components/NoticeIcon/index.zh-CN.md index 23dab2203ed8c6fb3db427359c0ad3b15533a089..fe722de7bc89ca6bd2568213d79ac06a75c9f545 100644 --- a/src/components/NoticeIcon/index.zh-CN.md +++ b/src/components/NoticeIcon/index.zh-CN.md @@ -16,11 +16,11 @@ bell | translate this please -> Change the bell Icon | ReactNode | ` { + getNavMenuItems = menusData => { if (!menusData) { return []; } return menusData .filter(item => item.name && !item.hideInMenu) - .map(item => this.getSubMenuOrItem(item, parent)) + .map(item => this.getSubMenuOrItem(item)) .filter(item => item); }; diff --git a/src/layouts/Header.js b/src/layouts/Header.js index 0059ee7ea951319140e6589da1134e5fbe3b12c2..9d4f7c54abe75f2599d6bd8f5acf668b46fbe849 100644 --- a/src/layouts/Header.js +++ b/src/layouts/Header.js @@ -155,7 +155,6 @@ export default connect(({ user, global, setting, loading }) => ({ collapsed: global.collapsed, fetchingMoreNotices: loading.effects['global/fetchMoreNotices'], fetchingNotices: loading.effects['global/fetchNotices'], - loadedAllNotices: global.loadedAllNotices, notices: global.notices, setting, }))(HeaderView); diff --git a/src/locales/en-US/globalHeader.js b/src/locales/en-US/globalHeader.js index 29f21d7d264c280642637ee533d762dc92e64423..60b6d4ec2d4608a8daf42407b3b5e8afd414b205 100644 --- a/src/locales/en-US/globalHeader.js +++ b/src/locales/en-US/globalHeader.js @@ -13,6 +13,5 @@ export default { 'component.noticeIcon.clear': 'Clear', 'component.noticeIcon.cleared': 'Cleared', 'component.noticeIcon.empty': 'No notifications', - 'component.noticeIcon.loaded': 'Loaded', - 'component.noticeIcon.loading-more': 'Loading more', + 'component.noticeIcon.view-more': 'View more', }; diff --git a/src/locales/pt-BR/globalHeader.js b/src/locales/pt-BR/globalHeader.js index eac034d50bd65844b3d5246011344f7c3fdab008..c92739919227815c35d19e1ccf39949fdb8ba255 100644 --- a/src/locales/pt-BR/globalHeader.js +++ b/src/locales/pt-BR/globalHeader.js @@ -14,5 +14,5 @@ export default { 'component.noticeIcon.cleared': 'Limpo', 'component.noticeIcon.empty': 'Sem notificações', 'component.noticeIcon.loaded': 'Carregado', - 'component.noticeIcon.loading-more': 'Carregar mais', + 'component.noticeIcon.view-more': 'Veja mais', }; diff --git a/src/locales/zh-CN/globalHeader.js b/src/locales/zh-CN/globalHeader.js index 204538294cedfe4d37dfa7436dadf9dc8f6b73ef..9fd66a5875f088d1071b48e87b1102c128663be8 100644 --- a/src/locales/zh-CN/globalHeader.js +++ b/src/locales/zh-CN/globalHeader.js @@ -13,6 +13,5 @@ export default { 'component.noticeIcon.clear': '清空', 'component.noticeIcon.cleared': '清空了', 'component.noticeIcon.empty': '暂无数据', - 'component.noticeIcon.loaded': '加载完毕', - 'component.noticeIcon.loading-more': '加载更多', + 'component.noticeIcon.view-more': '查看更多', }; diff --git a/src/locales/zh-TW/globalHeader.js b/src/locales/zh-TW/globalHeader.js index c7b4e6f6cdc0a42569640f04bfb1a1636ff88159..ed5845185c9e040b43d7d79e914d5358175a7adb 100644 --- a/src/locales/zh-TW/globalHeader.js +++ b/src/locales/zh-TW/globalHeader.js @@ -13,6 +13,5 @@ export default { 'component.noticeIcon.clear': '清空', 'component.noticeIcon.cleared': '清空了', 'component.noticeIcon.empty': '暫無資料', - 'component.noticeIcon.loaded': '加載完畢', - 'component.noticeIcon.loading-more': '加載更多', + 'component.noticeIcon.view-more': '查看更多', }; diff --git a/src/models/global.js b/src/models/global.js index 42895b5929507c5c31609bc8ef226f25095d648a..34cff599b1072d2df8615f09e634a5e2548de0bf 100644 --- a/src/models/global.js +++ b/src/models/global.js @@ -6,42 +6,14 @@ export default { state: { collapsed: false, notices: [], - loadedAllNotices: false, }, effects: { *fetchNotices(_, { call, put, select }) { const data = yield call(queryNotices); - const loadedAllNotices = data && data.length && data[data.length - 1] === null; - yield put({ - type: 'setLoadedStatus', - payload: loadedAllNotices, - }); yield put({ type: 'saveNotices', - payload: data.filter(item => item), - }); - const unreadCount = yield select( - state => state.global.notices.filter(item => !item.read).length - ); - yield put({ - type: 'user/changeNotifyCount', - payload: { - totalCount: data.length, - unreadCount, - }, - }); - }, - *fetchMoreNotices({ payload }, { call, put, select }) { - const data = yield call(queryNotices, payload); - const loadedAllNotices = data && data.length && data[data.length - 1] === null; - yield put({ - type: 'setLoadedStatus', - payload: loadedAllNotices, - }); - yield put({ - type: 'pushNotices', - payload: data.filter(item => item), + payload: data, }); const unreadCount = yield select( state => state.global.notices.filter(item => !item.read).length @@ -114,18 +86,6 @@ export default { notices: state.notices.filter(item => item.type !== payload), }; }, - pushNotices(state, { payload }) { - return { - ...state, - notices: [...state.notices, ...payload], - }; - }, - setLoadedStatus(state, { payload }) { - return { - ...state, - loadedAllNotices: payload, - }; - }, }, subscriptions: { diff --git a/src/pages/Authorized.js b/src/pages/Authorized.js index 875e1239d7c3a912073d6803dcbbc369cc25a60e..960f2c6b68e4d489968801317c3ba0d9a898b645 100644 --- a/src/pages/Authorized.js +++ b/src/pages/Authorized.js @@ -6,28 +6,20 @@ import Authorized from '@/utils/Authorized'; function AuthComponent({ children, location, routerData, status }) { const isLogin = status === 'ok'; + const getRouteAuthority = (path, routeData) => { + let authorities; + routeData.forEach(route => { + // match prefix + if (pathToRegexp(`${route.path}(.*)`).test(path)) { + authorities = route.authority || authorities; - const getRouteAuthority = (pathname, routeData) => { - const routes = routeData.slice(); // clone - - const getAuthority = (routeDatas, path) => { - let authorities; - routeDatas.forEach(route => { - // check partial route - if (pathToRegexp(`${route.path}(.*)`).test(path)) { - if (route.authority) { - authorities = route.authority; - } - // is exact route? - if (!pathToRegexp(route.path).test(path) && route.routes) { - authorities = getAuthority(route.routes, path); - } + // get children authority recursively + if (route.routes) { + authorities = getRouteAuthority(path, route.routes) || authorities; } - }); - return authorities; - }; - - return getAuthority(routes, pathname); + } + }); + return authorities; }; return ( {