Canvas: Edit/Deploy mode
Change-Id: I51e5b6c2a1f06009433b0d0824ffcf3dfe39d34e
diff --git a/apps/canvas/front/src/components/actions.tsx b/apps/canvas/front/src/components/actions.tsx
index 509b51c..f292c30 100644
--- a/apps/canvas/front/src/components/actions.tsx
+++ b/apps/canvas/front/src/components/actions.tsx
@@ -4,6 +4,14 @@
import { generateDodoConfig } from "@/lib/config";
import { useNodes, useReactFlow } from "@xyflow/react";
import { useToast } from "@/hooks/use-toast";
+import {
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuTrigger,
+} from "./ui/dropdown-menu";
+import { Menu } from "lucide-react";
function toNodeType(t: string): string {
if (t === "ingress") {
@@ -64,6 +72,7 @@
return;
}
setLoading(true);
+ store.setMode("deploy");
try {
const config = generateDodoConfig(projectId, nodes, env);
if (config == null) {
@@ -92,6 +101,7 @@
});
}
} catch (e) {
+ store.setMode("edit");
console.log(e);
toast({
variant: "destructive",
@@ -100,7 +110,7 @@
} finally {
setLoading(false);
}
- }, [projectId, instance, nodes, env, setLoading, toast, monitor]);
+ }, [projectId, instance, nodes, env, setLoading, toast, monitor, store]);
const save = useCallback(async () => {
if (projectId == null) {
return;
@@ -128,7 +138,7 @@
if (projectId == null) {
return;
}
- const resp = await fetch(`/api/project/${projectId}/saved`, {
+ const resp = await fetch(`/api/project/${projectId}/saved/${store.mode === "deploy" ? "deploy" : "draft"}`, {
method: "GET",
});
const inst = await resp.json();
@@ -142,7 +152,9 @@
store.setNodes([]);
instance.setViewport({ x: 0, y: 0, zoom: 1 });
}, [store, instance]);
- // TODO(gio): Update store
+ const edit = useCallback(async () => {
+ store.setMode("edit");
+ }, [store]);
const deleteProject = useCallback(async () => {
if (projectId == null) {
return;
@@ -154,12 +166,12 @@
clear();
store.setProject(undefined);
toast({
- title: "Save succeeded",
+ title: "Project deleted",
});
} else {
toast({
variant: "destructive",
- title: "Save failed",
+ title: "Failed to delete project",
description: await resp.text(),
});
}
@@ -214,22 +226,71 @@
setReloadProps({ disabled: projectId === undefined });
}
}, [ok, loading, reloading, projectId]);
- return (
- <>
- <Button onClick={deploy} {...deployProps}>
- Deploy
- </Button>
- <Button onClick={reload} {...reloadProps}>
- Reload
- </Button>
- <Button onClick={save}>Save</Button>
- <Button onClick={restoreSaved}>Restore</Button>
- <Button onClick={clear} variant="destructive">
- Clear
- </Button>
- <Button onClick={deleteProject} variant="destructive" disabled={projectId === undefined}>
- Delete
- </Button>
- </>
- );
+ if (store.mode === "deploy") {
+ return (
+ <div className="flex flex-row gap-1 items-center">
+ <Button onClick={edit} {...reloadProps}>
+ Edit
+ </Button>
+ <DropdownMenu>
+ <DropdownMenuTrigger>
+ <Menu className="rounded-md bg-gray-200 opacity-50" />
+ </DropdownMenuTrigger>
+ <DropdownMenuContent className="w-56">
+ <DropdownMenuGroup>
+ <DropdownMenuItem
+ onClick={reload}
+ className="cursor-pointer hover:bg-gray-200"
+ {...reloadProps}
+ >
+ Reload Services
+ </DropdownMenuItem>
+ <DropdownMenuItem
+ onClick={deleteProject}
+ disabled={projectId === undefined}
+ className="cursor-pointer hover:bg-gray-200"
+ >
+ Delete Project
+ </DropdownMenuItem>
+ </DropdownMenuGroup>
+ </DropdownMenuContent>
+ </DropdownMenu>
+ </div>
+ );
+ } else {
+ return (
+ <div className="flex flex-row gap-1 items-center">
+ <Button onClick={deploy} {...deployProps}>
+ Deploy
+ </Button>
+ <Button onClick={save}>Save</Button>
+ <DropdownMenu>
+ <DropdownMenuTrigger>
+ <Menu />
+ </DropdownMenuTrigger>
+ <DropdownMenuContent className="w-56">
+ <DropdownMenuGroup>
+ <DropdownMenuItem
+ onClick={restoreSaved}
+ disabled={projectId === undefined}
+ className="cursor-pointer hover:bg-gray-200"
+ >
+ Restore
+ </DropdownMenuItem>
+ <DropdownMenuItem onClick={clear} className="cursor-pointer hover:bg-gray-200">
+ Clear
+ </DropdownMenuItem>
+ <DropdownMenuItem
+ onClick={deleteProject}
+ disabled={projectId === undefined}
+ className="cursor-pointer hover:bg-gray-200"
+ >
+ Delete Project
+ </DropdownMenuItem>
+ </DropdownMenuGroup>
+ </DropdownMenuContent>
+ </DropdownMenu>
+ </div>
+ );
+ }
}