From 3cd4084f7804329bc039f77c4699aa6d3b025287 Mon Sep 17 00:00:00 2001 From: chihlasm Date: Tue, 14 Apr 2026 02:42:47 +0000 Subject: [PATCH] refactor(network): simplify diagram node visuals --- .../components/network/nodes/DeviceNode.tsx | 68 ++++------------ .../network/nodes/deviceRegistry.ts | 77 +++++++++---------- .../src/components/network/ui/base-node.tsx | 2 +- 3 files changed, 51 insertions(+), 96 deletions(-) diff --git a/frontend/src/components/network/nodes/DeviceNode.tsx b/frontend/src/components/network/nodes/DeviceNode.tsx index a1f732c0..b3189d6e 100644 --- a/frontend/src/components/network/nodes/DeviceNode.tsx +++ b/frontend/src/components/network/nodes/DeviceNode.tsx @@ -1,6 +1,5 @@ import { memo, useState, useRef, useEffect } from 'react' import { Position, NodeResizer, useReactFlow, type NodeProps } from '@xyflow/react' -import { HardDrive, Network, ShieldCheck } from 'lucide-react' import { BaseNode, BaseNodeHeader, BaseNodeContent } from '../ui/base-node' import { BaseHandle } from '../ui/base-handle' import { NodeStatusIndicator, type NodeStatus } from '../ui/node-status-indicator' @@ -31,48 +30,9 @@ const NODE_DEFAULT = 120 // default square side in px const NODE_MIN = 80 // minimum square side in px const NODE_MAX = 280 // maximum square side in px -function DeviceNodeChrome({ - category, - accentClass, - glyph, -}: { - category: string - accentClass: string - glyph: string -}) { - const MetaIcon = category === 'network' - ? Network - : category === 'security' - ? ShieldCheck - : HardDrive - - return ( - <> -
- - {glyph} - - - {CATEGORY_LABELS[category] ?? category} - -
-
-
- - Asset -
-
- - - -
- - ) -} - function DeviceNodeComponent({ id, data, selected, width, height }: NodeProps) { const nodeData = data as unknown as DeviceNodeData - const { icon: Icon, color, accentClass, surfaceClass, category, glyph } = getDeviceRenderConfig(nodeData.deviceType, nodeData.category) + const { icon: Icon, color, accentClass, surfaceClass, category } = getDeviceRenderConfig(nodeData.deviceType, nodeData.category) const status = (nodeData.properties?.status || 'unknown') as NodeStatus const ip = nodeData.properties?.ip const props = nodeData.properties || {} @@ -87,8 +47,8 @@ function DeviceNodeComponent({ id, data, selected, width, height }: NodeProps) { const labelPx = Math.max(9, Math.min(20, Math.round(scale * 11))) // IP font: 9px at default, clamped to [8, 16] const ipPx = Math.max(8, Math.min(16, Math.round(scale * 9))) - const typePx = Math.max(8, Math.min(13, Math.round(scale * 8.5))) - const iconPlateSize = Math.round(Math.max(36, Math.min(92, scale * 56))) + const metaPx = Math.max(8, Math.min(11, Math.round(scale * 8))) + const iconPlateSize = Math.round(Math.max(34, Math.min(82, scale * 50))) const [editing, setEditing] = useState(false) const [labelValue, setLabelValue] = useState(nodeData.label ?? '') @@ -124,19 +84,17 @@ function DeviceNodeComponent({ id, data, selected, width, height }: NodeProps) { - -
- - + +
+
-
-
+
@@ -176,16 +134,16 @@ function DeviceNodeComponent({ id, data, selected, width, height }: NodeProps) { )} - {nodeData.deviceType.replace(/-/g, ' ')} + {CATEGORY_LABELS[category] ?? nodeData.deviceType.replace(/-/g, ' ')} {ip && ( - + {ip} diff --git a/frontend/src/components/network/nodes/deviceRegistry.ts b/frontend/src/components/network/nodes/deviceRegistry.ts index c2385fe2..34271c8e 100644 --- a/frontend/src/components/network/nodes/deviceRegistry.ts +++ b/frontend/src/components/network/nodes/deviceRegistry.ts @@ -12,7 +12,6 @@ export interface DeviceRenderConfig { accentClass: string surfaceClass: string category: string - glyph: string } // Category-semantic color palette — each color carries meaning: @@ -66,13 +65,11 @@ function makeConfig( icon: LucideIcon, color: string, category: string, - glyph: string, ): DeviceRenderConfig { return { icon, color, category, - glyph, accentClass: CATEGORY_STYLES[category]?.accentClass ?? CATEGORY_STYLES.infrastructure.accentClass, surfaceClass: CATEGORY_STYLES[category]?.surfaceClass ?? CATEGORY_STYLES.infrastructure.surfaceClass, } @@ -80,60 +77,60 @@ function makeConfig( const SYSTEM_DEVICE_ICONS: Record = { // Network layer - 'router': makeConfig(Router, NETWORK_COLOR, 'network', 'RTR'), - 'switch': makeConfig(Network, NETWORK_COLOR, 'network', 'SW'), - 'access-point': makeConfig(Wifi, NETWORK_COLOR, 'network', 'AP'), - 'load-balancer': makeConfig(Gauge, NETWORK_COLOR, 'network', 'LB'), + 'router': makeConfig(Router, NETWORK_COLOR, 'network'), + 'switch': makeConfig(Network, NETWORK_COLOR, 'network'), + 'access-point': makeConfig(Wifi, NETWORK_COLOR, 'network'), + 'load-balancer': makeConfig(Gauge, NETWORK_COLOR, 'network'), // Security - 'firewall': makeConfig(BrickWallFire, SECURITY_COLOR, 'security', 'FW'), - 'badge-reader': makeConfig(KeyRound, SECURITY_COLOR, 'security', 'BR'), + 'firewall': makeConfig(BrickWallFire, SECURITY_COLOR, 'security'), + 'badge-reader': makeConfig(KeyRound, SECURITY_COLOR, 'security'), // Compute - 'server': makeConfig(Server, COMPUTE_COLOR, 'compute', 'SRV'), - 'vm': makeConfig(Boxes, COMPUTE_COLOR, 'compute', 'VM'), - 'container': makeConfig(Package, COMPUTE_COLOR, 'compute', 'CTR'), + 'server': makeConfig(Server, COMPUTE_COLOR, 'compute'), + 'vm': makeConfig(Boxes, COMPUTE_COLOR, 'compute'), + 'container': makeConfig(Package, COMPUTE_COLOR, 'compute'), // Storage - 'nas': makeConfig(Database, STORAGE_COLOR, 'storage', 'NAS'), - 'san': makeConfig(HardDrive, STORAGE_COLOR, 'storage', 'SAN'), - 'cloud-storage': makeConfig(CloudCog, STORAGE_COLOR, 'storage', 'CS'), + 'nas': makeConfig(Database, STORAGE_COLOR, 'storage'), + 'san': makeConfig(HardDrive, STORAGE_COLOR, 'storage'), + 'cloud-storage': makeConfig(CloudCog, STORAGE_COLOR, 'storage'), // Cloud / Internet - 'cloud': makeConfig(Cloud, CLOUD_COLOR, 'cloud', 'CLD'), - 'aws': makeConfig(Cloud, CLOUD_COLOR, 'cloud', 'AWS'), - 'azure': makeConfig(Cloud, CLOUD_COLOR, 'cloud', 'AZ'), - 'gcp': makeConfig(Cloud, CLOUD_COLOR, 'cloud', 'GCP'), - 'isp': makeConfig(Globe, CLOUD_COLOR, 'cloud', 'WAN'), + 'cloud': makeConfig(Cloud, CLOUD_COLOR, 'cloud'), + 'aws': makeConfig(Cloud, CLOUD_COLOR, 'cloud'), + 'azure': makeConfig(Cloud, CLOUD_COLOR, 'cloud'), + 'gcp': makeConfig(Cloud, CLOUD_COLOR, 'cloud'), + 'isp': makeConfig(Globe, CLOUD_COLOR, 'cloud'), // Endpoints - 'workstation': makeConfig(Monitor, ENDPOINT_COLOR, 'endpoint', 'WS'), - 'laptop': makeConfig(Laptop, ENDPOINT_COLOR, 'endpoint', 'LTP'), - 'tablet': makeConfig(Tablet, ENDPOINT_COLOR, 'endpoint', 'TAB'), - 'phone': makeConfig(Smartphone, ENDPOINT_COLOR, 'endpoint', 'PH'), - 'printer': makeConfig(Printer, ENDPOINT_COLOR, 'endpoint', 'PRN'), + 'workstation': makeConfig(Monitor, ENDPOINT_COLOR, 'endpoint'), + 'laptop': makeConfig(Laptop, ENDPOINT_COLOR, 'endpoint'), + 'tablet': makeConfig(Tablet, ENDPOINT_COLOR, 'endpoint'), + 'phone': makeConfig(Smartphone, ENDPOINT_COLOR, 'endpoint'), + 'printer': makeConfig(Printer, ENDPOINT_COLOR, 'endpoint'), // Infrastructure / physical - 'ups': makeConfig(BatteryCharging, INFRA_COLOR, 'infrastructure', 'UPS'), - 'pdu': makeConfig(PlugZap, INFRA_COLOR, 'infrastructure', 'PDU'), - 'rack': makeConfig(RectangleVertical, INFRA_COLOR, 'infrastructure', 'RCK'), - 'patch-panel': makeConfig(Cable, INFRA_COLOR, 'infrastructure', 'PP'), - 'camera': makeConfig(Camera, INFRA_COLOR, 'infrastructure', 'CAM'), - 'nvr': makeConfig(Video, INFRA_COLOR, 'infrastructure', 'NVR'), - 'iot': makeConfig(Radio, INFRA_COLOR, 'infrastructure', 'IOT'), + 'ups': makeConfig(BatteryCharging, INFRA_COLOR, 'infrastructure'), + 'pdu': makeConfig(PlugZap, INFRA_COLOR, 'infrastructure'), + 'rack': makeConfig(RectangleVertical, INFRA_COLOR, 'infrastructure'), + 'patch-panel': makeConfig(Cable, INFRA_COLOR, 'infrastructure'), + 'camera': makeConfig(Camera, INFRA_COLOR, 'infrastructure'), + 'nvr': makeConfig(Video, INFRA_COLOR, 'infrastructure'), + 'iot': makeConfig(Radio, INFRA_COLOR, 'infrastructure'), } const CATEGORY_DEFAULTS: Record = { - 'network': makeConfig(Router, NETWORK_COLOR, 'network', 'NET'), - 'compute': makeConfig(Server, COMPUTE_COLOR, 'compute', 'CPU'), - 'storage': makeConfig(Database, STORAGE_COLOR, 'storage', 'DB'), - 'cloud': makeConfig(Cloud, CLOUD_COLOR, 'cloud', 'CLD'), - 'endpoint': makeConfig(Monitor, ENDPOINT_COLOR, 'endpoint', 'END'), - 'infrastructure': makeConfig(PlugZap, INFRA_COLOR, 'infrastructure', 'INF'), - 'security': makeConfig(BrickWallFire, SECURITY_COLOR, 'security', 'SEC'), + 'network': makeConfig(Router, NETWORK_COLOR, 'network'), + 'compute': makeConfig(Server, COMPUTE_COLOR, 'compute'), + 'storage': makeConfig(Database, STORAGE_COLOR, 'storage'), + 'cloud': makeConfig(Cloud, CLOUD_COLOR, 'cloud'), + 'endpoint': makeConfig(Monitor, ENDPOINT_COLOR, 'endpoint'), + 'infrastructure': makeConfig(PlugZap, INFRA_COLOR, 'infrastructure'), + 'security': makeConfig(BrickWallFire, SECURITY_COLOR, 'security'), } -const FALLBACK: DeviceRenderConfig = makeConfig(Cpu, INFRA_COLOR, 'infrastructure', 'DEV') +const FALLBACK: DeviceRenderConfig = makeConfig(Cpu, INFRA_COLOR, 'infrastructure') export function getDeviceRenderConfig(slug: string, category?: string): DeviceRenderConfig { if (SYSTEM_DEVICE_ICONS[slug]) return SYSTEM_DEVICE_ICONS[slug] diff --git a/frontend/src/components/network/ui/base-node.tsx b/frontend/src/components/network/ui/base-node.tsx index a6e8f955..15a91dfd 100644 --- a/frontend/src/components/network/ui/base-node.tsx +++ b/frontend/src/components/network/ui/base-node.tsx @@ -6,7 +6,7 @@ export function BaseNode({ className, ...props }: ComponentProps<'div'>) {