import React, { Component, Fragment } from 'react'; import moment from 'moment'; import { Link } from '@reach/router'; import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap'; import { seafileAPI } from '../../utils/seafile-api'; import { Utils } from '../../utils/utils'; import { gettext, siteRoot, loginUrl, isPro, storages, canGenerateShareLink, canGenerateUploadLink, folderPermEnabled, enableRepoSnapshotLabel } from '../../utils/constants'; import Loading from '../../components/loading'; import ModalPortal from '../../components/modal-portal'; import DeleteItemPopup from './popups/delete-item'; import CommonToolbar from '../../components/toolbar/common-toolbar'; import RepoViewToolbar from '../../components/toolbar/repo-view-toobar'; import TransferDialog from '../../components/dialog/transfer-dialog'; import LibHistorySetting from '../../components/dialog/lib-history-setting-dialog'; import LibDetail from '../../components/dirent-detail/lib-details'; import RenameInput from '../../components/rename-input'; class Content extends Component { constructor(props) { super(props); this.state = { deleteItemPopupOpen: false, showTransfer: false, itemName: '', showHistorySetting: false, showDetails: false, libID: '', libSize: '', libUpdateTime: '' }; this.toggleDeleteItemPopup = this.toggleDeleteItemPopup.bind(this); this.showDeleteItemPopup = this.showDeleteItemPopup.bind(this); this.onTransfer = this.onTransfer.bind(this); this.onHistorySetting = this.onHistorySetting.bind(this); this.onFileTagChanged = this.onFileTagChanged.bind(this); this.onDetails = this.onDetails.bind(this); this.closeDetails = this.closeDetails.bind(this); this.operations = { showDeleteItemPopup: this.showDeleteItemPopup, onTransfer: this.onTransfer, onHistorySetting: this.onHistorySetting, onDetails: this.onDetails, onRenameRepo: this.props.renameRepo, }; } toggleDeleteItemPopup() { this.setState({ deleteItemPopupOpen: !this.state.deleteItemPopupOpen }); } showDeleteItemPopup(data) { this.toggleDeleteItemPopup(); this.setState({ deleteItemPopupData: data }); } onTransfer(itemName, itemID) { this.setState({ showTransfer: !this.state.showTransfer, itemName: itemName, libID: itemID }); } onHistorySetting(itemName, itemID) { this.setState({ showHistorySetting: !this.state.showHistorySetting, itemName: itemName, libID: itemID }); } onDetails(data) { const libSize = Utils.formatSize({bytes: data.size}); const libID = data.repo_id; const libUpdateTime = moment(data.last_modified).fromNow(); this.setState({ showDetails: !this.state.showDetails, libID: libID, libSize: libSize, libUpdateTime: libUpdateTime }); } closeDetails() { this.setState({ showDetails: !this.state.showDetails }) } onFileTagChanged() { seafileAPI.listFileTags(this.state.detailsRepoID, '/').then(res => { let fileTags = res.data.file_tags.map(item => { console.log(item); }); }); } render() { const {loading, errorMsg, items} = this.props.data; if (loading) { return ; } else if (errorMsg) { return

{errorMsg}

; } else { const emptyTip = (

{gettext('You have not created any libraries')}

{gettext('You can create a library to organize your files. For example, you can create one for each of your projects. Each library can be synchronized and shared separately.')}

); // TODO: test 'storage backend' const showStorageBackend = storages.length > 0; // only for desktop const desktopThead = ( {gettext("Library Type")} {gettext("Name")}{/*TODO: sort*/} {gettext("Actions")} {gettext("Size")} {showStorageBackend ? {gettext('Storage backend')} : null} {gettext("Last Update")}{/*TODO: sort*/} ); const mobileThead = ( {gettext("Library Type")} {gettext("Sort:")} {/* TODO: sort */} {gettext("name")} {gettext("last update")} {gettext("Actions")} ); const table = ( {window.innerWidth >= 768 ? desktopThead : mobileThead}
); const nonEmpty = ( {table} {this.state.showTransfer && } {this.state.showHistorySetting && } {this.state.showDetails && (
)}
); return items.length ? nonEmpty : emptyTip; } } } class TableBody extends Component { constructor(props) { super(props); this.state = { items: this.props.items }; } render() { let listItems = this.state.items.map(function(item, index) { return ; }, this); return ( {listItems} ); } } class Item extends Component { constructor(props) { super(props); this.state = { showOpIcon: false, operationMenuOpen: false, deleted: false, showChangeLibName: false, repoName: this.props.data.repo_name, }; this.handleMouseOver = this.handleMouseOver.bind(this); this.handleMouseOut = this.handleMouseOut.bind(this); this.toggleOperationMenu = this.toggleOperationMenu.bind(this); this.clickOperationMenuToggle = this.clickOperationMenuToggle.bind(this); this.share = this.share.bind(this); this.showDeleteItemPopup = this.showDeleteItemPopup.bind(this); this.deleteItem = this.deleteItem.bind(this); this.rename = this.rename.bind(this); this.transfer = this.transfer.bind(this); this.historySetting = this.historySetting.bind(this); this.changePassword = this.changePassword.bind(this); this.showLinks = this.showLinks.bind(this); this.folderPerm = this.folderPerm.bind(this); this.showDetails = this.showDetails.bind(this); this.label = this.label.bind(this); } handleMouseOver() { if (this.state.operationMenuOpen) { return; } this.setState({ showOpIcon: true }); } handleMouseOut() { if (this.state.operationMenuOpen) { return; } this.setState({ showOpIcon: false }); } toggleOperationMenu() { this.setState({ operationMenuOpen: !this.state.operationMenuOpen }); } clickOperationMenuToggle(e) { e.preventDefault(); this.toggleOperationMenu(); } share(e) { e.preventDefault(); // TODO } showDeleteItemPopup(e) { e.preventDefault(); // for `` const data = this.props.data; this.props.operations.showDeleteItemPopup({ repoName: data.repo_name, yesCallback: this.deleteItem, _this: this }); } deleteItem() { const data = this.props.data; seafileAPI.deleteRepo(data.repo_id).then((res) => { this.setState({ deleted: true }); // TODO: show feedback msg }).catch((error) => { // TODO: show feedback msg }); } rename() { this.setState({ showChangeLibName: !this.state.showChangeLibName }) } onChangeLibName = (e) => { this.setState({ repoName: e.target.value }) } updateLibName = () => { const itemID = this.props.data.repo_id; seafileAPI.renameRepo(itemID, this.state.repoName).then(res => { this.rename(); this.props.operations.onRenameRepo(itemID, this.state.repoName); }).catch(res => { // TODO res error }) } transfer() { const itemName = this.props.data.repo_name; const itemID = this.props.data.repo_id; this.props.operations.onTransfer(itemName, itemID); } historySetting() { const itemName = this.props.data.repo_name; const itemID = this.props.data.repo_id; this.props.operations.onHistorySetting(itemName, itemID); } changePassword() { } showLinks() { } folderPerm() { } showDetails() { let data = this.props.data; this.props.operations.onDetails(data); } label() { } render() { if (this.state.deleted) { return null; } const data = this.props.data; const permission = data.permission; let is_readonly = false; if (permission == 'r' || permission == 'preview') { is_readonly = true; } data.icon_url = Utils.getLibIconUrl({ is_encrypted: data.encrypted, is_readonly: is_readonly, size: Utils.isHiDPI() ? 48 : 24 }); data.icon_title = Utils.getLibIconTitle({ 'encrypted': data.encrypted, 'is_admin': data.is_admin, 'permission': permission }); data.url = `${siteRoot}#my-libs/lib/${data.repo_id}/`; let iconVisibility = this.state.showOpIcon ? '' : ' invisible'; let shareIconClassName = 'sf2-icon-share sf2-x op-icon' + iconVisibility; let deleteIconClassName = 'sf2-icon-delete sf2-x op-icon' + iconVisibility; let operationMenuToggleIconClassName = 'sf2-icon-caret-down item-operation-menu-toggle-icon op-icon'; if (window.innerWidth >= 768) { operationMenuToggleIconClassName += iconVisibility; } const showShareLinks = !data.encrypted && (canGenerateShareLink || canGenerateUploadLink); const commonToggle = ( ); const commonOperationsInMenu = ( {gettext('Rename')} {gettext('Transfer')} {gettext('History Setting')} {data.encrypted ? {gettext('Change Password')} : ''} {showShareLinks ? {gettext('Share Links')} : ''} {folderPermEnabled ? {gettext('Folder Permission')} : ''} {gettext('Details')} ); const desktopOperations = (
{commonToggle} {commonOperationsInMenu} {enableRepoSnapshotLabel ? {gettext('Label current state')} : ''}
); const mobileOperations = ( {commonToggle}
{gettext('Share')} {gettext('Delete')} {commonOperationsInMenu}
); const desktopItem = ( {data.icon_title} {this.state.showChangeLibName && ( )} {!this.state.showChangeLibName && data.repo_name && ( {data.repo_name} )} {!this.state.showChangeLibName && !data.repo_name && (gettext('Broken (please contact your administrator to fix this library)')) } {data.repo_name ? desktopOperations : ''} {Utils.formatSize({bytes: data.size})} {storages.length ? {data.storage_name} : null} {moment(data.last_modified).fromNow()} ); const mobileItem = ( {data.icon_title} {data.repo_name ? {data.repo_name} : gettext('Broken (please contact your administrator to fix this library)')}
{Utils.formatSize({bytes: data.size})} {moment(data.last_modified).fromNow()} {data.repo_name ? mobileOperations : ''} ); return window.innerWidth >= 768 ? desktopItem : mobileItem; } } class MyLibraries extends Component { constructor(props) { super(props); this.state = { loading: true, errorMsg: '', items: [] }; } componentDidMount() { seafileAPI.listRepos({type:'mine'}).then((res) => { // res: {data: {...}, status: 200, statusText: "OK", headers: {…}, config: {…}, …} this.setState({ loading: false, items: res.data.repos }); }).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.") }); } }); } onCreateRepo = (repo) => { seafileAPI.createMineRepo(repo).then((res) => { //todo update repoList }); } toggleTransferSubmit = (repoID) => { this.setState({ items: this.state.items.filter(item => item.repo_id !== repoID) }) } renameRepo = (repoID, newName) => { let array = this.state.items; for (var i=0; i < array.length; i++) { if (array[i].repo_id === repoID) { array[i].repo_name=newName; break; } } this.setState({ items: array }) } render() { return (

{gettext("My Libraries")}

); } } export default MyLibraries;