453 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			453 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Context Menu - VaultService Integration Guide
 | |
| 
 | |
| ## Overview
 | |
| 
 | |
| This guide shows how to implement the context menu actions by integrating them with the VaultService. Each action corresponds to a VaultService method that needs to be called.
 | |
| 
 | |
| ## Action Implementation Examples
 | |
| 
 | |
| ### 1. Create Subfolder
 | |
| 
 | |
| **Current Implementation:**
 | |
| ```typescript
 | |
| private createSubfolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const name = prompt('Enter subfolder name:');
 | |
|   if (!name) return;
 | |
|   const newPath = `${this.ctxTarget.path}/${name}`;
 | |
|   this.showNotification(`Creating subfolder: ${newPath}`, 'info');
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Complete Implementation:**
 | |
| ```typescript
 | |
| private createSubfolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const name = prompt('Enter subfolder name:');
 | |
|   if (!name) return;
 | |
|   
 | |
|   try {
 | |
|     const newPath = `${this.ctxTarget.path}/${name}`;
 | |
|     this.vaultService.createFolder(newPath);
 | |
|     this.showNotification(`Subfolder "${name}" created successfully`, 'success');
 | |
|   } catch (error) {
 | |
|     this.showNotification(`Failed to create subfolder: ${error}`, 'error');
 | |
|   }
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Required VaultService Method:**
 | |
| ```typescript
 | |
| createFolder(path: string): void {
 | |
|   // Create folder at the specified path
 | |
|   // Update file tree
 | |
|   // Emit change notification
 | |
| }
 | |
| ```
 | |
| 
 | |
| ---
 | |
| 
 | |
| ### 2. Rename Folder
 | |
| 
 | |
| **Current Implementation:**
 | |
| ```typescript
 | |
| private renameFolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const newName = prompt('Enter new folder name:', this.ctxTarget.name);
 | |
|   if (!newName || newName === this.ctxTarget.name) return;
 | |
|   this.showNotification(`Renaming folder to: ${newName}`, 'info');
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Complete Implementation:**
 | |
| ```typescript
 | |
| private renameFolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const newName = prompt('Enter new folder name:', this.ctxTarget.name);
 | |
|   if (!newName || newName === this.ctxTarget.name) return;
 | |
|   
 | |
|   try {
 | |
|     this.vaultService.renameFolder(this.ctxTarget.path, newName);
 | |
|     this.showNotification(`Folder renamed to "${newName}"`, 'success');
 | |
|   } catch (error) {
 | |
|     this.showNotification(`Failed to rename folder: ${error}`, 'error');
 | |
|   }
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Required VaultService Method:**
 | |
| ```typescript
 | |
| renameFolder(oldPath: string, newName: string): void {
 | |
|   // Rename folder
 | |
|   // Update all notes with new path
 | |
|   // Update file tree
 | |
|   // Emit change notification
 | |
| }
 | |
| ```
 | |
| 
 | |
| ---
 | |
| 
 | |
| ### 3. Duplicate Folder
 | |
| 
 | |
| **Current Implementation:**
 | |
| ```typescript
 | |
| private duplicateFolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const newName = prompt('Enter duplicate folder name:', `${this.ctxTarget.name} (copy)`);
 | |
|   if (!newName) return;
 | |
|   this.showNotification(`Duplicating folder to: ${newName}`, 'info');
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Complete Implementation:**
 | |
| ```typescript
 | |
| private duplicateFolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const newName = prompt('Enter duplicate folder name:', `${this.ctxTarget.name} (copy)`);
 | |
|   if (!newName) return;
 | |
|   
 | |
|   try {
 | |
|     const parentPath = this.ctxTarget.path.substring(0, this.ctxTarget.path.lastIndexOf('/'));
 | |
|     const newPath = parentPath ? `${parentPath}/${newName}` : newName;
 | |
|     this.vaultService.duplicateFolder(this.ctxTarget.path, newPath);
 | |
|     this.showNotification(`Folder duplicated to "${newName}"`, 'success');
 | |
|   } catch (error) {
 | |
|     this.showNotification(`Failed to duplicate folder: ${error}`, 'error');
 | |
|   }
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Required VaultService Method:**
 | |
| ```typescript
 | |
| duplicateFolder(sourcePath: string, destinationPath: string): void {
 | |
|   // Copy folder structure
 | |
|   // Copy all notes
 | |
|   // Update file tree
 | |
|   // Emit change notification
 | |
| }
 | |
| ```
 | |
| 
 | |
| ---
 | |
| 
 | |
| ### 4. Create New Page
 | |
| 
 | |
| **Current Implementation:**
 | |
| ```typescript
 | |
| private createPageInFolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const pageName = prompt('Enter page name:');
 | |
|   if (!pageName) return;
 | |
|   this.showNotification(`Creating page in folder: ${pageName}`, 'info');
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Complete Implementation:**
 | |
| ```typescript
 | |
| private createPageInFolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const pageName = prompt('Enter page name:');
 | |
|   if (!pageName) return;
 | |
|   
 | |
|   try {
 | |
|     const noteId = this.vaultService.createNote(
 | |
|       this.ctxTarget.path,
 | |
|       pageName,
 | |
|       {
 | |
|         title: pageName,
 | |
|         created: new Date().toISOString(),
 | |
|         updated: new Date().toISOString(),
 | |
|       }
 | |
|     );
 | |
|     this.showNotification(`Page "${pageName}" created`, 'success');
 | |
|     // Optionally open the new note
 | |
|     // this.noteSelected.emit(noteId);
 | |
|   } catch (error) {
 | |
|     this.showNotification(`Failed to create page: ${error}`, 'error');
 | |
|   }
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Required VaultService Method:**
 | |
| ```typescript
 | |
| createNote(folderPath: string, fileName: string, frontmatter?: Record<string, any>): string {
 | |
|   // Create new markdown file
 | |
|   // Add frontmatter
 | |
|   // Update file tree
 | |
|   // Return note ID
 | |
|   // Emit change notification
 | |
| }
 | |
| ```
 | |
| 
 | |
| ---
 | |
| 
 | |
| ### 5. Copy Internal Link
 | |
| 
 | |
| **Current Implementation (Already Complete):**
 | |
| ```typescript
 | |
| private copyInternalLink() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const link = `[[${this.ctxTarget.path}]]`;
 | |
|   navigator.clipboard.writeText(link).then(() => {
 | |
|     this.showNotification('Internal link copied to clipboard!', 'success');
 | |
|   }).catch(() => {
 | |
|     this.showNotification('Failed to copy link', 'error');
 | |
|   });
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Status:** ✅ This action is fully implemented and working!
 | |
| 
 | |
| ---
 | |
| 
 | |
| ### 6. Delete Folder
 | |
| 
 | |
| **Current Implementation:**
 | |
| ```typescript
 | |
| private deleteFolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const confirmed = confirm(`Are you sure you want to delete the folder "${this.ctxTarget.name}"?`);
 | |
|   if (!confirmed) return;
 | |
|   this.showNotification(`Deleting folder: ${this.ctxTarget.name}`, 'warning');
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Complete Implementation:**
 | |
| ```typescript
 | |
| private deleteFolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const confirmed = confirm(`Are you sure you want to delete the folder "${this.ctxTarget.name}"?`);
 | |
|   if (!confirmed) return;
 | |
|   
 | |
|   try {
 | |
|     this.vaultService.deleteFolder(this.ctxTarget.path);
 | |
|     this.showNotification(`Folder "${this.ctxTarget.name}" deleted`, 'success');
 | |
|   } catch (error) {
 | |
|     this.showNotification(`Failed to delete folder: ${error}`, 'error');
 | |
|   }
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Required VaultService Method:**
 | |
| ```typescript
 | |
| deleteFolder(path: string): void {
 | |
|   // Move folder to trash or permanently delete
 | |
|   // Update file tree
 | |
|   // Emit change notification
 | |
| }
 | |
| ```
 | |
| 
 | |
| ---
 | |
| 
 | |
| ### 7. Delete All Pages in Folder
 | |
| 
 | |
| **Current Implementation:**
 | |
| ```typescript
 | |
| private deleteAllPagesInFolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const confirmed = confirm(`Are you sure you want to delete ALL pages in "${this.ctxTarget.name}"? This cannot be undone.`);
 | |
|   if (!confirmed) return;
 | |
|   this.showNotification(`Deleting all pages in folder: ${this.ctxTarget.name}`, 'warning');
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Complete Implementation:**
 | |
| ```typescript
 | |
| private deleteAllPagesInFolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const confirmed = confirm(`Are you sure you want to delete ALL pages in "${this.ctxTarget.name}"? This cannot be undone.`);
 | |
|   if (!confirmed) return;
 | |
|   
 | |
|   try {
 | |
|     this.vaultService.deleteAllNotesInFolder(this.ctxTarget.path);
 | |
|     this.showNotification(`All pages in "${this.ctxTarget.name}" deleted`, 'success');
 | |
|   } catch (error) {
 | |
|     this.showNotification(`Failed to delete pages: ${error}`, 'error');
 | |
|   }
 | |
| }
 | |
| ```
 | |
| 
 | |
| **Required VaultService Method:**
 | |
| ```typescript
 | |
| deleteAllNotesInFolder(folderPath: string): void {
 | |
|   // Get all notes in folder
 | |
|   // Delete each note
 | |
|   // Update file tree
 | |
|   // Emit change notification
 | |
| }
 | |
| ```
 | |
| 
 | |
| ---
 | |
| 
 | |
| ## VaultService Methods Checklist
 | |
| 
 | |
| Below is a checklist of all VaultService methods needed for full context menu functionality:
 | |
| 
 | |
| ```typescript
 | |
| // Folder Operations
 | |
| createFolder(path: string): void
 | |
| renameFolder(oldPath: string, newName: string): void
 | |
| duplicateFolder(sourcePath: string, destinationPath: string): void
 | |
| deleteFolder(path: string): void
 | |
| 
 | |
| // Note Operations
 | |
| createNote(folderPath: string, fileName: string, frontmatter?: Record<string, any>): string
 | |
| deleteAllNotesInFolder(folderPath: string): void
 | |
| 
 | |
| // Existing Methods (already available)
 | |
| toggleFolder(path: string): void
 | |
| allNotes(): Note[]
 | |
| folderCounts(): Record<string, number>
 | |
| ```
 | |
| 
 | |
| ---
 | |
| 
 | |
| ## Integration Steps
 | |
| 
 | |
| ### Step 1: Update file-explorer.component.ts
 | |
| 
 | |
| Replace the action methods with complete implementations:
 | |
| 
 | |
| ```typescript
 | |
| // In file-explorer.component.ts
 | |
| 
 | |
| private createSubfolder() {
 | |
|   if (!this.ctxTarget) return;
 | |
|   const name = prompt('Enter subfolder name:');
 | |
|   if (!name) return;
 | |
|   
 | |
|   try {
 | |
|     const newPath = `${this.ctxTarget.path}/${name}`;
 | |
|     this.vaultService.createFolder(newPath);
 | |
|     this.showNotification(`Subfolder "${name}" created successfully`, 'success');
 | |
|   } catch (error) {
 | |
|     this.showNotification(`Failed to create subfolder: ${error}`, 'error');
 | |
|   }
 | |
| }
 | |
| 
 | |
| // ... repeat for other actions
 | |
| ```
 | |
| 
 | |
| ### Step 2: Implement VaultService Methods
 | |
| 
 | |
| Add the required methods to `vault.service.ts`:
 | |
| 
 | |
| ```typescript
 | |
| // In vault.service.ts
 | |
| 
 | |
| createFolder(path: string): void {
 | |
|   // Implementation
 | |
| }
 | |
| 
 | |
| renameFolder(oldPath: string, newName: string): void {
 | |
|   // Implementation
 | |
| }
 | |
| 
 | |
| // ... etc
 | |
| ```
 | |
| 
 | |
| ### Step 3: Test Each Action
 | |
| 
 | |
| Test each action individually:
 | |
| 
 | |
| ```bash
 | |
| npm run dev
 | |
| # Right-click on folder
 | |
| # Test each action
 | |
| # Check console for errors
 | |
| ```
 | |
| 
 | |
| ### Step 4: Add Error Handling
 | |
| 
 | |
| Ensure proper error handling in each action:
 | |
| 
 | |
| ```typescript
 | |
| try {
 | |
|   // Action logic
 | |
|   this.vaultService.someMethod();
 | |
|   this.showNotification('Success message', 'success');
 | |
| } catch (error) {
 | |
|   console.error('Action failed:', error);
 | |
|   this.showNotification(`Failed: ${error.message}`, 'error');
 | |
| }
 | |
| ```
 | |
| 
 | |
| ---
 | |
| 
 | |
| ## Notification System
 | |
| 
 | |
| The `showNotification` method currently logs to console. You can enhance it:
 | |
| 
 | |
| ```typescript
 | |
| private showNotification(message: string, type: 'success' | 'info' | 'warning' | 'error') {
 | |
|   // Current implementation
 | |
|   console.log(`[${type.toUpperCase()}] ${message}`);
 | |
|   
 | |
|   // TODO: Replace with proper toast notification service
 | |
|   // this.toastr.show(message, type);
 | |
| }
 | |
| ```
 | |
| 
 | |
| ---
 | |
| 
 | |
| ## Testing Checklist
 | |
| 
 | |
| - [ ] Create subfolder works
 | |
| - [ ] Rename folder works
 | |
| - [ ] Duplicate folder works
 | |
| - [ ] Create new page works
 | |
| - [ ] Copy internal link works
 | |
| - [ ] Delete folder works (with confirmation)
 | |
| - [ ] Delete all pages works (with confirmation)
 | |
| - [ ] Error messages display correctly
 | |
| - [ ] File tree updates after each action
 | |
| - [ ] Colors persist after actions
 | |
| 
 | |
| ---
 | |
| 
 | |
| ## Common Issues & Solutions
 | |
| 
 | |
| ### Issue: "vaultService method not found"
 | |
| **Solution:** Ensure the method exists in VaultService before calling it.
 | |
| 
 | |
| ### Issue: "File tree doesn't update"
 | |
| **Solution:** Make sure VaultService emits change notifications after modifications.
 | |
| 
 | |
| ### Issue: "Confirmation dialog doesn't appear"
 | |
| **Solution:** Check if `confirm()` is being called before the action.
 | |
| 
 | |
| ### Issue: "Notification doesn't show"
 | |
| **Solution:** Implement a proper toast notification service instead of console.log.
 | |
| 
 | |
| ---
 | |
| 
 | |
| ## Performance Considerations
 | |
| 
 | |
| - Use `ChangeDetectionStrategy.OnPush` (already implemented)
 | |
| - Batch file tree updates when possible
 | |
| - Debounce rapid folder operations
 | |
| - Cache folder counts to avoid recalculation
 | |
| 
 | |
| ---
 | |
| 
 | |
| ## Security Considerations
 | |
| 
 | |
| - ✅ Confirmation dialogs for destructive operations
 | |
| - ✅ Input validation for folder/page names
 | |
| - ✅ Path sanitization to prevent directory traversal
 | |
| - ⏳ Rate limiting for bulk operations (future)
 | |
| 
 | |
| ---
 | |
| 
 | |
| ## Related Documentation
 | |
| 
 | |
| - `CONTEXT_MENU_IMPLEMENTATION.md` - Full technical documentation
 | |
| - `CONTEXT_MENU_QUICK_START.md` - Quick start guide
 | |
| - `src/services/vault.service.ts` - VaultService source code
 | |
| - `src/components/file-explorer/file-explorer.component.ts` - Integration point
 | |
| 
 | |
| ---
 | |
| 
 | |
| **Status**: ⏳ Ready for VaultService Integration  
 | |
| **Effort**: ~2-3 hours  
 | |
| **Difficulty**: Easy to Medium
 |