Both SearchBar and SearchModal now fetch and search pending devices by
IP, hostname, and service name. Selecting a pending result opens the
sidebar to the Pending tab and highlights the matching device.
- Ctrl+F / Cmd+F opens floating search bar at top-center of canvas
- Filters nodes by label, IP, hostname and service name (case-insensitive)
- Shows match count and no-results message
- Click result selects node and flies camera to it with animation
- Escape or × closes the bar
- groupRect nodes excluded from results
- Handles grouped nodes with correct absolute position for navigation
- Add lasso/box selection via selectionOnDrag (Space to pan, lasso by default)
- Add lasso/pan toggle button in canvas controls (bottom-left)
- Multi-select panel in right panel when 2+ nodes selected (including zones)
- Create named Group node from selected nodes with bounding box math
- Group node: resizable, inline rename, show/hide border toggle, status summary
- GroupDetailPanel: lists members, online/offline count, ungroup action
- Fix group persistence after save/reload (extend proxmox container map to include group nodes)
- Fix groupRect serialization to preserve parent_id
- Remove background color from group and proxmox container node wrappers
- Add tests for all new store actions, GroupNode, MultiSelectPanel, GroupDetailPanel
- POST /scan/{run_id}/stop endpoint signals running scan to cancel
- Scanner checks cancellation flag between CIDR ranges and hosts, exits early
- Cancelled scans get status 'cancelled' instead of 'done'
- Stop button (red StopCircle) shown in Scan History panel for running scans
- 6 new backend tests, 5 new frontend tests
- Add 'Delete' to deleteKeyCode so both Backspace and Delete remove nodes
- Call snapshotHistory() in onBeforeDelete (keyboard) and in DetailPanel
handleDelete (button) so deletions can be undone with Ctrl+Z
- Opens panel and calls settingsApi.get
- Displays interval loaded from API
- Saves updated interval via settingsApi.save
- Shows error toast on save failure
- Toggles panel closed on second Settings click
- New GET/POST /api/v1/settings for status check interval
- Scan /api/v1/scan/config now handles ranges only
- Frontend: settingsApi client, SettingsPanel uses settingsApi
- ScanConfigModal no longer reads/writes interval
- 4 new backend tests for settings endpoint
- Add Settings item in sidebar actions section (below Save Canvas)
- Settings panel shows status check interval with save button
- Remove interval field from ScanConfigModal (now belongs in Settings)
- Scan modal shows a hint pointing to sidebar Settings
edges/index.tsx was never committed — both animation modes were
rendering as snake (truthy string check). Now uses animMode to
distinguish 'snake' (moving blob) from 'flow' (continuous flowing dashes).
- Label position toggle: inside (default) or outside the border
- Outside mode renders the label above/below the zone based on text_position
- Text size selector: 10/12/14/16/18/20px (default 12)
- Both fields persisted in custom_colors (no backend schema change needed)
- 8 new frontend tests, 1 new backend test
- Rename "Rectangle" → "Zone" in sidebar, add modal and edit modal
- Add border width selector (1–5px, default 2px) to the Zone modal
- Border width persisted in custom_colors.border_width and applied in GroupRectNode
CORS_ORIGINS was hardcoded in docker-compose.yml, silently overriding .env
and breaking login for users who change the frontend port. It now comes
from .env exclusively, with a clear comment in .env.example.
Login page now distinguishes network errors (CORS/offline) from wrong
credentials, and footer correctly references .env instead of config.yml.
Implements issue #5. Off by default; set LIVEVIEW_KEY in .env to enable.
No JWT required — key-based auth via ?key= query param.
Returns 403 when disabled or key is wrong.
Read-only ReactFlow canvas (pan/zoom, no editing).
Standalone mode loads from localStorage without a key.
Includes 8 backend tests and 9 frontend tests.
Add NodeResizer to BaseNode so users can drag corners to resize any node.
Persist width/height through the full stack: DB model, schemas, canvas
save/load route, and migration for existing databases.
Add tests covering save, update, clear, and load of node dimensions.
- Fix DockerNode default icon: use Anchor instead of Package
- Add border_style option to Group Rectangle (solid/dashed/dotted/double/none)
- Group node type selector by category (Hardware, Virtualization, IoT, Generic)
- Add tests for border style feature
Silent return when label was empty made the Add button appear broken.
Native browser required tooltip doesn't render in Radix Dialog portals.
Now shows inline red error message and highlights the field.
- Add animated toggle per edge in EdgeModal (cyan switch, "Flow Animation")
- SVG-native <animate> element for reliable cross-browser dot animation
- Persist animated field: backend model, schemas (EdgeBase/EdgeUpdate/EdgeSave), DB migration
- Include animated in App.tsx edgesToSave serialization so it survives save/reload
- Add animated: bool to EdgeData TypeScript type
- Add hideIp / toggleHideIp to canvasStore (UI-only, not persisted)
- Add maskIp util: 192.168.1.115 → 192.168.XX.XX (non-IPv4 passthrough)
- BaseNode reads hideIp from store and masks last two octets when active
- Sidebar shows Eye/EyeOff toggle below Scan Network, highlights when active
- Add custom SVG favicon and Logo component (house + network nodes motif)
- Update page title to Homelable with meta description
- Show Logo in sidebar header and toolbar
- Add theme store and ThemeModal for canvas style switching
- Refactor node colors and edge styles for theme support
- Add groupRect entry to NODE_DEFAULT_COLORS (required by Record<NodeType, NodeColors>)
- Explicitly type Select onValueChange callbacks as (v: string) to satisfy
stricter type inference in tsc -b build mode
- Any TCP service (except port 22 and known non-HTTP protocols) is now
clickable — fixes Sonarr, Radarr, Jellyfin, Proxmox web UI, etc.
- HTTPS auto-detected for port 443/8443 or names containing ssl/tls/https
- Non-HTTP blocklist: FTP, SMTP, DNS, LDAP, SMB, MySQL, Postgres,
Redis, MongoDB, Kafka, Memcached, etc.
- Inline "Add service" form in detail panel (name, port, tcp/udp)
- Remove button (×) on hover for each service row
- Group rect nodes excluded from detail panel
- getServiceUrl extracted to utils/serviceUrl.ts
- 13 new tests (79 total, all pass)
- 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)