- 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
302 lines
8.4 KiB
Markdown
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.
|