lynxkite / lynxkite-app /web /src /Directory.tsx
darabos's picture
Split LynxKite into several Python packages.
d7ccb5f
raw
history blame
2.88 kB
// 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>
);
}