Skip to content

Commit

Permalink
change layout
Browse files Browse the repository at this point in the history
  • Loading branch information
florianbgt committed Jan 15, 2025
1 parent 92de254 commit a454142
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 126 deletions.
91 changes: 68 additions & 23 deletions packages/app/src/components/FileExplorer/FileExplorer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Button, TextField, Tooltip } from "@radix-ui/themes";
import { Button, ScrollArea, TextField, Tooltip } from "@radix-ui/themes";
import { useEffect, useState } from "react";
import { Link, useParams } from "react-router";
import { FileExplorerSkeleton } from "./Skeleton";

interface FileProp {
path: string;
Expand All @@ -13,11 +14,13 @@ interface TreeData {
}

export default function FileExplorer(props: {
busy: boolean;
files: FileProp[];
focusedId?: string;
onNodeFocus: (id: string) => void;
onNodeUnfocus: (id: string) => void;
}) {
const [isOpen, setIsOpen] = useState<boolean>(true);
const [search, setSearch] = useState<string>("");
const [treeData, setTreeData] = useState<TreeData[]>([]);

Expand Down Expand Up @@ -115,34 +118,76 @@ export default function FileExplorer(props: {
}, [props.files, search]);

return (
<div className="flex flex-col gap-2 px-2">
<TextField.Root
placeholder="Search"
value={search}
onChange={(e) => setSearch(e.target.value)}
>
<TextField.Slot>
<div className="h-full flex flex-col">
<div className="flex justify-end">
<Button
className="text-text-light dark:text-text-dark p-0 mx-2 my-1"
size="1"
onClick={() => setIsOpen(!isOpen)}
variant="ghost"
radius="full"
>
<svg
width="20px"
height="20px"
width="40"
height="40"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M15.7955 15.8111L21 21M18 10.5C18 14.6421 14.6421 18 10.5 18C6.35786 18 3 14.6421 3 10.5C3 6.35786 6.35786 3 10.5 3C14.6421 3 18 6.35786 18 10.5Z" />
{isOpen ? (
<path d="M15 6L9 12L15 18" />
) : (
<path d="M9 6L15 12L9 18" />
)}
</svg>
</TextField.Slot>
</TextField.Root>
<ListElement
nodes={treeData}
focusedId={props.focusedId}
onNodeFocus={props.onNodeFocus}
onNodeUnfocus={props.onNodeUnfocus}
/>
</Button>
</div>

<div
style={{ width: isOpen ? "300px" : "0px" }}
className="grow flex flex-col gap-4 overflow-hidden transition-all duration-300 my-2"
>
{props.busy ? (
<FileExplorerSkeleton />
) : (
<>
<TextField.Root
placeholder="Search"
value={search}
onChange={(e) => setSearch(e.target.value)}
className={`transition-all duration-300 overflow-hidden ${!isOpen && "w-0"}`}
>
<TextField.Slot className="w-full">
<svg
width="20px"
height="20px"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M15.7955 15.8111L21 21M18 10.5C18 14.6421 14.6421 18 10.5 18C6.35786 18 3 14.6421 3 10.5C3 6.35786 6.35786 3 10.5 3C14.6421 3 18 6.35786 18 10.5Z" />
</svg>
</TextField.Slot>
</TextField.Root>
<ScrollArea scrollbars="vertical">
<ListElement
nodes={treeData}
focusedId={props.focusedId}
onNodeFocus={props.onNodeFocus}
onNodeUnfocus={props.onNodeUnfocus}
/>
</ScrollArea>
</>
)}
</div>
</div>
);
}
Expand Down
15 changes: 15 additions & 0 deletions packages/app/src/components/FileExplorer/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Skeleton } from "@radix-ui/themes";

export function FileExplorerSkeleton() {
return (
<div className="h-full flex flex-col justify-center items-center gap-5">
<Skeleton width="200px" height="75px" />
<Skeleton width="200px" height="75px" />
<Skeleton width="200px" height="75px" />
<Skeleton width="200px" height="75px" />
<Skeleton width="200px" height="75px" />
<Skeleton width="200px" height="75px" />
<Skeleton width="200px" height="75px" />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import GroupNode from "./GroupNode";
import EndpointNode from "./EndpointNode";
import SmoothEdge from "../SmoothEdge";
import Controls from "../Controls";
import { ReactFlowSkeleton } from "../Skeleton";

export default function SplitConfigureTree(props: {
loading: boolean;
busy: boolean;
endpoints: Endpoint[];
isOutOfSynced: boolean;
Expand Down Expand Up @@ -190,11 +192,15 @@ export default function SplitConfigureTree(props: {
}

useEffect(() => {
const element = document.querySelector(".react-flow__panel") as HTMLElement;
if (element) {
element.style.display = "none";
if (!props.loading) {
const element = document.querySelector(
".react-flow__panel",
) as HTMLElement;
if (element) {
element.style.display = "none";
}
}
}, []);
}, [props.loading]);

function onNodeDragStart(_event: React.MouseEvent, node: Node) {
setNodes((nds) =>
Expand All @@ -216,6 +222,10 @@ export default function SplitConfigureTree(props: {
);
}

if (props.loading) {
return <ReactFlowSkeleton />;
}

return (
<ReactFlow
nodeTypes={nodeTypes}
Expand Down
111 changes: 19 additions & 92 deletions packages/app/src/layout/ReactFlow.tsx
Original file line number Diff line number Diff line change
@@ -1,64 +1,31 @@
import { Button } from "@radix-ui/themes";
import { useContext, useEffect, useRef, useState } from "react";
import { useContext } from "react";
import { ThemeContext } from "../contexts/ThemeContext";
import { ReactFlowSkeleton } from "../components/ReactFlow/Skeleton";

export default function ReactFlowLayout(props: {
busy?: boolean;
sideBarSlot?: React.ReactNode;
chartSlot: React.ReactNode;
}) {
const themeContext = useContext(ThemeContext);

const containerRef = useRef<HTMLDivElement>(null);
// Set to 0px initially, and then update it to the actual height with the useEffect
const [height, setHeight] = useState("0px");

useEffect(() => {
if (containerRef.current) {
const { height: computedHeight } = window.getComputedStyle(
containerRef.current,
);
setHeight(computedHeight);
}
}, []);

const [isCollapsed, setIsCollapsed] = useState(false);

const toggleSidebar = () => {
setIsCollapsed(!isCollapsed);
};

return (
<div className="flex flex-col min-h-screen bg-background-light text-text-light dark:bg-background-dark dark:text-text-dark">
<div className="px-5 flex items-center gap-10 py-2">
<a
className="flex items-center gap-1 text-gray-light dark:text-gray-dark no-underline "
href="https://nanoapi.io"
target="_blank"
>
<img src="/logo.png" alt="logo" className="w-8 h-8" />
<span className="text-xl font-bold">NanoAPI</span>
</a>
<a
href="https://nanoapi.io/docs"
target="_blank"
className="text-gray-light dark:text-gray-dark no-underline hover:underline"
>
Documentation
</a>
<a
href="https://nanoapi.io/docs/faqs"
target="_blank"
className="text-gray-light dark:text-gray-dark no-underline hover:underline"
>
Help
</a>
</div>
<div ref={containerRef} className="grow flex gap-3 mx-5 mb-5">
<div className="flex flex-col gap-2 bg-secondaryBackground-light dark:bg-secondaryBackground-dark rounded-3xl p-3">
<div className="grow" />
<div className="flex flex-col space-y-2 border border-secondarySurface-light dark:border-secondarySurface-dark px-3 pt-2 pb-1 rounded-xl">
<div className="h-screen grow flex gap-3 bg-background-light text-text-light dark:bg-background-dark dark:text-text-dark px-4 py-3">
{props.sideBarSlot && (
<div className="flex flex-col gap-2 bg-secondaryBackground-light dark:bg-secondaryBackground-dark rounded-3xl px-2 py-2">
{props.sideBarSlot}
</div>
)}
<div className="flex w-full flex-col gap-2">
<div className="bg-secondaryBackground-light dark:bg-secondaryBackground-dark rounded-3xl flex justify-between items-center px-2 py-2 ">
<a
className="flex items-center gap-1 text-gray-light dark:text-gray-dark no-underline "
href="https://nanoapi.io"
target="_blank"
>
<img src="/logo.png" alt="logo" className="w-8 h-8" />
<span className="text-xl font-bold">NanoAPI</span>
</a>
<div className="flex gap-4 border border-secondarySurface-light dark:border-secondarySurface-dark px-3 py-2 rounded-xl">
<Button
variant="ghost"
size="1"
Expand Down Expand Up @@ -102,47 +69,7 @@ export default function ReactFlowLayout(props: {
</div>
</div>
<div className="relative grow bg-secondaryBackground-light dark:bg-secondaryBackground-dark rounded-3xl overflow-hidden">
{props.busy ? (
<ReactFlowSkeleton />
) : (
<>
{props.sideBarSlot && (
<div
className={`bg-secondaryBackground-light dark:bg-secondaryBackground-dark shadow-lg absolute top-0 left-0 z-10 h-full px-2 py-2 transition-transform duration-300 ${isCollapsed ? "-translate-x-full" : "translate-x-0"}`}
// We need to set the height as style attributes for reactflow to work
// https://reactflow.dev/learn "The <ReactFlow /> component must be wrapped in an element with a width and height."
style={{ height }}
>
<Button
className="absolute text-text-light dark:text-text-dark top-5 right-0 p-0 translate-x-full z-20"
onClick={toggleSidebar}
variant="ghost"
radius="full"
>
<svg
width="40"
height="40"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
xmlns="http://www.w3.org/2000/svg"
>
{isCollapsed ? (
<path d="M9 6L15 12L9 18" />
) : (
<path d="M15 6L9 12L15 18" />
)}
</svg>
</Button>
{props.sideBarSlot}
</div>
)}
{props.chartSlot}
</>
)}
{props.chartSlot}
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/pages/splitConfigure/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ export default function SplitConfigure() {

return (
<ReactFlowLayout
busy={firstLoading}
chartSlot={
<SplitConfigureTree
loading={firstLoading}
busy={busy}
endpoints={endpoints}
isOutOfSynced={isOutOfSynced}
Expand Down
3 changes: 1 addition & 2 deletions packages/app/src/pages/visualizer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,9 @@ export default function BaseVisualizer() {

return (
<ReactFlowLayout
busy={busy}
// sideBarSlot={<FileExplorer height={height} width={350} files={files} />}
sideBarSlot={
<FileExplorer
busy={busy}
files={files}
focusedId={focusedPath}
onNodeFocus={setFocusedPath}
Expand Down
17 changes: 13 additions & 4 deletions packages/app/src/pages/visualizer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import FileNode from "../../components/ReactFlow/VisualizerTree/FileNode";
import { layoutNodesAndEdges } from "../../service/dagree";
import Controls from "../../components/ReactFlow/Controls";
import { useOutletContext } from "react-router";
import { ReactFlowSkeleton } from "../../components/ReactFlow/Skeleton";

export default function Visualizer() {
const context = useOutletContext<{
Expand All @@ -39,11 +40,15 @@ export default function Visualizer() {
const [direction, setDirection] = useState<"TB" | "LR">("TB");

useEffect(() => {
const element = document.querySelector(".react-flow__panel") as HTMLElement;
if (element) {
element.style.display = "none";
if (!context.busy) {
const element = document.querySelector(
".react-flow__panel",
) as HTMLElement;
if (element) {
element.style.display = "none";
}
}
}, []);
}, [context.busy]);

useEffect(() => {
computeNodesAndEdgesFromFiles(context.files);
Expand Down Expand Up @@ -172,6 +177,10 @@ export default function Visualizer() {
context.onNodeUnfocus();
}

if (context.busy) {
return <ReactFlowSkeleton />;
}

return (
<ReactFlow
nodeTypes={nodeTypes}
Expand Down

0 comments on commit a454142

Please sign in to comment.