Commit graph

93 commits

Author SHA1 Message Date
Jan-Henrik Bruhn
d775cb8863 refactor: migrate undo/redo from per-state to per-document level
Refactors the history system to track complete document state instead of
individual timeline states, making timeline operations fully undoable.

BREAKING CHANGE: History is now per-document instead of per-timeline-state.
Existing undo/redo stacks will be cleared on first load with this change.

Changes:
- historyStore: Track complete document snapshots (timeline + all states + types)
- useDocumentHistory: Simplified to work with document-level operations
- timelineStore: All timeline operations now record history
  - createState, switchToState, deleteState, updateState, duplicateState
- Fixed redo button bug (was mutating Zustand state directly)

New capabilities:
- Undo/redo timeline state creation
- Undo/redo timeline state deletion
- Undo/redo switching between timeline states
- Undo/redo renaming timeline states
- Unified history for all document operations

Technical improvements:
- Proper Zustand state management (no direct mutations)
- Document snapshots include entire timeline structure
- History methods accept currentSnapshot parameter
- Removed TypeScript 'any' types for better type safety

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 22:38:23 +02:00
Jan-Henrik Bruhn
227b61b2a0 fix: improve bottom panel collapsed state and remove broken right panel close button
- Increase collapsed bottom panel height from 40px to 48px for better proportions
- Show current state indicator in bottom panel even when collapsed
- Remove unnecessary and broken close button from right panel header

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 22:22:42 +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
f0862650f4 doc: move some plans around 2025-10-11 22:08:53 +02:00
Jan-Henrik Bruhn
94c7845ca7 refactor: replace redundant window.confirm with custom dialog
Removes duplicate confirmation dialogs when deleting documents.
Previously, users were asked twice: once by the UI component's custom
dialog and again by window.confirm in the store.

Changes:
- Remove window.confirm from workspaceStore deleteDocument function
- Add useConfirm hook to DocumentTabs component for delete action
- Consistent confirmation UX across DocumentManager and DocumentTabs

Both components now show the same styled confirmation dialog with
proper handling of unsaved changes warnings.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 22:08:00 +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
2435c984ba fix: correct Material-UI icon prop usage in RightPanel
Fixed TypeScript build errors by replacing invalid `style` prop with
proper Material-UI icon props. Icon components only accept `fontSize`
and `className` props, not arbitrary style objects.

Changes:
- Move fontSize styling to wrapping div elements
- Use proper `fontSize="small"` prop on icon components
- Apply color styling to container div (unchanged)

This resolves two TypeScript errors at lines 565 and 597 where
`style={{ fontSize: '14px' }}` was incorrectly passed to MUI icons.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 12:23:45 +02:00
Jan-Henrik Bruhn
2db8b25d9e feat: enhance relation properties panel with live updates
Improvements to the relation properties panel:

1. Show actor labels instead of IDs in connection display
   - Display actor icons with type-specific colors
   - Show actor labels and type names (e.g., "Person", "Organization")
   - IDs available on hover via tooltips
   - Layout: [icon] Label (Type) → (Type) Label [icon]

2. Make relation type changes instant
   - Relation type dropdown now applies changes immediately
   - No more 500ms delay or "Saving changes..." message
   - Provides instant visual feedback like directionality toggles

3. Fix connection display updates
   - Connection info now reads current edge data from store
   - Source/target actors update immediately when reversing direction
   - Direction arrow updates immediately when changing directionality
   - Panel properly reflects all edge changes in real-time

Only the custom label text input retains debounced saves to avoid
excessive updates while typing.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 12:15:31 +02:00
Jan-Henrik Bruhn
e3e5b0768b perf: make relation directionality changes instant
Removes the 500ms debounce delay when changing edge directionality
in the right panel. Directionality toggle buttons now apply changes
immediately, providing instant visual feedback.

Text fields (relation type and custom label) still use debounced
saves to avoid excessive updates while typing.

Improves UX by making toggle interactions feel more responsive.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 12:07:53 +02:00
Jan-Henrik Bruhn
7f8af78432 feat: add settings icons to left panel section headers
Adds quick access to configuration modals from the left panel:
- Settings icon (⚙️) next to "Add Actors" section opens Actor Type config
- Settings icon next to "Relations" section opens Relation Type config
- Icons positioned between section title and expand/collapse chevron
- Tooltips provide clear indication of functionality

This provides convenient access to type configuration without needing
to navigate through the menu bar, improving workflow efficiency.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 12:06:11 +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
3a64d37f02 feat: implement directional relationships for edges
Adds full support for directed, bidirectional, and undirected relationships
between actors with visual arrow markers and intuitive controls.

**Type System:**
- Add EdgeDirectionality type (directed | bidirectional | undirected)
- Add directionality field to RelationData
- Add defaultDirectionality field to EdgeTypeConfig

**Visual Representation:**
- Directed edges: single arrow marker at target (→)
- Bidirectional edges: arrow markers at both ends (↔)
- Undirected edges: no arrow markers (—)
- Separate marker definitions for start/end to ensure correct orientation

**Property Panel Controls:**
- MUI ToggleButtonGroup for selecting directionality
- Visual connection indicator with directional symbols
- Reverse direction button (swaps source/target, only for directed edges)
- Live updates with 500ms debounce

**Edge Type Configuration:**
- Default directionality selector in edge type form
- Dropdown with helpful descriptions (→, ↔, —)
- Applied to both create and edit workflows

**Edge Creation:**
- New edges inherit defaultDirectionality from edge type config
- Falls back to 'directed' for backwards compatibility

**Reverse Direction:**
- Swaps source/target and sourceHandle/targetHandle
- Maintains edge ID and selection state
- Tracked in undo/redo history

Includes comprehensive UX specification document with wireframes,
interaction patterns, accessibility guidelines, and implementation phases.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 11:54:16 +02:00
Jan-Henrik Bruhn
74f5da0c7b fix: enable scrollbar in graph analysis panel when content overflows
Adds overflow-hidden to GraphMetrics outer container to establish proper
scrolling context. Without it, the flex container doesn't constrain child
height, preventing scrollbar from appearing when metrics content exceeds
available space.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-11 11:36:23 +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
5020ce0ed7 refactor: consolidate duplicate panel headers into reusable component
Consolidates three duplicate header implementations in RightPanel into a
single reusable PanelHeader component, following DRY principles.

Changes:
- Created PanelHeader component in RightPanel.tsx with consistent props
- Refactored Actor Properties to use PanelHeader
- Refactored Relation Properties to use PanelHeader
- Refactored Graph Analysis to use PanelHeader (removed internal header)
- All panel headers now have consistent appearance and behavior
- Supports optional close button and required collapse functionality

Benefits:
- Eliminates code duplication across panel views
- Ensures consistent UX across all panel states
- Easier to maintain and update header behavior in one place
- Reduces bundle size by removing redundant JSX

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 23:26:48 +02:00
Jan-Henrik Bruhn
3db4898902 fix: improve GraphMetrics header with collapse button
- Removed unnecessary refresh button (metrics auto-update via useMemo)
- Added collapse button to header (Ctrl+I)
- Matches behavior of Actor/Relation property panels
- Cleaner, more consistent UX

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 23:22:21 +02:00
Jan-Henrik Bruhn
0e90f022fc feat: add graph metrics and analysis to right panel
Implements section 6.1 from UX_ANALYSIS.md - Graph Metrics and Analysis.
Transforms the empty "No Selection" state in the right panel into a
valuable analysis dashboard.

Features:
- Graph analysis utility with metric calculations:
  - Actor/relation counts
  - Graph density (connectivity ratio)
  - Average connections per actor
  - Most connected actors (top 5)
  - Isolated actors count
  - Connected components detection
  - Breakdown by actor/relation type

- GraphMetrics component with sections:
  - Overview: basic stats and density
  - Most Connected Actors: ranked list
  - Graph Structure: isolated nodes, components
  - Type breakdowns: actors and relations by type
  - Visual polish: icons, tooltips, hover states
  - Warning highlights for isolated actors
  - Info highlights for multiple components

- Integration:
  - Replaces empty state in RightPanel
  - Automatically updates when graph changes
  - Memoized calculations for performance
  - Consistent styling with existing panels

Now provides immediate analytical value when opening a document,
making the application live up to its "Analyzer" name.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-10 23:20:22 +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
e778b29b56 feat: centralize keyboard shortcuts through shortcut manager
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>
2025-10-10 22:38:28 +02:00
Jan-Henrik Bruhn
cd1a93f88f feat: display actor type icons in left panel add buttons
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>
2025-10-10 22:31:56 +02:00
Jan-Henrik Bruhn
38cae3cdd9 fix: whoopsie doopsie accident - correct onAddNodeRequest type signature
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>
2025-10-10 22:29:45 +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
d6f5938c9c refactor: remove edit properties from context menus
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>
2025-10-10 22:17:23 +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
8d8ff2d200 fix: dont show anything in pane if more than one item is selected 2025-10-10 19:43:54 +02:00
Jan-Henrik Bruhn
79edc902c5 fix: remove unused variables 2025-10-10 18:14:05 +02:00
Jan-Henrik Bruhn
e7ff53dcd7 feat: side panels for properties and tools 2025-10-10 18:13:18 +02:00
Jan-Henrik Bruhn
09b62c69bd fix: clear graph editor when no document is active
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>
2025-10-10 16:54:40 +02:00
Jan-Henrik Bruhn
99ab514c0c fix: prevent cross-document state contamination in useActiveDocument
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>
2025-10-10 16:50:26 +02:00
Jan-Henrik Bruhn
ac252dc5ed fix: show keyboard shortcut help should be used with ctrl 2025-10-10 12:40:09 +02:00
Jan-Henrik Bruhn
df95a7c84c fix: fit view to content shortcut overrides typing the F letter everywhere 2025-10-10 12:39:37 +02:00
Jan-Henrik Bruhn
ce0ee71193 fix: logo path 2025-10-10 12:03:54 +02:00
Jan-Henrik Bruhn
236d394276 fix: change folder location base path for imports to deploy 2025-10-10 12:02:09 +02:00
Jan-Henrik Bruhn
4e335a8fde fix: refactor keyboard shortcut context 2025-10-10 11:54:51 +02:00
Jan-Henrik Bruhn
75cb26a991 fix: resolve effect dependencies 2025-10-10 11:40:14 +02:00
Jan-Henrik Bruhn
79bfd525dd fix: remove unused variable 2025-10-10 11:35:57 +02:00
Jan-Henrik Bruhn
0bd9a94337 feat: add github action to deploy to github pages 2025-10-10 11:27:51 +02:00
Jan-Henrik Bruhn
fd13213ff4 Add license 2025-10-10 11:24:47 +02:00
Jan-Henrik Bruhn
de57fd758b Add vibe warning 2025-10-10 11:23:36 +02:00
Jan-Henrik Bruhn
f56f928dcf Initial commit 2025-10-10 11:15:51 +02:00