feat: add NetworkCanvas wrapper and DiagramHeader components
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
87
frontend/src/components/network/NetworkCanvas.tsx
Normal file
87
frontend/src/components/network/NetworkCanvas.tsx
Normal file
@@ -0,0 +1,87 @@
|
||||
import { useCallback } from 'react'
|
||||
import {
|
||||
ReactFlow,
|
||||
Background,
|
||||
Controls,
|
||||
MiniMap,
|
||||
BackgroundVariant,
|
||||
type OnConnect,
|
||||
type OnNodesChange,
|
||||
type OnEdgesChange,
|
||||
type Node,
|
||||
type Edge,
|
||||
} from '@xyflow/react'
|
||||
import { nodeTypes } from './nodes/nodeTypes'
|
||||
import { edgeTypes } from './edges/edgeTypes'
|
||||
|
||||
interface NetworkCanvasProps {
|
||||
nodes: Node[]
|
||||
edges: Edge[]
|
||||
onNodesChange: OnNodesChange
|
||||
onEdgesChange: OnEdgesChange
|
||||
onConnect: OnConnect
|
||||
onNodeSelect: (node: Node | null) => void
|
||||
onEdgeSelect: (edge: Edge | null) => void
|
||||
onDrop: (event: React.DragEvent) => void
|
||||
onDragOver: (event: React.DragEvent) => void
|
||||
}
|
||||
|
||||
export function NetworkCanvas({
|
||||
nodes,
|
||||
edges,
|
||||
onNodesChange,
|
||||
onEdgesChange,
|
||||
onConnect,
|
||||
onNodeSelect,
|
||||
onEdgeSelect,
|
||||
onDrop,
|
||||
onDragOver,
|
||||
}: NetworkCanvasProps) {
|
||||
const handleSelectionChange = useCallback(({ nodes: selectedNodes, edges: selectedEdges }: { nodes: Node[]; edges: Edge[] }) => {
|
||||
if (selectedNodes.length === 1) {
|
||||
onNodeSelect(selectedNodes[0])
|
||||
onEdgeSelect(null)
|
||||
} else if (selectedEdges.length === 1) {
|
||||
onEdgeSelect(selectedEdges[0])
|
||||
onNodeSelect(null)
|
||||
} else {
|
||||
onNodeSelect(null)
|
||||
onEdgeSelect(null)
|
||||
}
|
||||
}, [onNodeSelect, onEdgeSelect])
|
||||
|
||||
const handlePaneClick = useCallback(() => {
|
||||
onNodeSelect(null)
|
||||
onEdgeSelect(null)
|
||||
}, [onNodeSelect, onEdgeSelect])
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onConnect={onConnect}
|
||||
onSelectionChange={handleSelectionChange}
|
||||
onPaneClick={handlePaneClick}
|
||||
onDrop={onDrop}
|
||||
onDragOver={onDragOver}
|
||||
nodeTypes={nodeTypes}
|
||||
edgeTypes={edgeTypes}
|
||||
defaultEdgeOptions={{ type: 'connection' }}
|
||||
deleteKeyCode={['Backspace', 'Delete']}
|
||||
multiSelectionKeyCode="Shift"
|
||||
fitView
|
||||
className="bg-page"
|
||||
>
|
||||
<Background variant={BackgroundVariant.Dots} color="var(--color-border-default)" gap={20} size={1} />
|
||||
<Controls className="!border-default !bg-card [&>button]:!border-default [&>button]:!bg-card [&>button]:!fill-text-primary" />
|
||||
<MiniMap
|
||||
nodeColor="var(--color-bg-elevated)"
|
||||
maskColor="rgba(0,0,0,0.5)"
|
||||
className="!border-default !bg-card"
|
||||
position="bottom-right"
|
||||
/>
|
||||
</ReactFlow>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user