summaryrefslogtreecommitdiff
path: root/frontend/src/App.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/App.tsx')
-rw-r--r--frontend/src/App.tsx24
1 files changed, 22 insertions, 2 deletions
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 5776091..8ae93c7 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useRef, useState } from 'react';
+import { useCallback, useEffect, useRef, useState } from 'react';
import ReactFlow, {
Background,
Controls,
@@ -47,7 +47,10 @@ function Flow() {
theme,
toggleTheme,
autoLayout,
- findNonOverlappingPosition
+ findNonOverlappingPosition,
+ setLastViewport,
+ saveCurrentBlueprint,
+ currentBlueprintPath
} = useFlowStore();
const reactFlowWrapper = useRef<HTMLDivElement>(null);
@@ -190,6 +193,22 @@ function Flow() {
createNodeFromArchive(archiveId, position);
};
+ // Ctrl/Cmd + S manual save
+ useEffect(() => {
+ const handler = (e: KeyboardEvent) => {
+ const isMac = navigator.platform.toLowerCase().includes('mac');
+ if ((isMac ? e.metaKey : e.ctrlKey) && e.key.toLowerCase() === 's') {
+ e.preventDefault();
+ const path = currentBlueprintPath;
+ if (path) {
+ saveCurrentBlueprint(path, getViewport());
+ }
+ }
+ };
+ window.addEventListener('keydown', handler);
+ return () => window.removeEventListener('keydown', handler);
+ }, [currentBlueprintPath, saveCurrentBlueprint, getViewport]);
+
return (
<div className={`w-screen h-screen flex ${theme === 'dark' ? 'dark bg-gray-900' : 'bg-white'}`}>
<LeftSidebar isOpen={isLeftOpen} onToggle={() => setIsLeftOpen(!isLeftOpen)} />
@@ -206,6 +225,7 @@ function Flow() {
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
+ onMoveEnd={(_, viewport) => setLastViewport(viewport)}
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
defaultEdgeOptions={{ type: 'merged' }}