Commit Graph

13 Commits

Author SHA1 Message Date
Pouzor ef96cafcc8 feat: IPv6 support and multi-IP per node (closes #60)
- maskIp handles IPv6 addresses (masks second and last group)
- maskIp handles comma-separated IP strings (masks each address)
- Add splitIps() helper to parse comma-separated IP field
- Add primaryIp() helper used by status checker (first IP wins)
- BaseNode renders each IP on its own line when comma-separated
- NodeModal placeholder shows comma-separated example
- Backend status_checker uses only first IP for connectivity checks
- Expand maskIp test suite: IPv6, comma-separated, splitIps, primaryIp
2026-04-19 22:13:40 +02: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 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 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 adb4474687 feat: add Docker node type, group rect border style, and categorized node type selector
- 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
2026-03-20 21:09:58 +01:00
Pouzor df3b7a8cb0 fix: show validation error when label is empty in NodeModal
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.
2026-03-16 01:01:47 +01:00
Pouzor 627f67336f feat: add 'none' check method — node always appears online 2026-03-08 00:41:17 +01:00
Pouzor d98bfba506 feat: add custom icon picker to node create/edit modal
- Add 65+ icons across 7 categories (Infrastructure, Media, Monitoring,
  Storage, Security, Automation, Dev & Containers, Communications) covering
  popular self-hosted apps: Home Assistant, Jellyfin, Plex, Grafana, Portainer,
  Pi-hole, Vaultwarden, Gitea, Nextcloud, Node-RED, Frigate, etc.
- New nodeIcons.ts utility with ICON_REGISTRY, ICON_MAP and resolveNodeIcon()
- Inline icon picker in NodeModal: collapsible panel with search + grid grouped
  by category; click to select, click again or Reset to revert to type default
- BaseNode uses resolveNodeIcon() so custom icon renders live on canvas
- Add custom_icon field to NodeData type, NodeBase/NodeUpdate schemas, Node ORM
  model, and database.py idempotent ALTER TABLE migration
2026-03-07 23:01:30 +01:00
Pouzor 37c963cf96 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
2026-03-07 14:31:05 +01:00
Pouzor 4fb9a8ee45 feat: edge edit mode + proxmox container mode toggle
- Double-click any link to open Edit Link modal (type, label, VLAN ID, delete)
- Add updateEdge / deleteEdge actions to canvasStore
- Add container_mode field to proxmox nodes (backend model, schemas, migration)
- NodeModal shows container toggle for proxmox type (defaults ON)
- ProxmoxGroupNode renders as regular BaseNode when container_mode is OFF
- setProxmoxContainerMode store action handles structural changes atomically
  (children parentId/extent, node dimensions)
- CanvasContainer filters edges between container proxmox and its children
- Canvas load respects container_mode when assigning parentId/extent
2026-03-07 14:15:08 +01:00
Pouzor a3e6a97404 feat: Proxmox nested nodes — VM/LXC rendered inside resizable group container
- ProxmoxGroupNode: resizable bordered container with orange accent, header
  bar (icon, label, IP, status dot), NodeResizer on selection
- nodeTypes: proxmox now uses ProxmoxGroupNode instead of BaseNode
- NodeData: added parent_id field
- canvasStore: addNode and loadCanvas wire parentId + extent='parent'
  for child nodes; loadCanvas sorts parents before children (RF requirement)
- NodeModal: Parent Proxmox dropdown appears when type is VM or LXC,
  lists all Proxmox nodes on the canvas
- App.tsx: passes proxmoxNodes to modals; child nodes positioned relative
  to parent (x:20, y:50); Proxmox nodes get width:300/height:200 on load
- layout.ts: Dagre skips child nodes (parentId set); uses actual group
  dimensions for Proxmox nodes in rank calculation
2026-03-07 00:50:50 +01:00
Pouzor 44a448e26d fix: all lint errors, test + lint pre-commit passing
Frontend:
- Split nodeTypes/edgeTypes into separate .ts files (react-refresh)
- Remove setState-in-effect in NodeModal (key prop reset)
- Fix handleSave accessed before declaration (useRef pattern)
- Exclude src/components/ui/** from eslint (shadcn generated)
- Use defineConfig from vitest/config for test type support

Backend:
- ruff --fix: sort imports, datetime.UTC alias
- Raise line-length to 120, ignore E501 in tests
- Break long update_node/update_edge signatures
- pyproject.toml: per-file-ignores for tests
2026-03-06 23:58:10 +01:00
Pouzor 150302c3f7 feat: Phase 2 — auth, node/edge modals, API wiring
- Login page: full-screen dark, grid bg, JWT flow
- Auth store (Zustand) + API client (axios + interceptors)
- NodeModal: add/edit form (type, label, hostname, IP, check method)
- EdgeModal: link type picker + VLAN ID + label on connect
- App: auth gate, canvas load from API (fallback to demo), Ctrl+S save
- CanvasContainer: expose onConnect prop for edge modal flow
2026-03-06 23:33:55 +01:00