Updates file tree behaviour

Signed-off-by: Mihovil Ilakovac <mihovil@ilakovac.com>
This commit is contained in:
Mihovil Ilakovac 2023-06-20 12:03:01 +02:00
parent 85cf960121
commit 20e3ee2c57
4 changed files with 80 additions and 16 deletions

View File

@ -3,7 +3,11 @@ app waspAi {
version: "^0.10.6" version: "^0.10.6"
}, },
title: "wasp-ai", title: "wasp-ai",
dependencies: [("uuid", "^9.0.0"), ("prismjs", "^1.29.0")], dependencies: [
("uuid", "^9.0.0"),
("prismjs", "^1.29.0"),
("react-accessible-treeview", "2.6.1")
],
client: { client: {
rootComponent: import { RootComponent } from "@client/RootComponent.jsx", rootComponent: import { RootComponent } from "@client/RootComponent.jsx",
} }

View File

@ -13,7 +13,7 @@ export function CodeHighlight(props = {}) {
...others ...others
} = props; } = props;
const langCls = language ? `language-${language}` : ""; const langCls = language ? `language-${language}` : "";
async function highlight() { function highlight() {
if (codeRef.current) { if (codeRef.current) {
Prism.highlightElement(codeRef.current); Prism.highlightElement(codeRef.current);
} }

View File

@ -0,0 +1,42 @@
import React, { useMemo } from "react";
export function FileTree({ paths, activeFilePath, onActivePathSelect }) {
const tree = useMemo(() => {
if (paths && paths.length > 0) {
const tree = {};
paths.forEach((path) => {
const pathParts = path.split("/");
let node = tree;
pathParts.forEach((part, i) => {
if (i === pathParts.length - 1) {
node[part] = path;
} else {
if (!node[part]) {
node[part] = {};
}
node = node[part];
}
});
});
return tree;
} else {
return null;
}
}, [paths]);
return (
<div className="flex flex-col gap-2">
{paths.map((path) => (
<div
key={path}
className={
"px-4 py-2 bg-slate-200 rounded cursor-pointer " +
(activeFilePath === path ? "bg-yellow-400" : "")
}
onClick={() => onActivePathSelect(path)}
>
<div className="font-bold">{path}</div>
</div>
))}
</div>
);
}

View File

@ -4,6 +4,7 @@ import startGeneratingNewApp from "@wasp/actions/startGeneratingNewApp";
import getAppGenerationResult from "@wasp/queries/getAppGenerationResult"; import getAppGenerationResult from "@wasp/queries/getAppGenerationResult";
import { useQuery } from "@wasp/queries"; import { useQuery } from "@wasp/queries";
import { CodeHighlight } from "../components/CodeHighlight"; import { CodeHighlight } from "../components/CodeHighlight";
import { FileTree } from "../components/FileTree";
const MainPage = () => { const MainPage = () => {
const [appName, setAppName] = useState(""); const [appName, setAppName] = useState("");
@ -68,6 +69,30 @@ const MainPage = () => {
} }
}, [activeFilePath]); }, [activeFilePath]);
const interestingFilePaths = useMemo(() => {
if (files) {
return Object.keys(files)
.filter(
(path) =>
path !== ".env.server" &&
path !== ".env.client" &&
path !== "src/client/vite-env.d.ts" &&
path !== "src/client/tsconfig.json" &&
path !== "src/server/tsconfig.json" &&
path !== "src/shared/tsconfig.json" &&
path !== ".gitignore" &&
path !== "src/.waspignore" &&
path !== ".wasproot"
)
.sort(
(a, b) =>
(a.endsWith(".wasp") ? 0 : 1) - (b.endsWith(".wasp") ? 0 : 1)
);
} else {
return [];
}
}, [files]);
return ( return (
<div className="container"> <div className="container">
<div <div
@ -167,19 +192,12 @@ const MainPage = () => {
Files Files
</h2> </h2>
<div className="grid gap-4 grid-cols-[300px_minmax(900px,_1fr)_100px]"> <div className="grid gap-4 grid-cols-[300px_minmax(900px,_1fr)_100px]">
<aside className="bg-slate-100 p-4 rounded flex flex-col gap-2 sticky top-0"> <aside className="bg-slate-100 p-4 rounded sticky top-0">
{Object.keys(files).map((path) => ( <FileTree
<div paths={interestingFilePaths}
key={path} activeFilePath={activeFilePath}
className={ onActivePathSelect={setActiveFilePath}
"px-4 py-2 bg-slate-200 rounded cursor-pointer " + />
(activeFilePath === path ? "bg-yellow-400" : "")
}
onClick={() => setActiveFilePath(path)}
>
<div className="font-bold">{path}</div>
</div>
))}
</aside> </aside>
{activeFilePath && ( {activeFilePath && (