# 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 { // 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 deleteAllNotesInFolder(folderPath: string): void // Existing Methods (already available) toggleFolder(path: string): void allNotes(): Note[] folderCounts(): Record ``` --- ## 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