diff --git a/frontend/src/components/canvas/nodes/index.tsx b/frontend/src/components/canvas/nodes/index.tsx index 2dcf080..cfb6604 100644 --- a/frontend/src/components/canvas/nodes/index.tsx +++ b/frontend/src/components/canvas/nodes/index.tsx @@ -1,7 +1,7 @@ import { type NodeProps, type Node } from '@xyflow/react' import { Globe, Router, Network, Server, Layers, Box, Container, - HardDrive, Cpu, Wifi, Circle, Cctv, Printer, Monitor, PlugZap, Anchor, Package, + HardDrive, Cpu, Wifi, Circle, Cctv, Printer, Monitor, PlugZap, Anchor, Package, Flame, } from 'lucide-react' import { BaseNode } from './BaseNode' import type { NodeData } from '@/types' @@ -10,6 +10,7 @@ type N = NodeProps> export const IspNode = (props: N) => export const RouterNode = (props: N) => +export const FirewallNode = (props: N) => export const SwitchNode = (props: N) => export const ServerNode = (props: N) => export const ProxmoxNode = (props: N) => diff --git a/frontend/src/components/canvas/nodes/nodeTypes.ts b/frontend/src/components/canvas/nodes/nodeTypes.ts index 6b33ac4..6adba16 100644 --- a/frontend/src/components/canvas/nodes/nodeTypes.ts +++ b/frontend/src/components/canvas/nodes/nodeTypes.ts @@ -1,4 +1,4 @@ -import { IspNode, RouterNode, SwitchNode, ServerNode, VmNode, LxcNode, NasNode, IotNode, ApNode, CameraNode, PrinterNode, ComputerNode, CplNode, DockerHostNode, DockerContainerNode, GenericNode } from './index' +import { IspNode, RouterNode, FirewallNode, SwitchNode, ServerNode, VmNode, LxcNode, NasNode, IotNode, ApNode, CameraNode, PrinterNode, ComputerNode, CplNode, DockerHostNode, DockerContainerNode, GenericNode } from './index' import { ProxmoxGroupNode } from './ProxmoxGroupNode' import { GroupRectNode } from './GroupRectNode' import { GroupNode } from './GroupNode' @@ -6,6 +6,7 @@ import { GroupNode } from './GroupNode' export const nodeTypes = { isp: IspNode, router: RouterNode, + firewall: FirewallNode, switch: SwitchNode, server: ServerNode, proxmox: ProxmoxGroupNode, diff --git a/frontend/src/components/modals/CustomStyleModal.tsx b/frontend/src/components/modals/CustomStyleModal.tsx index a0e0cb3..0c5b2f2 100644 --- a/frontend/src/components/modals/CustomStyleModal.tsx +++ b/frontend/src/components/modals/CustomStyleModal.tsx @@ -2,7 +2,7 @@ import { useState, useCallback } from 'react' import { toast } from 'sonner' import { Globe, Router, Network, Server, Layers, Box, Container, HardDrive, - Cpu, Wifi, Camera, Printer, Monitor, PlugZap, Anchor, Package, Circle, + Cpu, Wifi, Camera, Printer, Monitor, PlugZap, Anchor, Package, Circle, Flame, type LucideIcon, } from 'lucide-react' import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog' @@ -19,7 +19,7 @@ import { NODE_TYPE_LABELS, EDGE_TYPE_LABELS } from '@/types' // ── Node types exposed for custom style (skip groupRect/group) ─────────────── const EDITABLE_NODE_TYPES: NodeType[] = [ - 'isp', 'router', 'switch', 'server', 'proxmox', 'vm', 'lxc', 'nas', + 'isp', 'router', 'firewall', 'switch', 'server', 'proxmox', 'vm', 'lxc', 'nas', 'iot', 'ap', 'camera', 'printer', 'computer', 'cpl', 'docker_host', 'docker_container', 'generic', ] @@ -27,7 +27,7 @@ const EDITABLE_NODE_TYPES: NodeType[] = [ const EDITABLE_EDGE_TYPES: EdgeType[] = ['ethernet', 'wifi', 'iot', 'vlan', 'virtual', 'cluster'] const NODE_ICONS: Record = { - isp: Globe, router: Router, switch: Network, server: Server, proxmox: Layers, + isp: Globe, router: Router, firewall: Flame, switch: Network, server: Server, proxmox: Layers, vm: Box, lxc: Container, nas: HardDrive, iot: Cpu, ap: Wifi, camera: Camera, printer: Printer, computer: Monitor, cpl: PlugZap, docker_host: Anchor, docker_container: Package, generic: Circle, diff --git a/frontend/src/components/modals/NodeModal.tsx b/frontend/src/components/modals/NodeModal.tsx index 622b51b..31626b5 100644 --- a/frontend/src/components/modals/NodeModal.tsx +++ b/frontend/src/components/modals/NodeModal.tsx @@ -11,7 +11,7 @@ import { resolveNodeColors } from '@/utils/nodeColors' import { ICON_REGISTRY, ICON_CATEGORIES, NODE_TYPE_DEFAULT_ICONS } from '@/utils/nodeIcons' const NODE_TYPE_GROUPS: { label: string; types: NodeType[] }[] = [ - { label: 'Hardware', types: ['isp', 'router', 'switch', 'server', 'nas', 'ap', 'printer'] }, + { label: 'Hardware', types: ['isp', 'router', 'firewall', 'switch', 'server', 'nas', 'ap', 'printer'] }, { label: 'Virtualization', types: ['proxmox', 'vm', 'lxc', 'docker_host', 'docker_container'] }, { label: 'IoT', types: ['iot', 'camera', 'cpl'] }, { label: 'Generic', types: ['computer', 'generic', 'groupRect'] }, diff --git a/frontend/src/types/__tests__/types.test.ts b/frontend/src/types/__tests__/types.test.ts index 8191c72..57e6efd 100644 --- a/frontend/src/types/__tests__/types.test.ts +++ b/frontend/src/types/__tests__/types.test.ts @@ -4,7 +4,7 @@ import type { CheckMethod } from '@/types' describe('NODE_TYPE_LABELS', () => { it('has an entry for every node type', () => { - const expectedTypes = ['isp', 'router', 'switch', 'server', 'proxmox', 'vm', 'lxc', 'nas', 'iot', 'ap', 'camera', 'generic'] + const expectedTypes = ['isp', 'router', 'firewall', 'switch', 'server', 'proxmox', 'vm', 'lxc', 'nas', 'iot', 'ap', 'camera', 'generic'] expectedTypes.forEach((t) => { expect(NODE_TYPE_LABELS).toHaveProperty(t) expect(typeof NODE_TYPE_LABELS[t as keyof typeof NODE_TYPE_LABELS]).toBe('string') diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index b37ca34..2511a24 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -1,6 +1,7 @@ export type NodeType = | 'isp' | 'router' + | 'firewall' | 'switch' | 'server' | 'proxmox' @@ -116,6 +117,7 @@ export interface EdgeData extends Record { export const NODE_TYPE_LABELS: Record = { isp: 'ISP / Modem', router: 'Router', + firewall: 'Firewall', switch: 'Switch', server: 'Server', proxmox: 'Proxmox VE', diff --git a/frontend/src/utils/__tests__/themes.test.ts b/frontend/src/utils/__tests__/themes.test.ts index 48e9854..1a4b103 100644 --- a/frontend/src/utils/__tests__/themes.test.ts +++ b/frontend/src/utils/__tests__/themes.test.ts @@ -3,7 +3,7 @@ import { THEMES, THEME_ORDER, type ThemeId } from '../themes' import type { NodeType, EdgeType, NodeStatus } from '@/types' const NODE_TYPES: NodeType[] = [ - 'isp', 'router', 'switch', 'server', 'proxmox', 'vm', 'lxc', + 'isp', 'router', 'firewall', 'switch', 'server', 'proxmox', 'vm', 'lxc', 'nas', 'iot', 'ap', 'camera', 'printer', 'computer', 'cpl', 'docker_host', 'docker_container', 'generic', 'groupRect', ] const EDGE_TYPES: EdgeType[] = ['ethernet', 'wifi', 'iot', 'vlan', 'virtual', 'cluster'] diff --git a/frontend/src/utils/nodeIcons.ts b/frontend/src/utils/nodeIcons.ts index 3523718..5c329c8 100644 --- a/frontend/src/utils/nodeIcons.ts +++ b/frontend/src/utils/nodeIcons.ts @@ -9,7 +9,7 @@ import { // Storage & Databases Database, Archive, Cloud, FolderOpen, // Security & Auth - Shield, ShieldCheck, Lock, Key, Users, UserCheck, + Shield, ShieldCheck, Lock, Key, Users, UserCheck, Flame, // Automation & IoT Zap, Workflow, Bot, Home, Thermometer, Lightbulb, Radio, // Transfers & sync @@ -34,6 +34,7 @@ export const ICON_REGISTRY: IconEntry[] = [ // --- Infrastructure --- { key: 'globe', label: 'Globe / ISP', category: 'Infrastructure', icon: Globe }, { key: 'router', label: 'Router', category: 'Infrastructure', icon: Router }, + { key: 'flame', label: 'Firewall', category: 'Infrastructure', icon: Flame }, { key: 'network', label: 'Switch / Network', category: 'Infrastructure', icon: Network }, { key: 'server', label: 'Server', category: 'Infrastructure', icon: Server }, { key: 'layers', label: 'Proxmox / Hypervisor', category: 'Infrastructure', icon: Layers }, @@ -120,6 +121,7 @@ export const ICON_MAP: Record = Object.fromEntries( export const NODE_TYPE_DEFAULT_ICONS: Record = { isp: Globe, router: Router, + firewall: Flame, switch: Network, server: Server, proxmox: Layers, diff --git a/frontend/src/utils/themes.ts b/frontend/src/utils/themes.ts index 583aa29..202c0dd 100644 --- a/frontend/src/utils/themes.ts +++ b/frontend/src/utils/themes.ts @@ -44,6 +44,7 @@ export const THEMES: Record = { nodeAccents: { isp: { border: '#00d4ff', icon: '#00d4ff' }, router: { border: '#00d4ff', icon: '#00d4ff' }, + firewall: { border: '#f85149', icon: '#f85149' }, switch: { border: '#39d353', icon: '#39d353' }, server: { border: '#a855f7', icon: '#a855f7' }, proxmox: { border: '#ff6e00', icon: '#ff6e00' }, @@ -100,6 +101,7 @@ export const THEMES: Record = { nodeAccents: { isp: { border: '#22d3ee', icon: '#22d3ee' }, router: { border: '#22d3ee', icon: '#22d3ee' }, + firewall: { border: '#ef4444', icon: '#ef4444' }, switch: { border: '#4ade80', icon: '#4ade80' }, server: { border: '#c084fc', icon: '#c084fc' }, proxmox: { border: '#fb923c', icon: '#fb923c' }, @@ -156,6 +158,7 @@ export const THEMES: Record = { nodeAccents: { isp: { border: '#0284c7', icon: '#0284c7' }, router: { border: '#0284c7', icon: '#0284c7' }, + firewall: { border: '#dc2626', icon: '#dc2626' }, switch: { border: '#16a34a', icon: '#16a34a' }, server: { border: '#7c3aed', icon: '#7c3aed' }, proxmox: { border: '#ea580c', icon: '#ea580c' }, @@ -212,6 +215,7 @@ export const THEMES: Record = { nodeAccents: { isp: { border: '#00ffff', icon: '#00ffff' }, router: { border: '#00ffff', icon: '#00ffff' }, + firewall: { border: '#ff0040', icon: '#ff0040' }, switch: { border: '#00ff80', icon: '#00ff80' }, server: { border: '#ff00ff', icon: '#ff00ff' }, proxmox: { border: '#ff8800', icon: '#ff8800' }, @@ -268,6 +272,7 @@ export const THEMES: Record = { nodeAccents: { isp: { border: '#00ff41', icon: '#00ff41' }, router: { border: '#00ff41', icon: '#00ff41' }, + firewall: { border: '#88ff00', icon: '#88ff00' }, switch: { border: '#00cc33', icon: '#00cc33' }, server: { border: '#008822', icon: '#008822' }, proxmox: { border: '#33ff66', icon: '#33ff66' }, @@ -324,6 +329,7 @@ export const THEMES: Record = { nodeAccents: { isp: { border: '#00d4ff', icon: '#00d4ff' }, router: { border: '#00d4ff', icon: '#00d4ff' }, + firewall: { border: '#f85149', icon: '#f85149' }, switch: { border: '#39d353', icon: '#39d353' }, server: { border: '#a855f7', icon: '#a855f7' }, proxmox: { border: '#ff6e00', icon: '#ff6e00' },