ObsiViewer/docs/NOTE_CONTEXT_MENU_IMPLEMENTATION.md
Bruno Charest 0f7cc552ca feat: add note context menu with color and metadata controls
- 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
2025-10-24 13:45:02 -04:00

302 lines
8.4 KiB
Markdown

# 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:**
```json
{
"frontmatter": {
"favoris": true,
"readOnly": false,
"color": "#3B82F6"
}
}
```
**Response:**
```json
{
"id": "path/to/note",
"success": true,
"frontmatter": {
"favoris": true,
"readOnly": false,
"color": "#3B82F6"
}
}
```
### DELETE /api/vault/notes/:id
Moves note to trash directory.
**Response:**
```json
{
"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 `.trash` folder
- Read-only notes show confirmation dialog for deletion
- Frontmatter validation on server side
- Proper error handling and user feedback
## Testing
### Manual Testing
1. Right-click on any note in the list
2. Verify all actions are present and functional
3. Test color selection and gradient rendering
4. Verify keyboard navigation (↑↓, Enter, Esc)
5. Test permissions with read-only notes
### Automated Testing
Run the test script:
```bash
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 duplicated
- `noteShared` - When share URL is generated
- `noteOpenedFull` - When fullscreen mode activated
- `noteCopiedLink` - When internal link copied
- `noteFavoriteToggled` - When favorite status changes
- `noteInfoRequested` - When page info requested
- `noteReadOnlyToggled` - When read-only status changes
- `noteDeleted` - When note moved to trash
- `noteColorChanged` - 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
1. **Batch operations** - Select multiple notes for bulk actions
2. **Custom colors** - Color picker for unlimited color options
3. **Keyboard shortcuts** - Quick access to common actions
4. **Drag & drop** - Move notes between folders
5. **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 `NoteContextMenuComponent` is 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 `color` property 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:
```javascript
localStorage.setItem('debug', 'true');
```
## Files Modified
### New Files
- `src/components/note-context-menu/note-context-menu.component.ts`
- `src/app/services/note-context-menu.service.ts`
- `test-note-context-menu.mjs`
- `docs/NOTE_CONTEXT_MENU_IMPLEMENTATION.md`
### Modified Files
- `src/app/features/list/notes-list.component.ts` - Added context menu integration
- `src/types.ts` - Added `color` and `readOnly` to NoteFrontmatter
- `server/index-phase3-patch.mjs` - Added PATCH/DELETE endpoints
- `server/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.