2018-11-26 09:53:18 +00:00
import React , { Component } from 'react' ;
2018-12-26 08:07:22 +00:00
import { Link } from '@reach/router' ;
2018-11-19 03:53:44 +00:00
import { seafileAPI } from '../../utils/seafile-api' ;
import { Utils } from '../../utils/utils' ;
import { gettext , siteRoot , loginUrl , isPro } from '../../utils/constants' ;
2019-01-09 06:39:17 +00:00
import PermissionEditor from '../../components/select-editor/permission-editor' ;
2018-12-27 02:24:34 +00:00
import SharedRepoInfo from '../../models/shared-repo-info' ;
2018-11-19 03:53:44 +00:00
class Content extends Component {
2019-01-02 04:02:23 +00:00
sortByName = ( e ) => {
e . preventDefault ( ) ;
const sortBy = 'name' ;
const sortOrder = this . props . sortOrder == 'asc' ? 'desc' : 'asc' ;
this . props . sortItems ( sortBy , sortOrder ) ;
}
2018-11-19 03:53:44 +00:00
render ( ) {
2019-01-02 04:02:23 +00:00
const { loading , errorMsg , items , sortBy , sortOrder } = this . props ;
2018-11-19 03:53:44 +00:00
if ( loading ) {
return < span className = "loading-icon loading-tip" > < / s p a n > ;
} else if ( errorMsg ) {
return < p className = "error text-center" > { errorMsg } < / p > ;
} else {
const emptyTip = (
< div className = "empty-tip" >
< h2 > { gettext ( 'You have not shared any libraries' ) } < / h 2 >
< p > { gettext ( "You can share libraries with your friends and colleagues by clicking the share icon of your own libraries in your home page or creating a new library in groups you are in." ) } < / p >
< / d i v >
) ;
2019-01-02 04:02:23 +00:00
// sort
const sortByName = sortBy == 'name' ;
const sortIcon = sortOrder == 'asc' ? < span className = "fas fa-caret-up" > < / s p a n > : < s p a n c l a s s N a m e = " f a s f a - c a r e t - d o w n " > < / s p a n > ;
2018-11-19 03:53:44 +00:00
const table = (
2018-12-26 08:07:22 +00:00
< table className = "table-hover" >
2018-11-19 03:53:44 +00:00
< thead >
< tr >
2018-12-26 08:07:22 +00:00
< th width = "4%" > { /*icon*/ } < / t h >
2019-01-02 04:02:23 +00:00
< th width = "34%" > < a className = "d-block table-sort-op" href = "#" onClick = { this . sortByName } > { gettext ( 'Name' ) } { sortByName && sortIcon } < / a > < / t h >
2018-11-19 03:53:44 +00:00
< th width = "30%" > { gettext ( "Share To" ) } < / t h >
2018-12-26 08:07:22 +00:00
< th width = "24%" > { gettext ( "Permission" ) } < / t h >
2018-11-19 03:53:44 +00:00
< th width = "8%" > < / t h >
< / t r >
< / t h e a d >
2018-12-27 02:24:34 +00:00
< tbody >
{ items . map ( ( item , index ) => {
return ( < Item key = { index } item = { item } unshareFolder = { this . props . unshareFolder } / > ) ;
} ) }
< / t b o d y >
2018-11-19 03:53:44 +00:00
< / t a b l e >
) ;
return items . length ? table : emptyTip ;
}
}
}
class Item extends Component {
constructor ( props ) {
super ( props ) ;
2018-12-27 02:24:34 +00:00
let item = this . props . item ;
2018-11-19 03:53:44 +00:00
this . state = {
2018-12-27 02:24:34 +00:00
share _permission : item . share _permission ,
is _admin : item . is _admin ,
2018-11-19 03:53:44 +00:00
showOpIcon : false ,
unshared : false
} ;
2018-12-26 08:07:22 +00:00
this . permissions = [ 'rw' , 'r' ] ;
if ( isPro ) {
this . permissions = [ 'rw' , 'r' , 'cloud-edit' , 'preview' ] ;
}
2018-11-19 03:53:44 +00:00
}
2018-12-26 08:07:22 +00:00
onMouseEnter = ( ) => {
this . setState ( { showOpIcon : true } ) ;
2018-11-19 03:53:44 +00:00
}
2018-12-26 08:07:22 +00:00
onMouseLeave = ( ) => {
this . setState ( { showOpIcon : false } ) ;
2018-11-19 03:53:44 +00:00
}
2018-12-26 08:07:22 +00:00
changePerm = ( permission ) => {
2018-12-27 02:24:34 +00:00
const item = this . props . item ;
const share _type = item . share _type ;
2018-11-19 03:53:44 +00:00
let options = {
'share_type' : share _type ,
2018-12-27 02:24:34 +00:00
'permission' : permission
2018-11-19 03:53:44 +00:00
} ;
if ( share _type == 'personal' ) {
2018-12-27 02:24:34 +00:00
options . user = item . user _email ;
2018-11-19 03:53:44 +00:00
} else if ( share _type == 'group' ) {
2018-12-27 02:24:34 +00:00
options . group _id = item . group _id ;
} else if ( share _type === 'public' ) {
// nothing todo
}
seafileAPI . updateRepoSharePerm ( item . repo _id , options ) . then ( ( ) => {
2018-11-19 03:53:44 +00:00
this . setState ( {
2018-12-27 02:24:34 +00:00
share _permission : permission == 'admin' ? 'rw' : permission ,
is _admin : permission == 'admin' ,
2018-11-19 03:53:44 +00:00
} ) ;
// TODO: show feedback msg
// gettext("Successfully modified permission")
} ) . catch ( ( error ) => {
// TODO: show feedback msg
} ) ;
}
2018-12-27 02:24:34 +00:00
unshare = ( ) => {
this . props . unshareFolder ( this . props . item ) ;
}
2018-11-19 03:53:44 +00:00
2018-12-27 02:24:34 +00:00
getRepoParams = ( ) => {
let item = this . props . item ;
const { share _permission , is _admin } = this . state ;
2018-11-19 03:53:44 +00:00
let is _readonly = false ;
if ( share _permission == 'r' || share _permission == 'preview' ) {
is _readonly = true ;
}
2018-12-27 02:24:34 +00:00
let iconUrl = Utils . getLibIconUrl ( {
is _encrypted : item . encrypted ,
2018-11-19 03:53:44 +00:00
is _readonly : is _readonly ,
size : Utils . isHiDPI ( ) ? 48 : 24
} ) ;
2018-12-27 02:24:34 +00:00
let iconTitle = Utils . getLibIconTitle ( {
'encrypted' : item . encrypted ,
2018-11-19 03:53:44 +00:00
'is_admin' : is _admin ,
'permission' : share _permission
} ) ;
2018-12-27 02:24:34 +00:00
let repoUrl = ` ${ siteRoot } library/ ${ item . repo _id } / ${ item . repo _name } ` ;
return { iconUrl , iconTitle , repoUrl } ;
}
render ( ) {
let { iconUrl , iconTitle , repoUrl } = this . getRepoParams ( ) ;
let item = this . props . item ;
let { share _permission , is _admin } = this . state ;
2018-11-19 03:53:44 +00:00
let shareTo ;
2018-12-27 02:24:34 +00:00
const shareType = item . share _type ;
2018-11-19 03:53:44 +00:00
if ( shareType == 'personal' ) {
2018-12-27 02:24:34 +00:00
shareTo = < td title = { item . contact _email } > { item . user _name } < / t d > ;
2018-11-19 03:53:44 +00:00
} else if ( shareType == 'group' ) {
2018-12-27 02:24:34 +00:00
shareTo = < td > { item . group _name } < / t d > ;
2018-11-19 03:53:44 +00:00
} else if ( shareType == 'public' ) {
shareTo = < td > { gettext ( 'all members' ) } < / t d > ;
}
// show 'admin' perm or not
2018-12-27 02:24:34 +00:00
let showAdmin = isPro && ( item . share _type !== 'public' ) ;
if ( showAdmin && is _admin ) {
share _permission = 'admin' ;
2018-11-19 03:53:44 +00:00
}
let iconVisibility = this . state . showOpIcon ? '' : ' invisible' ;
2018-12-28 03:12:24 +00:00
let unshareIconClassName = 'unshare action-icon sf2-icon-x3' + iconVisibility ;
2018-11-19 03:53:44 +00:00
2018-12-27 02:24:34 +00:00
if ( showAdmin && this . permissions . indexOf ( 'admin' ) === - 1 ) {
2018-12-26 08:07:22 +00:00
this . permissions . splice ( 2 , 0 , 'admin' ) ; // add a item after 'r' permission;
}
2018-11-19 03:53:44 +00:00
2018-12-27 02:24:34 +00:00
return (
2018-12-26 08:07:22 +00:00
< tr onMouseEnter = { this . onMouseEnter } onMouseLeave = { this . onMouseLeave } >
2019-01-11 04:39:43 +00:00
< td > < img className = "icon" src = { iconUrl } title = { iconTitle } alt = { iconTitle } width = "24" / > < / t d >
2018-12-27 02:24:34 +00:00
< td > < Link to = { repoUrl } > { item . repo _name } < / L i n k > < / t d >
2018-11-19 03:53:44 +00:00
{ shareTo }
2018-12-26 08:07:22 +00:00
< td >
< PermissionEditor
isTextMode = { true }
isEditIconShow = { this . state . showOpIcon }
2018-12-27 02:24:34 +00:00
currentPermission = { share _permission }
2018-12-26 08:07:22 +00:00
permissions = { this . permissions }
onPermissionChangedHandler = { this . changePerm }
/ >
< / t d >
2018-11-19 03:53:44 +00:00
< td > < a href = "#" className = { unshareIconClassName } title = { gettext ( 'Unshare' ) } onClick = { this . unshare } > < / a > < / t d >
< / t r >
) ;
}
}
class ShareAdminLibraries extends Component {
2018-12-26 08:07:22 +00:00
2018-11-19 03:53:44 +00:00
constructor ( props ) {
super ( props ) ;
this . state = {
loading : true ,
errorMsg : '' ,
2019-01-02 04:02:23 +00:00
items : [ ] ,
sortBy : 'name' , // 'name' or 'time'
sortOrder : 'asc' // 'asc' or 'desc'
2018-11-19 03:53:44 +00:00
} ;
}
componentDidMount ( ) {
2018-11-19 06:26:23 +00:00
seafileAPI . listSharedRepos ( ) . then ( ( res ) => {
2018-11-19 03:53:44 +00:00
// res: {data: Array(2), status: 200, statusText: "OK", headers: {…}, config: {…}, …}
2018-12-27 02:24:34 +00:00
let items = res . data . map ( item => {
return new SharedRepoInfo ( item ) ;
} ) ;
2018-11-19 03:53:44 +00:00
this . setState ( {
loading : false ,
2019-01-02 04:02:23 +00:00
items : Utils . sortRepos ( items , this . state . sortBy , this . state . sortOrder )
2018-11-19 03:53:44 +00:00
} ) ;
} ) . catch ( ( error ) => {
if ( error . response ) {
if ( error . response . status == 403 ) {
this . setState ( {
loading : false ,
errorMsg : gettext ( "Permission denied" )
} ) ;
location . href = ` ${ loginUrl } ?next= ${ encodeURIComponent ( location . href ) } ` ;
} else {
this . setState ( {
loading : false ,
errorMsg : gettext ( "Error" )
} ) ;
}
} else {
this . setState ( {
loading : false ,
errorMsg : gettext ( "Please check the network." )
} ) ;
}
} ) ;
}
2018-12-27 02:24:34 +00:00
unshareFolder = ( item ) => {
const share _type = item . share _type ;
let options = {
'share_type' : share _type
} ;
if ( share _type == 'personal' ) {
options . user = item . user _email ;
} else if ( share _type == 'group' ) {
options . group _id = item . group _id ;
}
seafileAPI . unshareRepo ( item . repo _id , options ) . then ( ( res ) => {
let items = [ ] ;
if ( item . share _type === 'personal' ) {
items = this . state . items . filter ( repoItem => {
return ! ( repoItem . user _email === item . user _email && repoItem . repo _id === item . repo _id ) ;
} ) ;
} else if ( item . share _type === 'group' ) {
items = this . state . items . filter ( repoItem => {
return ! ( repoItem . group _id === item . group _id && repoItem . repo _id === item . repo _id ) ;
} ) ;
} else if ( item . share _type === 'public' ) {
items = this . state . items . filter ( repoItem => {
return ! ( repoItem . share _type === 'public' && repoItem . repo _id === item . repo _id ) ;
} ) ;
}
this . setState ( { items : items } ) ;
// TODO: show feedback msg
// gettext("Successfully deleted 1 item")
} ) . catch ( ( error ) => {
// TODO: show feedback msg
} ) ;
}
2019-01-02 04:02:23 +00:00
sortItems = ( sortBy , sortOrder ) => {
this . setState ( {
sortBy : sortBy ,
sortOrder : sortOrder ,
items : Utils . sortRepos ( this . state . items , sortBy , sortOrder )
} ) ;
}
2018-11-19 03:53:44 +00:00
render ( ) {
return (
2018-11-26 09:53:18 +00:00
< div className = "main-panel-center" >
< div className = "cur-view-container" id = "share-admin-libs" >
< div className = "cur-view-path" >
< h3 className = "sf-heading" > { gettext ( "Libraries" ) } < / h 3 >
< / d i v >
< div className = "cur-view-content" >
2018-12-27 02:24:34 +00:00
< Content
errorMsg = { this . state . errorMsg }
loading = { this . state . loading }
items = { this . state . items }
2019-01-02 04:02:23 +00:00
sortBy = { this . state . sortBy }
sortOrder = { this . state . sortOrder }
sortItems = { this . sortItems }
2018-12-27 02:24:34 +00:00
unshareFolder = { this . unshareFolder }
/ >
2018-11-26 06:00:32 +00:00
< / d i v >
2018-11-19 03:53:44 +00:00
< / d i v >
2018-11-26 09:53:18 +00:00
< / d i v >
2018-11-19 03:53:44 +00:00
) ;
}
}
export default ShareAdminLibraries ;