Commit graph

11 commits

Author SHA1 Message Date
Jan-Henrik Bruhn
66d47fb022 Fix duplicate label selection and add label wrapping
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.
2026-01-24 16:50:22 +01:00
Jan-Henrik Bruhn
4b865762a1 Address PR review comments
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>
2026-01-24 16:17:23 +01:00
Jan-Henrik Bruhn
8d71da76b2 Add shape-aware edge connections and edge-only handles
Improvements:
- Edges now follow actual node shape contours (circle, ellipse, pill, rectangle)
- Smooth arrow rotation using normal vectors at intersection points
- Custom bezier curves with control points aligned to shape normals
- Edge-only handles (30px strips) leaving center free for node dragging
- Proper offset calculations to prevent edge-shape overlap

Technical changes:
- Add getCircleIntersection() for perfect circle geometry
- Add getEllipseIntersection() with gradient-based normals
- Add getPillIntersection() for stadium shape (rounded caps + straight sides)
- Update getFloatingEdgeParams() to accept and use node shapes
- CustomEdge determines shapes from nodeType config and creates custom bezier paths
- Replace full-node handles with 4 edge-positioned handles (top/right/bottom/left)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-24 16:03:34 +01:00
Jan-Henrik Bruhn
c9c888d0ac Implement whole-node easy-connect handle system with floating edges
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>
2026-01-24 13:01:04 +01:00
Jan-Henrik Bruhn
3e2a7b6b20 Add multi-filter tangible support with presentation mode filtering
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>
2026-01-19 20:20:34 +01:00
Jan-Henrik Bruhn
b1e634d3c4 feat: add group minimize/maximize with floating edges and React Flow v12
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>
2025-10-20 11:52:44 +02:00
Jan-Henrik Bruhn
d98acf963b feat: implement label system and redesign filtering with positive filters
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>
2025-10-17 10:40:00 +02:00
Jan-Henrik Bruhn
e0784ff3d8 feat: add node shape variants with five distinct shapes
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>
2025-10-16 15:34:24 +02:00
Jan-Henrik Bruhn
ba6606d8b9 fix: dont show description in node visualization 2025-10-14 10:26:22 +02:00
Jan-Henrik Bruhn
1646cfb0ce feat: add search and filter functionality with Ctrl+F shortcut
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>
2025-10-12 12:11:29 +02:00
Jan-Henrik Bruhn
f56f928dcf Initial commit 2025-10-10 11:15:51 +02:00