import React from 'react'; import PropTypes from 'prop-types'; import classname from 'classnames'; import { Modal, ModalHeader, ModalBody, Dropdown, DropdownToggle, DropdownMenu, DropdownItem, TabPane, Nav, NavItem, NavLink, TabContent } from 'reactstrap'; import { Utils } from './utils/utils'; import { gettext } from './utils/constants'; import { seafileAPI } from './utils/seafile-api'; import Loading from './components/loading'; import NoticeItem from './components/common/notice-item'; import './css/toolbar.css'; import './css/search.css'; import './css/user-notifications.css'; const PER_PAGE = 20; class UserNotificationsDialog extends React.Component { constructor(props) { super(props); this.state = { isLoading: true, errorMsg: '', currentPage: 1, hasNextPage: false, items: [], isItemMenuShow: false, activeTab: 'general', }; } componentDidMount() { let urlParams = (new URL(window.location)).searchParams; const { currentPage } = this.state; this.setState({ currentPage: parseInt(urlParams.get('page') || currentPage) }, () => { this.getItems(this.state.currentPage); }); } getItems = (page, is_scroll = false) => { this.setState({ isLoading: true }); if (this.state.activeTab === 'general') { seafileAPI.listNotifications(page, PER_PAGE).then((res) => { if (is_scroll) { this.setState({ isLoading: false, items: [...this.state.items, ...res.data.notification_list], currentPage: page, hasNextPage: Utils.hasNextPage(page, PER_PAGE, res.data.count) }); } else { this.setState({ isLoading: false, items: [...res.data.notification_list], currentPage: page, hasNextPage: Utils.hasNextPage(page, PER_PAGE, res.data.count) }); } }).catch((error) => { this.setState({ isLoading: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } else if (this.state.activeTab === 'discussion') { seafileAPI.listSdocNotifications(page, PER_PAGE).then((res) => { if (is_scroll) { this.setState({ isLoading: false, items: [...this.state.items, ...res.data.notification_list], currentPage: page, hasNextPage: Utils.hasNextPage(page, PER_PAGE, res.data.count) }); } else { this.setState({ isLoading: false, items: [...res.data.notification_list], currentPage: page, hasNextPage: Utils.hasNextPage(page, PER_PAGE, res.data.count) }); } }).catch((error) => { this.setState({ isLoading: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } }; markAllRead = () => { if (this.state.activeTab === 'general') { seafileAPI.updateNotifications().then((res) => { this.setState({ items: this.state.items.map(item => { item.seen = true; return item; }) }); }).catch((error) => { this.setState({ isLoading: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } else if (this.state.activeTab === 'discussion') { seafileAPI.updateSdocNotifications().then((res) => { this.setState({ items: this.state.items.map(item => { item.seen = true; return item; }) }); }).catch((error) => { this.setState({ isLoading: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } }; clearAll = () => { if (this.state.activeTab === 'general') { seafileAPI.deleteNotifications().then((res) => { this.setState({ items: [] }); }).catch((error) => { this.setState({ isLoading: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } else if (this.state.activeTab === 'discussion') { seafileAPI.deleteSdocNotifications().then((res) => { this.setState({ items: [] }); }).catch((error) => { this.setState({ isLoading: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } }; toggle = () => { this.props.onNotificationDialogToggle(); }; tabItemClick = (tab) => { if (tab === this.state.activeTab) return; this.setState({ activeTab: tab, currentPage: 1 }, () => { this.getItems(this.state.currentPage); }); }; toggleDropDownMenu = () => { this.setState({ isItemMenuShow: !this.state.isItemMenuShow }); }; onHandleScroll = () => { if (!this.state.hasNextPage || this.state.isLoading || !this.tableRef) { return; } if (this.notificationTableRef.offsetHeight + this.notificationTableRef.scrollTop + 1 >= this.tableRef.offsetHeight) { this.getItems(this.state.currentPage + 1, true); } }; renderHeaderRowBtn = () => { return (
{gettext('Mark all read')} {gettext('Clear')}
); }; renderNoticeContent = (content) => { const { generalNoticeListUnseen, discussionNoticeListUnseen } = this.props; let activeTab = this.state.activeTab; return ( <>
{activeTab === 'general' &&
this.notificationTableRef = ref} onScroll={this.onHandleScroll}> {content}
} {activeTab === 'discussion' &&
this.notificationTableRef = ref} onScroll={this.onHandleScroll}> {content}
}
); }; render() { const { isLoading, errorMsg, items } = this.state; let content; if (errorMsg) { content =

{errorMsg}

; } else { const isDesktop = Utils.isDesktop(); const theadData = isDesktop ? [ { width: '2%', text: '' }, { width: '15%', text: gettext('User') }, { width: '63%', text: gettext('Message') }, { width: '20%', text: gettext('Update time') } ] : [ { width: '2%', text: '' }, { width: '13%', text: gettext('User') }, { width: '52%', text: gettext('Message') }, { width: '33%', text: gettext('Update time') } ]; content = ( this.tableRef = ref}> {theadData.map((item, index) => { return ; })} {items.map((item, index) => { return ( ); })}
{item.text}
); if (isLoading) { content = <>{content}; } } return ( {gettext('Notifications')} {this.renderNoticeContent(content)} ); } } UserNotificationsDialog.propTypes = { onNotificationDialogToggle: PropTypes.func.isRequired }; export default UserNotificationsDialog;