Label selection fix:
- Prevent duplicate labels when creating a label that already exists
- Check if label is already selected before adding to selection
Label wrapping improvements:
- Labels now wrap within a 200px container to prevent nodes growing too large
- LabelBadge updated to only truncate when maxWidth is explicitly provided
- Labels display full text without individual truncation
- Applies to both CustomNode and CustomEdge components
Note: Some overlap may occur with circular shapes - accepted for now.
Edge calculation improvements:
- Add zero radius/radii guards in circle and ellipse intersection functions
- Add clamping for pill straight edge intersections to prevent overflow
- Ensure intersection points stay within valid pill boundaries
Handle improvements:
- Add bidirectional connection support with overlapping source/target handles
- Each edge now has both source and target handles (8 total per node)
- Allows edges to connect in any direction from any side
- Fixes handle type restrictions that prevented flexible connections
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Migrated from 4-position handle system (top/right/bottom/left) to React Flow's
easy-connect pattern where the entire node surface is connectable and edges
dynamically route to the nearest point on the node border.
Key changes:
- Migration utility removes old 4-position handle references for backwards compatibility
- Full-coverage invisible handles on CustomNode and GroupNode (maximized state)
- Floating edges use node.measured dimensions and node.internals.positionAbsolute
- useInternalNode hook for correct absolute positioning of nodes in groups
- All edges now omit handle fields, allowing dynamic border calculations
This improves UX by making nodes easier to connect (whole surface vs tiny handles)
and edges intelligently route to optimal connection points.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Features:
- Extended tangible filters to support labels, actor types, and relation types
- Added configurable combine mode (OR/AND) for filter logic
- Separated presentation mode filters from editing mode filters
- Implemented backward compatibility with legacy filterLabels format
Filter Behavior:
- OR mode (default for tangibles): Show items matching ANY filter category
- AND mode (default for editing): Show items matching ALL filter categories
- Presentation mode uses tuioStore.presentationFilters
- Editing mode uses searchStore filters
UI Improvements:
- Replaced radio buttons with horizontal button layout for mode selection
- Replaced dropdown with horizontal buttons for combine mode selection
- Consolidated Name and Hardware ID fields into two-column layout
- More compact and consistent interface
Technical Changes:
- Added FilterConfig type with combineMode field
- Created tangibleMigration.ts for backward compatibility
- Created tangibleValidation.ts for multi-format validation
- Added useActiveFilters hook for mode-aware filter access
- Added nodeMatchesFilters and edgeMatchesFilters helper functions
- Updated cascade cleanup for node/edge type deletions
- Removed all TUIO debug logging
Tests:
- Added 44 comprehensive tests for useActiveFilters hook
- Added tests for tangibleMigration utility
- All 499 tests passing
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements comprehensive group minimize/maximize functionality and migrates
to React Flow v12 (@xyflow/react) with improved edge routing.
## Group Minimize/Maximize Features:
- Minimized groups render as compact 220×80px solid rectangles
- Original dimensions preserved in metadata and restored on maximize
- Child actors hidden (not filtered) to prevent React Flow state issues
- Solid color backgrounds (transparency removed for minimized state)
- Internal edges filtered out when group is minimized
- Dimension sync before minimize ensures correct size on maximize
## Floating Edges:
- Dynamic edge routing for connections to/from minimized groups
- Edges connect to closest point on minimized group border
- Regular actors maintain fixed handle connections
- Smooth transitions when toggling group state
## React Flow v12 Migration:
- Updated package from 'reactflow' to '@xyflow/react'
- Changed imports to named imports (ReactFlow is now named)
- Updated CSS imports to '@xyflow/react/dist/style.css'
- Fixed NodeProps/EdgeProps to use full Node/Edge types
- Added Record<string, unknown> to data interfaces for v12 compatibility
- Replaced useStore(state => state.connectionNodeId) with useConnection()
- Updated nodeInternals to nodeLookup (renamed in v12)
- Fixed event handler types for v12 API changes
## Edge Label Improvements:
- Added explicit z-index (1000) to edge labels via EdgeLabelRenderer
- Labels now properly render above edge paths
## Type Safety & Code Quality:
- Removed all 'any' type assertions in useDocumentHistory
- Fixed missing React Hook dependencies
- Fixed unused variable warnings
- All ESLint checks passing (0 errors, 0 warnings)
- TypeScript compilation clean
## Bug Fixes:
- Group drag positions now properly persisted to store
- Minimized group styling (removed dotted border, padding)
- Node visibility using 'hidden' property instead of array filtering
- Dimension sync prevents actors from disappearing on maximize
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements a comprehensive label system and completely redesigns all
filtering (labels, actor types, relation types) to use intuitive positive
filtering where empty selection shows all items.
Label System Features:
- Create, edit, delete labels with names, colors, and scope (actors/relations/both)
- Inline editing with click-to-edit UI for quick modifications
- Quick-add label forms in config modals
- Autocomplete label selector with inline label creation
- Label badges rendered on nodes and edges (no overflow limits)
- Full undo/redo support for label operations
- Label validation and cleanup when labels are deleted
- Labels stored per-document in workspace system
Filter System Redesign:
- Changed from negative to positive filtering for all filter types
- Empty selection = show all items (intuitive default)
- Selected items = show only those items (positive filter)
- Consistent behavior across actor types, relation types, and labels
- Clear visual feedback with selection counts and helper text
- Auto-zoom viewport adjustment works for all filter types including labels
Label Cleanup & Validation:
- When label deleted, automatically removed from all nodes/edges across all timeline states
- Label references validated during node/edge updates
- Unknown label IDs filtered out to maintain data integrity
UI Improvements:
- All labels rendered without overflow limits (removed +N more indicators)
- Filter checkboxes start unchecked (select to filter, not hide)
- Helper text explains current filter state
- Selection counts displayed in filter section headers
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements configurable shape variants for actor nodes, allowing visual
differentiation of node types beyond just color.
Features:
- Five shape options: rectangle, circle, rounded rectangle, ellipse, pill
- All shapes use pure CSS (border-radius) for consistent behavior
- Auto-grow with content
- Perfect shadow and selection/highlight effects
- Proper React Flow handle alignment
- Shape selector UI with visual previews
- Migration logic for existing documents (defaults to rectangle)
Shape characteristics:
- Rectangle: Standard, general purpose
- Circle: Round, for people and concepts
- Rounded Rectangle: Soft edges, friendly appearance
- Ellipse: Oval/horizontal, for processes and stages
- Pill: Capsule, compact for tags and labels
Technical approach:
- Uses border-radius for all shapes (no clip-path)
- Ensures boxShadow follows shape contours properly
- Each shape component maintains consistent props interface
- NodeShapeRenderer routes to appropriate shape component
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements search and filter feature from UX_ANALYSIS.md to help users
find actors and relations in complex graphs.
Features:
- Search store with Zustand for managing search/filter state
- Real-time search by actor label, description, or type name
- Filter by actor types (show/hide specific node types)
- Filter by relation types (show/hide specific edge types)
- Visual feedback: non-matching items dimmed to 20% opacity
- Matching items highlighted with colored glow when filters active
- Results counter showing X actors of Y total
- Ctrl+F keyboard shortcut to focus search input
- Expands left panel if collapsed
- Opens search section if closed
- Focuses search input field
UI improvements:
- Search input with magnifying glass icon and clear button
- Reset filters link (only visible when filters active)
- Checkboxes for each actor/relation type with visual indicators
- Smooth transitions and hover states
- Fixed icon overlap issue in search input
Components modified:
- CustomNode: Apply opacity/highlighting based on search matches
- CustomEdge: Apply opacity based on relation type filters
- LeftPanel: Full search UI with filters in existing section
- App: Wire up Ctrl+F shortcut with ref-based focus handler
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>