- Add collapsed state to NodeData.custom_colors (type=groupRect only)
- Implement toggleNodeCollapsed action in canvasStore (Zustand)
- Extend GroupRectNode UI with smooth chevron toggle button
- Rotating chevron icon (↓ → when collapsed)
- Shows '+N' badge when zone is hidden
- Reduces zone opacity to 0.6 when collapsed
- All transitions target 60 FPS (ease-out 200ms)
- Filter child nodes/edges in CanvasContainer based on parent collapse state
- Breadth-first traversal handles multi-level nesting
- Connecting edges to hidden nodes are automatically hidden
- Add comprehensive test coverage
- Store: toggleNodeCollapsed state mutation, unsaved flag
- Component: chevron rendering, click handlers, opacity transitions
- Persist collapsed state via YAML serialization (part of custom_colors)
Benefits:
- Declutter large Zigbee meshes, multi-building networks
- Preserve layout structure without deleting nodes
- Smooth 60 FPS transitions for UX polish
CONTRIBUTING.md compliance:
- Strict TypeScript types, no 'any'
- Zustand store pattern, no prop drilling
- Tests for store logic and component behavior
- Frontend linting requirements met
Co-authored-by: CyberClaw <noreply@openclaw.ai>
TS build failed in smoke-and-integration: NODE_TYPE_DEFAULT_ICONS and
all theme nodeAccents were missing zigbee_coordinator, zigbee_router,
zigbee_enddevice entries required by NodeType union.
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