2018-11-27 06:47:19 +00:00
import React , { Fragment } from 'react' ;
2018-10-13 09:07:54 +00:00
import PropTypes from 'prop-types' ;
2023-09-13 15:12:23 +00:00
import MediaQuery from 'react-responsive' ;
import { v4 as uuidv4 } from 'uuid' ;
2021-10-26 03:59:33 +00:00
import moment from 'moment' ;
2023-10-19 05:44:28 +00:00
import { Dropdown , DropdownToggle , DropdownItem } from 'reactstrap' ;
2021-08-31 10:00:02 +00:00
import { gettext , siteRoot , mediaUrl , username , useGoFileserver , fileServerRoot } from '../../utils/constants' ;
2018-11-30 03:52:19 +00:00
import { Utils } from '../../utils/utils' ;
2018-12-06 03:28:16 +00:00
import { seafileAPI } from '../../utils/seafile-api' ;
2018-10-25 05:36:06 +00:00
import URLDecorator from '../../utils/url-decorator' ;
2019-04-22 06:00:16 +00:00
import ItemDropdownMenu from '../dropdown-menu/item-dropdown-menu' ;
2019-01-30 09:37:13 +00:00
import Rename from '../rename' ;
2018-11-27 06:47:19 +00:00
import ModalPortal from '../modal-portal' ;
import MoveDirentDialog from '../dialog/move-dirent-dialog' ;
import CopyDirentDialog from '../dialog/copy-dirent-dialog' ;
2018-12-06 03:28:16 +00:00
import ShareDialog from '../dialog/share-dialog' ;
2019-04-12 07:54:05 +00:00
import ZipDownloadDialog from '../dialog/zip-download-dialog' ;
2019-04-17 02:48:44 +00:00
import EditFileTagDialog from '../dialog/edit-filetag-dialog' ;
2023-09-13 15:12:23 +00:00
import EditFileTagPopover from '../popover/edit-filetag-popover' ;
2019-05-15 00:01:48 +00:00
import LibSubFolderPermissionDialog from '../dialog/lib-sub-folder-permission-dialog' ;
2019-07-16 02:01:09 +00:00
import toaster from '../toast' ;
2023-10-19 05:44:28 +00:00
import FileTag from './file-tag' ;
2023-09-13 00:40:50 +00:00
import '../../css/dirent-list-item.css' ;
2018-12-28 03:12:24 +00:00
2018-10-13 09:07:54 +00:00
const propTypes = {
2018-11-22 03:26:00 +00:00
path : PropTypes . string . isRequired ,
2018-11-28 04:41:49 +00:00
repoID : PropTypes . string . isRequired ,
2018-10-13 09:07:54 +00:00
isItemFreezed : PropTypes . bool . isRequired ,
dirent : PropTypes . object . isRequired ,
onItemClick : PropTypes . func . isRequired ,
2019-04-22 04:18:35 +00:00
freezeItem : PropTypes . func . isRequired ,
unfreezeItem : PropTypes . func . isRequired ,
2018-11-23 12:19:42 +00:00
onItemRenameToggle : PropTypes . func . isRequired ,
onItemSelected : PropTypes . func . isRequired ,
2018-10-13 09:07:54 +00:00
onItemDelete : PropTypes . func . isRequired ,
2018-10-25 05:36:06 +00:00
onItemRename : PropTypes . func . isRequired ,
2018-11-27 06:47:19 +00:00
onItemMove : PropTypes . func . isRequired ,
onItemCopy : PropTypes . func . isRequired ,
2023-09-14 06:36:58 +00:00
onItemConvert : PropTypes . func . isRequired ,
2019-01-17 09:05:08 +00:00
onDirentClick : PropTypes . func . isRequired ,
2018-11-22 03:26:00 +00:00
updateDirent : PropTypes . func . isRequired ,
2019-03-11 03:14:49 +00:00
showImagePopup : PropTypes . func . isRequired ,
2018-12-18 09:21:01 +00:00
currentRepoInfo : PropTypes . object ,
2018-11-01 10:40:18 +00:00
isRepoOwner : PropTypes . bool ,
2019-03-11 03:14:49 +00:00
isAdmin : PropTypes . bool . isRequired ,
repoEncrypted : PropTypes . bool . isRequired ,
isGroupOwnedRepo : PropTypes . bool . isRequired ,
2019-04-11 13:04:47 +00:00
onItemMouseDown : PropTypes . func . isRequired ,
onItemContextMenu : PropTypes . func . isRequired ,
2019-04-13 02:45:11 +00:00
selectedDirentList : PropTypes . array . isRequired ,
activeDirent : PropTypes . object ,
2019-04-21 02:43:34 +00:00
getDirentItemMenuList : PropTypes . func . isRequired ,
2024-02-02 12:52:58 +00:00
repoTags : PropTypes . array . isRequired ,
2019-05-14 02:15:09 +00:00
onFileTagChanged : PropTypes . func ,
enableDirPrivateShare : PropTypes . bool . isRequired ,
2019-05-29 04:02:07 +00:00
showDirentDetail : PropTypes . func . isRequired ,
2019-06-17 08:11:54 +00:00
onItemsMove : PropTypes . func . isRequired ,
2019-07-26 06:55:09 +00:00
onShowDirentsDraggablePreview : PropTypes . func ,
2023-10-09 13:27:44 +00:00
loadDirentList : PropTypes . func ,
2018-10-13 09:07:54 +00:00
} ;
2020-05-06 10:24:16 +00:00
class DirentListItem extends React . Component {
2018-10-13 09:07:54 +00:00
constructor ( props ) {
super ( props ) ;
2023-08-17 00:57:09 +00:00
const { dirent } = this . props ;
const { isCustomPermission , customPermission } = Utils . getUserPermission ( dirent . permission ) ;
this . isCustomPermission = isCustomPermission ;
this . customPermission = customPermission ;
this . canPreview = true ;
this . canDrag = dirent . permission === 'rw' ;
if ( isCustomPermission ) {
const { preview , modify } = customPermission . permission ;
this . canPreview = preview || modify ;
this . canDrag = modify ;
}
2018-10-13 09:07:54 +00:00
this . state = {
isOperationShow : false ,
2018-10-25 05:36:06 +00:00
highlight : false ,
2019-04-12 07:54:05 +00:00
isZipDialogOpen : false ,
2018-11-27 06:47:19 +00:00
isMoveDialogShow : false ,
isCopyDialogShow : false ,
2018-12-06 03:28:16 +00:00
isShareDialogShow : false ,
2018-11-27 06:47:19 +00:00
isMutipleOperation : false ,
2023-08-17 00:57:09 +00:00
canDrag : this . canDrag ,
2018-12-18 01:02:16 +00:00
isShowTagTooltip : false ,
2019-03-27 03:25:27 +00:00
isDragTipShow : false ,
isDropTipshow : false ,
2019-04-17 02:48:44 +00:00
isEditFileTagShow : false ,
2019-05-15 00:01:48 +00:00
isPermissionDialogOpen : false ,
2019-08-30 10:10:48 +00:00
isOpMenuOpen : false // for mobile
2018-10-13 09:07:54 +00:00
} ;
2023-09-13 15:12:23 +00:00
this . tagListTitleID = ` tag-list-title- ${ uuidv4 ( ) } ` ;
2018-10-13 09:07:54 +00:00
}
2023-12-06 09:24:05 +00:00
UNSAFE _componentWillReceiveProps ( nextProps ) {
2020-04-11 09:54:52 +00:00
if ( nextProps . isItemFreezed !== this . props . isItemFreezed && ! nextProps . isItemFreezed ) {
2019-04-08 03:35:46 +00:00
this . setState ( {
highlight : false ,
isOperationShow : false ,
2019-04-13 08:56:06 +00:00
} , ( ) => {
if ( nextProps . activeDirent && nextProps . activeDirent . name === nextProps . dirent . name ) {
this . setState ( { isOperationShow : true } ) ;
}
2019-04-11 13:04:47 +00:00
} ) ;
2019-04-08 03:35:46 +00:00
}
}
2019-08-30 10:10:48 +00:00
toggleOpMenu = ( ) => {
this . setState ( {
isOpMenuOpen : ! this . state . isOpMenuOpen
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-08-30 10:10:48 +00:00
2018-10-13 09:07:54 +00:00
//UI Interactive
onMouseEnter = ( ) => {
if ( ! this . props . isItemFreezed ) {
this . setState ( {
highlight : true ,
isOperationShow : true ,
} ) ;
}
2023-08-17 00:57:09 +00:00
if ( this . state . canDrag ) {
2021-09-13 02:37:07 +00:00
this . setState ( { isDragTipShow : true } ) ;
}
2023-09-13 00:40:50 +00:00
} ;
2018-10-13 09:07:54 +00:00
onMouseOver = ( ) => {
if ( ! this . props . isItemFreezed ) {
this . setState ( {
highlight : true ,
isOperationShow : true ,
} ) ;
}
2023-08-17 00:57:09 +00:00
if ( this . state . canDrag ) {
2021-09-13 02:37:07 +00:00
this . setState ( { isDragTipShow : true } ) ;
}
2023-09-13 00:40:50 +00:00
} ;
2018-10-13 09:07:54 +00:00
onMouseLeave = ( ) => {
if ( ! this . props . isItemFreezed ) {
this . setState ( {
highlight : false ,
isOperationShow : false ,
} ) ;
}
2019-04-11 13:04:47 +00:00
this . setState ( { isDragTipShow : false } ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-13 09:07:54 +00:00
2019-04-22 04:18:35 +00:00
unfreezeItem = ( ) => {
2018-10-13 09:07:54 +00:00
this . setState ( {
2019-01-16 09:44:44 +00:00
highlight : false ,
2018-10-13 09:07:54 +00:00
isOperationShow : false ,
} ) ;
2019-04-22 04:18:35 +00:00
this . props . unfreezeItem ( ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-13 09:07:54 +00:00
//buiness handler
onItemSelected = ( ) => {
2018-11-23 12:19:42 +00:00
this . props . onItemSelected ( this . props . dirent ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-11-22 03:26:00 +00:00
2021-09-29 07:23:02 +00:00
onItemStarred = ( e ) => {
2018-10-25 05:36:06 +00:00
let dirent = this . props . dirent ;
2018-11-28 04:41:49 +00:00
let repoID = this . props . repoID ;
2018-10-25 05:36:06 +00:00
let filePath = this . getDirentPath ( dirent ) ;
2019-02-18 12:26:55 +00:00
2021-09-29 07:23:02 +00:00
e . preventDefault ( ) ;
2018-10-25 05:36:06 +00:00
if ( dirent . starred ) {
2019-03-27 03:28:00 +00:00
seafileAPI . unstarItem ( repoID , filePath ) . then ( ( ) => {
2018-11-28 00:57:42 +00:00
this . props . updateDirent ( this . props . dirent , 'starred' , false ) ;
2019-07-16 02:01:09 +00:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2018-10-25 05:36:06 +00:00
} ) ;
} else {
2019-02-18 12:26:55 +00:00
seafileAPI . starItem ( repoID , filePath ) . then ( ( ) => {
2018-11-28 00:57:42 +00:00
this . props . updateDirent ( this . props . dirent , 'starred' , true ) ;
2019-07-16 02:01:09 +00:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2018-10-25 05:36:06 +00:00
} ) ;
}
2023-09-13 00:40:50 +00:00
} ;
2018-11-22 03:26:00 +00:00
2019-01-17 09:05:08 +00:00
// on '<tr>'
onDirentClick = ( e ) => {
// '<td>' is clicked
2019-04-13 05:35:33 +00:00
e . stopPropagation ( ) ;
2019-01-17 09:05:08 +00:00
if ( e . target . tagName == 'TD' ) {
this . props . onDirentClick ( this . props . dirent ) ;
}
2023-09-13 00:40:50 +00:00
} ;
2019-01-17 09:05:08 +00:00
2018-11-30 03:52:19 +00:00
onItemClick = ( e ) => {
e . preventDefault ( ) ;
2019-01-16 09:45:46 +00:00
const dirent = this . props . dirent ;
2021-01-09 10:36:26 +00:00
if ( this . state . isRenameing ) {
return ;
}
2021-09-13 02:37:07 +00:00
if ( dirent . isDir ( ) ) {
this . props . onItemClick ( dirent ) ;
return ;
}
if ( ! this . canPreview ) {
return ;
}
2019-01-16 09:45:46 +00:00
if ( Utils . imageCheck ( dirent . name ) ) {
this . props . showImagePopup ( dirent ) ;
} else {
this . props . onItemClick ( dirent ) ;
}
2023-09-13 00:40:50 +00:00
} ;
2018-10-25 05:36:06 +00:00
onItemDelete = ( e ) => {
2021-09-29 07:23:02 +00:00
e . preventDefault ( ) ;
2018-10-25 05:36:06 +00:00
e . nativeEvent . stopImmediatePropagation ( ) ; //for document event
2018-11-22 03:26:00 +00:00
this . props . onItemDelete ( this . props . dirent ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-25 05:36:06 +00:00
2018-12-06 03:28:16 +00:00
onItemShare = ( e ) => {
2021-09-29 07:23:02 +00:00
e . preventDefault ( ) ;
2018-12-06 03:28:16 +00:00
e . nativeEvent . stopImmediatePropagation ( ) ; //for document event
this . setState ( { isShareDialogShow : ! this . state . isShareDialogShow } ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-12-06 03:28:16 +00:00
2023-12-26 09:50:06 +00:00
exportDocx = ( ) => {
const serviceUrl = window . app . config . serviceURL ;
let repoID = this . props . repoID ;
let filePath = this . getDirentPath ( this . props . dirent ) ;
let exportToDocxUrl = serviceUrl + '/repo/sdoc_export_to_docx/' + repoID + '/?file_path=' + filePath ;
window . location . href = exportToDocxUrl ;
} ;
2019-01-05 12:40:41 +00:00
closeSharedDialog = ( ) => {
this . setState ( { isShareDialogShow : ! this . state . isShareDialogShow } ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-01-05 12:40:41 +00:00
2019-08-30 10:10:48 +00:00
onMobileMenuItemClick = ( e ) => {
const operation = e . target . getAttribute ( 'data-op' ) ;
this . onMenuItemClick ( operation , e ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-08-30 10:10:48 +00:00
2019-04-21 09:56:55 +00:00
onMenuItemClick = ( operation , event ) => {
2018-10-25 05:36:06 +00:00
switch ( operation ) {
2020-11-02 05:56:35 +00:00
case 'Download' :
2019-04-11 13:04:47 +00:00
this . onItemDownload ( event ) ;
break ;
case 'Share' :
this . onItemShare ( event ) ;
break ;
2020-11-02 05:56:35 +00:00
case 'Delete' :
2019-04-11 13:04:47 +00:00
this . onItemDelete ( event ) ;
break ;
2019-01-31 09:37:02 +00:00
case 'Rename' :
this . onItemRenameToggle ( ) ;
break ;
case 'Move' :
this . onItemMoveToggle ( ) ;
break ;
case 'Copy' :
this . onItemCopyToggle ( ) ;
break ;
2019-04-17 02:48:44 +00:00
case 'Tags' :
this . onEditFileTagToggle ( ) ;
break ;
2019-01-31 09:37:02 +00:00
case 'Permission' :
this . onPermissionItem ( ) ;
break ;
case 'Unlock' :
this . onUnlockItem ( ) ;
break ;
case 'Lock' :
this . onLockItem ( ) ;
break ;
2024-04-11 10:26:48 +00:00
case 'Unfreeze Document' :
this . onUnlockItem ( ) ;
break ;
2023-11-14 08:06:45 +00:00
case 'Freeze Document' :
this . onFreezeDocument ( ) ;
break ;
2023-09-14 06:36:58 +00:00
case 'Convert to Markdown' :
this . onItemConvert ( event , 'markdown' ) ;
break ;
2023-12-26 09:50:06 +00:00
case 'Convert to docx' :
this . onItemConvert ( event , 'docx' ) ;
break ;
case 'Export docx' :
this . exportDocx ( ) ;
break ;
2023-09-14 06:36:58 +00:00
case 'Convert to sdoc' :
this . onItemConvert ( event , 'sdoc' ) ;
break ;
2019-01-31 09:37:02 +00:00
case 'History' :
this . onHistory ( ) ;
break ;
case 'Access Log' :
this . onAccessLog ( ) ;
break ;
2023-08-10 11:39:58 +00:00
case 'Properties' :
this . props . onDirentClick ( this . props . dirent ) ;
this . props . showDirentDetail ( 'info' ) ;
break ;
2019-01-31 09:37:02 +00:00
case 'Open via Client' :
this . onOpenViaClient ( ) ;
break ;
2021-09-13 08:37:15 +00:00
case 'Convert with ONLYOFFICE' :
this . onConvertWithONLYOFFICE ( ) ;
break ;
2019-01-31 09:37:02 +00:00
default :
break ;
2018-10-25 05:36:06 +00:00
}
2023-09-13 00:40:50 +00:00
} ;
2018-10-25 05:36:06 +00:00
2023-09-14 06:36:58 +00:00
onItemConvert = ( e , dstType ) => {
e . preventDefault ( ) ;
e . nativeEvent . stopImmediatePropagation ( ) ; //for document event
this . props . onItemConvert ( this . props . dirent , dstType ) ;
2023-09-18 02:20:47 +00:00
} ;
2023-09-14 06:36:58 +00:00
2019-04-17 02:48:44 +00:00
onEditFileTagToggle = ( ) => {
this . setState ( {
isEditFileTagShow : ! this . state . isEditFileTagShow
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-04-17 02:48:44 +00:00
onFileTagChanged = ( ) => {
let direntPath = this . getDirentPath ( this . props . dirent ) ;
this . props . onFileTagChanged ( this . props . dirent , direntPath ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-04-17 02:48:44 +00:00
2018-11-23 12:19:42 +00:00
onItemRenameToggle = ( ) => {
this . props . onItemRenameToggle ( this . props . dirent ) ;
2018-10-25 05:36:06 +00:00
this . setState ( {
isOperationShow : false ,
isRenameing : true ,
2023-08-17 00:57:09 +00:00
canDrag : false
2018-10-25 05:36:06 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-25 05:36:06 +00:00
onRenameConfirm = ( newName ) => {
2018-11-22 03:26:00 +00:00
this . props . onItemRename ( this . props . dirent , newName ) ;
2018-10-25 05:36:06 +00:00
this . onRenameCancel ( ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-25 05:36:06 +00:00
onRenameCancel = ( ) => {
2023-08-17 00:57:09 +00:00
this . setState ( {
isRenameing : false ,
canDrag : this . canDrag // set it back to the initial value
} ) ;
2019-04-22 04:18:35 +00:00
this . unfreezeItem ( ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-11-22 03:26:00 +00:00
2018-11-23 12:19:42 +00:00
onItemMoveToggle = ( ) => {
2018-11-27 06:47:19 +00:00
this . setState ( { isMoveDialogShow : ! this . state . isMoveDialogShow } ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-25 05:36:06 +00:00
2018-11-23 12:19:42 +00:00
onItemCopyToggle = ( ) => {
2018-11-27 06:47:19 +00:00
this . setState ( { isCopyDialogShow : ! this . state . isCopyDialogShow } ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-13 09:07:54 +00:00
2018-10-25 05:36:06 +00:00
onPermissionItem = ( ) => {
2019-05-15 00:01:48 +00:00
this . setState ( { isPermissionDialogOpen : ! this . state . isPermissionDialogOpen } ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-13 09:07:54 +00:00
2018-10-25 05:36:06 +00:00
onLockItem = ( ) => {
2018-11-28 04:41:49 +00:00
let repoID = this . props . repoID ;
2018-10-25 05:36:06 +00:00
let filePath = this . getDirentPath ( this . props . dirent ) ;
seafileAPI . lockfile ( repoID , filePath ) . then ( ( ) => {
2018-11-28 00:57:42 +00:00
this . props . updateDirent ( this . props . dirent , 'is_locked' , true ) ;
this . props . updateDirent ( this . props . dirent , 'locked_by_me' , true ) ;
2019-04-23 02:32:12 +00:00
let lockName = username . split ( '@' ) ;
this . props . updateDirent ( this . props . dirent , 'lock_owner_name' , lockName [ 0 ] ) ;
2019-07-16 02:01:09 +00:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2018-10-25 05:36:06 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2020-11-02 05:56:35 +00:00
2023-11-14 08:06:45 +00:00
onFreezeDocument = ( ) => {
let repoID = this . props . repoID ;
let filePath = this . getDirentPath ( this . props . dirent ) ;
seafileAPI . lockfile ( repoID , filePath , - 1 ) . then ( ( ) => {
2023-11-29 08:14:38 +00:00
this . props . updateDirent ( this . props . dirent , 'is_freezed' , true ) ;
2023-11-14 08:06:45 +00:00
this . props . updateDirent ( this . props . dirent , 'is_locked' , true ) ;
this . props . updateDirent ( this . props . dirent , 'locked_by_me' , true ) ;
let lockName = username . split ( '@' ) ;
this . props . updateDirent ( this . props . dirent , 'lock_owner_name' , lockName [ 0 ] ) ;
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
} ) ;
} ;
2018-10-25 05:36:06 +00:00
onUnlockItem = ( ) => {
2018-11-28 04:41:49 +00:00
let repoID = this . props . repoID ;
2018-10-25 05:36:06 +00:00
let filePath = this . getDirentPath ( this . props . dirent ) ;
seafileAPI . unlockfile ( repoID , filePath ) . then ( ( ) => {
2018-11-28 00:57:42 +00:00
this . props . updateDirent ( this . props . dirent , 'is_locked' , false ) ;
this . props . updateDirent ( this . props . dirent , 'locked_by_me' , false ) ;
2019-04-23 02:32:12 +00:00
this . props . updateDirent ( this . props . dirent , 'lock_owner_name' , '' ) ;
2019-07-16 02:01:09 +00:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
2018-10-25 05:36:06 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-25 05:36:06 +00:00
onHistory = ( ) => {
2018-11-28 04:41:49 +00:00
let repoID = this . props . repoID ;
2018-10-25 05:36:06 +00:00
let filePath = this . getDirentPath ( this . props . dirent ) ;
2019-02-11 09:38:28 +00:00
let url = URLDecorator . getUrl ( { type : 'file_revisions' , repoID : repoID , filePath : filePath } ) ;
2018-10-25 05:36:06 +00:00
location . href = url ;
2023-09-13 00:40:50 +00:00
} ;
2020-11-02 05:56:35 +00:00
2018-10-25 05:36:06 +00:00
onAccessLog = ( ) => {
2019-05-28 02:43:17 +00:00
let filePath = this . getDirentPath ( this . props . dirent ) ;
let path = siteRoot + 'repo/file-access/' + this . props . repoID + '/?p=' + encodeURIComponent ( filePath ) ;
window . open ( path ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-25 05:36:06 +00:00
onOpenViaClient = ( ) => {
2018-11-28 04:41:49 +00:00
let repoID = this . props . repoID ;
2018-10-25 05:36:06 +00:00
let filePath = this . getDirentPath ( this . props . dirent ) ;
let url = URLDecorator . getUrl ( { type : 'open_via_client' , repoID : repoID , filePath : filePath } ) ;
location . href = url ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-25 05:36:06 +00:00
2021-09-13 08:37:15 +00:00
onConvertWithONLYOFFICE = ( ) => {
let repoID = this . props . repoID ;
2023-09-13 00:40:50 +00:00
let filePath = this . getDirentPath ( this . props . dirent ) ;
2021-09-18 04:35:23 +00:00
seafileAPI . onlyofficeConvert ( repoID , filePath ) . then ( res => {
2023-09-13 00:40:50 +00:00
this . props . loadDirentList ( res . data . parent _dir ) ;
2021-09-18 04:35:23 +00:00
} ) . catch ( error => {
let errMessage = Utils . getErrorMsg ( error ) ;
toaster . danger ( errMessage ) ;
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2021-09-13 08:37:15 +00:00
2018-11-27 06:47:19 +00:00
onItemDownload = ( e ) => {
2021-09-29 07:23:02 +00:00
e . preventDefault ( ) ;
2018-11-27 06:47:19 +00:00
e . nativeEvent . stopImmediatePropagation ( ) ;
let dirent = this . props . dirent ;
2018-11-28 04:41:49 +00:00
let repoID = this . props . repoID ;
2018-11-27 06:47:19 +00:00
let direntPath = this . getDirentPath ( dirent ) ;
if ( dirent . type === 'dir' ) {
2021-08-31 10:00:02 +00:00
if ( ! useGoFileserver ) {
this . setState ( {
isZipDialogOpen : true
} ) ;
} else {
seafileAPI . zipDownload ( repoID , this . props . path , this . props . dirent . name ) . then ( ( res ) => {
const zipToken = res . data [ 'zip_token' ] ;
location . href = ` ${ fileServerRoot } zip/ ${ zipToken } ` ;
} ) . catch ( ( error ) => {
let errorMsg = Utils . getErrorMsg ( error ) ;
this . setState ( {
isLoading : false ,
errorMsg : errorMsg
} ) ;
} ) ;
}
2018-11-27 06:47:19 +00:00
} else {
let url = URLDecorator . getUrl ( { type : 'download_file_url' , repoID : repoID , filePath : direntPath } ) ;
location . href = url ;
}
2023-09-13 00:40:50 +00:00
} ;
2018-11-27 06:47:19 +00:00
2019-04-12 07:54:05 +00:00
closeZipDialog = ( ) => {
this . setState ( {
isZipDialogOpen : false
2018-11-27 06:47:19 +00:00
} ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-11-27 06:47:19 +00:00
2018-10-25 05:36:06 +00:00
getDirentPath = ( dirent ) => {
2018-11-22 03:26:00 +00:00
let path = this . props . path ;
2018-10-25 05:36:06 +00:00
return path === '/' ? path + dirent . name : path + '/' + dirent . name ;
2023-09-13 00:40:50 +00:00
} ;
2018-10-13 09:07:54 +00:00
2018-12-18 01:02:16 +00:00
onTagTooltipToggle = ( e ) => {
e . stopPropagation ( ) ;
2019-01-31 09:37:02 +00:00
this . setState ( { isShowTagTooltip : ! this . state . isShowTagTooltip } ) ;
2023-09-13 00:40:50 +00:00
} ;
2018-12-18 01:02:16 +00:00
2019-03-27 03:25:27 +00:00
onItemMove = ( destRepo , dirent , selectedPath , currentPath ) => {
this . props . onItemMove ( destRepo , dirent , selectedPath , currentPath ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-03-27 03:25:27 +00:00
onItemDragStart = ( e ) => {
2023-08-17 00:57:09 +00:00
if ( Utils . isIEBrower ( ) || ! this . state . canDrag ) {
2019-06-04 07:59:25 +00:00
return false ;
}
2019-04-12 07:54:05 +00:00
e . dataTransfer . effectAllowed = 'move' ;
2019-06-17 08:11:54 +00:00
let { selectedDirentList } = this . props ;
if ( selectedDirentList . length > 0 && selectedDirentList . includes ( this . props . dirent ) ) { // drag items and selectedDirentList include item
2019-07-26 06:55:09 +00:00
this . props . onShowDirentsDraggablePreview ( ) ;
e . dataTransfer . setDragImage ( this . refs . empty _content , 0 , 0 ) ; // Show an empty content
2019-06-18 13:35:39 +00:00
let selectedList = selectedDirentList . map ( item => {
let nodeRootPath = this . getDirentPath ( item ) ;
let dragStartItemData = { nodeDirent : item , nodeParentPath : this . props . path , nodeRootPath : nodeRootPath } ;
2019-06-18 09:55:57 +00:00
return dragStartItemData ;
} ) ;
2019-06-17 08:11:54 +00:00
selectedList = JSON . stringify ( selectedList ) ;
e . dataTransfer . setData ( 'applicaiton/drag-item-info' , selectedList ) ;
return ;
}
2019-07-26 06:55:09 +00:00
if ( e . dataTransfer && e . dataTransfer . setDragImage ) {
e . dataTransfer . setDragImage ( this . refs . drag _icon , 15 , 15 ) ;
}
2019-06-18 13:35:39 +00:00
let nodeRootPath = this . getDirentPath ( this . props . dirent ) ;
let dragStartItemData = { nodeDirent : this . props . dirent , nodeParentPath : this . props . path , nodeRootPath : nodeRootPath } ;
2019-06-17 08:11:54 +00:00
dragStartItemData = JSON . stringify ( dragStartItemData ) ;
2019-03-27 03:25:27 +00:00
e . dataTransfer . setData ( 'applicaiton/drag-item-info' , dragStartItemData ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-03-27 03:25:27 +00:00
2019-06-21 06:07:52 +00:00
onItemDragEnter = ( e ) => {
2023-08-17 00:57:09 +00:00
if ( Utils . isIEBrower ( ) || ! this . state . canDrag ) {
2019-06-04 07:59:25 +00:00
return false ;
}
2019-03-27 03:25:27 +00:00
if ( this . props . dirent . type === 'dir' ) {
2019-06-21 06:07:52 +00:00
e . stopPropagation ( ) ;
2019-03-27 03:25:27 +00:00
this . setState ( { isDropTipshow : true } ) ;
}
2023-09-13 00:40:50 +00:00
} ;
2020-11-02 05:56:35 +00:00
2019-03-27 03:25:27 +00:00
onItemDragOver = ( e ) => {
2023-08-17 00:57:09 +00:00
if ( Utils . isIEBrower ( ) || ! this . state . canDrag ) {
2019-06-04 07:59:25 +00:00
return false ;
}
2019-08-09 09:04:48 +00:00
if ( e . dataTransfer . dropEffect === 'copy' ) {
return ;
}
2019-03-27 03:25:27 +00:00
e . preventDefault ( ) ;
e . dataTransfer . dropEffect = 'move' ;
2023-09-13 00:40:50 +00:00
} ;
2019-03-27 03:25:27 +00:00
2019-06-21 06:07:52 +00:00
onItemDragLeave = ( e ) => {
2023-08-17 00:57:09 +00:00
if ( Utils . isIEBrower ( ) || ! this . state . canDrag ) {
2019-06-04 07:59:25 +00:00
return false ;
}
2019-06-21 06:07:52 +00:00
if ( this . props . dirent . type === 'dir' ) {
e . stopPropagation ( ) ;
}
2019-03-27 03:25:27 +00:00
this . setState ( { isDropTipshow : false } ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-03-27 03:25:27 +00:00
onItemDragDrop = ( e ) => {
2023-08-17 00:57:09 +00:00
if ( Utils . isIEBrower ( ) || ! this . state . canDrag ) {
2019-06-04 07:59:25 +00:00
return false ;
}
2019-03-27 03:25:27 +00:00
this . setState ( { isDropTipshow : false } ) ;
if ( e . dataTransfer . files . length ) { // uploaded files
return ;
}
2019-06-21 06:07:52 +00:00
if ( this . props . dirent . type === 'dir' ) {
e . stopPropagation ( ) ;
2019-07-26 06:55:09 +00:00
} else {
return ;
2019-06-21 06:07:52 +00:00
}
2019-03-27 03:25:27 +00:00
let dragStartItemData = e . dataTransfer . getData ( 'applicaiton/drag-item-info' ) ;
dragStartItemData = JSON . parse ( dragStartItemData ) ;
2019-06-17 08:11:54 +00:00
if ( Array . isArray ( dragStartItemData ) ) { //move items
2019-06-18 13:35:39 +00:00
let direntPaths = dragStartItemData . map ( draggedItem => {
2019-06-21 05:59:17 +00:00
return draggedItem . nodeRootPath ;
2019-06-17 08:11:54 +00:00
} ) ;
let selectedPath = Utils . joinPath ( this . props . path , this . props . dirent . name ) ;
if ( direntPaths . some ( direntPath => { return direntPath === selectedPath ; } ) ) { //eg; A/B, A/C --> A/B
return ;
}
2020-11-02 05:56:35 +00:00
2019-06-17 08:11:54 +00:00
this . props . onItemsMove ( this . props . currentRepoInfo , selectedPath ) ;
return ;
}
2019-06-18 04:06:24 +00:00
let { nodeDirent , nodeParentPath , nodeRootPath } = dragStartItemData ;
2019-03-27 03:25:27 +00:00
let dropItemData = this . props . dirent ;
if ( nodeDirent . name === dropItemData . name ) {
return ;
}
// copy the dirent to it's child. eg: A/B -> A/B/C
if ( dropItemData . type === 'dir' && nodeDirent . type === 'dir' ) {
if ( nodeParentPath !== this . props . path ) {
if ( this . props . path . indexOf ( nodeRootPath ) !== - 1 ) {
return ;
}
}
}
let selectedPath = Utils . joinPath ( this . props . path , this . props . dirent . name ) ;
this . onItemMove ( this . props . currentRepoInfo , nodeDirent , selectedPath , nodeParentPath ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-03-27 03:25:27 +00:00
2019-04-11 13:04:47 +00:00
onItemMouseDown = ( event ) => {
this . props . onItemMouseDown ( event ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-04-11 13:04:47 +00:00
onItemContextMenu = ( event ) => {
let dirent = this . props . dirent ;
this . props . onItemContextMenu ( event , dirent ) ;
2023-09-13 00:40:50 +00:00
} ;
2019-04-11 13:04:47 +00:00
2019-04-18 09:32:34 +00:00
renderItemOperation = ( ) => {
2019-12-23 04:03:06 +00:00
let { dirent , currentRepoInfo , selectedDirentList } = this . props ;
2021-09-13 02:37:07 +00:00
let canDownload = true ;
let canDelete = true ;
const { isCustomPermission , customPermission } = this ;
if ( isCustomPermission ) {
const { permission } = customPermission ;
canDownload = permission . download ;
canDelete = permission . delete ;
}
2019-10-12 06:54:25 +00:00
// https://dev.seafile.com/seahub/lib/d6f300e7-bb2b-4722-b83e-cf45e370bfbc/file/seaf-server%20%E5%8A%9F%E8%83%BD%E8%AE%BE%E8%AE%A1/%E6%9D%83%E9%99%90%E7%9B%B8%E5%85%B3/%E8%B5%84%E6%96%99%E5%BA%93%E6%9D%83%E9%99%90%E8%A7%84%E8%8C%83.md
2019-12-23 04:03:06 +00:00
let showShareBtn = Utils . isHasPermissionToShare ( currentRepoInfo , dirent . permission , dirent ) ;
2019-06-21 02:44:41 +00:00
2019-04-18 09:32:34 +00:00
return (
< Fragment >
2020-11-02 05:56:35 +00:00
{ selectedDirentList . length > 1 ?
2019-04-18 09:32:34 +00:00
< Fragment >
{ this . state . isOperationShow && ! dirent . isSelected &&
< div className = "operations" >
2021-09-29 07:23:02 +00:00
{ ( dirent . permission === 'rw' || dirent . permission === 'r' || ( isCustomPermission && canDownload ) ) && (
< a href = "#" className = "op-icon sf2-icon-download" title = { gettext ( 'Download' ) } role = "button" aria - label = { gettext ( 'Download' ) } onClick = { this . onItemDownload } > < / a >
) }
{ showShareBtn && (
< a href = "#" className = "op-icon sf2-icon-share" title = { gettext ( 'Share' ) } role = "button" aria - label = { gettext ( 'Share' ) } onClick = { this . onItemShare } > < / a >
) }
2023-08-01 07:27:19 +00:00
{ ( dirent . permission === 'rw' || dirent . permission === 'cloud-edit' || ( isCustomPermission && canDelete ) ) && (
2024-05-23 04:09:54 +00:00
< a href = "#" className = "op-icon sf3-font-delete1 sf3-font" title = { gettext ( 'Delete' ) } role = "button" aria - label = { gettext ( 'Delete' ) } onClick = { this . onItemDelete } > < / a >
2021-09-29 07:23:02 +00:00
) }
< ItemDropdownMenu
item = { this . props . dirent }
isHandleContextMenuEvent = { true }
getMenuList = { this . props . getDirentItemMenuList }
onMenuItemClick = { this . onMenuItemClick }
unfreezeItem = { this . unfreezeItem }
freezeItem = { this . props . freezeItem }
/ >
2019-04-18 09:32:34 +00:00
< / d i v >
}
2020-11-02 05:56:35 +00:00
< / F r a g m e n t > :
2019-04-18 09:32:34 +00:00
< Fragment >
2020-11-02 05:56:35 +00:00
{ this . state . isOperationShow &&
2019-04-18 09:32:34 +00:00
< div className = "operations" >
2021-09-29 07:23:02 +00:00
{ ( dirent . permission === 'rw' || dirent . permission === 'r' || ( isCustomPermission && canDownload ) ) && (
< a href = "#" className = "op-icon sf2-icon-download" title = { gettext ( 'Download' ) } role = "button" aria - label = { gettext ( 'Download' ) } onClick = { this . onItemDownload } > < / a >
) }
{ showShareBtn && (
< a href = "#" className = "op-icon sf2-icon-share" title = { gettext ( 'Share' ) } role = "button" aria - label = { gettext ( 'Share' ) } onClick = { this . onItemShare } > < / a >
) }
2023-08-01 07:27:19 +00:00
{ ( dirent . permission === 'rw' || dirent . permission === 'cloud-edit' || ( isCustomPermission && canDelete ) ) && (
2024-05-23 04:09:54 +00:00
< a href = "#" className = "op-icon sf3-font-delete1 sf3-font" title = { gettext ( 'Delete' ) } role = "button" aria - label = { gettext ( 'Delete' ) } onClick = { this . onItemDelete } > < / a >
2021-09-29 07:23:02 +00:00
) }
< ItemDropdownMenu
item = { this . props . dirent }
isHandleContextMenuEvent = { true }
getMenuList = { this . props . getDirentItemMenuList }
onMenuItemClick = { this . onMenuItemClick }
unfreezeItem = { this . unfreezeItem }
freezeItem = { this . props . freezeItem }
/ >
2019-04-18 09:32:34 +00:00
< / d i v >
}
< / F r a g m e n t >
}
< / F r a g m e n t >
2019-05-14 02:15:09 +00:00
) ;
2023-09-13 00:40:50 +00:00
} ;
2019-04-18 09:32:34 +00:00
2018-10-13 09:07:54 +00:00
render ( ) {
2019-04-18 09:32:34 +00:00
let { path , dirent , activeDirent } = this . props ;
2018-11-30 03:52:19 +00:00
let direntPath = Utils . joinPath ( path , dirent . name ) ;
2019-01-23 08:25:14 +00:00
let dirHref = '' ;
if ( this . props . currentRepoInfo ) {
dirHref = siteRoot + 'library/' + this . props . repoID + '/' + this . props . currentRepoInfo . repo _name + Utils . encodePath ( direntPath ) ;
}
2019-01-02 03:52:44 +00:00
let fileHref = siteRoot + 'lib/' + this . props . repoID + '/file' + Utils . encodePath ( direntPath ) ;
2023-07-24 02:47:12 +00:00
if ( dirent . is _sdoc _revision && dirent . revision _id ) {
fileHref = siteRoot + 'lib/' + this . props . repoID + '/revisions/' + dirent . revision _id + '/' ;
}
2019-07-03 09:46:24 +00:00
2019-01-29 07:22:02 +00:00
let iconUrl = Utils . getDirentIcon ( dirent ) ;
2019-01-08 05:53:01 +00:00
2019-03-28 05:32:22 +00:00
let trClass = this . state . highlight ? 'tr-highlight ' : '' ;
trClass += this . state . isDropTipshow ? 'tr-drop-effect' : '' ;
2019-04-13 02:45:11 +00:00
trClass += ( activeDirent && activeDirent . name === dirent . name ) ? 'tr-active' : '' ;
trClass += dirent . isSelected ? 'tr-active' : '' ;
2019-03-28 05:32:22 +00:00
2023-11-29 09:11:46 +00:00
let lockedInfo = dirent . is _freezed ? gettext ( 'Frozen by {name}' ) : gettext ( 'locked by {name}' ) ;
2023-11-29 08:14:38 +00:00
lockedInfo = lockedInfo . replace ( '{name}' , dirent . lock _owner _name ) ;
2019-08-30 10:10:48 +00:00
const isDesktop = Utils . isDesktop ( ) ;
2023-08-17 00:57:09 +00:00
const { canDrag } = this . state ;
2024-01-16 06:00:40 +00:00
const lockedImageUrl = ` ${ mediaUrl } img/file- ${ dirent . is _freezed ? 'freezed-32.svg' : 'locked-32.png' } ` ;
2023-11-21 05:53:40 +00:00
const lockedMessage = dirent . is _freezed ? gettext ( 'freezed' ) : gettext ( 'locked' ) ;
2019-08-30 10:10:48 +00:00
const desktopItem = (
2020-11-02 05:56:35 +00:00
< tr
className = { trClass }
2023-08-17 00:57:09 +00:00
draggable = { canDrag }
2021-09-29 07:23:02 +00:00
onFocus = { this . onMouseEnter }
2020-11-02 05:56:35 +00:00
onMouseEnter = { this . onMouseEnter }
onMouseOver = { this . onMouseOver }
onMouseLeave = { this . onMouseLeave }
onClick = { this . onDirentClick }
onDragStart = { this . onItemDragStart }
onDragEnter = { this . onItemDragEnter }
onDragOver = { this . onItemDragOver }
onDragLeave = { this . onItemDragLeave }
2019-08-30 10:10:48 +00:00
onDrop = { this . onItemDragDrop }
onMouseDown = { this . onItemMouseDown }
onContextMenu = { this . onItemContextMenu }
>
< td className = { ` pl10 ${ this . state . isDragTipShow ? 'tr-drag-effect' : '' } ` } >
2024-04-22 02:36:42 +00:00
< input type = "checkbox" className = "vam" onChange = { this . onItemSelected } checked = { dirent . isSelected } aria - label = { dirent . isSelected ? gettext ( 'Unselect this item' ) : gettext ( 'Select this item' ) } / >
2019-08-30 10:10:48 +00:00
< / t d >
< td className = "pl10" >
2021-09-29 07:23:02 +00:00
{ dirent . starred !== undefined &&
< a href = "#" role = "button" aria - label = { dirent . starred ? gettext ( 'Unstar' ) : gettext ( 'Star' ) } onClick = { this . onItemStarred } >
< i className = { ` fa-star ${ dirent . starred ? 'fas' : 'far star-empty' } ` } > < / i >
< / a >
}
2019-08-30 10:10:48 +00:00
< / t d >
< td className = "pl10" >
< div className = "dir-icon" >
2022-08-11 02:55:53 +00:00
{ ( this . canPreview && dirent . encoded _thumbnail _src ) ?
2019-08-30 10:10:48 +00:00
< img ref = 'drag_icon' src = { ` ${ siteRoot } ${ dirent . encoded _thumbnail _src } ` } className = "thumbnail cursor-pointer" onClick = { this . onItemClick } alt = "" / > :
< img ref = 'drag_icon' src = { iconUrl } width = "24" alt = '' / >
}
2023-11-21 05:53:40 +00:00
{ dirent . is _locked && < img className = "locked" src = { lockedImageUrl } alt = { lockedMessage } title = { lockedInfo } / > }
2019-08-30 10:10:48 +00:00
< div ref = "empty_content" style = { { position : 'absolute' , width : '1px' , height : '1px' } } > < / d i v >
< / d i v >
< / t d >
< td className = "name" >
2021-09-13 02:37:07 +00:00
{ this . state . isRenameing && < Rename hasSuffix = { dirent . type !== 'dir' } name = { dirent . name } onRenameConfirm = { this . onRenameConfirm } onRenameCancel = { this . onRenameCancel } / > }
{ ! this . state . isRenameing && (
< Fragment >
2023-09-13 00:40:50 +00:00
{ ( ! dirent . isDir ( ) && ! this . canPreview ) ?
2021-09-13 02:37:07 +00:00
< a className = "sf-link" onClick = { this . onItemClick } > { dirent . name } < / a > :
< a href = { dirent . type === 'dir' ? dirHref : fileHref } onClick = { this . onItemClick } > { dirent . name } < / a >
}
< / F r a g m e n t >
) }
2019-08-30 10:10:48 +00:00
< / t d >
2023-10-09 08:30:32 +00:00
< td className = "tag-list-title" >
2019-08-30 10:10:48 +00:00
{ ( dirent . type !== 'dir' && dirent . file _tags && dirent . file _tags . length > 0 ) && (
2023-10-19 05:44:28 +00:00
< div id = { this . tagListTitleID } className = "dirent-item tag-list tag-list-stacked" >
{ dirent . file _tags . map ( ( fileTag , index ) => {
return (
< FileTag fileTag = { fileTag } length = { dirent . file _tags . length } key = { index } index = { index } / >
) ;
} ) }
< / d i v >
2020-11-02 05:56:35 +00:00
) }
2023-10-09 10:28:17 +00:00
{ ( dirent . type !== 'dir' && ( ! dirent . file _tags || dirent . file _tags . length == 0 ) ) && (
< div id = { this . tagListTitleID } className = "dirent-item tag-list tag-list-stacked" > < / d i v >
) }
2019-08-30 10:10:48 +00:00
< / t d >
< td className = "operation" > { this . renderItemOperation ( ) } < / t d >
< td className = "file-size" > { dirent . size && dirent . size } < / t d >
2021-10-26 03:59:33 +00:00
< td className = "last-update" title = { moment . unix ( dirent . mtime ) . format ( 'llll' ) } > { dirent . mtime _relative } < / t d >
2019-08-30 10:10:48 +00:00
< / t r >
2020-11-02 05:56:35 +00:00
) ;
2019-08-30 10:10:48 +00:00
const mobileItem = (
< tr >
2021-01-09 10:36:26 +00:00
< td onClick = { this . onItemClick } >
2019-08-30 10:10:48 +00:00
< div className = "dir-icon" >
2022-08-11 02:55:53 +00:00
{ ( this . canPreview && dirent . encoded _thumbnail _src ) ?
2021-01-09 10:36:26 +00:00
< img src = { ` ${ siteRoot } ${ dirent . encoded _thumbnail _src } ` } className = "thumbnail cursor-pointer" alt = "" / > :
2019-08-30 10:10:48 +00:00
< img src = { iconUrl } width = "24" alt = "" / >
2018-11-27 06:47:19 +00:00
}
2023-11-21 05:53:40 +00:00
{ dirent . is _locked && < img className = "locked" src = { lockedImageUrl } alt = { lockedMessage } title = { lockedInfo } / > }
2019-08-30 10:10:48 +00:00
< / d i v >
< / t d >
2021-01-09 10:36:26 +00:00
< td onClick = { this . onItemClick } >
2021-09-13 02:37:07 +00:00
{ this . state . isRenameing && < Rename hasSuffix = { dirent . type !== 'dir' } name = { dirent . name } onRenameConfirm = { this . onRenameConfirm } onRenameCancel = { this . onRenameCancel } / > }
{ ! this . state . isRenameing && (
< Fragment >
{ ( ! dirent . isDir ( ) && ! this . canPreview ) ?
< a className = "sf-link" > { dirent . name } < / a > :
< a href = { dirent . type === 'dir' ? dirHref : fileHref } > { dirent . name } < / a >
}
< / F r a g m e n t >
) }
2019-08-30 10:10:48 +00:00
< br / >
{ dirent . size && < span className = "item-meta-info" > { dirent . size } < / s p a n > }
< span className = "item-meta-info" > { dirent . mtime _relative } < / s p a n >
< / t d >
< td >
< Dropdown isOpen = { this . state . isOpMenuOpen } toggle = { this . toggleOpMenu } >
< DropdownToggle
tag = "i"
className = "sf-dropdown-toggle fa fa-ellipsis-v ml-0"
2024-01-03 10:08:24 +00:00
title = { gettext ( 'More operations' ) }
aria - label = { gettext ( 'More operations' ) }
2019-08-30 10:10:48 +00:00
data - toggle = "dropdown"
aria - expanded = { this . state . isOpMenuOpen }
/ >
< div className = { this . state . isOpMenuOpen ? '' : 'd-none' } onClick = { this . toggleOpMenu } >
< div className = "mobile-operation-menu-bg-layer" > < / d i v >
< div className = "mobile-operation-menu" >
{ dirent . starred !== undefined &&
< DropdownItem className = "mobile-menu-item" onClick = { this . onItemStarred } > { dirent . starred ? gettext ( 'Unstar' ) : gettext ( 'Star' ) } < / D r o p d o w n I t e m > }
{ this . props . getDirentItemMenuList ( dirent , true ) . map ( ( item , index ) => {
if ( item != 'Divider' && item . key != 'Open via Client' ) {
2018-12-18 01:02:16 +00:00
return (
2019-08-30 10:10:48 +00:00
< DropdownItem className = "mobile-menu-item" key = { index } data - op = { item . key } onClick = { this . onMobileMenuItemClick } > { item . value } < / D r o p d o w n I t e m >
2018-12-18 01:02:16 +00:00
) ;
2021-09-29 07:23:02 +00:00
} else {
return null ;
2019-08-30 10:10:48 +00:00
}
} ) }
< / d i v >
< / d i v >
< / D r o p d o w n >
< / t d >
< / t r >
2020-11-02 05:56:35 +00:00
) ;
2019-08-30 10:10:48 +00:00
return (
< Fragment >
2020-11-02 05:56:35 +00:00
{ isDesktop ? desktopItem : mobileItem }
2018-11-27 06:47:19 +00:00
{ this . state . isMoveDialogShow &&
< ModalPortal >
< MoveDirentDialog
path = { this . props . path }
2018-11-28 04:41:49 +00:00
repoID = { this . props . repoID }
2018-11-27 06:47:19 +00:00
dirent = { this . props . dirent }
isMutipleOperation = { this . state . isMutipleOperation }
onItemMove = { this . props . onItemMove }
onCancelMove = { this . onItemMoveToggle }
2019-03-11 03:14:49 +00:00
repoEncrypted = { this . props . repoEncrypted }
2018-11-27 06:47:19 +00:00
/ >
< / M o d a l P o r t a l >
}
{ this . state . isCopyDialogShow &&
< ModalPortal >
< CopyDirentDialog
path = { this . props . path }
2018-11-28 04:41:49 +00:00
repoID = { this . props . repoID }
2018-11-27 06:47:19 +00:00
dirent = { this . props . dirent }
isMutipleOperation = { this . state . isMutipleOperation }
onItemCopy = { this . props . onItemCopy }
onCancelCopy = { this . onItemCopyToggle }
2019-03-11 03:14:49 +00:00
repoEncrypted = { this . props . repoEncrypted }
2018-11-27 06:47:19 +00:00
/ >
< / M o d a l P o r t a l >
}
2023-09-13 15:12:23 +00:00
< MediaQuery query = "(min-width: 768px)" >
{ this . state . isEditFileTagShow &&
< EditFileTagPopover
repoID = { this . props . repoID }
2024-02-02 12:52:58 +00:00
repoTags = { this . props . repoTags }
2023-09-13 15:12:23 +00:00
fileTagList = { dirent . file _tags }
filePath = { direntPath }
toggleCancel = { this . onEditFileTagToggle }
onFileTagChanged = { this . onFileTagChanged }
target = { this . tagListTitleID }
isEditFileTagShow = { this . state . isEditFileTagShow }
/ >
}
< / M e d i a Q u e r y >
< MediaQuery query = "(max-width: 767.8px)" >
{ this . state . isEditFileTagShow &&
< EditFileTagDialog
repoID = { this . props . repoID }
2024-02-02 12:52:58 +00:00
repoTags = { this . props . repoTags }
2023-09-13 15:12:23 +00:00
fileTagList = { dirent . file _tags }
filePath = { direntPath }
toggleCancel = { this . onEditFileTagToggle }
onFileTagChanged = { this . onFileTagChanged }
/ >
}
< / M e d i a Q u e r y >
2019-04-12 07:54:05 +00:00
{ this . state . isZipDialogOpen &&
2018-11-27 06:47:19 +00:00
< ModalPortal >
2019-04-12 07:54:05 +00:00
< ZipDownloadDialog
repoID = { this . props . repoID }
path = { this . props . path }
target = { this . props . dirent . name }
toggleDialog = { this . closeZipDialog }
2018-11-27 06:47:19 +00:00
/ >
< / M o d a l P o r t a l >
}
2018-12-06 03:28:16 +00:00
{ this . state . isShareDialogShow &&
< ModalPortal >
2020-11-02 05:56:35 +00:00
< ShareDialog
2018-12-14 07:09:07 +00:00
itemType = { dirent . type }
2018-12-06 03:28:16 +00:00
itemName = { dirent . name }
2018-12-14 07:09:07 +00:00
itemPath = { direntPath }
2019-01-29 02:06:26 +00:00
userPerm = { dirent . permission }
2018-12-06 03:28:16 +00:00
repoID = { this . props . repoID }
2020-07-21 03:16:33 +00:00
repoEncrypted = { this . props . repoEncrypted }
2019-01-29 02:06:26 +00:00
enableDirPrivateShare = { this . props . enableDirPrivateShare }
isGroupOwnedRepo = { this . props . isGroupOwnedRepo }
2019-01-05 12:40:41 +00:00
toggleDialog = { this . closeSharedDialog }
2018-12-06 03:28:16 +00:00
/ >
< / M o d a l P o r t a l >
}
2019-05-15 00:01:48 +00:00
{ this . state . isPermissionDialogOpen &&
< ModalPortal >
2020-11-02 05:56:35 +00:00
< LibSubFolderPermissionDialog
2019-05-15 00:01:48 +00:00
toggleDialog = { this . onPermissionItem }
repoID = { this . props . repoID }
folderPath = { direntPath }
folderName = { dirent . name }
2019-05-17 07:53:59 +00:00
isDepartmentRepo = { this . props . isGroupOwnedRepo }
2019-05-15 00:01:48 +00:00
/ >
< / M o d a l P o r t a l >
}
2018-11-27 06:47:19 +00:00
< / F r a g m e n t >
2018-10-13 09:07:54 +00:00
) ;
}
}
DirentListItem . propTypes = propTypes ;
export default DirentListItem ;