diff --git a/frontend/src/app.js b/frontend/src/app.js index 6494bf9f19..9f7fa1bd86 100644 --- a/frontend/src/app.js +++ b/frontend/src/app.js @@ -17,6 +17,7 @@ import ShareAdminShareLinks from './pages/share-admin/share-links'; import ShareAdminUploadLinks from './pages/share-admin/upload-links'; import SharedLibraries from './pages/shared-libs/shared-libs'; import MyLibraries from './pages/my-libs/my-libs'; +import MyLibDeleted from './pages/my-libs/my-libs-deleted'; import DirView from './components/dir-view/dir-view'; import Group from './pages/groups/group-view'; import Groups from './pages/groups/groups-view'; @@ -171,6 +172,7 @@ class App extends Component { + diff --git a/frontend/src/components/dialog/lib-history-setting-dialog.js b/frontend/src/components/dialog/lib-history-setting-dialog.js index 9cbc0df352..9eefe3f627 100644 --- a/frontend/src/components/dialog/lib-history-setting-dialog.js +++ b/frontend/src/components/dialog/lib-history-setting-dialog.js @@ -26,7 +26,7 @@ class LibHistorySetting extends React.Component { } componentDidMount() { - seafileAPI.getRepoHistortLimit(this.props.repoID).then(res => { + seafileAPI.getRepoHistoryLimit(this.props.repoID).then(res => { this.setState({ keepDays: res.data.keep_days, allHistory: res.data.keep_days < 0 ? true : false, @@ -44,7 +44,7 @@ class LibHistorySetting extends React.Component { let reg = /^-?\d+$/; let flag = reg.test(days); if (flag) { - seafileAPI.setRepoHistortLimit(repoID, days).then(res => { + seafileAPI.setRepoHistoryLimit(repoID, days).then(res => { this.setState({ keepDays: res.data.keep_days }); diff --git a/frontend/src/components/main-side-nav.js b/frontend/src/components/main-side-nav.js index ccb69f9f4a..7ddf635e46 100644 --- a/frontend/src/components/main-side-nav.js +++ b/frontend/src/components/main-side-nav.js @@ -127,7 +127,7 @@ class MainSideNav extends React.Component { Files - this.tabItemClick('my-libs')}> + this.tabItemClick('my-libs')}> {gettext('My Libraries')} diff --git a/frontend/src/components/toolbar/repo-view-toobar.js b/frontend/src/components/toolbar/repo-view-toobar.js index e2bdeb45b0..e04cfda0cf 100644 --- a/frontend/src/components/toolbar/repo-view-toobar.js +++ b/frontend/src/components/toolbar/repo-view-toobar.js @@ -1,8 +1,10 @@ import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; -import { gettext } from '../../utils/constants'; +import { Link } from '@reach/router'; +import { siteRoot, gettext } from '../../utils/constants'; import ModalPortal from '../modal-portal'; import CreateRepoDialog from '../dialog/create-repo-dialog'; +import { DropdownToggle, Dropdown, DropdownMenu, DropdownItem } from 'reactstrap'; const propTypes = { // isOwnLibrary: PropTypes.bool.isRequired, @@ -16,6 +18,7 @@ class RepoViewToolbar extends React.Component { super(props); this.state = { isCreateRepoDialogShow: false, + isOpen: false, }; } @@ -28,6 +31,14 @@ class RepoViewToolbar extends React.Component { this.setState({isCreateRepoDialogShow: !this.state.isCreateRepoDialogShow}); } + toggleMore = () => { + this.setState({ isOpen: !this.state.isOpen }); + } + + onDeleteRepoPage = () => { + console.log('turn to delete page'); + } + render() { return ( @@ -39,7 +50,16 @@ class RepoViewToolbar extends React.Component { {gettext('New Library')} {this.props.libraryType !== 'group' && ( - {gettext('More')} + + + {gettext('More')} + + + + {gettext('Deleted Libraries')} + + + )} diff --git a/frontend/src/pages/my-libs/my-libs-deleted.js b/frontend/src/pages/my-libs/my-libs-deleted.js new file mode 100644 index 0000000000..77a79fc9e9 --- /dev/null +++ b/frontend/src/pages/my-libs/my-libs-deleted.js @@ -0,0 +1,124 @@ +import React, { Component, Fragment } from 'react'; +import { Link } from '@reach/router'; +import { gettext, siteRoot, lang } from '../../utils/constants'; +import { seafileAPI } from '../../utils/seafile-api'; +import CommonToolbar from '../../components/toolbar/common-toolbar'; +import moment from 'moment'; +moment.locale(lang); + +class MyLibsDeleted extends Component { + + constructor(props) { + super(props); + this.state = { + deletedRepoList: [], + isLoading: false, + }; + } + + componentDidMount() { + seafileAPI.listDeletedRepo().then(res => { + this.setState({ + deletedRepoList: res.data + }); + }); + } + + refreshDeletedRepoList = (repoID) => { + this.setState({ + deletedRepoList: this.state.deletedRepoList.filter(item => item.repo_id !== repoID) + }); + } + + render() { + return ( + + + + + + + + + {gettext("My Libraries")} + / + {gettext('Deleted Libraries')} + + + + {(!this.state.isLoading && this.state.deletedRepoList.length === 0) && + + {gettext('No deleted libraries.')} + + } + { this.state.deletedRepoList.length !== 0 && + + {gettext('Tip: libraries deleted 30 days ago will be cleaned automatically.')} + + + } + + + + + ); + } +} + +class DeletedRepoTable extends Component { + + render() { + let deletedRepos = this.props.deletedRepoList; + return ( + + + + {/*img*/} + {gettext('Name')} + {gettext('Deleted Time')} + + + + + { deletedRepos && deletedRepos.map((item) => { + return ( + + ); + })} + + + ); + } +} + +class DeletedRepoItem extends Component { + + restoreDeletedRepo = () => { + let repoID = this.props.repo.repo_id; + seafileAPI.restoreDeletedRepo(repoID).then(res => { + this.props.refreshDeletedRepoList(repoID); + }) + } + + render() { + let localTime = moment.utc(this.props.repo.del_time).toDate(); + localTime = moment(localTime).fromNow(); + + return ( + + + {this.props.repo.repo_name} + {localTime} + + + ); + } +} + +export default MyLibsDeleted; diff --git a/seahub/urls.py b/seahub/urls.py index 2c5ca7c23f..66824debbc 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -206,6 +206,7 @@ urlpatterns = [ url(r'^groups/$', react_fake_view, name="groups"), url(r'^group/(?P\d+)/$', react_group, name="group"), url(r'^library/.*$', react_fake_view, name="lib_view"), + url(r'^my-libs/deleted/$', react_fake_view, name="my_libs_deleted"), ### Ajax ### url(r'^ajax/repo/(?P[-0-9a-f]{36})/dirents/$', get_dirents, name="get_dirents"),
{gettext('Tip: libraries deleted 30 days ago will be cleaned automatically.')}