diff --git a/frontend/src/components/canvas/nodes/index.tsx b/frontend/src/components/canvas/nodes/index.tsx index aec536d..4a71324 100644 --- a/frontend/src/components/canvas/nodes/index.tsx +++ b/frontend/src/components/canvas/nodes/index.tsx @@ -23,4 +23,5 @@ export const PrinterNode = (props: N) => export const ComputerNode = (props: N) => export const CplNode = (props: N) => export const DockerNode = (props: N) => +export const DockerContainerNode = (props: N) => export const GenericNode = (props: N) => diff --git a/frontend/src/components/canvas/nodes/nodeTypes.ts b/frontend/src/components/canvas/nodes/nodeTypes.ts index 00ae141..a70c4dc 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, DockerNode, GenericNode } from './index' +import { IspNode, RouterNode, SwitchNode, ServerNode, VmNode, LxcNode, NasNode, IotNode, ApNode, CameraNode, PrinterNode, ComputerNode, CplNode, DockerNode, DockerContainerNode, GenericNode } from './index' import { ProxmoxGroupNode } from './ProxmoxGroupNode' import { GroupRectNode } from './GroupRectNode' import { GroupNode } from './GroupNode' @@ -19,6 +19,7 @@ export const nodeTypes = { computer: ComputerNode, cpl: CplNode, docker: DockerNode, + docker_container: DockerContainerNode, generic: GenericNode, groupRect: GroupRectNode, group: GroupNode, diff --git a/frontend/src/components/modals/NodeModal.tsx b/frontend/src/components/modals/NodeModal.tsx index c39f078..6f50fee 100644 --- a/frontend/src/components/modals/NodeModal.tsx +++ b/frontend/src/components/modals/NodeModal.tsx @@ -1,4 +1,4 @@ -import { createElement, useState } from 'react' +import { Fragment, createElement, useState } from 'react' import { RotateCcw, ChevronDown } from 'lucide-react' import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { Button } from '@/components/ui/button' @@ -11,7 +11,7 @@ import { ICON_REGISTRY, ICON_CATEGORIES, NODE_TYPE_DEFAULT_ICONS } from '@/utils const NODE_TYPE_GROUPS: { label: string; types: NodeType[] }[] = [ { label: 'Hardware', types: ['isp', 'router', 'switch', 'server', 'nas', 'ap', 'printer'] }, - { label: 'Virtualization', types: ['proxmox', 'vm', 'lxc', 'docker'] }, + { label: 'Virtualization', types: ['proxmox', 'vm', 'lxc', 'docker', 'docker_container'] }, { label: 'IoT', types: ['iot', 'camera', 'cpl'] }, { label: 'Generic', types: ['computer', 'generic', 'groupRect'] }, ] @@ -78,11 +78,11 @@ export function NodeModal({ open, onClose, onSubmit, initial, title = 'Add Node' diff --git a/frontend/src/components/modals/SearchModal.tsx b/frontend/src/components/modals/SearchModal.tsx index 10f4b5c..824eb53 100644 --- a/frontend/src/components/modals/SearchModal.tsx +++ b/frontend/src/components/modals/SearchModal.tsx @@ -4,6 +4,7 @@ import { Search } from 'lucide-react' import { useCanvasStore } from '@/stores/canvasStore' import { scanApi } from '@/api/client' import type { PendingDevice } from '@/components/modals/PendingDeviceModal' +import { NODE_TYPE_LABELS } from '@/types' interface SearchModalProps { open: boolean @@ -89,7 +90,7 @@ export function SearchModal({ open, onClose, onOpenPending }: SearchModalProps) className="flex items-center gap-3 px-4 py-2 hover:bg-[#21262d] cursor-pointer" onClick={() => handleSelectNode(node.id)} > - {node.data.type} + {NODE_TYPE_LABELS[node.data.type] ?? node.data.type} {node.data.label} {node.data.ip && ( {node.data.ip} diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 2481349..5e522eb 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -14,6 +14,7 @@ export type NodeType = | 'computer' | 'cpl' | 'docker' + | 'docker_container' | 'generic' | 'groupRect' | 'group' @@ -127,6 +128,7 @@ export const NODE_TYPE_LABELS: Record = { computer: 'Computer', cpl: 'CPL / Powerline', docker: 'Docker Host', + docker_container: 'Docker Container', generic: 'Generic Device', groupRect: 'Group Rectangle', group: 'Node Group', diff --git a/frontend/src/utils/__tests__/themes.test.ts b/frontend/src/utils/__tests__/themes.test.ts index aa06ea5..0b93166 100644 --- a/frontend/src/utils/__tests__/themes.test.ts +++ b/frontend/src/utils/__tests__/themes.test.ts @@ -4,7 +4,7 @@ import type { NodeType, EdgeType, NodeStatus } from '@/types' const NODE_TYPES: NodeType[] = [ 'isp', 'router', 'switch', 'server', 'proxmox', 'vm', 'lxc', - 'nas', 'iot', 'ap', 'camera', 'printer', 'computer', 'cpl', 'docker', 'generic', 'groupRect', + 'nas', 'iot', 'ap', 'camera', 'printer', 'computer', 'cpl', 'docker', 'docker_container', 'generic', 'groupRect', ] const EDGE_TYPES: EdgeType[] = ['ethernet', 'wifi', 'iot', 'vlan', 'virtual', 'cluster'] const STATUS_TYPES: NodeStatus[] = ['online', 'offline', 'pending', 'unknown'] diff --git a/frontend/src/utils/nodeIcons.ts b/frontend/src/utils/nodeIcons.ts index 6dbf5f5..dc44049 100644 --- a/frontend/src/utils/nodeIcons.ts +++ b/frontend/src/utils/nodeIcons.ts @@ -133,6 +133,7 @@ export const NODE_TYPE_DEFAULT_ICONS: Record = { computer: Monitor, cpl: PlugZap, docker: Anchor, + docker_container: Container, generic: Circle, group: Circle, groupRect: Circle, diff --git a/frontend/src/utils/themes.ts b/frontend/src/utils/themes.ts index 23d0be0..1d5c90a 100644 --- a/frontend/src/utils/themes.ts +++ b/frontend/src/utils/themes.ts @@ -57,6 +57,7 @@ export const THEMES: Record = { computer: { border: '#a855f7', icon: '#a855f7' }, cpl: { border: '#e3b341', icon: '#e3b341' }, docker: { border: '#2496ED', icon: '#2496ED' }, + docker_container: { border: '#38bdf8', icon: '#38bdf8' }, generic: { border: '#8b949e', icon: '#8b949e' }, groupRect:{ border: '#00d4ff', icon: '#00d4ff' }, group: { border: '#00d4ff', icon: '#00d4ff' }, @@ -112,6 +113,7 @@ export const THEMES: Record = { computer: { border: '#c084fc', icon: '#c084fc' }, cpl: { border: '#fbbf24', icon: '#fbbf24' }, docker: { border: '#2496ED', icon: '#2496ED' }, + docker_container: { border: '#38bdf8', icon: '#38bdf8' }, generic: { border: '#94a3b8', icon: '#94a3b8' }, groupRect:{ border: '#22d3ee', icon: '#22d3ee' }, group: { border: '#22d3ee', icon: '#22d3ee' }, @@ -167,6 +169,7 @@ export const THEMES: Record = { computer: { border: '#7c3aed', icon: '#7c3aed' }, cpl: { border: '#b45309', icon: '#b45309' }, docker: { border: '#2496ED', icon: '#2496ED' }, + docker_container: { border: '#0ea5e9', icon: '#0ea5e9' }, generic: { border: '#6b7280', icon: '#6b7280' }, groupRect:{ border: '#0284c7', icon: '#0284c7' }, group: { border: '#0284c7', icon: '#0284c7' }, @@ -222,6 +225,7 @@ export const THEMES: Record = { computer: { border: '#ff00ff', icon: '#ff00ff' }, cpl: { border: '#ffff00', icon: '#ffff00' }, docker: { border: '#00aaff', icon: '#00aaff' }, + docker_container: { border: '#00ddff', icon: '#00ddff' }, generic: { border: '#8888ff', icon: '#8888ff' }, groupRect:{ border: '#00ffff', icon: '#00ffff' }, group: { border: '#00ffff', icon: '#00ffff' }, @@ -277,6 +281,7 @@ export const THEMES: Record = { computer: { border: '#008822', icon: '#008822' }, cpl: { border: '#66ff33', icon: '#66ff33' }, docker: { border: '#00cc88', icon: '#00cc88' }, + docker_container: { border: '#00dd99', icon: '#00dd99' }, generic: { border: '#006600', icon: '#006600' }, groupRect:{ border: '#00ff41', icon: '#00ff41' }, group: { border: '#00ff41', icon: '#00ff41' },