2024-07-18 11:58:42 +08:00
import React , { Fragment } from 'react' ;
2018-12-08 08:37:18 +08:00
import PropTypes from 'prop-types' ;
2019-03-19 10:35:21 +08:00
import cookie from 'react-cookies' ;
2024-11-25 10:23:42 +08:00
import classnames from 'classnames' ;
2024-04-26 21:51:50 +08:00
import { gettext , username , canAddRepo } from '../../utils/constants' ;
2018-12-08 08:37:18 +08:00
import { seafileAPI } from '../../utils/seafile-api' ;
2019-01-02 10:53:38 +08:00
import { Utils } from '../../utils/utils' ;
2018-12-10 13:44:11 +08:00
import Loading from '../../components/loading' ;
2019-06-10 17:30:10 +08:00
import EmptyTip from '../../components/empty-tip' ;
2018-12-10 17:59:26 +08:00
import ModalPortal from '../../components/modal-portal' ;
2019-05-28 17:48:44 +08:00
import toaster from '../../components/toast' ;
2024-09-14 13:51:28 +08:00
import { Group , Repo } from '../../models' ;
2018-12-10 17:59:26 +08:00
import CreateRepoDialog from '../../components/dialog/create-repo-dialog' ;
2024-06-21 17:32:03 +08:00
import GroupMembersDialog from '../../components/dialog/group-members-dialog' ;
2018-12-19 10:44:23 +08:00
import DismissGroupDialog from '../../components/dialog/dismiss-group-dialog' ;
import RenameGroupDialog from '../../components/dialog/rename-group-dialog' ;
2018-12-24 18:25:12 +08:00
import TransferGroupDialog from '../../components/dialog/transfer-group-dialog' ;
2021-02-10 09:59:32 +08:00
import ImportMembersDialog from '../../components/dialog/import-members-dialog' ;
2018-12-24 18:25:12 +08:00
import ManageMembersDialog from '../../components/dialog/manage-members-dialog' ;
2025-01-13 18:18:58 +08:00
import DepartmentDetailDialog from '../../components/dialog/department-detail-dialog' ;
2019-07-04 13:49:16 +08:00
import LeaveGroupDialog from '../../components/dialog/leave-group-dialog' ;
2018-12-10 18:19:03 +08:00
import SharedRepoListView from '../../components/shared-repo-list-view/shared-repo-list-view' ;
2019-07-18 20:21:50 +08:00
import SortOptionsDialog from '../../components/dialog/sort-options' ;
2024-06-21 17:32:03 +08:00
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar' ;
2024-11-25 10:23:42 +08:00
import ViewModes from '../../components/view-modes' ;
2025-01-22 14:38:40 +08:00
import AddRepos from '../../components/add-repos' ;
2024-11-25 10:23:42 +08:00
import ReposSortMenu from '../../components/sort-menu' ;
import { LIST _MODE } from '../../components/dir-view-mode/constants' ;
2018-12-29 18:25:18 +08:00
2018-12-24 18:25:12 +08:00
import '../../css/group-view.css' ;
2018-12-08 08:37:18 +08:00
const propTypes = {
2018-12-19 10:44:23 +08:00
onGroupChanged : PropTypes . func . isRequired ,
groupID : PropTypes . string ,
2018-12-08 08:37:18 +08:00
} ;
class GroupView extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = {
2020-08-17 11:53:33 +08:00
isLoading : true , // first loading
isLoadingMore : false ,
2018-12-08 08:37:18 +08:00
errMessage : '' ,
2018-12-08 16:35:00 +08:00
emptyTip : null ,
2018-12-08 08:37:18 +08:00
currentGroup : null ,
2018-12-29 18:25:18 +08:00
currentRepo : null ,
2018-12-08 16:35:00 +08:00
isStaff : false ,
2018-12-24 18:25:12 +08:00
isOwner : false ,
2024-11-25 10:23:42 +08:00
currentViewMode : localStorage . getItem ( 'sf_repo_list_view_mode' ) || LIST _MODE ,
2019-05-29 13:57:12 +08:00
sortBy : cookie . load ( 'seafile-repo-dir-sort-by' ) || 'name' , // 'name' or 'time' or 'size'
2019-04-12 14:30:08 +08:00
sortOrder : cookie . load ( 'seafile-repo-dir-sort-order' ) || 'asc' , // 'asc' or 'desc'
2019-07-18 20:21:50 +08:00
isSortOptionsDialogOpen : false ,
2018-12-08 08:37:18 +08:00
repoList : [ ] ,
2020-08-17 11:53:33 +08:00
currentPage : 1 ,
2023-06-13 16:42:42 +08:00
perPage : 300 ,
2020-08-17 11:53:33 +08:00
hasNextPage : false ,
2018-12-10 17:59:26 +08:00
libraryType : 'group' ,
isCreateRepoDialogShow : false ,
isDepartmentGroup : false ,
2025-01-13 18:18:58 +08:00
isShowDepartmentDetailDialog : false ,
2018-12-19 10:44:23 +08:00
showGroupDropdown : false ,
2018-12-24 18:25:12 +08:00
showGroupMembersPopover : false ,
2018-12-19 10:44:23 +08:00
showRenameGroupDialog : false ,
showDismissGroupDialog : false ,
2018-12-24 18:25:12 +08:00
showTransferGroupDialog : false ,
2021-02-10 09:59:32 +08:00
showImportMembersDialog : false ,
2018-12-24 18:25:12 +08:00
showManageMembersDialog : false ,
2019-07-05 11:05:26 +08:00
isLeaveGroupDialogOpen : false ,
2024-06-21 17:32:03 +08:00
isMembersDialogOpen : false
2018-12-19 10:44:23 +08:00
} ;
2018-12-08 08:37:18 +08:00
}
componentDidMount ( ) {
2024-09-14 13:51:28 +08:00
this . loadGroup ( this . props . groupID ) ;
2018-12-08 08:37:18 +08:00
}
2023-12-06 17:24:05 +08:00
UNSAFE _componentWillReceiveProps ( nextProps ) {
2018-12-08 08:37:18 +08:00
if ( nextProps . groupID !== this . props . groupID ) {
this . loadGroup ( nextProps . groupID ) ;
}
}
loadGroup = ( groupID ) => {
seafileAPI . getGroup ( groupID ) . then ( ( res ) => {
let currentGroup = new Group ( res . data ) ;
2018-12-08 16:35:00 +08:00
this . setState ( {
2024-09-14 13:51:28 +08:00
emptyTip : this . getEmptyTip ( currentGroup ) ,
currentGroup ,
isStaff : currentGroup . admins . indexOf ( username ) > - 1 , // for item operations
isDepartmentGroup : currentGroup . parent _group _id !== 0 ,
isOwner : currentGroup . owner === username ,
2020-08-25 14:54:19 +08:00
currentPage : 1 ,
2024-07-18 11:58:42 +08:00
repoList : [ ] // empty it for the current group
2020-08-25 14:54:19 +08:00
} , ( ) => {
this . loadRepos ( this . state . currentPage ) ;
2018-12-08 16:35:00 +08:00
} ) ;
2018-12-08 08:37:18 +08:00
} ) . catch ( ( error ) => {
2019-12-05 15:45:16 +08:00
this . setState ( {
isLoading : false ,
2019-12-19 13:44:30 +08:00
errMessage : Utils . getErrorMsg ( error , true ) // true: show login tip if 403
2020-11-02 13:56:35 +08:00
} ) ;
2018-12-08 08:37:18 +08:00
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-08 08:37:18 +08:00
2020-08-17 11:53:33 +08:00
loadRepos = ( page ) => {
const { perPage } = this . state ;
seafileAPI . listGroupRepos ( this . props . groupID , page , perPage ) . then ( ( res ) => {
let hasNextPage = true ;
if ( res . data . length < perPage ) {
hasNextPage = false ;
}
let repoList = this . state . repoList ;
let newRepoList = res . data . map ( item => {
2018-12-18 17:21:01 +08:00
let repo = new Repo ( item ) ;
return repo ;
2018-12-08 08:37:18 +08:00
} ) ;
2020-08-17 11:53:33 +08:00
if ( newRepoList . length ) {
repoList = repoList . concat ( newRepoList ) ;
}
2018-12-08 08:37:18 +08:00
this . setState ( {
isLoading : false ,
2020-08-17 11:53:33 +08:00
isLoadingMore : false ,
currentPage : page ,
hasNextPage : hasNextPage ,
2019-01-02 10:53:38 +08:00
repoList : Utils . sortRepos ( repoList , this . state . sortBy , this . state . sortOrder )
2018-12-08 08:37:18 +08:00
} ) ;
} ) . catch ( ( error ) => {
2019-12-05 15:45:16 +08:00
this . setState ( {
isLoading : false ,
2020-08-17 11:53:33 +08:00
isLoadingMore : false ,
2019-12-19 13:44:30 +08:00
errMessage : Utils . getErrorMsg ( error , true ) // true: show login tip if 403
2020-11-02 13:56:35 +08:00
} ) ;
2018-12-08 08:37:18 +08:00
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-08 08:37:18 +08:00
2018-12-08 16:35:00 +08:00
getEmptyTip = ( currentGroup ) => {
2018-12-08 08:37:18 +08:00
if ( currentGroup ) {
if ( currentGroup . parent _group _id === 0 ) {
2024-09-14 13:51:28 +08:00
return (
2024-08-20 11:19:11 +08:00
< EmptyTip
title = { gettext ( 'No libraries shared with this group' ) }
2024-11-20 20:36:24 +08:00
text = { gettext ( 'No libraries have been shared with this group yet. A library shared with a group can be accessed by all group members. You can share a library with a group in "My Libraries". You can also create a new library to be shared with this group by clicking the "New Library" item in the dropdown menu.' ) }
2024-08-20 11:19:11 +08:00
/ >
2018-12-08 08:37:18 +08:00
) ;
} else {
2024-07-18 11:58:42 +08:00
if ( currentGroup . admins . indexOf ( username ) == - 1 ) { // is a member of this group
2024-09-14 13:51:28 +08:00
return (
2024-10-23 07:43:02 +08:00
< EmptyTip title = { gettext ( 'No libraries' ) } / >
2018-12-08 08:37:18 +08:00
) ;
} else {
2024-09-14 13:51:28 +08:00
return (
2024-08-20 11:19:11 +08:00
< EmptyTip
title = { gettext ( 'No libraries' ) }
2024-11-20 20:36:24 +08:00
text = { gettext ( 'You can create libraries by clicking the "New Library" item in the dropdown menu.' ) }
2024-08-20 11:19:11 +08:00
/ >
2018-12-08 08:37:18 +08:00
) ;
}
}
}
2024-09-14 13:51:28 +08:00
return null ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-08 08:37:18 +08:00
2018-12-10 17:59:26 +08:00
onCreateRepoToggle = ( ) => {
2024-07-18 11:58:42 +08:00
this . setState ( { isCreateRepoDialogShow : ! this . state . isCreateRepoDialogShow } ) ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-10 17:59:26 +08:00
2018-12-16 11:17:17 +08:00
onCreateRepo = ( repo , groupOwnerType ) => {
2018-12-10 13:44:11 +08:00
let groupId = this . props . groupID ;
2018-12-16 11:17:17 +08:00
if ( groupOwnerType && groupOwnerType === 'department' ) {
2024-07-18 11:58:42 +08:00
seafileAPI . createGroupOwnedLibrary ( groupId , repo ) . then ( res => { // need modify endpoint api
2018-12-16 11:17:17 +08:00
let object = {
repo _id : res . data . id ,
repo _name : res . data . name ,
2018-12-17 15:12:10 +08:00
owner _name : res . data . group _name ,
2018-12-16 11:17:17 +08:00
owner _email : res . data . owner ,
permission : res . data . permission ,
mtime : res . data . mtime ,
size : res . data . size ,
encrypted : res . data . encrypted ,
} ;
2018-12-18 17:21:01 +08:00
let repo = new Repo ( object ) ;
2018-12-16 11:17:17 +08:00
let repoList = this . addRepoItem ( repo ) ;
2024-07-18 11:58:42 +08:00
this . setState ( { repoList : repoList } ) ;
2019-07-16 10:01:09 +08:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2018-12-16 11:17:17 +08:00
} ) ;
} else {
seafileAPI . createGroupRepo ( groupId , repo ) . then ( res => {
2018-12-18 17:21:01 +08:00
let repo = new Repo ( res . data ) ;
2018-12-16 11:17:17 +08:00
let repoList = this . addRepoItem ( repo ) ;
2024-07-18 11:58:42 +08:00
this . setState ( { repoList : repoList } ) ;
2019-07-16 10:01:09 +08:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2018-12-16 11:17:17 +08:00
} ) ;
}
this . onCreateRepoToggle ( ) ;
2023-09-13 08:40:50 +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-10 13:44:11 +08:00
} ) ;
2024-07-18 11:58:42 +08:00
this . setState ( { repoList : repoList } ) ;
2024-09-14 13:51:28 +08:00
this . loadGroup ( this . props . groupID ) ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-10 13:44:11 +08:00
2024-10-22 17:53:40 +08:00
onItemTransfer = ( repoId , groupID , owner ) => {
let repoList = this . state . repoList . filter ( item => {
return item . repo _id !== repoId ;
} ) ;
this . setState ( { repoList : repoList } ) ;
this . loadGroup ( this . props . groupID ) ;
} ;
2018-12-10 13:44:11 +08:00
addRepoItem = ( repo ) => {
let newRepoList = this . state . repoList . map ( item => { return item ; } ) ;
2018-12-22 15:18:53 +08:00
newRepoList . unshift ( repo ) ;
2018-12-10 13:44:11 +08:00
return newRepoList ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-10 13:44:11 +08:00
2018-12-10 18:37:59 +08:00
onItemUnshare = ( repo ) => {
2018-12-10 17:59:26 +08:00
let group = this . state . currentGroup ;
2019-07-02 15:36:08 +08:00
seafileAPI . unshareRepoToGroup ( repo . repo _id , group . id ) . then ( ( ) => {
2018-12-10 17:59:26 +08:00
let repoList = this . state . repoList . filter ( item => {
return item . repo _id !== repo . repo _id ;
} ) ;
2024-07-18 11:58:42 +08:00
this . setState ( { repoList : repoList } ) ;
2019-07-01 15:41:30 +08:00
this . loadGroup ( group . id ) ;
2019-07-16 10:01:09 +08:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2018-12-10 17:59:26 +08:00
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-10 17:59:26 +08:00
2019-02-11 15:22:42 +08:00
onItemRename = ( repo , newName ) => {
seafileAPI . renameGroupOwnedLibrary ( this . props . groupID , 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 ;
} ) ;
2024-07-18 11:58:42 +08:00
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
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-02-11 15:22:42 +08:00
2023-02-11 17:40:43 +08:00
onMonitorRepo = ( repo , monitored ) => {
let repoList = this . state . repoList . map ( item => {
if ( item . repo _id === repo . repo _id ) {
item . monitored = monitored ;
}
return item ;
} ) ;
2024-07-18 11:58:42 +08:00
this . setState ( { repoList : repoList } ) ;
2023-09-13 08:40:50 +08:00
} ;
2023-02-11 17:40:43 +08:00
2018-12-19 10:44:23 +08:00
toggleDismissGroupDialog = ( ) => {
this . setState ( {
2018-12-29 11:43:07 +08:00
showDismissGroupDialog : ! this . state . showDismissGroupDialog ,
showGroupDropdown : false ,
2018-12-19 10:44:23 +08:00
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-19 10:44:23 +08:00
toggleRenameGroupDialog = ( ) => {
this . setState ( {
2018-12-29 11:43:07 +08:00
showRenameGroupDialog : ! this . state . showRenameGroupDialog ,
showGroupDropdown : false ,
2018-12-19 10:44:23 +08:00
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-13 14:40:09 +08:00
2018-12-24 18:25:12 +08:00
toggleTransferGroupDialog = ( ) => {
this . setState ( {
2018-12-29 11:43:07 +08:00
showTransferGroupDialog : ! this . state . showTransferGroupDialog ,
showGroupDropdown : false ,
2018-12-24 18:25:12 +08:00
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-24 18:25:12 +08:00
2024-07-18 11:58:42 +08:00
toggleImportMembersDialog = ( ) => {
2021-02-10 09:59:32 +08:00
this . setState ( {
showImportMembersDialog : ! this . state . showImportMembersDialog
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2021-02-10 09:59:32 +08:00
2024-07-18 11:58:42 +08:00
importMembersInBatch = ( file ) => {
2021-02-10 09:59:32 +08:00
toaster . notify ( gettext ( 'It may take some time, please wait.' ) ) ;
seafileAPI . importGroupMembersViaFile ( this . state . currentGroup . id , file ) . then ( ( res ) => {
2023-09-13 08:40:50 +08:00
res . data . failed . forEach ( item => {
2024-09-14 13:51:28 +08:00
toaster . danger ( ` ${ item . email } : ${ item . error _msg } ` ) ;
2021-02-10 09:59:32 +08:00
} ) ;
} ) . catch ( ( error ) => {
let errMsg = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMsg ) ;
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-24 18:25:12 +08:00
toggleManageMembersDialog = ( ) => {
this . setState ( {
2018-12-29 11:43:07 +08:00
showManageMembersDialog : ! this . state . showManageMembersDialog ,
showGroupDropdown : false ,
2018-12-24 18:25:12 +08:00
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2018-12-24 18:25:12 +08:00
2019-07-04 13:49:16 +08:00
toggleLeaveGroupDialog = ( ) => {
this . setState ( {
2019-07-05 11:05:26 +08:00
isLeaveGroupDialogOpen : ! this . state . isLeaveGroupDialogOpen ,
2019-07-04 13:49:16 +08:00
showGroupDropdown : false ,
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-07-04 13:49:16 +08:00
2019-01-02 10:53:38 +08:00
sortItems = ( sortBy , sortOrder ) => {
2019-04-12 14:30:08 +08:00
cookie . save ( 'seafile-repo-dir-sort-by' , sortBy ) ;
cookie . save ( 'seafile-repo-dir-sort-order' , sortOrder ) ;
2019-01-02 10:53:38 +08:00
this . setState ( {
2024-09-14 13:51:28 +08:00
sortBy ,
sortOrder ,
2019-01-02 10:53:38 +08:00
repoList : Utils . sortRepos ( this . state . repoList , sortBy , sortOrder )
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-01-02 10:53:38 +08:00
2019-03-07 16:40:01 +08:00
translateRole = ( role ) => {
if ( role === 'Admin' ) {
return gettext ( 'Admin' ) ;
2020-11-02 13:56:35 +08:00
}
2019-03-07 16:40:01 +08:00
else if ( role === 'Member' ) {
return gettext ( 'Member' ) ;
}
else if ( role === 'Owner' ) {
return gettext ( 'Owner' ) ;
}
2023-09-13 08:40:50 +08:00
} ;
2019-03-07 16:40:01 +08:00
2019-07-18 20:21:50 +08:00
toggleSortOptionsDialog = ( ) => {
this . setState ( {
isSortOptionsDialogOpen : ! this . state . isSortOptionsDialogOpen
} ) ;
2023-09-13 08:40:50 +08:00
} ;
2019-07-18 20:21:50 +08:00
2020-08-17 11:53:33 +08:00
handleScroll = ( event ) => {
// isLoadingMore: to avoid repeated request
const { currentPage , hasNextPage , isLoadingMore } = this . state ;
if ( hasNextPage && ! isLoadingMore ) {
const clientHeight = event . target . clientHeight ;
const scrollHeight = event . target . scrollHeight ;
2024-07-18 11:58:42 +08:00
const scrollTop = event . target . scrollTop ;
2020-08-17 11:53:33 +08:00
const isBottom = ( clientHeight + scrollTop + 1 >= scrollHeight ) ;
if ( isBottom ) { // scroll to the bottom
2024-07-18 11:58:42 +08:00
this . setState ( { isLoadingMore : true } , ( ) => {
2020-08-17 11:53:33 +08:00
this . loadRepos ( currentPage + 1 ) ;
2020-11-02 13:56:35 +08:00
} ) ;
}
}
2023-09-13 08:40:50 +08:00
} ;
2020-08-17 11:53:33 +08:00
2024-06-21 17:32:03 +08:00
toggleMembersDialog = ( ) => {
this . setState ( {
isMembersDialogOpen : ! this . state . isMembersDialogOpen
} ) ;
} ;
getOpList = ( ) => {
const { currentGroup , isDepartmentGroup , isStaff , isOwner } = this . state ;
const opList = [ ] ;
if ( ( ! isDepartmentGroup && canAddRepo ) ||
( isDepartmentGroup && isStaff ) ) {
2024-09-19 17:40:38 +08:00
opList . push ( { 'text' : gettext ( 'New Library' ) , 'onClick' : this . onCreateRepoToggle } , 'Divider' ) ;
2024-06-21 17:32:03 +08:00
}
2024-07-18 11:58:42 +08:00
opList . push ( { 'text' : gettext ( 'Members' ) , 'onClick' : this . toggleMembersDialog } ) ;
2024-06-21 17:32:03 +08:00
if ( currentGroup ) {
if ( isStaff || isOwner ) {
2024-09-19 17:40:38 +08:00
opList . push ( { 'text' : gettext ( 'Import members' ) , 'onClick' : this . toggleImportMembersDialog } ) ;
opList . push ( { 'text' : gettext ( 'Manage members' ) , 'onClick' : this . toggleManageMembersDialog } ) ;
opList . push ( 'Divider' ) ;
2024-07-18 11:58:42 +08:00
opList . push ( { 'text' : gettext ( 'Rename' ) , 'onClick' : this . toggleRenameGroupDialog } ) ;
2024-06-21 17:32:03 +08:00
if ( isOwner ) {
2024-07-18 11:58:42 +08:00
opList . push ( { 'text' : gettext ( 'Transfer' ) , 'onClick' : this . toggleTransferGroupDialog } ) ;
2019-09-04 15:52:24 +08:00
}
2024-06-21 17:32:03 +08:00
if ( isOwner ) {
2024-07-18 11:58:42 +08:00
opList . push ( { 'text' : gettext ( 'Delete group' ) , 'onClick' : this . toggleDismissGroupDialog } ) ;
2024-06-21 17:32:03 +08:00
}
}
if ( ! isOwner && ! isDepartmentGroup ) {
2024-07-18 11:58:42 +08:00
opList . push ( { 'text' : gettext ( 'Leave group' ) , 'onClick' : this . toggleLeaveGroupDialog } ) ;
2019-09-04 15:52:24 +08:00
}
}
2024-06-21 17:32:03 +08:00
return opList ;
} ;
2024-11-25 10:23:42 +08:00
switchViewMode = ( newMode ) => {
this . setState ( {
currentViewMode : newMode
} , ( ) => {
localStorage . setItem ( 'sf_repo_list_view_mode' , newMode ) ;
} ) ;
} ;
onSelectSortOption = ( sortOption ) => {
const [ sortBy , sortOrder ] = sortOption . value . split ( '-' ) ;
this . setState ( { sortBy , sortOrder } , ( ) => {
this . sortItems ( sortBy , sortOrder ) ;
} ) ;
} ;
2025-01-13 18:18:58 +08:00
toggleDepartmentDetailDialog = ( ) => {
this . setState ( {
isShowDepartmentDetailDialog : ! this . state . isShowDepartmentDetailDialog
} ) ;
} ;
2024-06-21 17:32:03 +08:00
render ( ) {
2024-11-25 10:23:42 +08:00
const {
isLoading , repoList , errMessage , emptyTip ,
currentGroup , isDepartmentGroup , isMembersDialogOpen ,
currentViewMode , sortBy , sortOrder
} = this . state ;
2024-06-21 17:32:03 +08:00
2019-07-01 15:41:30 +08:00
let useRate = 0 ;
if ( isDepartmentGroup && currentGroup . group _quota ) {
useRate = currentGroup . group _quota _usage / currentGroup . group _quota * 100 + '%' ;
}
2024-06-21 17:32:03 +08:00
const opList = this . getOpList ( ) ;
2018-12-08 08:37:18 +08:00
return (
2018-12-10 13:44:11 +08:00
< Fragment >
2018-12-29 18:25:18 +08:00
< div className = "main-panel-center flex-row" >
2018-12-10 13:44:11 +08:00
< div className = "cur-view-container" >
< div className = "cur-view-path" >
2019-05-05 13:16:32 +08:00
{ currentGroup && (
2018-12-10 18:12:46 +08:00
< Fragment >
2024-06-21 17:32:03 +08:00
< div className = "sf-heading d-flex align-items-center" >
{ isDepartmentGroup &&
< span className = "sf3-font-department sf3-font nav-icon" title = { gettext ( 'This is a special group representing a department.' ) } > < / s p a n >
}
2018-12-10 18:12:46 +08:00
< span > { currentGroup . name } < / s p a n >
2025-01-21 13:39:10 +08:00
< SingleDropdownToolbar opList = { opList } / >
2024-06-21 17:32:03 +08:00
< / d i v >
2024-11-25 10:23:42 +08:00
< div className = "path-tool d-flex align-items-center" >
2019-07-01 18:40:49 +08:00
{ isDepartmentGroup && (
2024-06-21 17:32:03 +08:00
< >
2019-07-01 18:40:49 +08:00
{ currentGroup . group _quota > 0 &&
2024-11-25 10:23:42 +08:00
< div className = "department-usage-container mr-3" >
2019-07-01 18:40:49 +08:00
< div className = "department-usage" >
2024-07-18 11:58:42 +08:00
< span id = "quota-bar" className = "department-quota-bar" > < span id = "quota-usage" className = "usage" style = { { width : useRate } } > < / s p a n > < / s p a n >
2019-07-01 18:40:49 +08:00
< span className = "department-quota-info" > { Utils . bytesToSize ( currentGroup . group _quota _usage ) } / { Utils . bytesToSize ( currentGroup . group _quota ) } < / s p a n >
< / d i v >
2024-06-21 17:32:03 +08:00
< / d i v >
2019-07-01 18:40:49 +08:00
}
2024-06-21 17:32:03 +08:00
< / >
2018-12-10 18:12:46 +08:00
) }
2024-11-25 10:23:42 +08:00
{ Utils . isDesktop ( ) && (
< div className = "d-flex align-items-center" >
2025-01-22 14:38:40 +08:00
< AddRepos className = "mr-2" onAddRepo = { this . onCreateRepoToggle } / >
< ViewModes currentViewMode = { currentViewMode } switchViewMode = { this . switchViewMode } className = "mr-2" / >
2024-11-25 10:23:42 +08:00
< ReposSortMenu sortBy = { sortBy } sortOrder = { sortOrder } onSelectSortOption = { this . onSelectSortOption } / >
< / d i v >
) }
2024-09-14 13:51:28 +08:00
{ ( ! Utils . isDesktop ( ) && this . state . repoList . length > 0 ) &&
< span className = "sf3-font sf3-font-sort action-icon" onClick = { this . toggleSortOptionsDialog } > < / s p a n > }
2019-07-18 20:21:50 +08:00
{ this . state . isSortOptionsDialogOpen &&
< SortOptionsDialog
2024-11-25 10:23:42 +08:00
sortBy = { sortBy }
sortOrder = { sortOrder }
2019-07-18 20:21:50 +08:00
sortItems = { this . sortItems }
2024-11-25 10:23:42 +08:00
toggleDialog = { this . toggleSortOptionsDialog }
2019-07-18 20:21:50 +08:00
/ >
}
2018-12-10 18:12:46 +08:00
< / d i v >
< / F r a g m e n t >
) }
2018-12-10 13:44:11 +08:00
< / d i v >
2024-11-25 10:23:42 +08:00
< div
className = { classnames ( 'cur-view-content' , 'd-block' , 'repos-container' , { 'pt-3' : currentViewMode != LIST _MODE } ) }
onScroll = { this . handleScroll }
>
{ isLoading
? < Loading / >
: errMessage
? < p className = "error text-center mt-2" > { errMessage } < / p >
: repoList . length == 0
? emptyTip
: (
< SharedRepoListView
repoList = { this . state . repoList }
hasNextPage = { this . state . hasNextPage }
currentGroup = { this . state . currentGroup }
sortBy = { this . state . sortBy }
sortOrder = { this . state . sortOrder }
sortItems = { this . sortItems }
onItemUnshare = { this . onItemUnshare }
onItemDelete = { this . onItemDelete }
onItemRename = { this . onItemRename }
onMonitorRepo = { this . onMonitorRepo }
onTransferRepo = { this . onItemTransfer }
currentViewMode = { currentViewMode }
/ >
)
2018-12-10 13:44:11 +08:00
}
< / d i v >
< / d i v >
< / d i v >
2018-12-10 17:59:26 +08:00
{ this . state . isCreateRepoDialogShow && ! this . state . isDepartmentGroup && (
< ModalPortal >
2020-11-02 13:56:35 +08:00
< CreateRepoDialog
2018-12-10 17:59:26 +08:00
libraryType = { this . state . libraryType }
onCreateToggle = { this . onCreateRepoToggle }
onCreateRepo = { this . onCreateRepo }
/ >
< / M o d a l P o r t a l >
) }
{ this . state . isCreateRepoDialogShow && this . state . isDepartmentGroup &&
2020-11-02 13:56:35 +08:00
< CreateRepoDialog
2018-12-10 17:59:26 +08:00
onCreateToggle = { this . onCreateRepoToggle }
onCreateRepo = { this . onCreateRepo }
2019-06-24 17:01:14 +08:00
libraryType = 'department'
2018-12-10 17:59:26 +08:00
/ >
}
2024-06-21 17:32:03 +08:00
{ isMembersDialogOpen &&
< GroupMembersDialog
2024-08-27 12:02:42 +08:00
groupID = { this . props . groupID }
2024-06-21 17:32:03 +08:00
toggleDialog = { this . toggleMembersDialog }
/ >
}
2018-12-24 18:25:12 +08:00
{ this . state . showRenameGroupDialog &&
2018-12-19 10:44:23 +08:00
< RenameGroupDialog
showRenameGroupDialog = { this . state . showRenameGroupDialog }
toggleRenameGroupDialog = { this . toggleRenameGroupDialog }
loadGroup = { this . loadGroup }
groupID = { this . props . groupID }
onGroupChanged = { this . props . onGroupChanged }
2018-12-29 11:43:07 +08:00
currentGroupName = { currentGroup . name }
2018-12-19 10:44:23 +08:00
/ >
}
2018-12-24 18:25:12 +08:00
{ this . state . showDismissGroupDialog &&
2018-12-19 10:44:23 +08:00
< DismissGroupDialog
showDismissGroupDialog = { this . state . showDismissGroupDialog }
toggleDismissGroupDialog = { this . toggleDismissGroupDialog }
loadGroup = { this . loadGroup }
groupID = { this . props . groupID }
onGroupChanged = { this . props . onGroupChanged }
/ >
}
2018-12-24 18:25:12 +08:00
{ this . state . showTransferGroupDialog &&
< TransferGroupDialog
toggleTransferGroupDialog = { this . toggleTransferGroupDialog }
groupID = { this . props . groupID }
onGroupChanged = { this . props . onGroupChanged }
/ >
}
2021-02-10 09:59:32 +08:00
{ this . state . showImportMembersDialog &&
2018-12-24 18:25:12 +08:00
< ImportMembersDialog
toggleImportMembersDialog = { this . toggleImportMembersDialog }
2021-02-10 09:59:32 +08:00
importMembersInBatch = { this . importMembersInBatch }
2018-12-24 18:25:12 +08:00
/ >
2021-02-10 09:59:32 +08:00
}
2018-12-24 18:25:12 +08:00
{ this . state . showManageMembersDialog &&
< ManageMembersDialog
toggleManageMembersDialog = { this . toggleManageMembersDialog }
groupID = { this . props . groupID }
onGroupChanged = { this . props . onGroupChanged }
isOwner = { this . state . isOwner }
2025-01-13 18:18:58 +08:00
toggleDepartmentDetailDialog = { this . toggleDepartmentDetailDialog }
/ >
}
{ this . state . isShowDepartmentDetailDialog &&
< DepartmentDetailDialog
usedFor = 'add_group_member'
toggleDepartmentDetailDialog = { this . toggleDepartmentDetailDialog }
toggleManageMembersDialog = { this . toggleManageMembersDialog }
groupID = { this . props . groupID }
isOwner = { this . state . isOwner }
2018-12-24 18:25:12 +08:00
/ >
}
2019-07-05 11:05:26 +08:00
{ this . state . isLeaveGroupDialogOpen &&
2019-07-04 13:49:16 +08:00
< LeaveGroupDialog
toggleLeaveGroupDialog = { this . toggleLeaveGroupDialog }
groupID = { this . props . groupID }
onGroupChanged = { this . props . onGroupChanged }
/ >
}
2018-12-10 13:44:11 +08:00
< / F r a g m e n t >
2018-12-08 08:37:18 +08:00
) ;
}
}
GroupView . propTypes = propTypes ;
export default GroupView ;