From cf2bc1ec07b1aa59423374549aa81bd263805500 Mon Sep 17 00:00:00 2001 From: Ghraven Date: Fri, 12 Jun 2026 04:24:00 +0800 Subject: [PATCH] feat: export selected graph nodes as JSON --- .../context-menu/background-context-menu.tsx | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/flowsint-app/src/components/sketches/graph/context-menu/background-context-menu.tsx b/flowsint-app/src/components/sketches/graph/context-menu/background-context-menu.tsx index 7226269..db9f145 100644 --- a/flowsint-app/src/components/sketches/graph/context-menu/background-context-menu.tsx +++ b/flowsint-app/src/components/sketches/graph/context-menu/background-context-menu.tsx @@ -16,6 +16,7 @@ import { BadgeAlert, Plus, Download, + FileJson, Trash2 } from 'lucide-react' import { Enricher, Flow, GraphNode } from '@/types' @@ -423,10 +424,47 @@ type SubActionsProps = { selectedNodes: GraphNode[] } const SubActions = memo(({ selectedNodes }: SubActionsProps) => { - const contentToCopy = useMemo(() => selectedNodes.map((node) => node.nodeLabel).join('\n'), []) + const contentToCopy = useMemo( + () => selectedNodes.map((node) => node.nodeLabel).join('\n'), + [selectedNodes] + ) + const edges = useGraphStore((s) => s.edges) + const selectedEdges = useMemo(() => { + const selectedNodeIds = new Set(selectedNodes.map((node) => node.id)) + return edges.filter( + (edge) => selectedNodeIds.has(edge.source) && selectedNodeIds.has(edge.target) + ) + }, [edges, selectedNodes]) + + const handleExportJson = useCallback(() => { + const payload = { + exported_at: new Date().toISOString(), + nodes: selectedNodes, + edges: selectedEdges + } + const blob = new Blob([JSON.stringify(payload, null, 2)], { type: 'application/json' }) + const href = URL.createObjectURL(blob) + const link = document.createElement('a') + link.href = href + link.download = `flowsint-selection-${new Date().toISOString().replace(/[:.]/g, '-')}.json` + document.body.appendChild(link) + link.click() + link.remove() + URL.revokeObjectURL(href) + }, [selectedEdges, selectedNodes]) + return ( -
+
+
) })