b71c96897a
Three connected bugs in PR #158's collapse feature: 1. Toggle wired to the wrong component The chevron was on GroupRectNode and computed children via React Flow parentId. But in this codebase parentId is set by createGroup() on type=group nodes, not on groupRect zones — zones are decorative rectangles. Result: childrenCount was always 0 on every zone and the button never rendered, so the feature was unreachable from the UI. Fix: - Add the same chevron toggle to GroupNode (the actual container). parentId children are already known there, so the existing BFS in computeCollapseInfo hides them when data.collapsed flips. - For GroupRectNode, switch childrenCount to spatial containment so drawn zones also work: hit-test other nodes' bbox centres against the zone bbox. 2. Visibility filter ignored spatial zones Extend computeCollapseInfo with a second pass that hides every node whose centre lies inside a collapsed groupRect, plus the parentId subtrees of those nodes (so a Proxmox host inside a collapsed zone takes its VMs/LXCs with it). Edge rewiring routes vanished endpoints to the same visible zone via a unified hiddenBy map populated by both passes. 3. Save dropped data.collapsed for every type except groupRect The DevTools payload was the smoking gun: for a type=group node the serializer wrote custom_colors: {show_border: true} with no collapsed key, so the backend stored a stale false on every save. Only the groupRect branch of serializeNode/deserializeApiNode stashed and hoisted the flag. Move the stash + hoist to the general branch too (backend's custom_colors is dict[str, Any] so no schema change). Tests: 11 new cases for spatial containment + GroupNode toggle UI, and 4 round-trip cases for collapse on non-groupRect types.