Spaces:
Running
Running
| // The directory browser. | |
| import { useParams } from "react-router"; | |
| import useSWR from 'swr' | |
| import logo from './assets/logo.png'; | |
| // @ts-ignore | |
| import Home from '~icons/tabler/home' | |
| // @ts-ignore | |
| import Folder from '~icons/tabler/folder' | |
| // @ts-ignore | |
| import FolderPlus from '~icons/tabler/folder-plus' | |
| // @ts-ignore | |
| import File from '~icons/tabler/file' | |
| // @ts-ignore | |
| import FilePlus from '~icons/tabler/file-plus' | |
| const fetcher = (url: string) => fetch(url).then((res) => res.json()); | |
| export default function () { | |
| const { path } = useParams(); | |
| const encodedPath = encodeURIComponent(path || ''); | |
| const list = useSWR(`/api/dir/list?path=${encodedPath}`, fetcher) | |
| function link(item: any) { | |
| if (item.type === 'directory') { | |
| return `/dir/${item.name}`; | |
| } else { | |
| return `/edit/${item.name}`; | |
| } | |
| } | |
| function shortName(item: any) { | |
| return item.name.split('/').pop(); | |
| } | |
| function newName(list: any[]) { | |
| let i = 0; | |
| while (true) { | |
| const name = `Untitled${i ? ` ${i}` : ''}`; | |
| if (!list.find(item => item.name === name)) { | |
| return name; | |
| } | |
| i++; | |
| } | |
| } | |
| function newWorkspaceIn(path: string, list: any[]) { | |
| const pathSlash = path ? `${path}/` : ''; | |
| return `/edit/${pathSlash}${newName(list)}`; | |
| } | |
| async function newFolderIn(path: string, list: any[]) { | |
| const pathSlash = path ? `${path}/` : ''; | |
| const name = newName(list); | |
| const res = await fetch(`/api/dir/mkdir`, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ path: pathSlash + name }), | |
| }); | |
| list = await res.json(); | |
| } | |
| return ( | |
| <div className="directory"> | |
| <div className="logo"> | |
| <a href="https://lynxkite.com/"><img src={logo} className="logo-image" alt="LynxKite logo" /></a> | |
| <div className="tagline">The Complete Graph Data Science Platform</div> | |
| </div> | |
| <div className="entry-list"> | |
| {list.error && <p className="error">{list.error.message}</p>} | |
| {list.isLoading && | |
| <div className="loading spinner-border" role="status"> | |
| <span className="visually-hidden">Loading...</span> | |
| </div>} | |
| {list.data && | |
| <> | |
| <div className="actions"> | |
| <a href={newWorkspaceIn(path || "", list.data)}><FilePlus /> New workspace</a> | |
| <a href="" onClick={() => newFolderIn(path || "", list.data)}><FolderPlus /> New folder</a> | |
| </div> | |
| {path && <div className="breadcrumbs"><a href="/dir/"><Home /></a> {path} </div>} | |
| {list.data.map((item: any) => | |
| <a key={link(item)} className="entry" href={link(item)}> | |
| {item.type === 'directory' ? <Folder /> : <File />} | |
| {shortName(item)} | |
| </a> | |
| )} | |
| </> | |
| } | |
| </div> | |
| </div> | |
| ); | |
| } | |