2024-04-19 14:51:41 +08:00
import React , { Fragment } from 'react' ;
import PropTypes from 'prop-types' ;
import cookie from 'react-cookies' ;
import { seafileAPI } from '../../utils/seafile-api' ;
import { gettext , canAddPublicRepo } from '../../utils/constants' ;
import { Utils } from '../../utils/utils' ;
import Repo from '../../models/repo' ;
import toaster from '../../components/toast' ;
import Loading from '../../components/loading' ;
import EmptyTip from '../../components/empty-tip' ;
import SharedRepoListView from '../../components/shared-repo-list-view/shared-repo-list-view' ;
import SortOptionsDialog from '../../components/dialog/sort-options' ;
2024-07-09 15:08:47 +08:00
import SingleDropdownToolbar from '../../components/toolbar/single-dropdown-toolbar' ;
import ModalPortal from '../../components/modal-portal' ;
import CreateRepoDialog from '../../components/dialog/create-repo-dialog' ;
import ShareRepoDialog from '../../components/dialog/share-repo-dialog' ;
2024-09-10 11:46:50 +08:00
import { LIST _MODE } from '../../components/dir-view-mode/constants' ;
2024-04-19 14:51:41 +08:00
const propTypes = {
2024-06-17 09:32:05 +08:00
currentViewMode : PropTypes . string ,
2024-05-16 16:19:49 +08:00
inAllLibs : PropTypes . bool ,
repoList : PropTypes . array ,
2024-04-19 14:51:41 +08:00
} ;
class PublicSharedView extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = {
isLoading : true ,
errMessage : '' ,
repoList : [ ] ,
2024-07-09 15:08:47 +08:00
isCreateRepoDialogOpen : false ,
isSelectRepoDialogOpen : false ,
2024-04-19 14:51:41 +08:00
sortBy : cookie . load ( 'seafile-repo-dir-sort-by' ) || 'name' , // 'name' or 'time' or 'size'
sortOrder : cookie . load ( 'seafile-repo-dir-sort-order' ) || 'asc' , // 'asc' or 'desc'
isSortOptionsDialogOpen : false ,
libraryType : 'public' ,
} ;
}
componentDidMount ( ) {
2024-05-16 16:19:49 +08:00
if ( ! this . props . repoList ) {
2024-07-18 11:58:42 +08:00
seafileAPI . listRepos ( { type : 'public' } ) . then ( ( res ) => {
2024-05-16 16:19:49 +08:00
let repoList = res . data . repos . map ( ( item ) => {
return new Repo ( item ) ;
} ) ;
this . setState ( {
isLoading : false ,
repoList : Utils . sortRepos ( repoList , this . state . sortBy , this . state . sortOrder )
} ) ;
} ) . catch ( ( error ) => {
this . setState ( {
isLoading : false ,
errMessage : Utils . getErrorMsg ( error , true )
} ) ;
2024-04-19 14:51:41 +08:00
} ) ;
2024-05-16 16:19:49 +08:00
} else {
2024-04-19 14:51:41 +08:00
this . setState ( {
isLoading : false ,
2024-05-16 16:19:49 +08:00
repoList : Utils . sortRepos ( this . props . repoList , this . state . sortBy , this . state . sortOrder )
2024-04-19 14:51:41 +08:00
} ) ;
2024-05-16 16:19:49 +08:00
}
2024-04-19 14:51:41 +08:00
}
onItemUnshare = ( repo ) => {
2024-07-18 11:58:42 +08:00
seafileAPI . unshareRepo ( repo . repo _id , { share _type : 'public' } ) . then ( ( ) => {
2024-04-19 14:51:41 +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 } ) ;
2024-04-19 14:51:41 +08:00
let message = gettext ( 'Successfully unshared {name}' ) . replace ( '{name}' , repo . repo _name ) ;
toaster . success ( message ) ;
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
if ( errMessage === gettext ( 'Error' ) ) {
errMessage = gettext ( 'Failed to unshare {name}' ) . replace ( '{name}' , repo . repo _name ) ;
}
toaster ( errMessage ) ;
} ) ;
} ;
onItemDelete = ( ) => {
// todo need to optimized
} ;
addRepoItem = ( repo ) => {
let isExist = false ;
let repoIndex = 0 ;
let repoList = this . state . repoList ;
for ( let i = 0 ; i < repoList . length ; i ++ ) {
if ( repo . repo _id === repoList [ i ] . repo _id ) {
isExist = true ;
repoIndex = i ;
break ;
}
}
if ( isExist ) {
this . state . repoList . splice ( repoIndex , 1 ) ;
}
let newRepoList = this . state . repoList . map ( item => { return item ; } ) ;
newRepoList . unshift ( repo ) ;
2024-07-18 11:58:42 +08:00
this . setState ( { repoList : newRepoList } ) ;
2024-04-19 14:51:41 +08:00
} ;
sortItems = ( sortBy , sortOrder ) => {
cookie . save ( 'seafile-repo-dir-sort-by' , sortBy ) ;
cookie . save ( 'seafile-repo-dir-sort-order' , sortOrder ) ;
this . setState ( {
sortBy : sortBy ,
sortOrder : sortOrder ,
repoList : Utils . sortRepos ( this . state . repoList , sortBy , sortOrder )
} ) ;
} ;
toggleSortOptionsDialog = ( ) => {
this . setState ( {
isSortOptionsDialogOpen : ! this . state . isSortOptionsDialogOpen
} ) ;
} ;
renderContent = ( ) => {
2024-09-10 11:46:50 +08:00
const { inAllLibs = false , currentViewMode = LIST _MODE } = this . props ; // inAllLibs: in 'All Libs'('Files') page
2024-05-16 14:51:07 +08:00
const { errMessage } = this . state ;
const emptyTip = inAllLibs ?
2024-06-17 09:32:05 +08:00
< p className = { ` libraries-empty-tip-in- ${ currentViewMode } -mode ` } > { gettext ( 'No public libraries' ) } < / p > : (
2024-08-20 11:19:11 +08:00
< EmptyTip
title = { gettext ( 'No public libraries' ) }
text = { gettext ( 'No public libraries have been created yet. A public library is accessible by all users. You can create a public library by clicking the "Add Library" button in the menu bar.' ) }
>
2024-05-16 14:51:07 +08:00
< / E m p t y T i p >
) ;
2024-04-19 14:51:41 +08:00
return (
< >
{ this . state . isLoading && < Loading / > }
{ ( ! this . state . isLoading && errMessage ) && errMessage }
{ ( ! this . state . isLoading && this . state . repoList . length === 0 ) && emptyTip }
{ ( ! this . state . isLoading && this . state . repoList . length > 0 ) &&
< SharedRepoListView
libraryType = { this . state . libraryType }
repoList = { this . state . repoList }
sortBy = { this . state . sortBy }
sortOrder = { this . state . sortOrder }
sortItems = { this . sortItems }
onItemUnshare = { this . onItemUnshare }
onItemDelete = { this . onItemDelete }
theadHidden = { inAllLibs }
2024-06-17 09:32:05 +08:00
currentViewMode = { currentViewMode }
2024-08-12 12:14:03 +08:00
inAllLibs = { inAllLibs }
2024-04-19 14:51:41 +08:00
/ >
}
< / >
) ;
} ;
renderSortIconInMobile = ( ) => {
return (
< >
{ ( ! Utils . isDesktop ( ) && this . state . repoList . length > 0 ) && < span className = "sf3-font sf3-font-sort action-icon" onClick = { this . toggleSortOptionsDialog } > < / s p a n > }
< / >
) ;
} ;
2024-07-09 15:08:47 +08:00
onCreateRepoToggle = ( ) => {
2024-07-18 11:58:42 +08:00
this . setState ( { isCreateRepoDialogOpen : ! this . state . isCreateRepoDialogOpen } ) ;
2024-07-09 15:08:47 +08:00
} ;
onSelectRepoToggle = ( ) => {
2024-07-18 11:58:42 +08:00
this . setState ( { isSelectRepoDialogOpen : ! this . state . isSelectRepoDialogOpen } ) ;
2024-07-09 15:08:47 +08:00
} ;
onCreateRepo = ( repo ) => {
this . onCreateRepoToggle ( ) ;
seafileAPI . createPublicRepo ( repo ) . then ( res => {
let object = {
repo _id : res . data . id ,
repo _name : res . data . name ,
permission : res . data . permission ,
size : res . data . size ,
owner _name : res . data . owner _name ,
owner _email : res . data . owner ,
mtime : res . data . mtime ,
encrypted : res . data . encrypted ,
} ;
let repo = new Repo ( object ) ;
this . addRepoItem ( repo ) ;
} ) . catch ( ( error ) => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
} ) ;
} ;
onRepoSelectedHandler = ( selectedRepoList ) => {
selectedRepoList . forEach ( repo => {
2024-07-18 11:58:42 +08:00
seafileAPI . selectOwnedRepoToPublic ( repo . repo _id , { share _type : 'public' , permission : repo . sharePermission } ) . then ( ( ) => {
2024-07-09 15:08:47 +08:00
this . addRepoItem ( repo ) ;
} ) . catch ( ( error ) => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
} ) ;
} ) ;
} ;
2024-04-19 14:51:41 +08:00
render ( ) {
2024-09-10 11:46:50 +08:00
const { inAllLibs = false , currentViewMode = LIST _MODE } = this . props ; // inAllLibs: in 'All Libs'('Files') page
2024-04-19 14:51:41 +08:00
if ( inAllLibs ) {
return (
< >
2024-09-10 11:46:50 +08:00
< div className = { ` d-flex justify-content-between mt-3 py-1 ${ currentViewMode == LIST _MODE ? 'sf-border-bottom' : '' } ` } >
2024-04-26 21:51:50 +08:00
< h4 className = "sf-heading m-0" >
< span className = "sf3-font-share-with-all sf3-font nav-icon" aria - hidden = "true" > < / s p a n >
{ gettext ( 'Shared with all' ) }
< / h 4 >
2024-04-19 14:51:41 +08:00
{ this . renderSortIconInMobile ( ) }
< / d i v >
{ this . renderContent ( ) }
< / >
) ;
}
return (
< Fragment >
< div className = "main-panel-center" >
< div className = "cur-view-container" >
< div className = "cur-view-path" >
2024-07-09 15:08:47 +08:00
< h3 className = "sf-heading m-0" >
{ gettext ( 'Shared with all' ) }
{ canAddPublicRepo &&
< SingleDropdownToolbar
opList = { [
2024-07-18 11:58:42 +08:00
{ 'text' : gettext ( 'Share existing libraries' ) , 'onClick' : this . onSelectRepoToggle } ,
{ 'text' : gettext ( 'New Library' ) , 'onClick' : this . onCreateRepoToggle }
2024-07-09 15:08:47 +08:00
] }
/ >
}
< / h 3 >
2024-04-19 14:51:41 +08:00
{ this . renderSortIconInMobile ( ) }
< / d i v >
< div className = "cur-view-content" >
{ this . renderContent ( ) }
< / d i v >
< / d i v >
< / d i v >
{ this . state . isSortOptionsDialogOpen &&
< SortOptionsDialog
toggleDialog = { this . toggleSortOptionsDialog }
sortBy = { this . state . sortBy }
sortOrder = { this . state . sortOrder }
sortItems = { this . sortItems }
/ >
}
2024-07-09 15:08:47 +08:00
{ this . state . isCreateRepoDialogOpen && (
< ModalPortal >
< CreateRepoDialog
libraryType = { this . state . libraryType }
onCreateToggle = { this . onCreateRepoToggle }
onCreateRepo = { this . onCreateRepo }
/ >
< / M o d a l P o r t a l >
) }
{ this . state . isSelectRepoDialogOpen && (
< ModalPortal >
< ShareRepoDialog
onRepoSelectedHandler = { this . onRepoSelectedHandler }
onShareRepoDialogClose = { this . onSelectRepoToggle }
/ >
< / M o d a l P o r t a l >
) }
2024-04-19 14:51:41 +08:00
< / F r a g m e n t >
) ;
}
}
PublicSharedView . propTypes = propTypes ;
export default PublicSharedView ;