diff --git a/frontend/src/components/network/NetworkCanvas.tsx b/frontend/src/components/network/NetworkCanvas.tsx
index 4d9ce5b2..1c6569b8 100644
--- a/frontend/src/components/network/NetworkCanvas.tsx
+++ b/frontend/src/components/network/NetworkCanvas.tsx
@@ -28,6 +28,7 @@ interface NetworkCanvasProps {
isDragOver?: boolean
onNodeContextMenu?: (event: React.MouseEvent, node: Node) => void
onPaneContextMenu?: (event: MouseEvent | React.MouseEvent) => void
+ onPaneClick?: () => void
}
export function NetworkCanvas({
@@ -44,6 +45,7 @@ export function NetworkCanvas({
isDragOver,
onNodeContextMenu,
onPaneContextMenu,
+ onPaneClick: onPaneClickProp,
}: NetworkCanvasProps) {
const handleSelectionChange = useCallback(({ nodes: selectedNodes, edges: selectedEdges }: { nodes: Node[]; edges: Edge[] }) => {
if (selectedNodes.length === 1) {
@@ -61,7 +63,8 @@ export function NetworkCanvas({
const handlePaneClick = useCallback(() => {
onNodeSelect(null)
onEdgeSelect(null)
- }, [onNodeSelect, onEdgeSelect])
+ onPaneClickProp?.()
+ }, [onNodeSelect, onEdgeSelect, onPaneClickProp])
return (
diff --git a/frontend/src/components/network/panels/DeviceToolbar.tsx b/frontend/src/components/network/panels/DeviceToolbar.tsx
index 2aa38970..53411006 100644
--- a/frontend/src/components/network/panels/DeviceToolbar.tsx
+++ b/frontend/src/components/network/panels/DeviceToolbar.tsx
@@ -1,5 +1,5 @@
import { useState, useMemo, useCallback } from 'react'
-import { Search, Plus, ChevronDown, ChevronRight, X, LayoutGrid, GripVertical } from 'lucide-react'
+import { Search, Plus, ChevronDown, ChevronRight, X, LayoutGrid, GripVertical, Globe } from 'lucide-react'
import { getDeviceRenderConfig, CATEGORY_LABELS, CATEGORY_ORDER } from '../nodes/deviceRegistry'
import type { DeviceTypeResponse, DeviceTypeCreate } from '@/types'
import { deviceTypesApi } from '@/api'
@@ -122,6 +122,31 @@ export function DeviceToolbar({ deviceTypes, onDeviceTypesChange }: DeviceToolba
})}
+ {/* Internet section */}
+
+
+ Internet
+
+
+
{
+ e.dataTransfer.setData('application/reactflow-device', JSON.stringify({
+ slug: 'isp',
+ label: 'ISP',
+ category: 'cloud',
+ }))
+ e.dataTransfer.effectAllowed = 'move'
+ }}
+ className="flex cursor-grab items-center gap-2 rounded px-2 py-1.5 text-xs text-primary hover:bg-elevated active:cursor-grabbing active:scale-[0.98] transition-transform"
+ >
+
+
+ ISP
+
+
+
+
{/* Grouping section */}
diff --git a/frontend/src/pages/NetworkDiagrams/DiagramEditor.tsx b/frontend/src/pages/NetworkDiagrams/DiagramEditor.tsx
index d5c5b9ad..0ddcb4eb 100644
--- a/frontend/src/pages/NetworkDiagrams/DiagramEditor.tsx
+++ b/frontend/src/pages/NetworkDiagrams/DiagramEditor.tsx
@@ -495,6 +495,7 @@ function DiagramEditorInner() {
isDragOver={isDragOver}
onNodeContextMenu={handleNodeContextMenu}
onPaneContextMenu={handlePaneContextMenu}
+ onPaneClick={closeContextMenu}
/>