hoist function to fileTree component

pull/4767/head
Joseph Izang 7 months ago
parent 0bc7fad0c8
commit 85bb0e816d
  1. 43
      libs/remix-ui/workspace/src/lib/components/file-explorer.tsx
  2. 72
      libs/remix-ui/workspace/src/lib/components/flat-tree-drop.tsx
  3. 21
      libs/remix-ui/workspace/src/lib/components/flat-tree.tsx

@ -300,16 +300,16 @@ export const FileExplorer = (props: FileExplorerProps) => {
* @param src path of the source
* @returns {void}
*/
const moveFileSilently = async (dest: string, sourcesrc: string[]) => {
if (dest.length === 0 || sourcesrc.length === 0) return
if (await moveFilesIsAllowed(sourcesrc, dest) === false) return
const moveFileSilently = async (dest: string, src: string) => {
if (dest.length === 0 || src.length === 0) return
if (await moveFileIsAllowed(src, dest) === false) return
try {
props.dispatchMoveFiles(sourcesrc, dest)
props.dispatchMoveFile(src, dest)
} catch (error) {
props.modal(
intl.formatMessage({ id: 'filePanel.movingFileFailed' }),
intl.formatMessage({ id: 'filePanel.movingFileFailedMsg' }, { src: sourcesrc.join(' ') }),
intl.formatMessage({ id: 'filePanel.movingFileFailedMsg' }, { src }),
intl.formatMessage({ id: 'filePanel.close' }),
async () => { }
)
@ -323,35 +323,34 @@ export const FileExplorer = (props: FileExplorerProps) => {
* @param src path of the source
* @returns {void}
*/
const moveFolderSilently = async (dest: string, sourcesrc: string[]) => {
if (dest.length === 0 || sourcesrc.length === 0) return
if (await moveFoldersIsAllowed(sourcesrc, dest) === false) return
const moveFolderSilently = async (dest: string, src: string) => {
if (dest.length === 0 || src.length === 0) return
if (await moveFolderIsAllowed(src, dest) === false) return
// console.log('moveFolderSilently', { src, dest, sourcesrc })
try {
props.dispatchMoveFolders(sourcesrc, dest)
props.dispatchMoveFolder(src, dest)
} catch (error) {
props.modal(
intl.formatMessage({ id: 'filePanel.movingFolderFailed' }),
intl.formatMessage({ id: 'filePanel.movingFolderFailedMsg' }, { src: sourcesrc.join(' ') }),
intl.formatMessage({ id: 'filePanel.movingFolderFailedMsg' }, { src }),
intl.formatMessage({ id: 'filePanel.close' }),
async () => { }
)
}
}
const handleFileMove = async (dest: string, sourcesrc: string[]) => {
if (await moveFilesIsAllowed(sourcesrc, dest) === false) return
console.log('What files have been selected?', filesSelected)
const files = filesSelected && filesSelected.length > 0 && filesSelected.join(' ')
const src = files.length > 0 ? files : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join(' ')
console.log('handleFileMove sourcesrc', {files, sourcesrc, dest, src })
const handleFileMove = async (dest: string, copySrc: string) => {
if (await moveFileIsAllowed(copySrc, dest) === false) return
const src = filesSelected && filesSelected.length > 0 ? filesSelected.join(' ') : ''
console.log('handleFileMove sourcesrc', {src, copySrc, dest })
try {
props.modal(
intl.formatMessage({ id: 'filePanel.moveFile' }),
intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }),
intl.formatMessage({ id: 'filePanel.yes' }),
() => props.dispatchMoveFiles(sourcesrc, dest),
() => props.dispatchMoveFile(copySrc, dest),
intl.formatMessage({ id: 'filePanel.cancel' }),
() => { }
)
@ -365,17 +364,17 @@ export const FileExplorer = (props: FileExplorerProps) => {
}
}
const handleFolderMove = async (dest: string, sourcesrc: string[]) => {
if (await moveFoldersIsAllowed(sourcesrc, dest) === false) return
const handleFolderMove = async (dest: string, src: string) => {
if (await moveFolderIsAllowed(src, dest) === false) return
const folders = filesSelected && filesSelected.length > 0 && filesSelected.join(' ')
console.log(folders)
const src = folders.length > 0 ? folders : sourcesrc.length === 1 ? sourcesrc[0] : sourcesrc.join(' ')
try {
props.modal(
intl.formatMessage({ id: 'filePanel.moveFile' }),
intl.formatMessage({ id: 'filePanel.moveFileMsg1' }, { src, dest }),
intl.formatMessage({ id: 'filePanel.yes' }),
() => props.dispatchMoveFolders(sourcesrc, dest),
() => props.dispatchMoveFolder(src, dest),
intl.formatMessage({ id: 'filePanel.cancel' }),
() => { }
)

@ -1,6 +1,6 @@
import React, { SyntheticEvent, useContext, useEffect, useRef, useState } from 'react'
import { DragStructure, FileType, FlatTreeDropProps } from '../types'
import { getEventTarget } from '../utils/getEventTarget'
import { buildMultiSelectedItemProfiles, getEventTarget } from '../utils/getEventTarget'
import { extractParentFromKey } from '@remix-ui/helper'
import { FileSystemContext } from '../contexts'
@ -14,20 +14,14 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => {
// folder to open
const [folderToOpen, setFolderToOpen] = useState<string>()
const globalFEContext = useContext(FileSystemContext)
const [selectedItems, setSelectedItems] = useState<DragStructure[]>([])
<<<<<<< HEAD
=======
useEffect(() => {
}, [globalFEContext.fs.focusElement.length])
const [selectedItems, setSelectedItems] = useState<DragStructure[]>([])
>>>>>>> consume function to move files silently
const onDragOver = async (e: SyntheticEvent) => {
e.preventDefault()
const target = await getEventTarget(e)
buildMultiSelectedItemProfiles(target)
if (!target || !target.path) {
clearTimeout(timer)
setFolderToOpen(null)
@ -56,7 +50,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => {
event.preventDefault()
const target = await getEventTarget(event)
const items = buildMultiSelectedItemProfiles(target)
// const items = buildMultiSelectedItemProfiles(target)
const filePaths = []
let dragDestination: any
@ -69,62 +63,32 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => {
dragDestination = getFlatTreeItem(target.path)
}
items.forEach((item) => filePaths.push(item.path))
props.selectedItems.forEach((item) => filePaths.push(item.path))
props.setFilesSelected(filePaths)
if (dragDestination.isDirectory) {
if (dragSource.isDirectory) {
moveFolder(dragDestination.path, [dragSource.path])
await moveFoldersSilently(items, dragDestination.path)
moveFolder(dragDestination.path, dragSource.path)
await moveFoldersSilently(props.selectedItems, dragDestination.path)
} else {
moveFile(dragDestination.path, [dragSource.path])
await moveFilesSilently(items, dragDestination.path)
moveFile(dragDestination.path, dragSource.path)
await moveFilesSilently(props.selectedItems, dragDestination.path)
}
} else {
const path = extractParentFromKey(dragDestination.path) || '/'
if (dragSource.isDirectory) {
moveFolder(path, [dragSource.path])
await moveFoldersSilently(items, dragDestination.path)
moveFolder(path, dragSource.path)
await moveFoldersSilently(props.selectedItems, dragDestination.path)
} else {
moveFile(path, [dragSource.path])
await moveFilesSilently(items, dragDestination.path)
}
}
document.querySelectorAll('li.remix_selected').forEach(item => {
item.classList.remove('remix_selected')
})
}
/**
* When multiple files are selected in FileExplorer,
* and these files are dragged to a target folder,
* this function will build the profile of each selected item
* in FileExplorer so they can be moved when dropped
* @param target - Initial target item in FileExplorer
* @returns - {DragStructure} Array of selected items
*/
const buildMultiSelectedItemProfiles = (target: {
path: string
type: string
content: string
position: {
top: number
left: number
moveFile(path, dragSource.path)
await moveFilesSilently(props.selectedItems, dragDestination.path)
}
}) => {
const selectItems = []
document.querySelectorAll('li.remix_selected').forEach(item => {
const dragTarget = {
position: { top: target?.position.top || 0, left: target?.position.left || 0 },
path: item.getAttribute('data-path') || item.getAttribute('data-label-path') || '',
type: item.getAttribute('data-type') || item.getAttribute('data-label-type') || '',
content: item.textContent || ''
}
selectItems.push(dragTarget)
document.querySelectorAll('li.remixui_selected').forEach(item => {
item.classList.remove('remixui_selected')
item.classList.remove('bg-secondary')
})
return selectItems
}
/**
@ -138,7 +102,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => {
const promises = items.filter(item => item.path !== targetPath)
.map(async (item) => {
if (item.type === 'file') {
await props.moveFileSilently(targetPath, [item.path])
await props.moveFileSilently(targetPath, item.path)
}
})
await Promise.all(promises)
@ -155,7 +119,7 @@ export const FlatTreeDrop = (props: FlatTreeDropProps) => {
const promises = items.filter(item => item.path !== targetPath)
.map(async (item) => {
if (item.type === 'folder') {
await props.moveFolderSilently(targetPath, [item.path])
await props.moveFolderSilently(targetPath, item.path)
}
})
await Promise.all(promises)

@ -1,11 +1,11 @@
import React, { SyntheticEvent, useEffect, useRef, useState, RefObject, useMemo, useContext, Dispatch } from 'react'
import { Popover } from 'react-bootstrap'
import { FileType, WorkspaceElement } from '../types'
import { DragStructure, FileType, WorkspaceElement } from '../types'
import { getPathIcon } from '@remix-ui/helper';
import { Virtuoso, VirtuosoHandle } from 'react-virtuoso'
import { FlatTreeItemInput } from './flat-tree-item-input';
import { FlatTreeDrop } from './flat-tree-drop';
import { getEventTarget } from '../utils/getEventTarget';
import { buildMultiSelectedItemProfiles, getEventTarget } from '../utils/getEventTarget';
import { fileDecoration, FileDecorationIcons } from '@remix-ui/file-decorators';
import { FileHoverIcons } from './file-explorer-hovericons';
import { deletePath } from '../actions';
@ -36,10 +36,10 @@ interface FlatTreeProps {
handleContextMenu: (pageX: number, pageY: number, path: string, content: string, type: string) => void
handleTreeClick: (e: SyntheticEvent) => void
handleClickFolder: (path: string, type: string) => void
moveFile: (dest: string, src: string[]) => void
moveFolder: (dest: string, src: string[]) => void
moveFolderSilently: (dest: string, src: string[]) => Promise<void>
moveFileSilently: (dest: string, src: string[]) => Promise<void>
moveFile: (dest: string, src: string) => void
moveFolder: (dest: string, src: string) => void
moveFolderSilently: (dest: string, src: string) => Promise<void>
moveFileSilently: (dest: string, src: string) => Promise<void>
setFilesSelected: Dispatch<React.SetStateAction<string[]>>
fileState: fileDecoration[]
createNewFile?: any
@ -71,12 +71,14 @@ export const FlatTree = (props: FlatTreeProps) => {
const ref = useRef(null)
const containerRef = useRef<HTMLDivElement>(null)
const virtuoso = useRef<VirtuosoHandle>(null)
const [selectedItems, setSelectedItems] = useState<DragStructure[]>([])
const labelClass = (file: FileType) =>
props.focusEdit.element === file.path
? 'bg-light'
: props.focusElement.findIndex((item) => item.key === file.path) !== -1
? 'bg-secondary remix_selected'
? 'bg-secondary remixui_selected'
: hover == file.path
? 'bg-light border-no-shift'
: props.focusContext.element === file.path && props.focusEdit.element !== file.path
@ -107,6 +109,9 @@ export const FlatTree = (props: FlatTreeProps) => {
const target = await getEventTarget(event)
setDragSource(flatTree.find((item) => item.path === target.path))
setIsDragging(true)
const items = buildMultiSelectedItemProfiles(target)
setSelectedItems(items)
setFilesSelected(items.map((item) => item.path))
}
useEffect(() => {
@ -258,6 +263,8 @@ export const FlatTree = (props: FlatTreeProps) => {
setFilesSelected={setFilesSelected}
handleClickFolder={handleClickFolder}
expandPath={expandPath}
selectedItems={selectedItems}
setSelectedItems={setSelectedItems}
>
<div data-id="treeViewUltreeViewMenu"
className='d-flex h-100 w-100 pb-2'

Loading…
Cancel
Save