feat: add Group Rectangle — resizable decorative zones on canvas

- New GroupRectNode: rounded rect with NodeResizer (8 handles), no
  connection handles, always behind network nodes via negative zIndex
- GroupRectModal: label, font preset (Inter/Mono/Serif), 3×3 text
  position grid, text/border/background color pickers, z-order 1–9
- Sidebar: "Add Rectangle" button (below Add Node), group rects
  excluded from node count stats
- Save/load: size persisted in custom_colors.width/height, no backend
  schema changes required
- elevateNodesOnSelect=false on ReactFlow so selected rects never
  pop above network nodes
- Tests: 3 new store tests + 9 GroupRectModal tests (66 total, all pass)
This commit is contained in:
Pouzor
2026-03-10 16:59:40 +01:00
parent c0f1d1ff1a
commit 1e72366d03
10 changed files with 604 additions and 27 deletions
+25 -1
View File
@@ -14,6 +14,18 @@ export type NodeType =
| 'computer'
| 'cpl'
| 'generic'
| 'groupRect'
export type TextPosition =
| 'top-left'
| 'top-center'
| 'top-right'
| 'middle-left'
| 'center'
| 'middle-right'
| 'bottom-left'
| 'bottom-center'
| 'bottom-right'
export type EdgeType = 'ethernet' | 'wifi' | 'iot' | 'vlan' | 'virtual' | 'cluster'
@@ -45,7 +57,18 @@ export interface NodeData extends Record<string, unknown> {
notes?: string
parent_id?: string
container_mode?: boolean
custom_colors?: { border?: string; background?: string; icon?: string }
custom_colors?: {
border?: string
background?: string
icon?: string
// Group rectangle extras (type === 'groupRect')
text_color?: string
text_position?: TextPosition
font?: string
z_order?: number
width?: number
height?: number
}
custom_icon?: string
}
@@ -76,6 +99,7 @@ export const NODE_TYPE_LABELS: Record<NodeType, string> = {
computer: 'Computer',
cpl: 'CPL / Powerline',
generic: 'Generic Device',
groupRect: 'Group Rectangle',
}
export const STATUS_COLORS: Record<NodeStatus, string> = {