|
|
@ -2,14 +2,17 @@ import React, {useEffect, useState, useRef, SyntheticEvent} from 'react' // esli |
|
|
|
import {useIntl} from 'react-intl' |
|
|
|
import {useIntl} from 'react-intl' |
|
|
|
import {TreeView} from '@remix-ui/tree-view' // eslint-disable-line
|
|
|
|
import {TreeView} from '@remix-ui/tree-view' // eslint-disable-line
|
|
|
|
import {FileExplorerMenu} from './file-explorer-menu' // eslint-disable-line
|
|
|
|
import {FileExplorerMenu} from './file-explorer-menu' // eslint-disable-line
|
|
|
|
import {FileExplorerProps, WorkSpaceState} from '../types' |
|
|
|
import {FileExplorerContextMenu} from './file-explorer-context-menu' // eslint-disable-line
|
|
|
|
|
|
|
|
import {FileExplorerProps, FileType, WorkSpaceState} from '../types' |
|
|
|
|
|
|
|
|
|
|
|
import '../css/file-explorer.css' |
|
|
|
import '../css/file-explorer.css' |
|
|
|
import {checkSpecialChars, extractNameFromKey, extractParentFromKey, joinPath} from '@remix-ui/helper' |
|
|
|
import {checkSpecialChars, extractNameFromKey, extractParentFromKey, joinPath} from '@remix-ui/helper' |
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
import {FileRender} from './file-render' |
|
|
|
import {FileRender} from './file-render' |
|
|
|
import {Drag} from '@remix-ui/drag-n-drop' |
|
|
|
import {Drag, Draggable} from '@remix-ui/drag-n-drop' |
|
|
|
import {ROOT_PATH} from '../utils/constants' |
|
|
|
import {ROOT_PATH} from '../utils/constants' |
|
|
|
|
|
|
|
import { fileKeySort } from '../utils' |
|
|
|
|
|
|
|
import { moveFileIsAllowed, moveFolderIsAllowed } from '../actions' |
|
|
|
|
|
|
|
|
|
|
|
export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
const intl = useIntl() |
|
|
|
const intl = useIntl() |
|
|
@ -31,6 +34,7 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
} = props |
|
|
|
} = props |
|
|
|
const [state, setState] = useState<WorkSpaceState>(workspaceState) |
|
|
|
const [state, setState] = useState<WorkSpaceState>(workspaceState) |
|
|
|
const treeRef = useRef<HTMLDivElement>(null) |
|
|
|
const treeRef = useRef<HTMLDivElement>(null) |
|
|
|
|
|
|
|
const [childrenKeys, setChildrenKeys] = useState<string[]>([]) |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
useEffect(() => { |
|
|
|
if (contextMenuItems) { |
|
|
|
if (contextMenuItems) { |
|
|
@ -288,9 +292,17 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
props.dispatchHandleExpandPath(expandPath) |
|
|
|
props.dispatchHandleExpandPath(expandPath) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const handleFileMove = (dest: string, src: string) => { |
|
|
|
const handleFileMove = async (dest: string, src: string) => { |
|
|
|
|
|
|
|
if(await moveFileIsAllowed(src, dest) === false) return |
|
|
|
try { |
|
|
|
try { |
|
|
|
props.dispatchMoveFile(src, dest) |
|
|
|
props.modal( |
|
|
|
|
|
|
|
intl.formatMessage({ id: 'filePanel.moveFile' }), |
|
|
|
|
|
|
|
intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }), |
|
|
|
|
|
|
|
intl.formatMessage({ id: 'filePanel.yes' }), |
|
|
|
|
|
|
|
() => props.dispatchMoveFile(src, dest), |
|
|
|
|
|
|
|
intl.formatMessage({ id: 'filePanel.cancel' }), |
|
|
|
|
|
|
|
() => {} |
|
|
|
|
|
|
|
) |
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
props.modal( |
|
|
|
props.modal( |
|
|
|
intl.formatMessage({ id: 'filePanel.movingFileFailed' }), |
|
|
|
intl.formatMessage({ id: 'filePanel.movingFileFailed' }), |
|
|
@ -301,9 +313,17 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const handleFolderMove = (dest: string, src: string) => { |
|
|
|
const handleFolderMove = async (dest: string, src: string) => { |
|
|
|
|
|
|
|
if(await moveFolderIsAllowed(src, dest) === false) return |
|
|
|
try { |
|
|
|
try { |
|
|
|
props.dispatchMoveFolder(src, dest) |
|
|
|
props.modal( |
|
|
|
|
|
|
|
intl.formatMessage({ id: 'filePanel.moveFile' }), |
|
|
|
|
|
|
|
intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }), |
|
|
|
|
|
|
|
intl.formatMessage({ id: 'filePanel.yes' }), |
|
|
|
|
|
|
|
() => props.dispatchMoveFolder(src, dest), |
|
|
|
|
|
|
|
intl.formatMessage({ id: 'filePanel.cancel' }), |
|
|
|
|
|
|
|
() => {} |
|
|
|
|
|
|
|
) |
|
|
|
} catch (error) { |
|
|
|
} catch (error) { |
|
|
|
props.modal( |
|
|
|
props.modal( |
|
|
|
intl.formatMessage({ id: 'filePanel.movingFolderFailed' }), |
|
|
|
intl.formatMessage({ id: 'filePanel.movingFolderFailed' }), |
|
|
@ -314,6 +334,20 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
|
|
if (files[ROOT_PATH]){ |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
const children: FileType[] = files[ROOT_PATH] as any |
|
|
|
|
|
|
|
setChildrenKeys(fileKeySort(children)) |
|
|
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
setChildrenKeys(Object.keys(files[ROOT_PATH])) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else{ |
|
|
|
|
|
|
|
setChildrenKeys([]) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, [props]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<Drag onFileMoved={handleFileMove} onFolderMoved={handleFolderMove}> |
|
|
|
<Drag onFileMoved={handleFileMove} onFolderMoved={handleFolderMove}> |
|
|
|
<div ref={treeRef} tabIndex={0} style={{outline: 'none'}}> |
|
|
|
<div ref={treeRef} tabIndex={0} style={{outline: 'none'}}> |
|
|
@ -339,10 +373,10 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
</span> |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</li> |
|
|
|
</li> |
|
|
|
<div className="pb-4 mb-4"> |
|
|
|
<div> |
|
|
|
<TreeView id="treeViewMenu"> |
|
|
|
<TreeView id="treeViewMenu"> |
|
|
|
{files[ROOT_PATH] && |
|
|
|
{files[ROOT_PATH] && |
|
|
|
Object.keys(files[ROOT_PATH]).map((key, index) => ( |
|
|
|
childrenKeys.map((key, index) => ( |
|
|
|
<FileRender |
|
|
|
<FileRender |
|
|
|
file={files[ROOT_PATH][key]} |
|
|
|
file={files[ROOT_PATH][key]} |
|
|
|
fileDecorations={fileState} |
|
|
|
fileDecorations={fileState} |
|
|
@ -364,6 +398,9 @@ export const FileExplorer = (props: FileExplorerProps) => { |
|
|
|
} |
|
|
|
} |
|
|
|
</TreeView> |
|
|
|
</TreeView> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<Draggable isDraggable={false} file={{ name: '/', path: '/', type: 'folder', isDirectory: true }} expandedPath={props.expandPath} handleClickFolder={null}> |
|
|
|
|
|
|
|
<div className='d-block w-100 pb-4 mb-4'></div> |
|
|
|
|
|
|
|
</Draggable> |
|
|
|
</TreeView> |
|
|
|
</TreeView> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</Drag> |
|
|
|
</Drag> |
|
|
|