From 4ade0f7cbbee6708fdf9cbc11bd07adf77fbc891 Mon Sep 17 00:00:00 2001 From: shanshuirenjia <978987373@qq.com> Date: Wed, 12 Dec 2018 11:38:27 +0800 Subject: [PATCH] update code structure --- .../mylib-repo-list-view/content.js | 195 +++++++ .../components/mylib-repo-list-view/item.js | 277 ++++++++++ .../popups/delete-item.js | 0 .../mylib-repo-list-view/table-body.js | 25 + frontend/src/pages/my-libs/my-libs.js | 492 +----------------- 5 files changed, 505 insertions(+), 484 deletions(-) create mode 100644 frontend/src/components/mylib-repo-list-view/content.js create mode 100644 frontend/src/components/mylib-repo-list-view/item.js rename frontend/src/{pages/my-libs => components/mylib-repo-list-view}/popups/delete-item.js (100%) create mode 100644 frontend/src/components/mylib-repo-list-view/table-body.js diff --git a/frontend/src/components/mylib-repo-list-view/content.js b/frontend/src/components/mylib-repo-list-view/content.js new file mode 100644 index 0000000000..8af397a887 --- /dev/null +++ b/frontend/src/components/mylib-repo-list-view/content.js @@ -0,0 +1,195 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import moment from 'moment'; +import { gettext, storages} from '../../utils/constants'; +import { Utils } from '../../utils/utils'; +import { seafileAPI } from '../../utils/seafile-api'; +import TransferDialog from '../dialog/transfer-dialog'; +import LibHistorySetting from '../dialog/lib-history-setting-dialog'; +import LibDetail from '../dirent-detail/lib-details'; +import Loading from '../loading'; +import ModalPortal from '../modal-portal'; +import DeleteItemPopup from './popups/delete-item'; +import TableBody from './table-body'; + +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; + } + } +} + +export default Content; \ No newline at end of file diff --git a/frontend/src/components/mylib-repo-list-view/item.js b/frontend/src/components/mylib-repo-list-view/item.js new file mode 100644 index 0000000000..692bb5aa20 --- /dev/null +++ b/frontend/src/components/mylib-repo-list-view/item.js @@ -0,0 +1,277 @@ + +import React, { Component } from 'react'; +import moment from 'moment'; +import { Link } from '@reach/router'; +import { Dropdown, DropdownMenu, DropdownToggle, DropdownItem } from 'reactstrap'; +import { gettext, siteRoot, storages, canGenerateShareLink, canGenerateUploadLink, folderPermEnabled, enableRepoSnapshotLabel } from '../../utils/constants'; +import { Utils } from '../../utils/utils'; +import { seafileAPI } from '../../utils/seafile-api'; +import RenameInput from '../../components/rename-input'; + +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; + } +} + +export default Item; \ No newline at end of file diff --git a/frontend/src/pages/my-libs/popups/delete-item.js b/frontend/src/components/mylib-repo-list-view/popups/delete-item.js similarity index 100% rename from frontend/src/pages/my-libs/popups/delete-item.js rename to frontend/src/components/mylib-repo-list-view/popups/delete-item.js diff --git a/frontend/src/components/mylib-repo-list-view/table-body.js b/frontend/src/components/mylib-repo-list-view/table-body.js new file mode 100644 index 0000000000..6cfde7a493 --- /dev/null +++ b/frontend/src/components/mylib-repo-list-view/table-body.js @@ -0,0 +1,25 @@ +import React, { Component } from 'react'; +import Item from './item'; + +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} + ); + } +} + +export default TableBody; \ No newline at end of file diff --git a/frontend/src/pages/my-libs/my-libs.js b/frontend/src/pages/my-libs/my-libs.js index 0d9e889ce7..0ba112104f 100644 --- a/frontend/src/pages/my-libs/my-libs.js +++ b/frontend/src/pages/my-libs/my-libs.js @@ -1,486 +1,11 @@ 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 { gettext, loginUrl} from '../../utils/constants'; 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); - }); - }); - } +import Content from '../../components/mylib-repo-list-view/content'; - 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) { @@ -543,9 +68,7 @@ class MyLibraries extends Component { break; } } - this.setState({ - items: array - }) + this.setState({items: array}); } render() { @@ -561,10 +84,11 @@ class MyLibraries extends Component {

{gettext("My Libraries")}

- +