import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { Dropdown, DropdownToggle, DropdownItem } from 'reactstrap'; import moment from 'moment'; import { seafileAPI } from '../../utils/seafile-api'; import { gettext } from '../../utils/constants'; import toaster from '../../components/toast'; import EmptyTip from '../../components/empty-tip'; import ConfirmUnlinkDeviceDialog from '../../components/dialog/confirm-unlink-device'; import { Utils } from '../../utils/utils'; class Content extends Component { render() { const { loading, errorMsg, items } = this.props.data; if (loading) { return ; } else if (errorMsg) { return

{errorMsg}

; } else { const emptyTip = ( ); const desktopThead = ( {gettext('Platform')} {gettext('Device Name')} {gettext('IP')} {gettext('Last Access')} ); const mobileThead = ( ); const isDesktop = Utils.isDesktop(); return items.length ? ( {isDesktop ? desktopThead : mobileThead} {items.map((item, index) => { return ; })}
) : emptyTip; } } } Content.propTypes = { data: PropTypes.object.isRequired, }; class Item extends Component { constructor(props) { super(props); this.state = { isOpMenuOpen: false, // for mobile isOpIconShown: false, unlinked: false, isConfirmUnlinkDialogOpen: false }; } toggleOpMenu = () => { this.setState({ isOpMenuOpen: !this.state.isOpMenuOpen }); }; handleMouseOver = () => { this.setState({ isOpIconShown: true }); }; handleMouseOut = () => { this.setState({ isOpIconShown: false }); }; toggleDialog = () => { this.setState({ isConfirmUnlinkDialogOpen: !this.state.isConfirmUnlinkDialogOpen }); }; handleClick = (e) => { e.preventDefault(); const data = this.props.data; if (data.is_desktop_client) { this.toggleDialog(); } else { const wipeDevice = true; this.unlinkDevice(wipeDevice); } }; unlinkDevice = (wipeDevice) => { const data = this.props.data; seafileAPI.unlinkDevice(data.platform, data.device_id, wipeDevice).then((res) => { this.setState({ unlinked: true }); let msg = gettext('Successfully unlinked %(name)s.'); msg = msg.replace('%(name)s', data.device_name); toaster.success(msg); }).catch((error) => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); }; renderDesktopItem = () => { const data = this.props.data; let opClasses = 'sf3-font-delete1 sf3-font unlink-device action-icon'; opClasses += this.state.isOpIconShown ? '' : ' invisible'; return ( {data.platform} {data.device_name} {data.last_login_ip} {moment(data.last_accessed).fromNow()} ); }; renderMobileItem = () => { const data = this.props.data; return ( {data.device_name}
{data.last_login_ip} {moment(data.last_accessed).fromNow()} {data.platform}
{gettext('Unlink')}
); }; render() { if (this.state.unlinked) { return null; } return ( {this.props.isDesktop ? this.renderDesktopItem() : this.renderMobileItem()} {this.state.isConfirmUnlinkDialogOpen && } ); } } Item.propTypes = { isDesktop: PropTypes.bool.isRequired, data: PropTypes.object.isRequired, }; class LinkedDevices extends Component { constructor(props) { super(props); this.state = { loading: true, errorMsg: '', items: [] }; } componentDidMount() { seafileAPI.listLinkedDevices().then((res) => { this.setState({ loading: false, items: res.data }); }).catch((error) => { this.setState({ loading: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } render() { return (

{gettext('Linked Devices')}

); } } export default LinkedDevices;