Canvas: Restore viewport on project select
Change-Id: I3dd60983ca0abe5fd3b84011bad384d50fa90dc1
diff --git a/apps/canvas/front/src/ProjectSelect.tsx b/apps/canvas/front/src/ProjectSelect.tsx
index 4367bef..5df5f6d 100644
--- a/apps/canvas/front/src/ProjectSelect.tsx
+++ b/apps/canvas/front/src/ProjectSelect.tsx
@@ -55,7 +55,7 @@
useEffect(() => {
refreshProjects();
- });
+ }, [refreshProjects]);
const [createNewOpen, setCreateNewOpen] = useState(false);
const onSelect = useCallback(
diff --git a/apps/canvas/front/src/components/canvas.tsx b/apps/canvas/front/src/components/canvas.tsx
index 252c1b9..861437f 100644
--- a/apps/canvas/front/src/components/canvas.tsx
+++ b/apps/canvas/front/src/components/canvas.tsx
@@ -10,7 +10,7 @@
Panel,
useStoreApi,
} from "@xyflow/react";
-import { useStateStore, AppState, AppNode } from "@/lib/state";
+import { useStateStore, AppState, AppNode, useZoom } from "@/lib/state";
import { useShallow } from "zustand/react/shallow";
import { useCallback, useEffect, useMemo } from "react";
import { NodeGatewayHttps } from "@/components/node-gateway-https";
@@ -36,6 +36,7 @@
const store = useStateStore();
const instance = useReactFlow();
const flow = useStoreApi();
+ const viewport = useZoom();
useEffect(() => {
store.setViewport({
width: flow.getState().width,
@@ -45,6 +46,9 @@
transformZoom: flow.getState().transform[2],
});
}, [store, flow]);
+ useEffect(() => {
+ instance.setViewport(viewport);
+ }, [viewport, instance]);
const nodeTypes = useMemo(
() => ({
network: NodeNetwork,
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,
});