Commit graph

18 commits

Author SHA1 Message Date
Jan-Henrik Bruhn
f5adbc8ead feat: add resizable actor grouping with full undo/redo support
Implements visual grouping of actors with context menu operations,
resizable containers, and complete history tracking integration.

Features:
- Create groups from multiple selected actors via context menu
- Groups visualized as resizable containers with child nodes
- Ungroup actors (non-destructive) or delete group with actors
- Right-click context menu with group-specific operations
- Dedicated GroupEditorPanel for group properties
- Smart minimum size constraint based on child node positions
- Full undo/redo support for group operations and resizes

Technical Implementation:
- GroupNode component with React Flow NodeResizer integration
- Atomic createGroupWithActors operation for consistent history
- Parent-child relationship using React Flow v11 parentId pattern
- Groups stored separately from actors in graphStore
- Fixed history tracking to sync graphStore before snapshots
- Resize tracking to prevent state sync loops during interaction
- Dynamic minimum dimensions to keep children inside bounds
- Sanitization of orphaned parentId references on state load

History Fixes:
- pushToHistory now syncs timeline with graphStore before snapshot
- Prevents missing groups/nodes in history states
- Ensures undo/redo correctly restores all graph elements
- Atomic state updates to avoid React Flow processing stale state

Storage & Persistence:
- Groups saved in timeline states and document structure
- Safe JSON serialization to prevent prototype pollution
- Cleanup utilities for removing __proto__ from localStorage

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-18 20:06:59 +02:00
Jan-Henrik Bruhn
9d3dfff64a refactor: remove non-functional Ctrl+A select-all shortcut
Removes the Ctrl+A keyboard shortcut and associated select-all functionality
that was not working properly.

Changes:
- Remove select-all shortcut definition from useGlobalShortcuts
- Remove "Select All" menu item from View menu
- Remove handleSelectAll stub function from App.tsx
- Clean up onSelectAll prop from MenuBar component

The select-all feature was dysfunctional (only logging to console) and
not properly implemented, so it has been removed entirely.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-13 12:49:47 +02:00
Jan-Henrik Bruhn
3ab90e5dd3 fix: allow double click on state nodes and improve their design 2025-10-12 14:49:15 +02:00
Jan-Henrik Bruhn
5275b52f0a refactor: move undo/redo to Edit menu and implement unified menu system
Removes the upper toolbar and consolidates undo/redo controls into the
Edit menu for a cleaner interface with more screen space.

Changes:
- Move undo/redo buttons from Toolbar to Edit menu with descriptions
- Remove Toolbar component from App layout
- Implement closeAllMenus event system for coordinated menu management
- Add event listeners to close menus when clicking on graph/timeline canvas
- Add cross-menu closing: context menus close menu bar and vice versa
- Fix React warning by deferring event dispatch with setTimeout

Benefits:
- Cleaner UI with more vertical space for graph editor
- Unified menu system prevents multiple menus open simultaneously
- Context menus and menu bar dropdowns coordinate properly
- Consistent UX: clicking anywhere closes open menus

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-12 12:35:30 +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
bd36dd365a refactor: make header more compact with horizontal layout
Reduces header height by restructuring the layout to display all
elements on a single horizontal line instead of stacking vertically.

Changes:
- Move subtitle to the right of the title with a separator border
- Reduce vertical padding from py-4 to py-3
- Decrease logo size from 10x10 to 8x8
- Reduce title size from text-2xl to text-xl

This provides more vertical space for the main content area while
maintaining all header information in a cleaner, more compact design.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 22:13:11 +02:00
Jan-Henrik Bruhn
28f8224284 feat: add timeline system for multi-state constellation analysis
Implements a comprehensive timeline system that enables documents to contain
multiple constellation states with branching timelines. This allows users to
create different versions of their analysis for temporal evolution, alternative
scenarios, or what-if analysis.

Core Features:
- Timeline store managing multiple states per document with branching structure
- Visual timeline panel with React Flow-based state graph visualization
- State management: create, switch, rename, duplicate (parallel/series), delete
- Per-state undo/redo history (max 50 actions per state)
- Context menu for timeline node operations
- Collapsible timeline panel (always visible, moved toolbar to panel header)

Architecture Changes:
- Document structure: removed top-level graph field, states now only in timeline
- Global types: nodeTypes and edgeTypes are now global per document, not per state
- State graphs: only contain nodes and edges, types inherited from document
- Persistence: full timeline serialization/deserialization with all states
- History system: converted from document-level to per-state independent stacks

Timeline Components:
- TimelineView: main timeline visualization with state nodes and edges
- BottomPanel: collapsible container with timeline controls in header
- StateNode: custom node component showing state info and active indicator
- CreateStateDialog: dialog for creating new timeline states
- RenameStateDialog: dialog for renaming existing states
- Context menu: right-click operations (rename, duplicate parallel/series, delete)

Document Management:
- Documents always have timeline (initialized with root state on creation)
- Timeline persisted with document in localStorage
- Export/import includes complete timeline with all states
- Migration support for legacy single-state documents

Store Updates:
- timelineStore: manages timelines, states, and timeline operations
- historyStore: per-state history with independent undo/redo stacks
- workspaceStore: saves/loads timeline data, handles global types
- panelStore: added timeline panel visibility state
- useActiveDocument: syncs timeline state with graph editor

Context Menu Improvements:
- Smart viewport edge detection to prevent overflow
- Click-outside detection for React Flow panes
- Consistent styling across application

Files Added:
- src/types/timeline.ts - Timeline type definitions
- src/stores/timelineStore.ts - Timeline state management
- src/components/Timeline/TimelineView.tsx - Main timeline component
- src/components/Timeline/BottomPanel.tsx - Timeline panel container
- src/components/Timeline/StateNode.tsx - State node visualization
- src/components/Timeline/CreateStateDialog.tsx - State creation dialog
- src/components/Timeline/RenameStateDialog.tsx - State rename dialog

Files Removed:
- src/stores/persistence/middleware.ts - Obsolete persistence middleware

Documentation:
- Added comprehensive timeline feature documentation
- Implementation checklists and quick reference guides
- Temporal analysis concepts and UX guidelines

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 22:00:34 +02:00
Jan-Henrik Bruhn
c1a2d926cd feat: add document naming dialog before creation
Implements a user-friendly dialog that prompts for document names before
creating new documents, replacing the default "Untitled Analysis" behavior.

Features:
- InputDialog component for text input with validation
- useCreateDocument hook to centralize naming logic
- Pre-filled default value "Untitled Analysis"
- Validation to prevent empty document names
- Helpful placeholder text with examples
- Keyboard shortcuts (Enter/Escape)
- Auto-focus and select input field

Updated all document creation entry points:
- Menu Bar: "New Document" and "New from Template"
- Document Tabs: "+" button
- Document Manager: "New Document" button
- Empty State: "New Document" button
- Keyboard shortcut: Ctrl+N

This provides a consistent UX across the application and reduces code
duplication by using a single reusable hook.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 12:03:05 +02:00
Jan-Henrik Bruhn
869e4d5f68 fix: lint issues unused fns 2025-10-10 23:33:15 +02:00
Jan-Henrik Bruhn
045b1aa4d6 fix: remove non-functional panel toggle keyboard shortcuts
Removes Ctrl+B and Ctrl+I keyboard shortcuts that were causing panels
to disappear completely instead of collapsing properly. Also updates
all panel tooltips to no longer reference the removed shortcuts.

Changes:
- Removed Ctrl+B (left panel) and Ctrl+I (right panel) shortcut handlers
- Updated left panel tooltips: removed "(Ctrl+B)" references
- Updated right panel tooltips: removed "(Ctrl+I)" references
- Tooltips now simply show "Collapse Panel" / "Expand Panel"
- Escape key handler preserved for closing property panels

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 23:30:41 +02:00
Jan-Henrik Bruhn
8998061262 feat: add toast notification system for visual feedback
Implements toast notifications from UX_ANALYSIS.md to provide clear,
non-intrusive feedback for user actions.

Features:
- Toast store with Zustand for global state management
- Four toast variants: success, error, info, warning
- Auto-dismiss after configurable duration (default 4s)
- Max 3 visible toasts with FIFO queue
- Smart positioning that avoids right panel overlap
- Smooth slide-in/fade-out animations

Notifications added for:
- File operations (import/export success/errors)
- Document operations (create/delete/rename/duplicate)
- Workspace operations (import/export)

Toast container dynamically repositions based on right panel state
to ensure toasts never overlap with critical UI elements.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 23:13:28 +02:00
Jan-Henrik Bruhn
d7d91798f1 feat: add crispy PNG/SVG graph export with tight cropping 🔥
Implemented image export functionality using html-to-image that actually
slaps. No more bloated screenshots with miles of blank space - this baby
wraps your graph tighter than shrink wrap on a fresh deck.

Features:
- PNG export with proper 300 DPI quality (4x pixelRatio)
- SVG vector export for infinite scaling
- Smart bounds calculation that hugs your nodes
- Configurable padding (default: 10px of breathing room)
- Accessible via File menu

Technical highlights:
- Direct transform calculation instead of getViewportForBounds bloat
- Proper pixelRatio handling (not that 16x scaling nonsense)
- Based on React Flow's official pattern but actually optimized
- Uses html-to-image@1.11.11 (newer versions are broken)

Export quality goes hard. Print-ready PNGs. Crisp. Clean. Chef's kiss.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 23:01:33 +02:00
Jan-Henrik Bruhn
f308edbfa6 fix: replace any types with explicit function signatures
Replace TypeScript 'any' types with explicit function signatures to fix ESLint errors. This improves type safety for the onAddNodeRequest callback.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 22:20:47 +02:00
Jan-Henrik Bruhn
ae334efd34 refactor: move undo/redo to toolbar, simplify left panel
Reorganized the UI to improve clarity and reduce duplication:
- Reintroduced Toolbar component below document tabs
- Moved undo/redo controls from left panel to toolbar
- Simplified toolbar to show only undo/redo (removed actor/relation controls)
- Removed History section from left panel
- Left panel now focuses on content management (actors, relations, etc.)

The toolbar now provides a consistent, always-visible location for history
controls across the top of the editor, while the left panel is dedicated to
adding and managing graph content.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 22:16:05 +02:00
Jan-Henrik Bruhn
5aeb187efe fix: ensure only newly created items are selected
Fixed selection state inconsistency when adding nodes or edges. Previously,
both the new item and previously selected items would remain selected due to
a race condition between Zustand store updates and ReactFlow state syncing.

Changes:
- Added pendingSelectionRef to track items that should be selected after
  Zustand sync completes
- Modified useEffect sync logic to preserve selection state normally, but
  apply pending selection when new items are added
- Unified node creation logic between context menu and left panel to ensure
  consistent behavior
- When adding nodes/edges, all other items are now properly deselected

The fix ensures selection state lives only in ReactFlow (not Zustand) and
is properly coordinated during store updates.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 22:12:12 +02:00
Jan-Henrik Bruhn
e7ff53dcd7 feat: side panels for properties and tools 2025-10-10 18:13:18 +02:00
Jan-Henrik Bruhn
ce0ee71193 fix: logo path 2025-10-10 12:03:54 +02:00
Jan-Henrik Bruhn
f56f928dcf Initial commit 2025-10-10 11:15:51 +02:00