🎉 1.0.0-RC2
This commit is contained in:
parent
53f8528b9e
commit
96c65c8b94
|
|
@ -17,15 +17,11 @@ class TimelineChart extends React.Component {
|
||||||
y2: 'y2',
|
y2: 'y2',
|
||||||
},
|
},
|
||||||
borderWidth = 2,
|
borderWidth = 2,
|
||||||
data = [
|
data: sourceData,
|
||||||
{
|
|
||||||
x: 0,
|
|
||||||
y1: 0,
|
|
||||||
y2: 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
const data = Array.isArray(sourceData) ? sourceData : [{ x: 0, y1: 0, y2: 0 }];
|
||||||
|
|
||||||
data.sort((a, b) => a.x - b.x);
|
data.sort((a, b) => a.x - b.x);
|
||||||
|
|
||||||
let max;
|
let max;
|
||||||
|
|
|
||||||
2
src/components/Ellipsis/index.d.ts
vendored
2
src/components/Ellipsis/index.d.ts
vendored
|
|
@ -16,6 +16,6 @@ export interface IEllipsisProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getStrFullLength(str: string): number;
|
export function getStrFullLength(str: string): number;
|
||||||
export function cutStrByFullLength(str: string, maxLength: number): number;
|
export function cutStrByFullLength(str: string, maxLength: number): string;
|
||||||
|
|
||||||
export default class Ellipsis extends React.Component<IEllipsisProps, any> {}
|
export default class Ellipsis extends React.Component<IEllipsisProps, any> {}
|
||||||
|
|
|
||||||
|
|
@ -63,13 +63,30 @@ 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() {
|
render() {
|
||||||
const {
|
const {
|
||||||
currentUser,
|
currentUser,
|
||||||
|
fetchingMoreNotices,
|
||||||
fetchingNotices,
|
fetchingNotices,
|
||||||
|
loadedAllNotices,
|
||||||
onNoticeVisibleChange,
|
onNoticeVisibleChange,
|
||||||
onMenuClick,
|
onMenuClick,
|
||||||
onNoticeClear,
|
onNoticeClear,
|
||||||
|
skeletonCount,
|
||||||
theme,
|
theme,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const menu = (
|
const menu = (
|
||||||
|
|
@ -94,6 +111,11 @@ export default class GlobalHeaderRight extends PureComponent {
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
|
const loadMoreProps = {
|
||||||
|
skeletonCount,
|
||||||
|
loadedAll: loadedAllNotices,
|
||||||
|
loading: fetchingMoreNotices,
|
||||||
|
};
|
||||||
const noticeData = this.getNoticeData();
|
const noticeData = this.getNoticeData();
|
||||||
const unreadMsg = this.getUnreadData(noticeData);
|
const unreadMsg = this.getUnreadData(noticeData);
|
||||||
let className = styles.right;
|
let className = styles.right;
|
||||||
|
|
@ -137,8 +159,11 @@ export default class GlobalHeaderRight extends PureComponent {
|
||||||
locale={{
|
locale={{
|
||||||
emptyText: formatMessage({ id: 'component.noticeIcon.empty' }),
|
emptyText: formatMessage({ id: 'component.noticeIcon.empty' }),
|
||||||
clear: formatMessage({ id: 'component.noticeIcon.clear' }),
|
clear: formatMessage({ id: 'component.noticeIcon.clear' }),
|
||||||
|
loadedAll: formatMessage({ id: 'component.noticeIcon.loaded' }),
|
||||||
|
loadMore: formatMessage({ id: 'component.noticeIcon.loading-more' }),
|
||||||
}}
|
}}
|
||||||
onClear={onNoticeClear}
|
onClear={onNoticeClear}
|
||||||
|
onLoadMore={this.fetchMoreNotices}
|
||||||
onPopupVisibleChange={onNoticeVisibleChange}
|
onPopupVisibleChange={onNoticeVisibleChange}
|
||||||
loading={fetchingNotices}
|
loading={fetchingNotices}
|
||||||
clearClose
|
clearClose
|
||||||
|
|
@ -150,6 +175,7 @@ export default class GlobalHeaderRight extends PureComponent {
|
||||||
name="notification"
|
name="notification"
|
||||||
emptyText={formatMessage({ id: 'component.globalHeader.notification.empty' })}
|
emptyText={formatMessage({ id: 'component.globalHeader.notification.empty' })}
|
||||||
emptyImage="https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg"
|
emptyImage="https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg"
|
||||||
|
{...loadMoreProps}
|
||||||
/>
|
/>
|
||||||
<NoticeIcon.Tab
|
<NoticeIcon.Tab
|
||||||
count={unreadMsg.message}
|
count={unreadMsg.message}
|
||||||
|
|
@ -158,6 +184,7 @@ export default class GlobalHeaderRight extends PureComponent {
|
||||||
name="message"
|
name="message"
|
||||||
emptyText={formatMessage({ id: 'component.globalHeader.message.empty' })}
|
emptyText={formatMessage({ id: 'component.globalHeader.message.empty' })}
|
||||||
emptyImage="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg"
|
emptyImage="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg"
|
||||||
|
{...loadMoreProps}
|
||||||
/>
|
/>
|
||||||
<NoticeIcon.Tab
|
<NoticeIcon.Tab
|
||||||
count={unreadMsg.event}
|
count={unreadMsg.event}
|
||||||
|
|
@ -166,6 +193,7 @@ export default class GlobalHeaderRight extends PureComponent {
|
||||||
name="event"
|
name="event"
|
||||||
emptyText={formatMessage({ id: 'component.globalHeader.event.empty' })}
|
emptyText={formatMessage({ id: 'component.globalHeader.event.empty' })}
|
||||||
emptyImage="https://gw.alipayobjects.com/zos/rmsportal/HsIsxMZiWKrNUavQUXqx.svg"
|
emptyImage="https://gw.alipayobjects.com/zos/rmsportal/HsIsxMZiWKrNUavQUXqx.svg"
|
||||||
|
{...loadMoreProps}
|
||||||
/>
|
/>
|
||||||
</NoticeIcon>
|
</NoticeIcon>
|
||||||
{currentUser.name ? (
|
{currentUser.name ? (
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ export default class HeaderSearch extends PureComponent {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
onSearch: PropTypes.func,
|
onSearch: PropTypes.func,
|
||||||
|
onChange: PropTypes.func,
|
||||||
onPressEnter: PropTypes.func,
|
onPressEnter: PropTypes.func,
|
||||||
defaultActiveFirstOption: PropTypes.bool,
|
defaultActiveFirstOption: PropTypes.bool,
|
||||||
dataSource: PropTypes.array,
|
dataSource: PropTypes.array,
|
||||||
|
|
@ -22,6 +23,7 @@ export default class HeaderSearch extends PureComponent {
|
||||||
defaultActiveFirstOption: false,
|
defaultActiveFirstOption: false,
|
||||||
onPressEnter: () => {},
|
onPressEnter: () => {},
|
||||||
onSearch: () => {},
|
onSearch: () => {},
|
||||||
|
onChange: () => {},
|
||||||
className: '',
|
className: '',
|
||||||
placeholder: '',
|
placeholder: '',
|
||||||
dataSource: [],
|
dataSource: [],
|
||||||
|
|
@ -61,8 +63,11 @@ export default class HeaderSearch extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
onChange = value => {
|
onChange = value => {
|
||||||
const { onChange } = this.props;
|
const { onSearch, onChange } = this.props;
|
||||||
this.setState({ value });
|
this.setState({ value });
|
||||||
|
if (onSearch) {
|
||||||
|
onSearch(value);
|
||||||
|
}
|
||||||
if (onChange) {
|
if (onChange) {
|
||||||
onChange(value);
|
onChange(value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
src/components/NoticeIcon/NoticeIconTab.d.ts
vendored
14
src/components/NoticeIcon/NoticeIconTab.d.ts
vendored
|
|
@ -1,4 +1,6 @@
|
||||||
|
import { SkeletonProps } from 'antd/lib/skeleton';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
export interface INoticeIconData {
|
export interface INoticeIconData {
|
||||||
avatar?: string | React.ReactNode;
|
avatar?: string | React.ReactNode;
|
||||||
title?: React.ReactNode;
|
title?: React.ReactNode;
|
||||||
|
|
@ -9,14 +11,18 @@ export interface INoticeIconData {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface INoticeIconTabProps {
|
export interface INoticeIconTabProps {
|
||||||
list?: INoticeIconData[];
|
|
||||||
count?: number;
|
count?: number;
|
||||||
title?: string;
|
|
||||||
name?: string;
|
|
||||||
emptyText?: React.ReactNode;
|
emptyText?: React.ReactNode;
|
||||||
emptyImage?: string;
|
emptyImage?: string;
|
||||||
style?: React.CSSProperties;
|
list?: INoticeIconData[];
|
||||||
|
loadedAll?: boolean;
|
||||||
|
loading?: boolean;
|
||||||
|
name?: string;
|
||||||
showClear?: boolean;
|
showClear?: boolean;
|
||||||
|
skeletonCount?: number;
|
||||||
|
skeletonProps?: SkeletonProps;
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class NoticeIconTab extends React.Component<INoticeIconTabProps, any> {}
|
export default class NoticeIconTab extends React.Component<INoticeIconTabProps, any> {}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Avatar, List } from 'antd';
|
import { Avatar, List, Skeleton } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import styles from './NoticeList.less';
|
import styles from './NoticeList.less';
|
||||||
|
|
||||||
|
let ListElement = null;
|
||||||
|
|
||||||
export default function NoticeList({
|
export default function NoticeList({
|
||||||
data = [],
|
data = [],
|
||||||
onClick,
|
onClick,
|
||||||
|
|
@ -11,7 +13,14 @@ export default function NoticeList({
|
||||||
locale,
|
locale,
|
||||||
emptyText,
|
emptyText,
|
||||||
emptyImage,
|
emptyImage,
|
||||||
|
loading,
|
||||||
|
onLoadMore,
|
||||||
|
visible,
|
||||||
|
loadedAll = true,
|
||||||
|
scrollToLoad = true,
|
||||||
showClear = true,
|
showClear = true,
|
||||||
|
skeletonCount = 5,
|
||||||
|
skeletonProps = {},
|
||||||
}) {
|
}) {
|
||||||
if (data.length === 0) {
|
if (data.length === 0) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -21,10 +30,36 @@ export default function NoticeList({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const loadingList = Array.from({ length: loading ? skeletonCount : 0 }).map(() => ({ loading }));
|
||||||
|
const LoadMore = loadedAll ? (
|
||||||
|
<div className={classNames(styles.loadMore, styles.loadedAll)}>
|
||||||
|
<span>{locale.loadedAll}</span>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className={styles.loadMore} onClick={onLoadMore}>
|
||||||
|
<span>{locale.loadMore}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<List className={styles.list}>
|
<List className={styles.list} loadMore={LoadMore} onScroll={onScroll}>
|
||||||
{data.map((item, i) => {
|
{[...data, ...loadingList].map((item, i) => {
|
||||||
const itemCls = classNames(styles.item, {
|
const itemCls = classNames(styles.item, {
|
||||||
[styles.read]: item.read,
|
[styles.read]: item.read,
|
||||||
});
|
});
|
||||||
|
|
@ -33,30 +68,32 @@ export default function NoticeList({
|
||||||
typeof item.avatar === 'string' ? (
|
typeof item.avatar === 'string' ? (
|
||||||
<Avatar className={styles.avatar} src={item.avatar} />
|
<Avatar className={styles.avatar} src={item.avatar} />
|
||||||
) : (
|
) : (
|
||||||
item.avatar
|
<span className={styles.iconElement}>{item.avatar}</span>
|
||||||
)
|
)
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<List.Item className={itemCls} key={item.key || i} onClick={() => onClick(item)}>
|
<List.Item className={itemCls} key={item.key || i} onClick={() => onClick(item)}>
|
||||||
<List.Item.Meta
|
<Skeleton avatar title={false} active {...skeletonProps} loading={item.loading}>
|
||||||
className={styles.meta}
|
<List.Item.Meta
|
||||||
avatar={<span className={styles.iconElement}>{leftIcon}</span>}
|
className={styles.meta}
|
||||||
title={
|
avatar={leftIcon}
|
||||||
<div className={styles.title}>
|
title={
|
||||||
{item.title}
|
<div className={styles.title}>
|
||||||
<div className={styles.extra}>{item.extra}</div>
|
{item.title}
|
||||||
</div>
|
<div className={styles.extra}>{item.extra}</div>
|
||||||
}
|
|
||||||
description={
|
|
||||||
<div>
|
|
||||||
<div className={styles.description} title={item.description}>
|
|
||||||
{item.description}
|
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.datetime}>{item.datetime}</div>
|
}
|
||||||
</div>
|
description={
|
||||||
}
|
<div>
|
||||||
/>
|
<div className={styles.description} title={item.description}>
|
||||||
|
{item.description}
|
||||||
|
</div>
|
||||||
|
<div className={styles.datetime}>{item.datetime}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Skeleton>
|
||||||
</List.Item>
|
</List.Item>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@
|
||||||
.list {
|
.list {
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
.item {
|
.item {
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
@ -52,6 +55,16 @@
|
||||||
margin-top: -1.5px;
|
margin-top: -1.5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.loadMore {
|
||||||
|
padding: 8px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
color: @primary-6;
|
||||||
|
text-align: center;
|
||||||
|
&.loadedAll {
|
||||||
|
cursor: unset;
|
||||||
|
color: rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.notFound {
|
.notFound {
|
||||||
|
|
|
||||||
8
src/components/NoticeIcon/index.d.ts
vendored
8
src/components/NoticeIcon/index.d.ts
vendored
|
|
@ -8,11 +8,17 @@ export interface INoticeIconProps {
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
onClear?: (tabName: string) => void;
|
onClear?: (tabName: string) => void;
|
||||||
onItemClick?: (item: INoticeIconData, tabProps: INoticeIconProps) => void;
|
onItemClick?: (item: INoticeIconData, tabProps: INoticeIconProps) => void;
|
||||||
|
onLoadMore?: (tabProps: INoticeIconProps) => void;
|
||||||
onTabChange?: (tabTile: string) => void;
|
onTabChange?: (tabTile: string) => void;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
onPopupVisibleChange?: (visible: boolean) => void;
|
onPopupVisibleChange?: (visible: boolean) => void;
|
||||||
popupVisible?: boolean;
|
popupVisible?: boolean;
|
||||||
locale?: { emptyText: string; clear: string };
|
locale?: {
|
||||||
|
emptyText: string;
|
||||||
|
clear: string;
|
||||||
|
loadedAll: string;
|
||||||
|
loadMore: string;
|
||||||
|
};
|
||||||
clearClose?: boolean;
|
clearClose?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,32 +13,40 @@ Property | Description | Type | Default
|
||||||
----|------|-----|------
|
----|------|-----|------
|
||||||
count | Total number of messages | number | -
|
count | Total number of messages | number | -
|
||||||
bell | Change the bell Icon | ReactNode | `<Icon type='bell' />`
|
bell | Change the bell Icon | ReactNode | `<Icon type='bell' />`
|
||||||
loading | Popup card loading status | boolean | false
|
loading | Popup card loading status | boolean | `false`
|
||||||
onClear | Click to clear button the callback | function(tabName) | -
|
onClear | Click to clear button the callback | function(tabName) | -
|
||||||
onItemClick | Click on the list item's callback | function(item, tabProps) | -
|
onItemClick | Click on the list item's callback | function(item, tabProps) | -
|
||||||
onTabChange | Switching callbacks for tabs | function(tabTitle) | -
|
onLoadMore | Callback of click for loading more | function(tabProps, event) | -
|
||||||
onPopupVisibleChange | Popup Card Showing or Hiding Callbacks | function(visible) | -
|
onPopupVisibleChange | Popup Card Showing or Hiding Callbacks | function(visible) | -
|
||||||
|
onTabChange | Switching callbacks for tabs | function(tabTitle) | -
|
||||||
popupVisible | Popup card display state | boolean | -
|
popupVisible | Popup card display state | boolean | -
|
||||||
locale | Default message text | Object | `{ emptyText: '暂无数据', clear: '清空' }`
|
locale | Default message text | Object | `{ emptyText: 'No notifications', clear: 'Clear', loadedAll: 'Loaded', loadMore: 'Loading more' }`
|
||||||
|
clearClose | Close menu after clear | boolean | `false`
|
||||||
|
|
||||||
### NoticeIcon.Tab
|
### NoticeIcon.Tab
|
||||||
|
|
||||||
Property | Description | Type | Default
|
Property | Description | Type | Default
|
||||||
----|------|-----|------
|
----|------|-----|------
|
||||||
title | header for message Tab | string | -
|
count | Unread messages count of this tab | number | list.length
|
||||||
name | identifier for message Tab | string | -
|
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 | `[]`
|
list | List data, format refer to the following table | Array | `[]`
|
||||||
showClear | Clear button display status | boolean | true
|
loadedAll | All messages have been loaded | boolean | `true`
|
||||||
emptyText | message text when list is empty | ReactNode | -
|
loading | Loading status of this tab | boolean | `false`
|
||||||
emptyImage | image when list is empty | string | -
|
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 | -
|
||||||
|
|
||||||
### Tab data
|
### Tab data
|
||||||
|
|
||||||
Property | Description | Type | Default
|
Property | Description | Type | Default
|
||||||
----|------|-----|------
|
----|------|-----|------
|
||||||
avatar | avatar img url | string \| ReactNode | -
|
avatar | avatar img url | string \| ReactNode | -
|
||||||
title | title | ReactNode | -
|
title | title | ReactNode | -
|
||||||
description | description info | ReactNode | -
|
description | description info | ReactNode | -
|
||||||
datetime | Timestamps | ReactNode | -
|
datetime | Timestamps | ReactNode | -
|
||||||
extra |Additional information in the upper right corner of the list item | ReactNode | -
|
extra | Additional information in the upper right corner of the list item | ReactNode | -
|
||||||
|
clickClose | Close menu after clicking list item | boolean | `false`
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ export default class NoticeIcon extends PureComponent {
|
||||||
locale: {
|
locale: {
|
||||||
emptyText: 'No notifications',
|
emptyText: 'No notifications',
|
||||||
clear: 'Clear',
|
clear: 'Clear',
|
||||||
|
loadedAll: 'Loaded',
|
||||||
|
loadMore: 'Loading more',
|
||||||
},
|
},
|
||||||
emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
|
emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
|
||||||
};
|
};
|
||||||
|
|
@ -51,25 +53,53 @@ export default class NoticeIcon extends PureComponent {
|
||||||
onTabChange(tabType);
|
onTabChange(tabType);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onLoadMore = (tabProps, event) => {
|
||||||
|
const { onLoadMore } = this.props;
|
||||||
|
onLoadMore(tabProps, event);
|
||||||
|
};
|
||||||
|
|
||||||
getNotificationBox() {
|
getNotificationBox() {
|
||||||
|
const { visible } = this.state;
|
||||||
const { children, loading, locale } = this.props;
|
const { children, loading, locale } = this.props;
|
||||||
if (!children) {
|
if (!children) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const panes = React.Children.map(children, child => {
|
const panes = React.Children.map(children, child => {
|
||||||
const { list, title, name, count } = child.props;
|
const {
|
||||||
|
list,
|
||||||
|
title,
|
||||||
|
name,
|
||||||
|
count,
|
||||||
|
emptyText,
|
||||||
|
emptyImage,
|
||||||
|
showClear,
|
||||||
|
loadedAll,
|
||||||
|
scrollToLoad,
|
||||||
|
skeletonCount,
|
||||||
|
skeletonProps,
|
||||||
|
loading: tabLoading,
|
||||||
|
} = child.props;
|
||||||
const len = list && list.length ? list.length : 0;
|
const len = list && list.length ? list.length : 0;
|
||||||
const msgCount = count || count === 0 ? count : len;
|
const msgCount = count || count === 0 ? count : len;
|
||||||
const tabTitle = msgCount > 0 ? `${title} (${msgCount})` : title;
|
const tabTitle = msgCount > 0 ? `${title} (${msgCount})` : title;
|
||||||
return (
|
return (
|
||||||
<TabPane tab={tabTitle} key={name}>
|
<TabPane tab={tabTitle} key={name}>
|
||||||
<List
|
<List
|
||||||
{...child.props}
|
|
||||||
data={list}
|
data={list}
|
||||||
onClick={item => this.onItemClick(item, child.props)}
|
emptyImage={emptyImage}
|
||||||
onClear={() => this.onClear(name)}
|
emptyText={emptyText}
|
||||||
title={title}
|
loadedAll={loadedAll}
|
||||||
|
loading={tabLoading}
|
||||||
locale={locale}
|
locale={locale}
|
||||||
|
onClear={() => this.onClear(name)}
|
||||||
|
onClick={item => this.onItemClick(item, child.props)}
|
||||||
|
onLoadMore={event => this.onLoadMore(child.props, event)}
|
||||||
|
scrollToLoad={scrollToLoad}
|
||||||
|
showClear={showClear}
|
||||||
|
skeletonCount={skeletonCount}
|
||||||
|
skeletonProps={skeletonProps}
|
||||||
|
title={title}
|
||||||
|
visible={visible}
|
||||||
/>
|
/>
|
||||||
</TabPane>
|
</TabPane>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.ant-tabs-bar {
|
.ant-tabs-bar {
|
||||||
margin-bottom: 4px;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,26 +13,32 @@ order: 9
|
||||||
----|------|-----|------
|
----|------|-----|------
|
||||||
count | 图标上的消息总数 | number | -
|
count | 图标上的消息总数 | number | -
|
||||||
bell | translate this please -> Change the bell Icon | ReactNode | `<Icon type='bell' />`
|
bell | translate this please -> Change the bell Icon | ReactNode | `<Icon type='bell' />`
|
||||||
loading | 弹出卡片加载状态 | boolean | false
|
loading | 弹出卡片加载状态 | boolean | `false`
|
||||||
onClear | 点击清空按钮的回调 | function(tabName) | -
|
onClear | 点击清空按钮的回调 | function(tabName) | -
|
||||||
onItemClick | 点击列表项的回调 | function(item, tabProps) | -
|
onItemClick | 点击列表项的回调 | function(item, tabProps) | -
|
||||||
onTabChange | 切换页签的回调 | function(tabTitle) | -
|
onLoadMore | 加载更多的回调 | function(tabProps, event) | -
|
||||||
onPopupVisibleChange | 弹出卡片显隐的回调 | function(visible) | -
|
onPopupVisibleChange | 弹出卡片显隐的回调 | function(visible) | -
|
||||||
|
onTabChange | 切换页签的回调 | function(tabTitle) | -
|
||||||
popupVisible | 控制弹层显隐 | boolean | -
|
popupVisible | 控制弹层显隐 | boolean | -
|
||||||
locale | 默认文案 | Object | `{ emptyText: '暂无数据', clear: '清空' }`
|
locale | 默认文案 | Object | `{ emptyText: 'No notifications', clear: 'Clear', loadedAll: 'Loaded', loadMore: 'Loading more' }`
|
||||||
clearClose | 点击清空按钮后关闭通知菜单 | boolean | false
|
clearClose | 点击清空按钮后关闭通知菜单 | boolean | `false`
|
||||||
|
|
||||||
### NoticeIcon.Tab
|
### NoticeIcon.Tab
|
||||||
|
|
||||||
参数 | 说明 | 类型 | 默认值
|
参数 | 说明 | 类型 | 默认值
|
||||||
----|------|-----|------
|
----|------|-----|------
|
||||||
title | 消息分类的页签标题 | string | -
|
count | 当前 Tab 未读消息数量 | number | list.length
|
||||||
name | 消息分类的标识符 | string | -
|
|
||||||
list | 列表数据,格式参照下表 | Array | `[]`
|
|
||||||
showClear | 是否显示清空按钮 | boolean | true
|
|
||||||
emptyText | 针对每个 Tab 定制空数据文案 | ReactNode | -
|
emptyText | 针对每个 Tab 定制空数据文案 | ReactNode | -
|
||||||
emptyImage | 针对每个 Tab 定制空数据图片 | string | -
|
emptyImage | 针对每个 Tab 定制空数据图片 | string | -
|
||||||
|
list | 列表数据,格式参照下表 | Array | `[]`
|
||||||
|
loadedAll | 已加载完所有消息 | boolean | `true`
|
||||||
|
loading | 当前 Tab 的加载状态 | boolean | `false`
|
||||||
|
name | 消息分类的标识符 | string | -
|
||||||
|
scrollToLoad | 允许滚动自加载 | boolean | `true`
|
||||||
|
skeletonCount | 加载时占位骨架的数量 | number | `5`
|
||||||
|
skeletonProps | 加载时占位骨架的属性 | SkeletonProps | `{}`
|
||||||
|
showClear | 是否显示清空按钮 | boolean | `true`
|
||||||
|
title | 消息分类的页签标题 | string | -
|
||||||
|
|
||||||
### Tab data
|
### Tab data
|
||||||
|
|
||||||
|
|
@ -43,4 +49,4 @@ title | 标题 | ReactNode | -
|
||||||
description | 描述信息 | ReactNode | -
|
description | 描述信息 | ReactNode | -
|
||||||
datetime | 时间戳 | ReactNode | -
|
datetime | 时间戳 | ReactNode | -
|
||||||
extra | 额外信息,在列表项右上角 | ReactNode | -
|
extra | 额外信息,在列表项右上角 | ReactNode | -
|
||||||
clickClose | 点击列表项关闭通知菜单 | boolean | false
|
clickClose | 点击列表项关闭通知菜单 | boolean | `false`
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ export default class SiderMenu extends PureComponent {
|
||||||
<div className={styles.logo} id="logo">
|
<div className={styles.logo} id="logo">
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<img src={logo} alt="logo" />
|
<img src={logo} alt="logo" />
|
||||||
<h1>Sword</h1>
|
<h1>Sword Admin</h1>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<Suspense fallback={<PageLoading />}>
|
<Suspense fallback={<PageLoading />}>
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export default class TopNavHeader extends PureComponent {
|
||||||
<div className={styles.logo} key="logo" id="logo">
|
<div className={styles.logo} key="logo" id="logo">
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<img src={logo} alt="logo" />
|
<img src={logo} alt="logo" />
|
||||||
<h1>Sword</h1>
|
<h1>Sword Admin</h1>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user