Canvas: Implement delete project

Change-Id: I0c2abfde3d813376b9f22ab8dc8b1752262679cb
diff --git a/apps/canvas/front/src/components/actions.tsx b/apps/canvas/front/src/components/actions.tsx
index 7d0afe7..66235b3 100644
--- a/apps/canvas/front/src/components/actions.tsx
+++ b/apps/canvas/front/src/components/actions.tsx
@@ -125,7 +125,30 @@
     const clear = useCallback(() => {
         store.setEdges([]);
         store.setNodes([]);
+        instance.setViewport({ x: 0, y: 0, zoom: 1 });
     }, [store]);
+    // TODO(gio): Update store
+    const deleteProject = useCallback(async () => {
+        if (projectId == null) {
+            return;
+        }
+        const resp = await fetch(`/api/project/${projectId}`, {
+            method: "DELETE",
+        });
+        if (resp.ok) {
+            clear();
+            store.setProject(undefined);
+            toast({
+                title: "Save succeeded",
+            });
+        } else {
+            toast({
+                variant: "destructive",
+                title: "Save failed",
+                description: await resp.text(),
+            });
+        }            
+    }, [store, clear]);
     const [props, setProps] = useState({});
     useEffect(() => {
         if (loading) {
@@ -141,7 +164,8 @@
             <Button onClick={deploy} {...props}>Deploy</Button>
             <Button onClick={save}>Save</Button>
             <Button onClick={restoreSaved}>Restore</Button>
-            <Button onClick={clear}>Clear</Button>
+            <Button onClick={clear} variant="destructive">Clear</Button>
+            <Button onClick={deleteProject} variant="destructive" disabled={projectId === undefined}>Delete</Button>
         </>
     )
 }
\ No newline at end of file
diff --git a/apps/canvas/front/src/lib/state.ts b/apps/canvas/front/src/lib/state.ts
index f2836f1..51f67a6 100644
--- a/apps/canvas/front/src/lib/state.ts
+++ b/apps/canvas/front/src/lib/state.ts
@@ -273,7 +273,7 @@
   onConnect: OnConnect;
   setNodes: (nodes: AppNode[]) => void;
   setEdges: (edges: Edge[]) => void;
-  setProject: (projectId: string) => void;
+  setProject: (projectId: string | undefined) => void;
   setProjects: (projects: Project[]) => void;
   updateNode: <T extends NodeType>(id: string, data: DeepPartial<(AppNode & (Pick<AppNode, "type"> | { type: T }))>) => void;
   updateNodeData: <T extends NodeType>(id: string, data: DeepPartial<(AppNode & (Pick<AppNode, "type"> | { type: T }))["data"]>) => void;