Canvas: Restore viewport on project select

Change-Id: I3dd60983ca0abe5fd3b84011bad384d50fa90dc1
diff --git a/apps/canvas/front/src/lib/state.ts b/apps/canvas/front/src/lib/state.ts
index d64f81f..b8db5b5 100644
--- a/apps/canvas/front/src/lib/state.ts
+++ b/apps/canvas/front/src/lib/state.ts
@@ -1,7 +1,7 @@
 import { Category, defaultCategories } from "./categories";
 import { CreateValidators, Validator } from "./config";
 import { GitHubService, GitHubServiceImpl } from "./github";
-import type { Edge, Node, OnConnect, OnEdgesChange, OnNodesChange } from "@xyflow/react";
+import type { Edge, Node, OnConnect, OnEdgesChange, OnNodesChange, Viewport as ReactFlowViewport } from "@xyflow/react";
 import {
 	addEdge,
 	applyEdgeChanges,
@@ -377,6 +377,7 @@
 	projects: Project[];
 	nodes: AppNode[];
 	edges: Edge[];
+	zoom: ReactFlowViewport;
 	categories: Category[];
 	messages: Message[];
 	env: Env;
@@ -403,10 +404,10 @@
 const messagesSelector = (state: AppState) => state.messages;
 const githubServiceSelector = (state: AppState) => state.githubService;
 const envSelector = (state: AppState) => state.env;
-const dimensionsSelector = (state: AppState) => state.dimensions;
+const zoomSelector = (state: AppState) => state.zoom;
 
-export function useDimensions(): Dimensions {
-	return useStateStore(dimensionsSelector);
+export function useZoom(): ReactFlowViewport {
+	return useStateStore(zoomSelector);
 }
 
 export function useProjectId(): string | undefined {
@@ -457,9 +458,6 @@
 
 export const useStateStore = create<AppState>((set, get): AppState => {
 	const setN = (nodes: AppNode[]) => {
-		if (nodes.length == 0) {
-			console.trace("setN", nodes);
-		}
 		set({
 			nodes,
 			messages: v(nodes),
@@ -473,7 +471,14 @@
 		});
 		const inst = await resp.json();
 		setN(inst.nodes || []);
-		get().setEdges(inst.edges || []);
+		set({ edges: inst.edges || [] });
+		if (
+			get().zoom.x !== inst.viewport.x ||
+			get().zoom.y !== inst.viewport.y ||
+			get().zoom.zoom !== inst.viewport.zoom
+		) {
+			set({ zoom: inst.viewport });
+		}
 	};
 
 	function updateNodeData<T extends NodeType>(id: string, data: NodeDataUpdate<T>): void {
@@ -669,6 +674,11 @@
 			width: 800,
 			height: 600,
 		},
+		zoom: {
+			x: 0,
+			y: 0,
+			zoom: 1,
+		},
 		githubService: null,
 		setViewport: (viewport) => {
 			const { viewport: vp } = get();
@@ -769,7 +779,6 @@
 				console.error("Failed to fetch integrations:", error);
 			} finally {
 				if (JSON.stringify(get().env) !== JSON.stringify(env)) {
-					console.log(env);
 					set({ env });
 					const newNetworks = env.networks.filter(
 						(x) => !get().nodes.some((n) => n.type === "network" && n.data.domain === x.domain),
@@ -801,6 +810,9 @@
 			set({ mode });
 		},
 		setProject: async (projectId) => {
+			if (projectId === get().projectId) {
+				return;
+			}
 			set({
 				projectId,
 			});