2019-05-15 00:01:48 +00:00
import React , { Fragment } from 'react' ;
import PropTypes from 'prop-types' ;
import { Button , Input , InputGroup , InputGroupAddon } from 'reactstrap' ;
import { gettext , isPro , siteRoot } from '../../utils/constants' ;
2023-09-04 01:50:14 +00:00
import { seafileAPI } from '../../utils/seafile-api' ;
import { Utils } from '../../utils/utils' ;
2019-05-15 00:01:48 +00:00
import SharePermissionEditor from '../select-editor/share-permission-editor' ;
2024-09-23 01:48:43 +00:00
import FileChooser from '../file-chooser' ;
2023-09-18 02:01:30 +00:00
import { SeahubSelect , NoGroupMessage } from '../common/select' ;
2024-07-24 06:59:26 +00:00
import toaster from '../../components/toast' ;
2019-05-15 00:01:48 +00:00
class GroupItem extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = {
isOperationShow : false
} ;
}
2020-11-02 05:56:35 +00:00
2019-05-15 00:01:48 +00:00
onMouseEnter = ( ) => {
2024-07-18 03:58:42 +00:00
this . setState ( { isOperationShow : true } ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
onMouseLeave = ( ) => {
2024-07-18 03:58:42 +00:00
this . setState ( { isOperationShow : false } ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
deleteGroupPermissionItem = ( ) => {
let item = this . props . item ;
this . props . deleteGroupPermissionItem ( item ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
onChangeGroupPermission = ( permission ) => {
let item = this . props . item ;
this . props . onChangeGroupPermission ( item , permission ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
render ( ) {
let item = this . props . item ;
return (
2021-10-08 08:52:17 +00:00
< tr onMouseEnter = { this . onMouseEnter } onMouseLeave = { this . onMouseLeave } onFocus = { this . onMouseEnter } >
2019-05-15 00:01:48 +00:00
< td >
2023-09-13 00:40:50 +00:00
< a href = { ` ${ siteRoot } group/ ${ item . group _id } / ` } target = "_blank" rel = "noreferrer" > { item . group _name } < / a >
2019-05-15 00:01:48 +00:00
< / t d >
{ this . props . showPath &&
< td >
< a href = { ` ${ siteRoot } library/ ${ item . repo _id } / ${ Utils . encodePath ( this . props . repoName + item . folder _path ) } ` } > { item . folder _name } < / a >
< / t d >
}
< td >
2020-11-02 05:56:35 +00:00
< SharePermissionEditor
2019-05-15 00:01:48 +00:00
isTextMode = { true }
2023-08-24 04:10:05 +00:00
autoFocus = { true }
2019-05-15 00:01:48 +00:00
isEditIconShow = { this . state . isOperationShow }
currentPermission = { item . permission }
permissions = { this . props . permissions }
onPermissionChanged = { this . onChangeGroupPermission }
/ >
< / t d >
< td >
< span
2021-10-08 08:52:17 +00:00
tabIndex = "0"
role = "button"
2019-05-15 00:01:48 +00:00
className = { ` sf2-icon-x3 action-icon ${ this . state . isOperationShow ? '' : 'hide' } ` }
2020-11-02 05:56:35 +00:00
onClick = { this . deleteGroupPermissionItem }
2021-10-08 08:52:17 +00:00
onKeyDown = { Utils . onKeyDown }
2019-05-15 00:01:48 +00:00
title = { gettext ( 'Delete' ) }
2021-10-08 08:52:17 +00:00
aria - label = { gettext ( 'Delete' ) }
2019-05-15 00:01:48 +00:00
>
< / s p a n >
< / t d >
< / t r >
) ;
}
}
2023-09-13 00:40:50 +00:00
GroupItem . propTypes = {
item : PropTypes . object . isRequired ,
permissions : PropTypes . array . isRequired ,
showPath : PropTypes . bool . isRequired ,
2024-07-24 06:59:26 +00:00
repoName : PropTypes . string ,
2023-09-13 00:40:50 +00:00
deleteGroupPermissionItem : PropTypes . func . isRequired ,
onChangeGroupPermission : PropTypes . func . isRequired ,
} ;
2019-05-15 00:01:48 +00:00
const propTypes = {
2019-05-16 09:28:04 +00:00
repoID : PropTypes . string . isRequired ,
2023-09-13 00:40:50 +00:00
isDepartmentRepo : PropTypes . bool ,
repoName : PropTypes . string ,
folderPath : PropTypes . string ,
2019-05-15 00:01:48 +00:00
} ;
2023-11-21 07:35:17 +00:00
class LibSubFolderSetGroupPermissionDialog extends React . Component {
2019-05-15 00:01:48 +00:00
constructor ( props ) {
super ( props ) ;
this . state = {
selectedOption : null ,
errorMsg : [ ] ,
permission : 'rw' ,
groupPermissionItems : [ ] ,
folderPath : '' ,
showFileChooser : false
} ;
this . options = [ ] ;
if ( ! isPro ) {
this . permissions = [ 'r' , 'rw' ] ;
} else {
2023-08-31 02:09:25 +00:00
this . permissions = [ 'r' , 'rw' , 'cloud-edit' , 'preview' , 'invisible' ] ;
2019-05-15 00:01:48 +00:00
}
}
handleSelectChange = ( option ) => {
2024-07-18 03:58:42 +00:00
this . setState ( { selectedOption : option } ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
componentDidMount ( ) {
this . loadOptions ( ) ;
this . listGroupPermissionItems ( ) ;
}
loadOptions = ( ) => {
seafileAPI . shareableGroups ( ) . then ( ( res ) => {
this . options = res . data . map ( ( item , index ) => {
return {
id : item . id ,
label : item . name ,
value : item . name
} ;
} ) ;
2024-07-24 06:59:26 +00:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2019-05-15 00:01:48 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
listGroupPermissionItems = ( ) => {
2019-05-16 09:28:04 +00:00
const { isDepartmentRepo , repoID , folderPath } = this . props ;
2019-05-17 01:14:26 +00:00
const request = isDepartmentRepo ?
seafileAPI . listDepartmentRepoGroupFolderPerm ( repoID , folderPath ) :
seafileAPI . listGroupFolderPerm ( repoID , folderPath ) ;
request . then ( ( res ) => {
2019-05-15 00:01:48 +00:00
if ( res . data . length !== 0 ) {
this . setState ( {
groupPermissionItems : res . data
} ) ;
}
2024-07-24 06:59:26 +00:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2019-05-15 00:01:48 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
setPermission = ( permission ) => {
2024-07-18 03:58:42 +00:00
this . setState ( { permission : permission } ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
addGroupFolderPerm = ( ) => {
const { selectedOption } = this . state ;
const folderPath = this . props . folderPath || this . state . folderPath ;
if ( ! selectedOption || ! folderPath ) {
return false ;
}
2019-05-17 01:14:26 +00:00
const request = this . props . isDepartmentRepo ?
seafileAPI . addDepartmentRepoGroupFolderPerm ( this . props . repoID , this . state . permission , folderPath , selectedOption . id ) :
2019-06-24 07:44:22 +00:00
seafileAPI . addGroupFolderPerm ( this . props . repoID , this . state . permission , folderPath , selectedOption . id ) ;
2019-05-17 01:14:26 +00:00
request . then ( res => {
2019-05-15 00:01:48 +00:00
let errorMsg = [ ] ;
if ( res . data . failed . length > 0 ) {
for ( let i = 0 ; i < res . data . failed . length ; i ++ ) {
errorMsg [ i ] = res . data . failed [ i ] ;
}
}
this . setState ( {
errorMsg : errorMsg ,
groupPermissionItems : this . state . groupPermissionItems . concat ( res . data . success ) ,
selectedOption : null ,
permission : 'rw' ,
folderPath : ''
} ) ;
2024-07-24 06:59:26 +00:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2020-11-02 05:56:35 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
deleteGroupPermissionItem = ( item ) => {
2019-05-17 01:14:26 +00:00
const request = this . props . isDepartmentRepo ?
seafileAPI . deleteDepartmentRepoGroupFolderPerm ( item . repo _id , item . permission , item . folder _path , item . group _id ) :
2019-06-24 07:44:22 +00:00
seafileAPI . deleteGroupFolderPerm ( item . repo _id , item . permission , item . folder _path , item . group _id ) ;
2019-05-17 01:14:26 +00:00
request . then ( ( ) => {
2019-05-15 00:01:48 +00:00
this . setState ( {
2020-11-02 05:56:35 +00:00
groupPermissionItems : this . state . groupPermissionItems . filter ( deletedItem => { return deletedItem != item ; } )
2019-05-15 00:01:48 +00:00
} ) ;
2024-07-24 06:59:26 +00:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2019-05-15 00:01:48 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
onChangeGroupPermission = ( item , permission ) => {
2019-05-17 01:14:26 +00:00
const request = this . props . isDepartmentRepo ?
seafileAPI . updateDepartmentRepoGroupFolderPerm ( item . repo _id , permission , item . folder _path , item . group _id ) :
seafileAPI . updateGroupFolderPerm ( item . repo _id , permission , item . folder _path , item . group _id ) ;
request . then ( ( ) => {
2019-05-15 00:01:48 +00:00
this . updateGroupPermission ( item , permission ) ;
2024-07-24 06:59:26 +00:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2019-05-15 00:01:48 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2020-11-02 05:56:35 +00:00
2019-05-15 00:01:48 +00:00
updateGroupPermission = ( item , permission ) => {
let groupID = item . group _id ;
let groupPermissionItems = this . state . groupPermissionItems . map ( sharedItem => {
let sharedItemGroupID = sharedItem . group _id ;
if ( groupID === sharedItemGroupID && item . folder _path === sharedItem . folder _path ) {
sharedItem . permission = permission ;
}
return sharedItem ;
} ) ;
2024-07-18 03:58:42 +00:00
this . setState ( { groupPermissionItems : groupPermissionItems } ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
onSetSubFolder = ( e ) => {
this . setState ( {
2020-11-02 05:56:35 +00:00
folderPath : e . target . value
2019-05-15 00:01:48 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
toggleFileChooser = ( ) => {
this . setState ( {
showFileChooser : ! this . state . showFileChooser ,
folderPath : ''
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
toggleSubFolder = ( repo , path , item ) => {
this . setState ( {
folderPath : path ,
2020-11-02 05:56:35 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
handleSubmit = ( ) => {
this . setState ( {
2024-05-29 12:29:50 +00:00
folderPath : this . state . folderPath || '/' ,
2019-05-15 00:01:48 +00:00
showFileChooser : ! this . state . showFileChooser
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
onRepoItemClick = ( ) => {
this . setState ( {
2020-11-02 05:56:35 +00:00
folderPath : '/'
2019-05-15 00:01:48 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-05-15 00:01:48 +00:00
render ( ) {
let showPath = this . props . folderPath ? false : true ;
if ( this . state . showFileChooser ) {
return (
< div >
2021-12-15 06:55:16 +00:00
< FileChooser
repoID = { this . props . repoID }
2019-05-15 00:01:48 +00:00
mode = { 'only_current_library' }
onDirentItemClick = { this . toggleSubFolder }
onRepoItemClick = { this . onRepoItemClick }
/ >
< div className = "modal-footer" >
< Button color = "secondary" onClick = { this . toggleFileChooser } > { gettext ( 'Cancel' ) } < / B u t t o n >
< Button color = "primary" onClick = { this . handleSubmit } > { gettext ( 'Submit' ) } < / B u t t o n >
< / d i v >
< / d i v >
) ;
}
2020-04-04 06:32:11 +00:00
const thead = (
< thead >
< tr >
< th width = { showPath ? '32%' : '55%' } > { gettext ( 'Group' ) } < / t h >
{ showPath &&
< th width = "32%" > { gettext ( 'Folder' ) } < / t h >
}
< th width = { showPath ? '24%' : '30%' } > { gettext ( 'Permission' ) } < / t h >
< th width = { showPath ? '12%' : '15%' } > < / t h >
< / t r >
< / t h e a d >
) ;
2019-05-15 00:01:48 +00:00
return (
< Fragment >
2024-10-15 04:02:31 +00:00
< p className = "text-gray small" > { gettext ( 'Folder permission is only effective after the library is shared to users or groups. It is used to fine tune sub-folder permissions.' ) } < / p >
2020-04-04 06:32:11 +00:00
< table className = "w-xs-250" >
{ thead }
2019-05-15 00:01:48 +00:00
< tbody >
< tr >
< td >
2023-09-18 02:01:30 +00:00
< SeahubSelect
2019-05-15 00:01:48 +00:00
onChange = { this . handleSelectChange }
options = { this . options }
placeholder = { gettext ( 'Select a group' ) }
maxMenuHeight = { 200 }
value = { this . state . selectedOption }
2023-09-18 02:01:30 +00:00
components = { { NoOptionsMessage : NoGroupMessage } }
2019-05-15 00:01:48 +00:00
/ >
< / t d >
{ showPath &&
< td >
< InputGroup >
< Input value = { this . state . folderPath } onChange = { this . onSetSubFolder } / >
< InputGroupAddon addonType = "append" > < Button className = "sf2-icon-plus" onClick = { this . toggleFileChooser } > < / B u t t o n > < / I n p u t G r o u p A d d o n >
< / I n p u t G r o u p >
< / t d >
}
< td >
2020-11-02 05:56:35 +00:00
< SharePermissionEditor
2019-05-15 00:01:48 +00:00
isTextMode = { false }
isEditIconShow = { false }
currentPermission = { this . state . permission }
permissions = { this . permissions }
onPermissionChanged = { this . setPermission }
/ >
< / t d >
< td >
2024-07-13 07:15:22 +00:00
< Button color = "primary" onClick = { this . addGroupFolderPerm } > { gettext ( 'Submit' ) } < / B u t t o n >
2019-05-15 00:01:48 +00:00
< / t d >
< / t r >
2020-11-02 05:56:35 +00:00
{ this . state . errorMsg . length > 0 &&
2019-05-15 00:01:48 +00:00
this . state . errorMsg . map ( ( item , index ) => {
let errMessage = item . group _id + ': ' + item . error _msg ;
return (
< tr key = { index } >
< td colSpan = { 3 } > < p className = "error" > { errMessage } < / p > < / t d >
< / t r >
) ;
2020-11-02 05:56:35 +00:00
} )
2019-05-15 00:01:48 +00:00
}
< / t b o d y >
< / t a b l e >
< div className = "share-list-container" >
2020-04-04 06:32:11 +00:00
< table className = "table-thead-hidden w-xs-250" >
{ thead }
2019-05-15 00:01:48 +00:00
< tbody >
{ this . state . groupPermissionItems . map ( ( item , index ) => {
return (
2020-11-02 05:56:35 +00:00
< GroupItem
key = { index }
item = { item }
2019-05-15 00:01:48 +00:00
permissions = { this . permissions }
deleteGroupPermissionItem = { this . deleteGroupPermissionItem }
onChangeGroupPermission = { this . onChangeGroupPermission }
showPath = { showPath }
repoName = { this . props . repoName }
/ >
) ;
} ) }
< / t b o d y >
< / t a b l e >
< / d i v >
< / F r a g m e n t >
) ;
}
}
2023-11-21 07:35:17 +00:00
LibSubFolderSetGroupPermissionDialog . propTypes = propTypes ;
2019-05-15 00:01:48 +00:00
2023-11-21 07:35:17 +00:00
export default LibSubFolderSetGroupPermissionDialog ;