index.js 3.94 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
  static defaultProps = {
    onItemClick: () => {},
    onPopupVisibleChange: () => {},
    onTabChange: () => {},
    onClear: () => {},
19
    onViewMore: () => {},
20
    loading: false,
wingsico's avatar
wingsico committed
21
    clearClose: false,
22
    locale: {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
23 24
      emptyText: 'No notifications',
      clear: 'Clear',
25
      viewMore: '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

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

61
  getNotificationBox() {
wingsico's avatar
wingsico committed
62
    const { children, loading, locale } = this.props;
63 64 65
    if (!children) {
      return null;
    }
jim's avatar
jim committed
66
    const panes = React.Children.map(children, child => {
67
      const { list, title, count, emptyText, emptyImage, showClear, showViewMore } = child.props;
68 69
      const len = list && list.length ? list.length : 0;
      const msgCount = count || count === 0 ? count : len;
70 71
      const localeTitle = locale[title] || title;
      const tabTitle = msgCount > 0 ? `${localeTitle} (${msgCount})` : localeTitle;
72
      return (
73
        <TabPane tab={tabTitle} key={title}>
74
          <List
75
            data={list}
何乐's avatar
何乐 committed
76 77 78
            emptyImage={emptyImage}
            emptyText={emptyText}
            locale={locale}
79
            onClear={() => this.onClear(title)}
何乐's avatar
何乐 committed
80
            onClick={item => this.onItemClick(item, child.props)}
81
            onViewMore={event => this.onViewMore(child.props, event)}
何乐's avatar
何乐 committed
82
            showClear={showClear}
83
            showViewMore={showViewMore}
84
            title={title}
85 86 87 88 89
          />
        </TabPane>
      );
    });
    return (
90 91 92 93 94 95 96
      <Fragment>
        <Spin spinning={loading} delay={0}>
          <Tabs className={styles.tabs} onChange={this.onTabChange}>
            {panes}
          </Tabs>
        </Spin>
      </Fragment>
97 98
    );
  }
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
99

100 101 102 103 104 105
  handleVisibleChange = visible => {
    const { onPopupVisibleChange } = this.props;
    this.setState({ visible });
    onPopupVisibleChange(visible);
  };

106
  render() {
107 108
    const { className, count, popupVisible, bell } = this.props;
    const { visible } = this.state;
109 110
    const noticeButtonClass = classNames(className, styles.noticeButton);
    const notificationBox = this.getNotificationBox();
111
    const NoticeBellIcon = bell || <Icon type="bell" className={styles.icon} />;
112
    const trigger = (
113
      <span className={classNames(noticeButtonClass, { opened: visible })}>
jim's avatar
jim committed
114
        <Badge count={count} style={{ boxShadow: 'none' }} className={styles.badge}>
115
          {NoticeBellIcon}
116 117 118 119 120 121
        </Badge>
      </span>
    );
    if (!notificationBox) {
      return trigger;
    }
afc163's avatar
afc163 committed
122 123
    const popoverProps = {};
    if ('popupVisible' in this.props) {
ι™ˆεΈ…'s avatar
ι™ˆεΈ… committed
124
      popoverProps.visible = popupVisible;
afc163's avatar
afc163 committed
125
    }
126
    return (
127
      <HeaderDropdown
128
        placement="bottomRight"
129 130 131 132 133
        overlay={notificationBox}
        overlayClassName={styles.popover}
        trigger={['click']}
        visible={visible}
        onVisibleChange={this.handleVisibleChange}
afc163's avatar
afc163 committed
134
        {...popoverProps}
135
        ref={node => (this.popover = ReactDOM.findDOMNode(node))} // eslint-disable-line
136 137
      >
        {trigger}
138
      </HeaderDropdown>
139 140 141
    );
  }
}