import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Link } from '@reach/router'; import moment from 'moment'; import { Dropdown, DropdownToggle, DropdownItem } from 'reactstrap'; import { seafileAPI } from '../../utils/seafile-api'; import { Utils } from '../../utils/utils'; import { isPro, gettext, siteRoot, canGenerateUploadLink } from '../../utils/constants'; import ShareLink from '../../models/share-link'; import ShareLinkPermissionEditor from '../../components/select-editor/share-link-permission-editor'; import Loading from '../../components/loading'; import toaster from '../../components/toast'; import EmptyTip from '../../components/empty-tip'; import ShareLinkPermissionSelect from '../../components/dialog/share-link-permission-select'; import ShareAdminLink from '../../components/dialog/share-admin-link'; import SortOptionsDialog from '../../components/dialog/sort-options'; 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; if (loading) { return ; } else if (errorMsg) { return

{errorMsg}

; } else { const emptyTip = (

{gettext('No share links')}

{gettext('You have not created any share links yet. A share link can be used to share files and folders with anyone. You can create a share link for a file or folder by clicking the share icon to the right of its name.')}

); // sort const sortByName = sortBy == 'name'; const sortByTime = sortBy == 'time'; const sortIcon = sortOrder == 'asc' ? : ; const isDesktop = Utils.isDesktop(); // only for some columns const columnWidths = isPro ? ['14%', '7%', '14%'] : ['21%', '14%', '20%']; const table = ( {isDesktop ? ( {isPro && } ) : ( )} {items.map((item, index) => { return (); })}
{/*icon*/} {gettext('Name')} {sortByName && sortIcon} {gettext('Library')}{gettext('Permission')}{gettext('Visits')} {gettext('Expiration')} {sortByTime && sortIcon} {/*Operations*/}
); return items.length ? table : emptyTip; } } } const itemPropTypes = { item: PropTypes.object.isRequired, isDesktop: PropTypes.bool.isRequired, onRemoveLink: PropTypes.func.isRequired }; class Item extends Component { constructor(props) { super(props); this.state = { isOpIconShown: false, isOpMenuOpen: false, // for mobile isPermSelectDialogOpen: false, // for mobile isLinkDialogOpen: false, permissionOptions: [], currentPermission: '', }; } componentDidMount() { if (isPro) { this.updatePermissionOptions(); } } updatePermissionOptions = () => { const item = this.props.item; let itemType = item.is_dir ? (item.path === '/' ? 'library' : 'dir') : 'file'; let permission = item.repo_folder_permission; let permissionOptions = Utils.getShareLinkPermissionList(itemType, permission, item.path, item.can_edit); let currentPermission = Utils.getShareLinkPermissionStr(this.props.item.permissions); this.setState({ permissionOptions: permissionOptions, currentPermission: currentPermission }); } toggleOpMenu = () => { this.setState({ isOpMenuOpen: !this.state.isOpMenuOpen }); } togglePermSelectDialog = () => { this.setState({ isPermSelectDialogOpen: !this.state.isPermSelectDialogOpen }); } toggleLinkDialog = () => { this.setState({ isLinkDialogOpen: !this.state.isLinkDialogOpen }); } handleMouseOver = () => { this.setState({isOpIconShown: true}); } handleMouseOut = () => { this.setState({isOpIconShown: false}); } viewLink = (e) => { e.preventDefault(); this.toggleLinkDialog(); } removeLink = (e) => { e.preventDefault(); this.props.onRemoveLink(this.props.item); } renderExpiration = () => { const item = this.props.item; if (!item.expire_date) { return '--'; } const expire_date = moment(item.expire_date).format('YYYY-MM-DD'); const expire_time = moment(item.expire_date).format('YYYY-MM-DD HH:mm:ss'); return ({expire_date}); } changePerm = (permission) => { const item = this.props.item; const permissionDetails = Utils.getShareLinkPermissionObject(permission).permissionDetails; seafileAPI.updateShareLink(item.token, JSON.stringify(permissionDetails)).then(() => { this.setState({ currentPermission: permission }); let message = gettext('Successfully modified permission.'); toaster.success(message); }).catch((error) => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } render() { const item = this.props.item; const { currentPermission, permissionOptions , isOpIconShown, isPermSelectDialogOpen, isLinkDialogOpen } = this.state; let iconUrl, objUrl; if (item.is_dir) { let path = item.path === '/' ? '/' : item.path.slice(0, item.path.length - 1); iconUrl = Utils.getFolderIconUrl(false); objUrl = `${siteRoot}library/${item.repo_id}/${encodeURIComponent(item.repo_name)}${Utils.encodePath(path)}`; } else { iconUrl = Utils.getFileIconUrl(item.obj_name); objUrl = `${siteRoot}lib/${item.repo_id}/file${Utils.encodePath(item.path)}`; } const desktopItem = ( {item.is_dir ? {item.obj_name} : {item.obj_name} } {item.repo_name} {isPro && } {item.view_cnt} {this.renderExpiration()} {!item.is_expired && } ); const mobileItem = ( {item.is_dir ? {item.obj_name} : {item.obj_name} } {isPro && {Utils.getShareLinkPermissionObject(currentPermission).text}}
{item.repo_name}
{gettext('Visits')}: {item.view_cnt} {gettext('Expiration')}: {this.renderExpiration()}
{(isPro && !item.is_expired) && {gettext('Permission')}} {!item.is_expired && {gettext('View')}} {gettext('Remove')}
{isPermSelectDialogOpen && }
); return ( {this.props.isDesktop ? desktopItem : mobileItem} {isLinkDialogOpen && } ); } } Item.propTypes = itemPropTypes; class ShareAdminShareLinks extends Component { constructor(props) { super(props); this.state = { loading: true, errorMsg: '', items: [], sortBy: 'name', // 'name' or 'time' sortOrder: 'asc' // 'asc' or 'desc' }; // for mobile this.sortOptions = [ {value: 'name-asc', text: gettext('By name ascending')}, {value: 'name-desc', text: gettext('By name descending')}, {value: 'time-asc', text: gettext('By expiration ascending')}, {value: 'time-desc', text: gettext('By expiration descending')} ]; } _sortItems = (items, sortBy, sortOrder) => { let comparator; switch (`${sortBy}-${sortOrder}`) { case 'name-asc': comparator = function(a, b) { var result = Utils.compareTwoWord(a.obj_name, b.obj_name); return result; }; break; case 'name-desc': comparator = function(a, b) { var result = Utils.compareTwoWord(a.obj_name, b.obj_name); return -result; }; break; case 'time-asc': comparator = function(a, b) { return a.expire_date < b.expire_date ? -1 : 1; }; break; case 'time-desc': comparator = function(a, b) { return a.expire_date < b.expire_date ? 1 : -1; }; break; // no default } items.sort((a, b) => { if (a.is_dir && !b.is_dir) { return -1; } else if (!a.is_dir && b.is_dir) { return 1; } else { return comparator(a, b); } }); return items; } sortItems = (sortBy, sortOrder) => { this.setState({ sortBy: sortBy, sortOrder: sortOrder, items: this._sortItems(this.state.items, sortBy, sortOrder) }); } componentDidMount() { seafileAPI.listUserShareLinks().then((res) => { let items = res.data.map(item => { return new ShareLink(item); }); this.setState({ loading: false, items: this._sortItems(items, this.state.sortBy, this.state.sortOrder) }); }).catch((error) => { this.setState({ loading: false, errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403 }); }); } onRemoveLink = (item) => { seafileAPI.deleteShareLink(item.token).then(() => { let items = this.state.items.filter(uploadItem => { return uploadItem.token !== item.token; }); this.setState({items: items}); let message = gettext('Successfully deleted 1 item.'); toaster.success(message); }).catch((error) => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } toggleSortOptionsDialog = () => { this.setState({ isSortOptionsDialogOpen: !this.state.isSortOptionsDialogOpen }); } render() { return (
  • {gettext('Share Links')}
  • {canGenerateUploadLink && (
  • {gettext('Upload Links')}
  • )}
{(!Utils.isDesktop() && this.state.items.length > 0) && }
{this.state.isSortOptionsDialogOpen && }
); } } export default ShareAdminShareLinks;