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
This commit is contained in:
@@ -0,0 +1,301 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user