2018-12-10 11:52:44 +08:00
import React , { Fragment } from 'react' ;
2018-12-08 08:37:18 +08:00
import PropTypes from 'prop-types' ;
2019-12-05 15:45:16 +08:00
import { gettext , siteRoot , canAddGroup } from '../../utils/constants' ;
2018-12-10 11:52:44 +08:00
import { seafileAPI } from '../../utils/seafile-api' ;
2019-07-16 10:01:09 +08:00
import { Utils } from '../../utils/utils' ;
2018-12-10 11:52:44 +08:00
import Loading from '../../components/loading' ;
import Group from '../../models/group' ;
2018-12-18 17:21:01 +08:00
import Repo from '../../models/repo' ;
2019-05-28 17:48:44 +08:00
import toaster from '../../components/toast' ;
2018-12-12 18:24:47 +08:00
import GroupsToolbar from '../../components/toolbar/groups-toolbar' ;
2018-12-10 18:19:03 +08:00
import SharedRepoListView from '../../components/shared-repo-list-view/shared-repo-list-view' ;
2018-12-12 18:24:47 +08:00
import CreateGroupDialog from '../../components/dialog/create-group-dialog' ;
2018-12-29 18:25:18 +08:00
import LibDetail from '../../components/dirent-detail/lib-details' ;
2019-06-11 14:11:10 +08:00
import EmptyTip from '../../components/empty-tip' ;
2018-12-08 08:37:18 +08:00
2018-12-10 11:52:44 +08:00
import '../../css/groups.css' ;
2018-12-08 08:37:18 +08:00
2018-12-10 11:52:44 +08:00
const propTypes = {
group : PropTypes . object . isRequired ,
2019-01-31 17:37:02 +08:00
onItemDetails : PropTypes . func . isRequired ,
2018-12-08 08:37:18 +08:00
} ;
2018-12-10 11:52:44 +08:00
class RepoListViewPanel extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = {
repoList : [ ] ,
} ;
}
componentDidMount ( ) {
let group = this . props . group ;
2018-12-10 13:30:44 +08:00
let repoList = group . repos . map ( item => {
2018-12-18 17:21:01 +08:00
let repo = new Repo ( item ) ;
2018-12-10 13:30:44 +08:00
return repo ;
2018-12-10 11:52:44 +08:00
} ) ;
2018-12-10 13:30:44 +08:00
this . setState ( { repoList : repoList } ) ;
2018-12-10 11:52:44 +08:00
}
2018-12-10 18:37:59 +08:00
onItemUnshare = ( repo ) => {
let group = this . props . group ;
2019-07-02 15:36:08 +08:00
seafileAPI . unshareRepoToGroup ( repo . repo _id , group . id ) . then ( ( ) => {
2018-12-10 18:37:59 +08:00
let repoList = this . state . repoList . filter ( item => {
return item . repo _id !== repo . repo _id ;
} ) ;
this . setState ( { repoList : repoList } ) ;
2019-07-16 10:01:09 +08:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2018-12-10 18:37:59 +08:00
} ) ;
}
2018-12-16 11:17:17 +08:00
onItemDelete = ( repo ) => {
2020-07-27 11:06:59 +08:00
let repoList = this . state . repoList . filter ( item => {
return item . repo _id !== repo . repo _id ;
2018-12-16 11:17:17 +08:00
} ) ;
2020-07-27 11:06:59 +08:00
this . setState ( { repoList : repoList } ) ;
2018-12-16 11:17:17 +08:00
}
2019-02-11 15:22:42 +08:00
onItemRename = ( repo , newName ) => {
let group = this . props . group ;
seafileAPI . renameGroupOwnedLibrary ( group . id , repo . repo _id , newName ) . then ( res => {
let repoList = this . state . repoList . map ( item => {
if ( item . repo _id === repo . repo _id ) {
item . repo _name = newName ;
}
return item ;
} ) ;
this . setState ( { repoList : repoList } ) ;
2019-07-16 10:01:09 +08:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2019-02-11 15:22:42 +08:00
} ) ;
}
2018-12-16 11:17:17 +08:00
2018-12-10 11:52:44 +08:00
render ( ) {
let group = this . props . group ;
const emptyTip = < p className = "group-item-empty-tip" > { gettext ( 'No libraries' ) } < / p > ;
return (
2018-12-13 22:11:08 +08:00
< div className = "group-list-panel" >
2018-12-10 11:52:44 +08:00
< h4 className = "group-item-heading ellipsis" >
< a href = { ` ${ siteRoot } group/ ${ group . id } / ` } title = { group . name } > { group . name } < / a >
< / h 4 >
{ this . state . repoList . length === 0 ?
emptyTip :
2018-12-10 18:19:03 +08:00
< SharedRepoListView
2018-12-10 11:52:44 +08:00
isShowTableThread = { false }
isShowRepoOwner = { false }
currentGroup = { this . props . group }
repoList = { this . state . repoList }
2018-12-10 18:37:59 +08:00
onItemUnshare = { this . onItemUnshare }
2018-12-16 11:17:17 +08:00
onItemDelete = { this . onItemDelete }
2018-12-29 18:25:18 +08:00
onItemDetails = { this . props . onItemDetails }
2019-02-11 15:22:42 +08:00
onItemRename = { this . onItemRename }
2018-12-10 11:52:44 +08:00
/ >
}
2018-12-13 22:11:08 +08:00
< / d i v >
2018-12-10 11:52:44 +08:00
) ;
}
2019-01-31 17:37:02 +08:00
}
2018-12-10 11:52:44 +08:00
RepoListViewPanel . propTypes = propTypes ;
class GroupsView extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = {
isLoading : true ,
errorMsg : '' ,
groupList : [ ] ,
2018-12-12 18:24:47 +08:00
showAddGroupModal : false ,
2018-12-29 18:25:18 +08:00
isShowDetails : false ,
currentRepo : null ,
2019-01-31 17:37:02 +08:00
} ;
2018-12-10 11:52:44 +08:00
}
2018-12-12 18:24:47 +08:00
listGroups = ( ) => {
2019-01-08 13:55:00 +08:00
seafileAPI . listGroups ( true ) . then ( ( res ) => {
2018-12-10 11:52:44 +08:00
// `{'with_repos': 1}`: list repos of every group
// res: {data: [...], status: 200, statusText: "OK", headers: {…}, config: {…}, …}
2018-12-10 13:30:44 +08:00
let groupList = res . data . map ( item => {
2018-12-10 11:52:44 +08:00
let group = new Group ( item ) ;
return group ;
2019-01-31 17:37:02 +08:00
} ) ;
2018-12-10 11:52:44 +08:00
this . setState ( {
isLoading : false ,
2020-01-02 11:29:31 +08:00
groupList : groupList . sort ( ( a , b ) => {
return a . name . toLowerCase ( ) < b . name . toLowerCase ( ) ? - 1 : 1 ;
} )
2018-12-10 11:52:44 +08:00
} ) ;
} ) . catch ( ( error ) => {
2019-12-05 15:45:16 +08:00
this . setState ( {
isLoading : false ,
errorMsg : Utils . getErrorMsg ( error , true ) // true: show login tip if 403
} ) ;
2018-12-10 11:52:44 +08:00
} ) ;
}
2018-12-08 08:37:18 +08:00
2018-12-12 18:24:47 +08:00
toggleAddGroupModal = ( ) => {
this . setState ( {
showAddGroupModal : ! this . state . showAddGroupModal
} ) ;
}
2018-12-13 17:55:22 +08:00
onCreateGroup = ( ) => {
this . setState ( {
showAddGroupModal : false ,
isLoading : true ,
groupList : [ ] ,
} ) ;
this . listGroups ( ) ;
}
2018-12-12 18:24:47 +08:00
componentDidMount ( ) {
this . listGroups ( ) ;
}
2018-12-29 18:25:18 +08:00
onItemDetails = ( repo ) => {
this . setState ( {
isShowDetails : true ,
currentRepo : repo ,
} ) ;
}
closeDetails = ( ) => {
this . setState ( { isShowDetails : false } ) ;
}
2018-12-08 08:37:18 +08:00
render ( ) {
2019-06-11 14:11:10 +08:00
const emptyTip = (
< EmptyTip >
2020-01-03 16:50:17 +08:00
< h2 > { gettext ( 'No groups' ) } < / h 2 >
2019-06-11 14:11:10 +08:00
{ canAddGroup ?
2020-01-03 16:50:17 +08:00
< p > { gettext ( 'You are not in any groups. Groups allow multiple people to collaborate on libraries. You can create a group by clicking the "New Group" button in the menu bar.' ) } < / p > :
< p > { gettext ( 'You are not in any groups. Groups allow multiple people to collaborate on libraries. Groups you join will be listed here.' ) } < / p >
2019-06-11 14:11:10 +08:00
}
< / E m p t y T i p >
) ;
2018-12-08 08:37:18 +08:00
return (
2018-12-10 11:52:44 +08:00
< Fragment >
2018-12-12 18:24:47 +08:00
< GroupsToolbar
onShowSidePanel = { this . props . onShowSidePanel }
onSearchedClick = { this . props . onSearchedClick }
toggleAddGroupModal = { this . toggleAddGroupModal }
/ >
2018-12-29 18:25:18 +08:00
< div className = "main-panel-center flex-row" >
2018-12-10 11:52:44 +08:00
< div className = "cur-view-container" >
< div className = "cur-view-path" >
2019-01-31 17:37:02 +08:00
< h3 className = "sf-heading" > { gettext ( 'My Groups' ) } < / h 3 >
2018-12-10 11:52:44 +08:00
< / d i v >
2018-12-13 16:35:11 +08:00
< div className = "cur-view-content cur-view-content-groups" >
2018-12-10 11:52:44 +08:00
{ this . state . isLoading && < Loading / > }
2019-12-19 13:44:30 +08:00
{ ( ! this . state . isLoading && this . state . errorMsg ) && < div className = "error text-center mt-2" > { this . state . errorMsg } < / d i v > }
2019-06-11 14:11:10 +08:00
{ ( ! this . state . isLoading && ! this . state . errorMsg && this . state . groupList . length == 0 ) && emptyTip }
2018-12-10 11:52:44 +08:00
{ ! this . state . isLoading && this . state . groupList . map ( ( group , index ) => {
return (
2018-12-29 18:25:18 +08:00
< RepoListViewPanel
key = { index }
group = { group }
onItemDetails = { this . onItemDetails }
/ >
2018-12-10 11:52:44 +08:00
) ;
} ) }
< / d i v >
< / d i v >
2018-12-29 18:25:18 +08:00
{ this . state . isShowDetails && (
< div className = "cur-view-detail" >
< LibDetail currentRepo = { this . state . currentRepo } closeDetails = { this . closeDetails } / >
< / d i v >
) }
2018-12-10 11:52:44 +08:00
< / d i v >
2018-12-12 18:24:47 +08:00
{ this . state . showAddGroupModal &&
< CreateGroupDialog
toggleAddGroupModal = { this . toggleAddGroupModal }
2018-12-13 17:55:22 +08:00
onCreateGroup = { this . onCreateGroup }
2018-12-12 18:24:47 +08:00
showAddGroupModal = { this . state . showAddGroupModal }
/ >
}
2018-12-10 11:52:44 +08:00
< / F r a g m e n t >
2018-12-08 08:37:18 +08:00
) ;
}
}
2018-12-12 18:24:47 +08:00
const GroupsViewPropTypes = {
onShowSidePanel : PropTypes . func . isRequired ,
onSearchedClick : PropTypes . func . isRequired ,
} ;
GroupsView . propTypes = GroupsViewPropTypes ;
2018-12-08 08:37:18 +08:00
2018-12-10 11:52:44 +08:00
export default GroupsView ;