index.js 4.27 KB
Newer Older
1
import React, { PureComponent, Fragment } from 'react';
wingsico's avatar
wingsico committed
2
import ReactDOM from 'react-dom';
3
import { Icon, Tabs, Badge, Spin } from 'antd';
4
import classNames from 'classnames';
5
import HeaderDropdown from '../HeaderDropdown';
6 7 8 9 10 11
import List from './NoticeList';
import styles from './index.less';

const { TabPane } = Tabs;

export default class NoticeIcon extends PureComponent {
jim's avatar
jim committed
12 13
  static Tab = TabPane;

14 15 16 17 18 19
  static defaultProps = {
    onItemClick: () => {},
    onPopupVisibleChange: () => {},
    onTabChange: () => {},
    onClear: () => {},
    loading: false,
wingsico's avatar
wingsico committed
20
    clearClose: false,
21
    locale: {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
22 23
      emptyText: 'No notifications',
      clear: 'Clear',
何乐's avatar
何乐 committed
24 25
      loadedAll: 'Loaded',
      loadMore: 'Loading more',
26
    },
afc163's avatar
afc163 committed
27
    emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
28
  };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
29

30 31 32 33
  state = {
    visible: false,
  };

34 35
  onItemClick = (item, tabProps) => {
    const { onItemClick } = this.props;
wingsico's avatar
wingsico committed
36
    const { clickClose } = item;
37
    onItemClick(item, tabProps);
wingsico's avatar
wingsico committed
38 39 40
    if (clickClose) {
      this.popover.click();
    }
jim's avatar
jim committed
41
  };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
42

43
  onClear = name => {
wingsico's avatar
wingsico committed
44
    const { onClear, clearClose } = this.props;
45
    onClear(name);
wingsico's avatar
wingsico committed
46 47 48
    if (clearClose) {
      this.popover.click();
    }
49
  };
wingsico's avatar
wingsico committed
50

jim's avatar
jim committed
51
  onTabChange = tabType => {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
52
    const { onTabChange } = this.props;
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
53
    onTabChange(tabType);
jim's avatar
jim committed
54
  };
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
55

何乐's avatar
何乐 committed
56 57 58 59 60
  onLoadMore = (tabProps, event) => {
    const { onLoadMore } = this.props;
    onLoadMore(tabProps, event);
  };

61
  getNotificationBox() {
何乐's avatar
何乐 committed
62
    const { visible } = this.state;
wingsico's avatar
wingsico committed
63
    const { children, loading, locale } = this.props;
64 65 66
    if (!children) {
      return null;
    }
jim's avatar
jim committed
67
    const panes = React.Children.map(children, child => {
何乐's avatar
何乐 committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81
      const {
        list,
        title,
        name,
        count,
        emptyText,
        emptyImage,
        showClear,
        loadedAll,
        scrollToLoad,
        skeletonCount,
        skeletonProps,
        loading: tabLoading,
      } = child.props;
82 83 84
      const len = list && list.length ? list.length : 0;
      const msgCount = count || count === 0 ? count : len;
      const tabTitle = msgCount > 0 ? `${title} (${msgCount})` : title;
85
      return (
86
        <TabPane tab={tabTitle} key={name}>
87
          <List
88
            data={list}
何乐's avatar
何乐 committed
89 90 91 92 93
            emptyImage={emptyImage}
            emptyText={emptyText}
            loadedAll={loadedAll}
            loading={tabLoading}
            locale={locale}
94
            onClear={() => this.onClear(name)}
何乐's avatar
何乐 committed
95 96 97 98 99 100
            onClick={item => this.onItemClick(item, child.props)}
            onLoadMore={event => this.onLoadMore(child.props, event)}
            scrollToLoad={scrollToLoad}
            showClear={showClear}
            skeletonCount={skeletonCount}
            skeletonProps={skeletonProps}
101
            title={title}
何乐's avatar
何乐 committed
102
            visible={visible}
103 104 105 106 107
          />
        </TabPane>
      );
    });
    return (
108 109 110 111 112 113 114
      <Fragment>
        <Spin spinning={loading} delay={0}>
          <Tabs className={styles.tabs} onChange={this.onTabChange}>
            {panes}
          </Tabs>
        </Spin>
      </Fragment>
115 116
    );
  }
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
117

118 119 120 121 122 123
  handleVisibleChange = visible => {
    const { onPopupVisibleChange } = this.props;
    this.setState({ visible });
    onPopupVisibleChange(visible);
  };

124
  render() {
125 126
    const { className, count, popupVisible, bell } = this.props;
    const { visible } = this.state;
127 128
    const noticeButtonClass = classNames(className, styles.noticeButton);
    const notificationBox = this.getNotificationBox();
129
    const NoticeBellIcon = bell || <Icon type="bell" className={styles.icon} />;
130
    const trigger = (
131
      <span className={classNames(noticeButtonClass, { opened: visible })}>
jim's avatar
jim committed
132
        <Badge count={count} style={{ boxShadow: 'none' }} className={styles.badge}>
133
          {NoticeBellIcon}
134 135 136 137 138 139
        </Badge>
      </span>
    );
    if (!notificationBox) {
      return trigger;
    }
afc163's avatar
afc163 committed
140 141
    const popoverProps = {};
    if ('popupVisible' in this.props) {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
142
      popoverProps.visible = popupVisible;
afc163's avatar
afc163 committed
143
    }
144
    return (
145
      <HeaderDropdown
146
        placement="bottomRight"
147 148 149 150 151
        overlay={notificationBox}
        overlayClassName={styles.popover}
        trigger={['click']}
        visible={visible}
        onVisibleChange={this.handleVisibleChange}
afc163's avatar
afc163 committed
152
        {...popoverProps}
153
        ref={node => (this.popover = ReactDOM.findDOMNode(node))} // eslint-disable-line
154 155
      >
        {trigger}
156
      </HeaderDropdown>
157 158 159
    );
  }
}