Canvas: Update layout

Combine separate Overview and Canvas tabs into one Build tab
Add Overview <-> Canvas switcher to Actions

Change-Id: I40f7742be587b475ae6e88af2bcf9cae34f93168
diff --git a/apps/canvas/front/src/lib/state.ts b/apps/canvas/front/src/lib/state.ts
index 5e9315b..b0237a9 100644
--- a/apps/canvas/front/src/lib/state.ts
+++ b/apps/canvas/front/src/lib/state.ts
@@ -196,6 +196,7 @@
 export type AppState = {
 	projectId: string | undefined;
 	mode: "edit" | "deploy";
+	buildMode: "overview" | "canvas";
 	projects: Project[];
 	nodes: AppNode[];
 	edges: Edge[];
@@ -219,6 +220,7 @@
 	setEdges: (edges: Edge[]) => void;
 	setProject: (projectId: string | undefined) => Promise<void>;
 	setMode: (mode: "edit" | "deploy") => void;
+	setBuildMode: (buildMode: "overview" | "canvas") => void;
 	updateNode: <T extends NodeType>(id: string, node: NodeUpdate<T>) => void;
 	updateNodeData: <T extends NodeType>(id: string, data: NodeDataUpdate<T>) => void;
 	replaceEdge: (c: Connection, id?: string) => void;
@@ -234,6 +236,7 @@
 const githubRepositoriesSelector = (state: AppState) => state.githubRepositories;
 const githubRepositoriesLoadingSelector = (state: AppState) => state.githubRepositoriesLoading;
 const githubRepositoriesErrorSelector = (state: AppState) => state.githubRepositoriesError;
+const buildModeSelector = (state: AppState) => state.buildMode;
 
 export function useZoom(): ReactFlowViewport {
 	return useStateStore(zoomSelector);
@@ -314,6 +317,10 @@
 	return useStateStore((state) => state.mode);
 }
 
+export function useBuildMode(): "overview" | "canvas" {
+	return useStateStore(buildModeSelector);
+}
+
 const v: Validator = CreateValidators();
 
 function getRandomPosition({ width, height, transformX, transformY, transformZoom }: Viewport): XYPosition {
@@ -626,13 +633,7 @@
 			setN(inst.nodes);
 			set({ edges: inst.edges });
 			injectNetworkNodes();
-			if (
-				get().zoom.x !== inst.viewport.x ||
-				get().zoom.y !== inst.viewport.y ||
-				get().zoom.zoom !== inst.viewport.zoom
-			) {
-				set({ zoom: inst.viewport });
-			}
+			// TODO(gio): set viewport
 		};
 
 		eventSource.onerror = (err) => {
@@ -645,6 +646,7 @@
 	return {
 		projectId: undefined,
 		mode: "edit",
+		buildMode: "overview",
 		projects: [],
 		nodes: [],
 		edges: [],
@@ -801,6 +803,9 @@
 				connectToStateStream(projectId, mode);
 			}
 		},
+		setBuildMode: (buildMode) => {
+			set({ buildMode });
+		},
 		setProject: async (projectId) => {
 			const currentProjectId = get().projectId;
 			if (projectId === currentProjectId) {