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>
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>
All keyboard shortcut labels in the MenuBar now come from the
centralized keyboard shortcut manager via the new useShortcutLabels
hook, eliminating hardcoded duplicates.
Changes:
- Add useShortcutLabels hook for retrieving formatted shortcut labels
- Update MenuBar to use dynamic shortcut labels from manager
- Platform-aware display (Cmd on Mac, Ctrl elsewhere)
- Shortcuts automatically update if changed in manager
- Fix MUI icon fontSize prop issue in LeftPanel
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace generic circle icons with the actual node type icons in the
left panel's "Add Actors" section. Icons now match the visual
representation of actors in the graph, making it more intuitive to
identify actor types. Falls back to circle if no icon is defined.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed TypeScript error where onAddNodeRequest callback parameter type
was incorrectly defined. The prop expects a function that receives a
callback, not the node type ID directly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
Removed the "Edit Properties" option from both node and edge context menus,
leaving only the "Delete" option. Users can simply click on nodes/edges to
select them and edit properties in the right panel, making the context menu
option redundant.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
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>
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>
Fixes an issue where nodes from a previous document would persist when
creating a new document after closing all documents.
The problem occurred because:
1. When all documents were closed (activeDocumentId becomes null), the
graph store wasn't being cleared
2. When a new document was created, stale data from the old document
could contaminate the new document through race conditions
Changes:
- Clear nodes and edges from graph store when activeDocumentId is null
- Add safeguard to prevent saving stale graph data to newly created
documents before they've been fully loaded
- Maintain proper state tracking to prevent cross-document contamination
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added lastSyncedStateRef to track the graph state that was last loaded/synced
for each document. This prevents stale comparisons when switching between
documents by ensuring dirty checks only run against the correct document's
state.
Changes:
- Track last synced state (nodes, edges, nodeTypes, edgeTypes) per document
- Skip dirty check if graph state belongs to a different document
- Compare current graph state against last synced state instead of active document
- Update last synced state reference when loading or saving changes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>