Canvas: Monitor deployment

Change-Id: If5895724025e8e4082a372563c159cbf2216b97f
diff --git a/apps/canvas/front/src/components/actions.tsx b/apps/canvas/front/src/components/actions.tsx
index cc09a59..7d0afe7 100644
--- a/apps/canvas/front/src/components/actions.tsx
+++ b/apps/canvas/front/src/components/actions.tsx
@@ -1,4 +1,4 @@
-import { AppNode, useEnv, useMessages, useProjectId, useStateStore } from "@/lib/state";
+import { AppNode, nodeLabel, useEnv, useMessages, useProjectId, useStateStore } from "@/lib/state";
 import { Button } from "./ui/button";
 import { useCallback, useEffect, useState } from "react";
 import { generateDodoConfig } from "@/lib/config";
@@ -18,6 +18,31 @@
     useEffect(() => {
         setOk(!messages.some((m) => m.type === "FATAL"));
     }, [messages, setOk]);
+    const monitor = useCallback(async () => {
+        const m = async function() {
+            const resp = await fetch(`/api/project/${projectId}/status`, {
+                method: "GET",
+                headers: {
+                    "Content-Type": "application/json",
+                },
+            })
+            if (resp.status !== 200) {
+                return;
+            }
+            const data: { type: string, name: string, status: string }[] = await resp.json();
+            console.log(data);
+            for (const n of nodes) {
+                console.log(nodeLabel(n));
+                for (const d of data) {
+                    if (nodeLabel(n) === d.name) {
+                        store.updateNodeData(n.id, { state: d.status });
+                    }
+                }
+            }
+            setTimeout(m, 1000);
+        };
+        setTimeout(m, 100);
+    }, [projectId, nodes]);
     const deploy = useCallback(async () => {
         if (projectId == null) {
             return;
@@ -42,6 +67,7 @@
                 toast({
                     title: "Deployment succeeded",
                 });
+                monitor();
             } else {
                 toast({
                     variant: "destructive",
@@ -96,6 +122,10 @@
         store.setEdges(inst.edges || []);
         instance.setViewport({ x, y, zoom });
     }, [projectId, instance, st]);
+    const clear = useCallback(() => {
+        store.setEdges([]);
+        store.setNodes([]);
+    }, [store]);
     const [props, setProps] = useState({});
     useEffect(() => {
         if (loading) {
@@ -111,6 +141,7 @@
             <Button onClick={deploy} {...props}>Deploy</Button>
             <Button onClick={save}>Save</Button>
             <Button onClick={restoreSaved}>Restore</Button>
+            <Button onClick={clear}>Clear</Button>
         </>
     )
 }
\ No newline at end of file