s3browser-frontend/src/components/FileBrowser.tsx

176 lines
4.1 KiB
TypeScript
Raw Normal View History

2021-07-26 12:54:22 +00:00
import React from "react"
import { useState } from "react"
2021-08-10 09:21:18 +00:00
import { useContextMenu } from "react-contexify"
2021-08-06 11:59:01 +00:00
import uploadFile from "../functions/uploadFile"
2021-08-16 20:17:43 +00:00
import { useCopyMutation, useCreateDirMutation, useDeleteFileMutation, useMoveMutation, useOpenDirQuery } from "../generated/graphql"
2021-07-27 17:24:52 +00:00
import Breadcrum from "./Breadcrum"
2021-08-16 20:17:43 +00:00
import CreateDirButton from "./CreateDirButton"
2021-08-01 19:42:26 +00:00
import DragAndDrop from "./DragAndDrop"
2021-08-13 23:33:20 +00:00
import FileBrowserContextMenu, { Action, CONTEXT_MENU_DIR, CONTEXT_MENU_FILE } from "./FileBrowserContextMenu"
2021-07-26 12:54:22 +00:00
import FileBrowserElement from "./FileBrowserElement"
2021-07-28 10:49:35 +00:00
import FileOpen from "./FileOpen"
2021-08-15 15:27:06 +00:00
import FileUploadButton from "./FileUploadButton"
2021-07-26 12:54:22 +00:00
const FileBrowser: React.FC = () => {
const [path,setPath] = useState("/")
2021-07-28 10:49:35 +00:00
const [openFileId, setOpenFileId] = useState("")
const [showFile, setShowFile] = useState(false)
2021-07-26 12:54:22 +00:00
2021-08-15 23:42:29 +00:00
const [srcID,setSrcID] = useState("")
2021-08-16 00:05:12 +00:00
const [pasteAction,setPasteAction] = useState<Action>()
2021-08-15 23:42:29 +00:00
2021-08-13 23:33:20 +00:00
const [deleteMutation] = useDeleteFileMutation()
2021-08-15 23:42:29 +00:00
const [copyMutation] = useCopyMutation()
2021-08-16 00:05:12 +00:00
const [moveMutation] = useMoveMutation()
2021-08-16 20:17:43 +00:00
const [createDirMutation] = useCreateDirMutation()
2021-08-13 23:33:20 +00:00
2021-08-10 09:21:18 +00:00
const { show: showFileContext } = useContextMenu({
id: CONTEXT_MENU_FILE,
})
const { show: showDirContext } = useContextMenu({
id: CONTEXT_MENU_DIR,
})
2021-08-16 10:34:01 +00:00
const { data, loading, refetch: refetchDir } = useOpenDirQuery({
2021-07-26 12:54:22 +00:00
variables:{
path
}
})
2021-08-06 11:59:01 +00:00
async function handleDrop(files:FileList) {
const wait: Promise<boolean>[] = []
2021-08-01 19:42:26 +00:00
for (let i = 0; i < files.length; i++) {
const file = files[i]
2021-08-06 11:59:01 +00:00
wait.push(uploadFile(file, path + file.name))
2021-08-01 19:42:26 +00:00
}
2021-08-06 11:59:01 +00:00
await Promise.all(wait)
2021-08-16 10:34:01 +00:00
refetchDir()
2021-08-01 19:42:26 +00:00
}
2021-08-10 09:21:18 +00:00
function openFileContextMenu(e: React.MouseEvent, id: string) {
e.preventDefault()
showFileContext(e,{
props:{
id
}
})
}
function openDirContextMenu(e: React.MouseEvent, id: string) {
e.preventDefault()
showDirContext(e,{
props:{
id
}
})
}
2021-08-16 10:34:01 +00:00
async function onContextSelect(action:Action, id: string) {
2021-08-13 23:33:20 +00:00
switch (action) {
case Action.FileDelete:
2021-08-16 10:34:01 +00:00
await deleteMutation({variables:{id}})
refetchDir()
2021-08-13 23:33:20 +00:00
break
2021-08-15 23:42:29 +00:00
case Action.FileCopy:
2021-08-16 00:05:12 +00:00
case Action.FileMove:
2021-08-15 23:42:29 +00:00
setSrcID(id)
2021-08-16 00:05:12 +00:00
setPasteAction(action)
2021-08-15 23:42:29 +00:00
break
case Action.FilePaste:
2021-08-16 00:05:12 +00:00
if (pasteAction === Action.FileCopy){
2021-08-16 10:34:01 +00:00
await copyMutation({variables:{src:srcID,dest:path}})
refetchDir()
2021-08-16 00:05:12 +00:00
}
if (pasteAction === Action.FileMove){
2021-08-16 10:34:01 +00:00
await moveMutation({variables:{src:srcID,dest:path}})
refetchDir()
2021-08-16 00:05:12 +00:00
}
2021-08-15 23:42:29 +00:00
break
2021-08-13 23:33:20 +00:00
default:
break
}
}
2021-07-26 12:54:22 +00:00
return (
<div>
2021-08-13 23:33:20 +00:00
<FileBrowserContextMenu
onSelect={onContextSelect}
2021-08-15 23:42:29 +00:00
pasteActive={!!srcID}
2021-08-13 23:33:20 +00:00
/>
2021-08-01 19:42:26 +00:00
<DragAndDrop
2021-08-06 11:59:01 +00:00
handleDrop={async (files)=>{
await handleDrop(files)
}}
2021-08-01 19:42:26 +00:00
>
2021-08-20 17:24:05 +00:00
<div className="flex justify-between">
<Breadcrum path={path} onDirClick={(newPath)=>{
setPath(newPath)
}}/>
<div className="ml-auto">
<CreateDirButton
onPressed={async (dirName)=>{
await createDirMutation({variables:{path:dirName}})
refetchDir()
}}
/>
</div>
<div>
<FileUploadButton
onUpload={(files)=>handleDrop(files)}
/>
</div>
</div>
2021-08-01 19:42:26 +00:00
<div>
{loading &&
2021-08-17 13:39:45 +00:00
<div>Loading...</div> // TODO: center
2021-08-01 19:42:26 +00:00
}
2021-08-17 13:39:45 +00:00
<table className="w-full">
<thead className="border-b-2">
2021-08-01 19:42:26 +00:00
<tr>
2021-08-17 13:39:45 +00:00
<th className="text-left">Name</th>
<th className="text-left">Last Modified</th>
<th className="text-left">Size</th>
2021-08-01 19:42:26 +00:00
</tr>
</thead>
2021-08-17 13:39:45 +00:00
<tbody className="divide-y">
2021-07-26 12:54:22 +00:00
2021-08-01 19:42:26 +00:00
{ data?.directorys.map(v => (<FileBrowserElement
key={v?.id}
dir={v}
onClick={(dir)=>{
setPath(dir.id)
}}
2021-08-10 09:21:18 +00:00
onContextMenu={(e)=>{
openDirContextMenu(e,v.id)
}}
2021-08-01 19:42:26 +00:00
/>))}
{ data?.files.map(v => (<FileBrowserElement
key={v?.id}
file={v}
onClick={(file)=>{
setOpenFileId(file.id)
setShowFile(true)
}}
2021-08-10 09:21:18 +00:00
onContextMenu={(e)=>{
openFileContextMenu(e,v.id)
}}
2021-08-01 19:42:26 +00:00
/>))}
</tbody>
</table>
</div>
{<FileOpen id={openFileId} show={showFile} onCloseClick={()=>{
setShowFile(false)
}} />}
</DragAndDrop>
2021-07-26 12:54:22 +00:00
</div>
)
}
export default FileBrowser