import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; import { Link } from '@reach/router'; import { seafileAPI } from '../../utils/seafile-api'; import { Utils } from '../../utils/utils'; import Repo from '../../models/repo'; import { gettext, siteRoot, loginUrl, isPro } from '../../utils/constants'; import Loading from '../../components/loading'; import ModalPotal from '../../components/modal-portal'; import ShareDialog from '../../components/dialog/share-dialog'; class Content extends Component { sortByName = (e) => { e.preventDefault(); const sortBy = 'name'; const sortOrder = this.props.sortOrder == 'asc' ? 'desc' : 'asc'; this.props.sortItems(sortBy, sortOrder); } sortByTime = (e) => { e.preventDefault(); const sortBy = 'time'; const sortOrder = this.props.sortOrder == 'asc' ? 'desc' : 'asc'; this.props.sortItems(sortBy, sortOrder); } render() { const { loading, errorMsg, items, sortBy, sortOrder } = this.props; const emptyTip = (

{gettext('No libraries have been shared with you')}

{gettext('No libraries have been shared directly with you. You can find more shared libraries at "Shared with groups".')}

); if (loading) { return ; } else if (errorMsg) { return

{errorMsg}

; } else { // sort const sortByName = sortBy == 'name'; const sortByTime = sortBy == 'time'; const sortIcon = sortOrder == 'asc' ? : ; const desktopThead = ( {gettext('Library Type')} {gettext('Name')} {sortByName && sortIcon} {gettext('Actions')} {gettext('Size')} {gettext('Last Update')} {sortByTime && sortIcon} {gettext('Owner')} ); const mobileThead = ( {gettext('Library Type')} {gettext('Sort:')} {gettext('name')} {sortByName && sortIcon} {gettext('last update')} {sortByTime && sortIcon} {gettext('Actions')} ); const table = ( {window.innerWidth >= 768 ? desktopThead : mobileThead}
); return items.length ? table : emptyTip; } } } Content.propTypes = { loading: PropTypes.bool.isRequired, errorMsg: PropTypes.string.isRequired, items: PropTypes.array.isRequired, sortBy: PropTypes.string.isRequired, sortOrder: PropTypes.string.isRequired, sortItems: PropTypes.func.isRequired }; class TableBody extends Component { render() { let listItems = this.props.items.map(function(item, index) { return ; }, this); return ( {listItems} ); } } TableBody.propTypes = { items: PropTypes.array.isRequired }; class Item extends Component { constructor(props) { super(props); this.state = { showOpIcon: false, unshared: false, isShowSharedDialog: false, isStarred: this.props.data.starred, }; this.handleMouseOver = this.handleMouseOver.bind(this); this.handleMouseOut = this.handleMouseOut.bind(this); this.share = this.share.bind(this); this.leaveShare = this.leaveShare.bind(this); } handleMouseOver() { this.setState({ showOpIcon: true }); } handleMouseOut() { this.setState({ showOpIcon: false }); } share(e) { e.preventDefault(); this.setState({isShowSharedDialog: true}); } leaveShare(e) { e.preventDefault(); const data = this.props.data; let request; if (data.owner_email.indexOf('@seafile_group') == -1) { let options = { 'share_type': 'personal', 'from': data.owner_email }; request = seafileAPI.leaveShareRepo(data.repo_id, options); } else { request = seafileAPI.leaveShareGroupOwnedRepo(data.repo_id); } request.then((res) => { this.setState({ unshared: true }); // TODO: show feedback msg }).catch((error) => { // TODO: show feedback msg }); } toggleShareDialog = () => { this.setState({isShowSharedDialog: false}); } onStarRepo = () => { if (this.state.isStarred) { seafileAPI.unStarItem(this.props.data.repo_id, '/').then(() => { this.setState({isStarred: !this.state.isStarred}); }); } else { seafileAPI.starItem(this.props.data.repo_id, '/').then(() => { this.setState({isStarred: !this.state.isStarred}); }) } } render() { if (this.state.unshared) { return null; } const data = this.props.data; data.icon_url = Utils.getLibIconUrl(data); data.icon_title = Utils.getLibIconTitle(data); data.url = `${siteRoot}#shared-libs/lib/${data.repo_id}/`; let iconVisibility = this.state.showOpIcon ? '' : ' invisible'; let shareIconClassName = 'op-icon sf2-icon-share repo-share-btn' + iconVisibility; let leaveShareIconClassName = 'op-icon sf2-icon-x3' + iconVisibility; const desktopItem = ( {!this.state.isStarred && } {this.state.isStarred && } {data.icon_title} {data.repo_name} {(isPro && data.is_admin) && } {data.size} {moment(data.last_modified).fromNow()} {data.owner_name} {this.state.isShowSharedDialog && ( )} ); const mobileItem = ( {data.icon_title} {data.repo_name}
{data.owner_name} {data.size} {moment(data.last_modified).fromNow()} {(isPro && data.is_admin) && } {this.state.isShowSharedDialog && ( )}
); return window.innerWidth >= 768 ? desktopItem : mobileItem; } } Item.propTypes = { data: PropTypes.object.isRequired }; class SharedLibraries extends Component { constructor(props) { super(props); this.state = { loading: true, errorMsg: '', items: [], sortBy: 'name', // 'name' or 'time' sortOrder: 'asc' // 'asc' or 'desc' }; } componentDidMount() { seafileAPI.listRepos({type:'shared'}).then((res) => { // res: {data: {...}, status: 200, statusText: "OK", headers: {…}, config: {…}, …} let repoList = res.data.repos.map((item) => { return new Repo(item); }); this.setState({ loading: false, items: Utils.sortRepos(repoList, this.state.sortBy, this.state.sortOrder) }); }).catch((error) => { if (error.response) { if (error.response.status == 403) { this.setState({ loading: false, errorMsg: gettext('Permission denied') }); location.href = `${loginUrl}?next=${encodeURIComponent(location.href)}`; } else { this.setState({ loading: false, errorMsg: gettext('Error') }); } } else { this.setState({ loading: false, errorMsg: gettext('Please check the network.') }); } }); } sortItems = (sortBy, sortOrder) => { this.setState({ sortBy: sortBy, sortOrder: sortOrder, items: Utils.sortRepos(this.state.items, sortBy, sortOrder) }); } render() { return (

{gettext('Shared with me')}

); } } export default SharedLibraries;