feat: per-node custom color styling (border, background, icon)

- Add resolveNodeColors() utility merging type defaults with per-node overrides
- Default colors per node type (cyan=isp/router/lxc/ap, green=switch/nas,
  purple=server/vm, orange=proxmox, amber=iot, gray=generic)
- Remove glowColor prop from BaseNode — colors now come from node data
- ProxmoxGroupNode uses resolveNodeColors for group border/header/icon
- NodeModal: Appearance section with 3 color swatches (border, background, icon)
  — click swatch to open native color picker; Reset to defaults button
- custom_colors persisted as JSON in DB (backend model + schemas + migration)
- 7 new unit tests for resolveNodeColors covering all node types + partial overrides
This commit is contained in:
Pouzor
2026-03-07 14:31:05 +01:00
parent 0fe3c6390a
commit 37c963cf96
12 changed files with 174 additions and 32 deletions
+11 -12
View File
@@ -8,15 +8,14 @@ import type { NodeData } from '@/types'
type N = NodeProps<Node<NodeData>>
export const IspNode = (props: N) => <BaseNode {...props} icon={Globe} glowColor="#00d4ff" />
export const RouterNode = (props: N) => <BaseNode {...props} icon={Router} glowColor="#00d4ff" />
export const SwitchNode = (props: N) => <BaseNode {...props} icon={Network} glowColor="#39d353" />
export const ServerNode = (props: N) => <BaseNode {...props} icon={Server} glowColor="#a855f7" />
export const ProxmoxNode = (props: N) => <BaseNode {...props} icon={Layers} glowColor="#ff6e00" />
export const VmNode = (props: N) => <BaseNode {...props} icon={Box} glowColor="#a855f7" />
export const LxcNode = (props: N) => <BaseNode {...props} icon={Container} glowColor="#00d4ff" />
export const NasNode = (props: N) => <BaseNode {...props} icon={HardDrive} glowColor="#39d353" />
export const IotNode = (props: N) => <BaseNode {...props} icon={Cpu} glowColor="#e3b341" />
export const ApNode = (props: N) => <BaseNode {...props} icon={Wifi} glowColor="#00d4ff" />
export const GenericNode = (props: N) => <BaseNode {...props} icon={Circle} glowColor="#8b949e" />
export const IspNode = (props: N) => <BaseNode {...props} icon={Globe} />
export const RouterNode = (props: N) => <BaseNode {...props} icon={Router} />
export const SwitchNode = (props: N) => <BaseNode {...props} icon={Network} />
export const ServerNode = (props: N) => <BaseNode {...props} icon={Server} />
export const ProxmoxNode = (props: N) => <BaseNode {...props} icon={Layers} />
export const VmNode = (props: N) => <BaseNode {...props} icon={Box} />
export const LxcNode = (props: N) => <BaseNode {...props} icon={Container} />
export const NasNode = (props: N) => <BaseNode {...props} icon={HardDrive} />
export const IotNode = (props: N) => <BaseNode {...props} icon={Cpu} />
export const ApNode = (props: N) => <BaseNode {...props} icon={Wifi} />
export const GenericNode = (props: N) => <BaseNode {...props} icon={Circle} />