Commit Graph

57 Commits

Author SHA1 Message Date
Pouzor 3deb750441 fix: NaN guard on settings interval input and validate release URL scheme 2026-04-21 11:43:15 +02:00
Pouzor 88554ef952 fix: stop click propagation on pending device checkbox to prevent modal opening 2026-04-21 11:37:43 +02:00
Pouzor 110592f89e fix: checkbox onChange anti-pattern in PendingDevicesPanel 2026-04-21 11:28:55 +02:00
Pouzor 8b8da5584c feat: add logout button to sidebar 2026-04-21 11:23:52 +02:00
findthelorax cd6a788f77 fix: test was missing leading / 2026-04-20 14:37:08 +02:00
findthelorax 9cf6a48b04 fix: port input to text numeric and removed up/down arrows 2026-04-20 14:37:08 +02:00
findthelorax 2c94616afa cleanup path examples 2026-04-20 14:37:08 +02:00
findthelorax c7be851c34 feature: add support for services to use a path 2026-04-20 14:37:08 +02:00
Pouzor 0193f933ce feat: bulk approve/hide pending devices (#70)
- Backend: POST /scan/pending/bulk-approve and /scan/pending/bulk-hide endpoints (registered before dynamic routes to avoid conflict); bulk-approve response includes device_ids for frontend mapping
- Frontend: PendingDevicesPanel gains per-row checkboxes, select-all, and a bulk action bar (Approve N / Hide N) that appears when ≥1 device is selected
- Tests: 6 new backend API tests + 7 new frontend UI tests for bulk selection flows
2026-04-19 22:13:40 +02:00
Pouzor 2e6ee9dad2 fix: handle multi-IP and add tests for clickable IP link
Follow-up to #78:
- Use primaryIp() so href targets the first IP when data.ip is comma-separated (e.g. "192.168.1.1, 2001:db8::1")
- Add primaryIp() helper to maskIp.ts
- Add 4 tests covering single IP link, absent IP, multi-IP href, multi-IP display text
2026-04-19 22:04:37 +02:00
findthelorax 81b109f981 feat: make IP Address clickable in detail panel
- Display IP as a clickable link that opens http://<ip> in a new tab
- Match the existing Hostname link styling and behavior
- Add external link icon to indicate it's clickable
2026-04-19 10:08:09 -04:00
Pouzor 3d89ba3b6f feat: replace static hardware fields with dynamic node properties
Replaces the 4 fixed hardware columns (cpu_count, cpu_model, ram_gb,
disk_gb) with a flexible properties system. Each property has a key,
value, icon (from a curated Lucide picker), and a visibility toggle
that controls whether it appears on the canvas node card.

- Backend: add `properties` JSON column to Node model; data migration
  converts existing hardware rows to properties with correct icons
  (idempotent, old columns kept for safety)
- Backend: add `properties` to NodeBase, NodeUpdate, NodeSave schemas
  and canvasSerializer so values survive canvas save/load
- Frontend: add NodeProperty type; new propertyIcons.ts registry (20
  icons); BaseNode renders visible properties with legacy hardware
  fallback for unmigrated nodes
- Frontend: DetailPanel gains interactive properties section (add /
  edit / remove / toggle visibility / icon picker) replacing the
  read-only hardware block; hardware section removed from NodeModal
- Tests: 6 migration tests, 7 API tests, 8 DetailPanel property tests,
  6 BaseNode render/fallback tests, 9 propertyIcons util tests
2026-04-09 13:47:36 +02:00
Pouzor 75c7f25a30 feat: display app version in sidebar with GitHub release check 2026-04-08 12:22:39 +02:00
Pouzor 4d8bb246f1 fix: scan no longer triggers before user confirms in ScanConfigModal 2026-04-05 14:35:10 +02:00
Pouzor bd22891fab fix: correct UTC timestamp display and pre-existing code quality issues 2026-04-05 03:06:29 +02:00
Pouzor d96b502524 fix: correct UTC timestamp display in scan history, pending devices, and detail panel 2026-04-05 02:50:23 +02:00
Pouzor 9cb9d02459 feat: extend search (Ctrl+F and Ctrl+K) to include pending devices
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.
2026-04-05 02:40:12 +02:00
Pouzor 38c5bcb606 feat: configurable bottom handles, scanner rewrite, UI polish
## New features
- Configurable bottom connection points per node (1–4 handles)
- Fit view on load
- LiveView improvements
- Node modal: inline Type/Icon picker, default icon in trigger
- Remove redundant Save button from ScanConfigModal

## Scanner fixes
- Phase 1: replace nmap ARP sweep with concurrent asyncio ping sweep
  (50 parallel pings, 1s timeout). Zero false positives, works in any
  Docker network mode. Supplements with /proc/net/arp for ICMP-blocked devices.
- Phase 2: explicit -sS (root) / -sT (non-root) scan type; bump
  host-timeout to 60s; gather(return_exceptions=True) so one failing
  host doesn't abort the batch
- Fix 404 on missing device in hide/ignore
- Validate CIDR ranges to prevent nmap injection
- Thread-safe cancel set, pre-fetch canvas/hidden IPs (no N+1 queries)
- Logging: attach StreamHandler to root logger so app.* logs are visible

## Tests
- 21 backend scanner tests (ping sweep, ARP cache, Phase 2 tolerance)
- Full NodeModal coverage (53 tests)
- LiveView, store, edge label tests
2026-04-04 23:15:47 +02:00
Pouzor 0a72f9be67 test: add tests for useStatusPolling hook and Sidebar component
- 12 tests for useStatusPolling: WebSocket lifecycle, auth guards,
  message routing (status/scan_device_found), error resilience, cleanup
- 21 tests for Sidebar: render, collapse/expand, node stats, action
  callbacks, view navigation, scan trigger, settings panel toggle
2026-04-03 22:55:56 +02:00
Pouzor 0b89244317 feat: lasso selection, multi-select panel, and named groups
- 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
2026-04-01 23:15:52 +02:00
Pouzor 057891f7d5 feat: add stop scan button in UI with backend cancellation support
- 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
2026-04-01 14:18:44 +02:00
Pouzor 1444a81150 fix: DEL key deletes nodes and deletion is now undoable
- 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
2026-03-31 00:19:27 +02:00
Pouzor 350dc14a16 test: add SettingsPanel tests covering settingsApi integration
- 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
2026-03-30 23:14:42 +02:00
Pouzor 68c7672cea feat: split scan config and app settings into separate endpoints
- 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
2026-03-30 23:06:51 +02:00
Pouzor 58381b97d2 feat: move status check interval to sidebar Settings panel
- 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
2026-03-30 22:21:36 +02:00
Pouzor ea539d6e31 fix: null guards, aria-labels, and missing tests for DetailPanel
- Extract const services = data.services ?? [] for consistent null safety
- Add aria-label to close and delete buttons
- Add tests: close, edit callback, delete (confirm/cancel), add service, remove service, undefined services
2026-03-29 19:28:52 +02:00
Pouzor f657e45995 fix: null guard data.services and aria-label on delete button
Fixes crash when services is undefined on legacy nodes.
Adds aria-label="Delete node" for accessibility.
2026-03-29 19:25:55 +02:00
Pouzor 3fe9fa7ca8 feat: add inline edit for services in detail panel
Replaces service badge with in-place form when pencil icon is clicked.
State is scoped to nodeId so switching nodes auto-resets edit/add forms.
2026-03-29 19:24:22 +02:00
Pouzor f0222247bb feat: add inline edit for services in detail panel 2026-03-29 19:19:29 +02:00
Pouzor 38a06682e5 feat: rename Rectangle to Zone, add border width selector
- 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
2026-03-29 01:47:04 +01:00
Pouzor daf3f59590 ui: swap icons between Export and PNG buttons 2026-03-24 01:35:39 +01:00
Pouzor 212eb37e34 ui: place Export next to Import, swap PNG/Export icons 2026-03-24 01:34:13 +01:00
Pouzor 61b8a210fe ui: rename toolbar buttons — YAML export to Export, PNG export to PNG 2026-03-24 01:31:22 +01:00
Pouzor e7ab9a1d7a feat: add YAML import — merge nodes/edges from .yaml file into canvas 2026-03-24 01:14:54 +01:00
Pouzor 2e49c14028 feat: add YAML export — serialize canvas nodes/edges to downloadable .yaml file 2026-03-23 21:59:04 +01:00
Pouzor 06ec18a137 feat: add hardware specs to nodes (CPU, RAM, Disk) with canvas display
- Add cpu_count, cpu_model, ram_gb, disk_gb, show_hardware fields to NodeData
- NodeModal: collapsible Hardware section with toggle to show specs on canvas
- BaseNode: 2-line hardware section with Cpu/MemoryStick/HardDrive icons, only renders set fields
- DetailPanel: Hardware section with GB/TB formatting
- Backend: schema, model, DB migration, canvas save/load support
- Tests: frontend (NodeModal, DetailPanel) + backend (canvas persist/load)
2026-03-21 00:01:15 +01:00
Pouzor f8cadba17b feat: export node inventory as Markdown table (copy to clipboard) 2026-03-13 12:36:31 +01:00
Pouzor 5f7cb1bf11 feat: make hostname clickable in detail panel (opens in new tab) 2026-03-13 12:31:07 +01:00
Pouzor ba032a45af feat: canvas history (undo/redo), copy/paste nodes, node search, shortcuts modal
- Undo/Redo (Ctrl+Z / Ctrl+Y): 50-entry snapshot stack in canvasStore; snapshot before all mutations and on node drag stop
- Copy/Paste (Ctrl+C / Ctrl+V): copy selected nodes to clipboard, paste with +50px offset and new IDs
- Node search (Ctrl+K): spotlight overlay — fuzzy search by label/IP/hostname, jumps + focuses matched node
- Shortcuts modal (?): lists all keyboard shortcuts, accessible via ? key or toolbar ? button
- Toolbar: undo/redo buttons (disabled when stack empty), ? help button
2026-03-12 11:56:38 +01:00
Pouzor 271bbf2d01 feat: add hide IP toggle in sidebar
- 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
2026-03-11 16:15:22 +01:00
Pouzor 92d505f78c feat: add logo, favicon, and theme system
- 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
2026-03-11 14:29:15 +01:00
Pouzor 1f1dfd807b feat: add/remove services in detail panel + fix service URL detection
- 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)
2026-03-10 17:29:41 +01:00
Pouzor 1e72366d03 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)
2026-03-10 16:59:40 +01:00
Pouzor 6f7f6be5b6 fix: remove asChild from TooltipTrigger — base-ui does not support Radix asChild prop 2026-03-10 00:11:56 +01:00
Pouzor 20d9473f38 feat: detect virtual machines from MAC OUI and show badge on pending devices
Backend:
- Add MAC OUI lookup table (QEMU 52:54:00, Proxmox bc:24:11, VMware, VBox, Hyper-V)
- suggest_node_type() now accepts mac param and uses OUI as a low-priority hint

Frontend:
- Detect VM type from MAC prefix on pending device cards
- Show colored badge (QEMU / PVE / VMware / VBox / Hyper-V) in orange with tooltip
2026-03-09 22:22:38 +01:00
Pouzor 99b40fa9e9 fix: prioritize named service over SSH/HTTP/HTTPS for pending device card title 2026-03-09 21:54:15 +01:00
Pouzor 1d6d8f0178 feat: enhance pending device cards with service badges and recognized service title
- Show recognized service name (Home Assistant, Synology, Proxmox, etc.) as
  card title instead of IP when detected via service signatures
- Keep IP displayed smaller below when title differs from IP
- Add SSH / HTTP / HTTPS badges as colored pills
- Show +N badge for additional services beyond the three common ones
2026-03-09 21:46:40 +01:00
Pouzor 7ba5e888b4 feat: add standalone (frontend-only) mode via VITE_STANDALONE build flag
- App.tsx: bypass auth gate, swap canvas save/load to localStorage
- Sidebar.tsx: hide scan views and Scan Network button
- useStatusPolling.ts: skip WebSocket connection
- Dockerfile.frontend: accept VITE_STANDALONE build arg
- docker-publish.yml: build ghcr.io/pouzor/homelable-frontend-standalone image
- docker-compose.standalone.yml: frontend-only compose file
- install.sh: add --standalone flag

Usage:
  curl -fsSL .../install.sh | bash -s -- --standalone
  cd homelable && docker compose up -d
2026-03-09 14:00:25 +01:00
Pouzor acc5bc6a64 fix: cast Service[] to ServiceInfo[] in pending device approve 2026-03-09 11:09:03 +01:00
Pouzor c6733e4dcd fix: resolve TypeScript build errors blocking Docker image
- nodeColors.ts: add missing camera/printer/computer/cpl entries to Record<NodeType, NodeColors>
- CanvasContainer.tsx: use ConnectionMode enum instead of bare string literal
- export.ts: cast style object to Partial<CSSStyleDeclaration> for CSS custom property
- Sidebar.tsx: cast suggested_type to NodeType to satisfy NodeData type
2026-03-09 11:07:22 +01:00