반응형
참고
- Mui Tree View로 파일, 폴더 뷰 만들기
- Mui로 파일 브라우저 만들기
- 파일 브라우저에서 파일 다운로드하기
파일 브라우저에서는 폴더가 앞에, 파일이 뒤에 배치되지만,
현재 구현한 내용은 glob으로 주어진 순서대로 배치되고 있어서 폴더가 뒤로 배치되는 경우도 발생한다.
폴더만 따로, 파일만 따로 glob을 구현해서 따로 fileUI를 만들 수 있지만,
여기에서는 간단히 경로를 보고 파일인지 폴더인지 판단한 후, 재정렬한다.
해당 경로를 "/"로 구분한 뒤, 마지막의 이름에 "."이 있다면 파일로 판단한다.
그리고 폴더와 파일을 따로 filter로 구분한 후, sort로 정렬하고 폴더가 먼저 배치되도록 setFileUI로 합쳤다.
const isFile = (path) => {
let spt = path.split("/");
return spt[spt.length - 1].includes(".");
}
const sortFileUI = (path) => {
let dir = path.filter((val) => isFile(val) === false);
let files = path.filter((val) => isFile(val));
dir.sort();
files.sort();
setFileUI([...dir, ...files]);
}
이제 getFilesForFileBrowser에서 setFileUI를 sortFileUI로 수정하자.
const getFilesForFileBrowser = (path) => {
let server = `http://192.168.55.120:3002`;
/* /D:/... 앞의 / 삭제 */
path = path.substring(1, path.length);
fetch(`${server}/useGlob?path=${path}/*`)
.then((res) => res.json())
.then((data) => sortFileUI(data.findPath));
}
FileBrowser.js 의 전체 코드는 다음과 같다.
import React, { useEffect, useState } from "react";
import TreeView from "@mui/lab/TreeView";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import TreeItem from "@mui/lab/TreeItem";
import FileUI from "./FileUI";
const FileBrowser = () => {
const [treeInfo, setTreeInfo] = useState({});
const [fileUi, setFileUI] = useState([]);
let tmpTreeInfo = {};
let nodeId = 0;
const appendChild = (arr, info) => {
if (arr.child === undefined) arr.child = [];
if (arr.child.findIndex((item) => item.label === info) === -1) {
arr.child.push({ label: info, nodeId });
nodeId++;
}
};
const makeDirectories = (directories) => {
tmpTreeInfo = {};
for (let d of directories) {
let split = d.split("/");
let len = split.length;
let current = tmpTreeInfo;
for (let i = 0; i < len; i++) {
appendChild(current, split[i]);
current = current.child.find((item) => item.label === split[i]);
}
}
//console.log(tmpTreeInfo);
setTreeInfo(tmpTreeInfo);
};
const getFiles = () => {
// setTreeInfo(localData);
// return;
let server = `http://192.168.55.120:3002`;
let path = `D:\\github\\globfiles\\**`;
fetch(`${server}/useGlob?path=${path}`)
.then((res) => res.json())
.then((data) => makeDirectories(data.findPath));
};
const isFile = (path) => {
let spt = path.split("/");
return spt[spt.length - 1].includes(".");
}
const sortFileUI = (path) => {
let dir = path.filter((val) => isFile(val) === false);
let files = path.filter((val) => isFile(val));
dir.sort();
files.sort();
setFileUI([...dir, ...files]);
}
const getFilesForFileBrowser = (path) => {
let server = `http://192.168.55.120:3002`;
/* /D:/... 앞의 / 삭제 */
path = path.substring(1, path.length);
fetch(`${server}/useGlob?path=${path}/*`)
.then((res) => res.json())
.then((data) => sortFileUI(data.findPath));
}
const makeTreeItem = (info, parent) => {
if (info.child === undefined) return;
return info.child.map((item, idx) => (
<TreeItem
key={idx}
nodeId={item.nodeId.toString()}
label={item.label}
onClick={() => getFilesForFileBrowser(`${parent}/${item.label}`)}
>
{makeTreeItem(item, `${parent}/${item.label}`)}
</TreeItem>
));
};
useEffect(() => {
getFiles();
}, []);
return (
<div
style={{
display: "grid",
gridTemplateColumns: "20% 1% auto",
gridGap: "25px",
width: "100%",
}}
>
{/* <button onClick={getFiles}>test</button> */}
<div>
<a href="https://bloodstrawberry.tistory.com/1175" target="_blank" rel="noreferrer">Node Server 구현 필요</a>
<TreeView
aria-label="file system navigator"
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
sx={{ height: 500, overflowX: "hidden" }}
//sx={{ height: 240, flexGrow: 1, maxWidth: 400, overflowY: "auto" }}
>
{makeTreeItem(treeInfo, "")}
</TreeView>
</div>
<div style={{ borderRight: "2px solid black" }} />
<div>
{fileUi.map((f, idx) => <FileUI key={idx} pathInfo={f}/>)}
</div>
</div>
);
};
export default FileBrowser;
반응형
댓글