- Added PATCH endpoint for updating note frontmatter with YAML parsing and merging - Added DELETE endpoint to move notes to .trash directory with timestamped filenames - Implemented note context menu with actions like duplicate, share, favorite, and delete - Added color picker to context menu with gradient background visualization - Extended NoteFrontmatter type with readOnly and color properties - Added YAML frontmatter parser with support
8.4 KiB
8.4 KiB
Note Context Menu Implementation
Overview
This document describes the implementation of a comprehensive context menu for notes in the Notes-list component, providing quick access to common note operations.
Features Implemented
✅ Core Actions
- Duplicate - Create a copy of the note with "copy" suffix
- Share page - Generate and copy shareable URL
- Open in full screen - Open note in fullscreen mode
- Copy internal link - Copy Obsidian-style internal link
- Add to Favorites - Toggle favorite status
- Page Information - Display note metadata and statistics
- Read Only (toggle) - Toggle read-only protection
- Delete - Move note to trash (with confirmation)
✅ Visual Features
- Color indicator - 8-color palette for note organization
- Gradient backgrounds - Subtle right-to-left gradient based on note color
- Consistent styling - Matches existing folder context menu design
- Dark/Light theme support - Fully responsive to theme changes
- Accessibility - Full keyboard navigation and ARIA support
Architecture
Components
1. NoteContextMenuComponent
- Location:
src/components/note-context-menu/note-context-menu.component.ts - Purpose: Renders the context menu UI with all actions and color palette
- Features:
- Standalone Angular component
- OnPush change detection
- Anti-overflow positioning
- Keyboard navigation (↑↓, Enter, Esc)
- Permission-based action disabling
2. NoteContextMenuService
- Location:
src/app/services/note-context-menu.service.ts - Purpose: Handles all context menu business logic and API calls
- Features:
- State management (position, visibility, target note)
- API integration for all note operations
- Toast notifications
- Event emission for UI updates
3. Enhanced NotesListComponent
- Location:
src/app/features/list/notes-list.component.ts - Purpose: Integrates context menu into note list
- Features:
- Right-click event handling
- Gradient background rendering based on note colors
- Context menu action delegation
Server Endpoints
1. POST /api/vault/notes
- Purpose: Create new note (existing)
- Used by: Duplicate action
2. PATCH /api/vault/notes/:id
- Purpose: Update note frontmatter
- Used by: Favorite toggle, read-only toggle, color change
- Implementation:
server/index-phase3-patch.mjs
3. DELETE /api/vault/notes/:id
- Purpose: Move note to trash
- Used by: Delete action
- Implementation:
server/index-phase3-patch.mjs
Data Flow
User right-clicks on note
↓
NotesListComponent.openContextMenu()
↓
NoteContextMenuService.openForNote()
↓
NoteContextMenuComponent rendered
↓
User clicks action
↓
NoteContextMenuService.handleAction()
↓
API call to server
↓
Toast notification + UI update
API Endpoints
PATCH /api/vault/notes/:id
Updates note frontmatter properties.
Request:
{
"frontmatter": {
"favoris": true,
"readOnly": false,
"color": "#3B82F6"
}
}
Response:
{
"id": "path/to/note",
"success": true,
"frontmatter": {
"favoris": true,
"readOnly": false,
"color": "#3B82F6"
}
}
DELETE /api/vault/notes/:id
Moves note to trash directory.
Response:
{
"id": "path/to/note",
"success": true,
"trashPath": ".trash/note_2025-10-24T17-13-28-456Z.md"
}
Color System
Available Colors
#00AEEF- Cyan#3B82F6- Blue#22C55E- Green#F59E0B- Orange#EF4444- Red#A855F7- Purple#8B5CF6- Indigo#64748B- Slate
Implementation
- Colors stored in
frontmatter.color - Gradient backgrounds use 14% opacity
- Consistent with folder color system
Permissions & Security
Action Permissions
- Duplicate: Disabled if note is read-only
- Share: Disabled if note is private or publishing disabled
- Read Only Toggle: Always available (configurable)
- Delete: Always available with confirmation
Safety Features
- All deletions move to
.trashfolder - Read-only notes show confirmation dialog for deletion
- Frontmatter validation on server side
- Proper error handling and user feedback
Testing
Manual Testing
- Right-click on any note in the list
- Verify all actions are present and functional
- Test color selection and gradient rendering
- Verify keyboard navigation (↑↓, Enter, Esc)
- Test permissions with read-only notes
Automated Testing
Run the test script:
node test-note-context-menu.mjs
Test Coverage
- ✅ Note creation
- ✅ Frontmatter updates (favorite, color)
- ✅ Note deletion (trash)
- ✅ Error handling (404, validation)
- ✅ API response formats
Integration Points
Existing Services
- VaultService: Note data and refresh
- ToastService: User notifications
- NotesListStateService: UI state management
Events Emitted
noteDuplicated- When note is duplicatednoteShared- When share URL is generatednoteOpenedFull- When fullscreen mode activatednoteCopiedLink- When internal link copiednoteFavoriteToggled- When favorite status changesnoteInfoRequested- When page info requestednoteReadOnlyToggled- When read-only status changesnoteDeleted- When note moved to trashnoteColorChanged- When note color changes
Performance Considerations
Optimizations
- OnPush change detection strategy
- Lazy menu rendering (only when visible)
- Minimal DOM manipulation
- Efficient gradient calculations
Memory Usage
- Context menu state is lightweight
- No heavy computations in UI thread
- Proper cleanup on component destruction
Browser Compatibility
Supported Features
- ✅ Modern browsers (Chrome, Firefox, Safari, Edge)
- ✅ Clipboard API for copy operations
- ✅ CSS custom properties for theming
- ✅ Event handling and keyboard navigation
Fallbacks
- Clipboard API falls back to modal display
- Gradient backgrounds gracefully degrade
- Toast notifications work without animation
Future Enhancements
Potential Improvements
- Batch operations - Select multiple notes for bulk actions
- Custom colors - Color picker for unlimited color options
- Keyboard shortcuts - Quick access to common actions
- Drag & drop - Move notes between folders
- Preview mode - Quick note preview in context menu
Extension Points
- Additional context menu actions can be easily added
- Custom permission systems can be integrated
- Alternative color schemes can be implemented
Troubleshooting
Common Issues
Context menu doesn't appear
- Check that
NoteContextMenuComponentis imported - Verify right-click event is not prevented by other handlers
- Check z-index conflicts with other overlays
Actions not working
- Verify server endpoints are properly registered
- Check API response formats in browser dev tools
- Ensure note IDs are correctly formatted
Colors not applying
- Check that
colorproperty is in frontmatter - Verify gradient calculation logic
- Check CSS custom properties are defined
Performance issues
- Ensure OnPush change detection is working
- Check for unnecessary re-renders in dev tools
- Verify menu cleanup on close
Debug Mode
Enable debug logging by setting:
localStorage.setItem('debug', 'true');
Files Modified
New Files
src/components/note-context-menu/note-context-menu.component.tssrc/app/services/note-context-menu.service.tstest-note-context-menu.mjsdocs/NOTE_CONTEXT_MENU_IMPLEMENTATION.md
Modified Files
src/app/features/list/notes-list.component.ts- Added context menu integrationsrc/types.ts- AddedcolorandreadOnlyto NoteFrontmatterserver/index-phase3-patch.mjs- Added PATCH/DELETE endpointsserver/index.mjs- Added endpoint imports and setup
Summary
The note context menu implementation provides a comprehensive, accessible, and performant solution for note management in ObsiViewer. It maintains consistency with existing UI patterns while adding powerful new functionality for users.
Key Achievements
- ✅ Full feature parity with folder context menu
- ✅ Consistent visual design and behavior
- ✅ Comprehensive error handling and user feedback
- ✅ Accessibility compliance
- ✅ Performance optimized
- ✅ Extensible architecture for future enhancements
The implementation is production-ready and can be safely deployed to users.