blob: 1c86aae9c8e042216d9d788d55b24e32b6740f63 [file] [log] [blame]
import React, { useMemo } from "react";
import { useStateStore, useLeadAgent } from "@/lib/state";
import { NodeDetails } from "./components/node-details";
import { Actions } from "./components/actions";
import { Canvas } from "./components/canvas";
import { Separator } from "./components/ui/separator";
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "./components/ui/resizable";
import { AppNode, NodeType } from "config";
const sections: { title: string; nodes: NodeType[] }[] = [
{
title: "Services",
nodes: ["app"],
},
{
title: "Databases",
nodes: ["postgresql", "mongodb"],
},
{
title: "File systems",
nodes: ["volume"],
},
];
export function Overview(): React.ReactNode {
const leadAgent = useLeadAgent();
if (leadAgent) {
return (
<ResizablePanelGroup direction="horizontal" className="w-full h-full">
<ResizablePanel defaultSize={25}>
<iframe
key={leadAgent.name}
src={`${leadAgent.address}?m`}
title={leadAgent.agentName}
className="w-full h-full"
/>
</ResizablePanel>
<ResizableHandle withHandle />
<ResizablePanel defaultSize={75} className="!overflow-y-auto !overflow-x-hidden">
<OverviewImpl />
</ResizablePanel>
</ResizablePanelGroup>
);
} else {
return <OverviewImpl />;
}
}
function OverviewImpl(): React.ReactNode {
const store = useStateStore();
const nodes = useMemo(() => {
return store.nodes.filter((n) => n.type !== "network" && n.type !== "github" && n.type !== undefined);
}, [store.nodes]);
const groupedNodes = useMemo(() => {
return sections
.map((s) => ({
title: s.title,
nodes: nodes.filter((n) => s.nodes.includes(n.type)),
}))
.filter((s) => s.nodes.length > 0);
}, [nodes]);
const isDeployMode = useMemo(() => store.mode === "deploy", [store.mode]);
return (
<div className="h-full w-full overflow-auto bg-white p-2">
<div className="w-full flex flex-row justify-end">
<Actions isOverview={true} />
<Canvas className="hidden" />
</div>
<div className="flex flex-col gap-4 pt-2">
{groupedNodes.map((s, index) => (
<>
{index > 0 && <Separator />}
<Section key={s.title} title={s.title} nodes={s.nodes} isDeployMode={isDeployMode} />
</>
))}
</div>
</div>
);
}
function Section({
title,
nodes,
isDeployMode,
}: {
title: string;
nodes: AppNode[];
isDeployMode: boolean;
}): React.ReactNode {
if (nodes.length === 0) return null;
return (
<div className="w-full">
<h2 className="text-lg font-semibold mb-2">{title}</h2>
<div className="flex flex-wrap gap-4 pl-4">
{nodes.map((n) => (
<NodeDetails
key={n.id}
node={n}
disabled={isDeployMode}
showName={true}
isOverview={true}
className="min-w-[500px] rounded-lg border-gray-200 border-2 p-2"
/>
))}
</div>
</div>
);
}