feat: Implement collection deletion and loading spinners
- Add API endpoint and handler to delete collections - Introduce LoadingSpinner component for async operations - Show loading spinners during file loading and preview rendering - Enhance modal accessibility by removing aria-hidden attribute - Refactor delete functionality to distinguish between collections and files/folders - Remove unused collection definitions from config
This commit is contained in:
		| @@ -16,6 +16,10 @@ class MarkdownEditor { | ||||
|         this.editor = null; // Will be initialized later | ||||
|         this.isShowingCustomPreview = false; // Flag to prevent auto-update when showing binary files | ||||
|  | ||||
|         // Initialize loading spinners (will be created lazily when needed) | ||||
|         this.editorSpinner = null; | ||||
|         this.previewSpinner = null; | ||||
|  | ||||
|         // Only initialize CodeMirror if not in read-only mode (view mode) | ||||
|         if (!readOnly) { | ||||
|             this.initCodeMirror(); | ||||
| @@ -206,11 +210,34 @@ class MarkdownEditor { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Initialize loading spinners (lazy initialization) | ||||
|      */ | ||||
|     initLoadingSpinners() { | ||||
|         if (!this.editorSpinner && !this.readOnly && this.editorElement) { | ||||
|             this.editorSpinner = new LoadingSpinner(this.editorElement, 'Loading file...'); | ||||
|         } | ||||
|         if (!this.previewSpinner && this.previewElement) { | ||||
|             this.previewSpinner = new LoadingSpinner(this.previewElement, 'Rendering preview...'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Load file | ||||
|      */ | ||||
|     async loadFile(path) { | ||||
|         try { | ||||
|             // Initialize loading spinners if not already done | ||||
|             this.initLoadingSpinners(); | ||||
|  | ||||
|             // Show loading spinners | ||||
|             if (this.editorSpinner) { | ||||
|                 this.editorSpinner.show('Loading file...'); | ||||
|             } | ||||
|             if (this.previewSpinner) { | ||||
|                 this.previewSpinner.show('Loading preview...'); | ||||
|             } | ||||
|  | ||||
|             // Reset custom preview flag when loading text files | ||||
|             this.isShowingCustomPreview = false; | ||||
|  | ||||
| @@ -232,8 +259,25 @@ class MarkdownEditor { | ||||
|  | ||||
|             // Save as last viewed page | ||||
|             this.saveLastViewedPage(path); | ||||
|  | ||||
|             // Hide loading spinners | ||||
|             if (this.editorSpinner) { | ||||
|                 this.editorSpinner.hide(); | ||||
|             } | ||||
|             if (this.previewSpinner) { | ||||
|                 this.previewSpinner.hide(); | ||||
|             } | ||||
|  | ||||
|             // No notification for successful file load - it's not critical | ||||
|         } catch (error) { | ||||
|             // Hide loading spinners on error | ||||
|             if (this.editorSpinner) { | ||||
|                 this.editorSpinner.hide(); | ||||
|             } | ||||
|             if (this.previewSpinner) { | ||||
|                 this.previewSpinner.hide(); | ||||
|             } | ||||
|  | ||||
|             console.error('Failed to load file:', error); | ||||
|             if (window.showNotification) { | ||||
|                 window.showNotification('Failed to load file', 'danger'); | ||||
| @@ -409,6 +453,14 @@ class MarkdownEditor { | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             // Initialize loading spinners if not already done | ||||
|             this.initLoadingSpinners(); | ||||
|  | ||||
|             // Show preview loading spinner (only if not already shown by loadFile) | ||||
|             if (this.previewSpinner && !this.previewSpinner.isVisible()) { | ||||
|                 this.previewSpinner.show('Rendering preview...'); | ||||
|             } | ||||
|  | ||||
|             // Step 0: Convert JSX-style syntax to HTML | ||||
|             let processedContent = this.convertJSXToHTML(markdown); | ||||
|  | ||||
| @@ -422,6 +474,9 @@ class MarkdownEditor { | ||||
|             if (!this.marked) { | ||||
|                 console.error("Markdown parser (marked) not initialized."); | ||||
|                 previewDiv.innerHTML = `<div class="alert alert-danger">Preview engine not loaded.</div>`; | ||||
|                 if (this.previewSpinner) { | ||||
|                     this.previewSpinner.hide(); | ||||
|                 } | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
| @@ -459,6 +514,13 @@ class MarkdownEditor { | ||||
|                     console.warn('Mermaid rendering error:', error); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Hide preview loading spinner after a small delay to ensure rendering is complete | ||||
|             setTimeout(() => { | ||||
|                 if (this.previewSpinner) { | ||||
|                     this.previewSpinner.hide(); | ||||
|                 } | ||||
|             }, 100); | ||||
|         } catch (error) { | ||||
|             console.error('Preview rendering error:', error); | ||||
|             previewDiv.innerHTML = ` | ||||
| @@ -467,6 +529,11 @@ class MarkdownEditor { | ||||
|                     ${error.message} | ||||
|                 </div> | ||||
|             `; | ||||
|  | ||||
|             // Hide loading spinner on error | ||||
|             if (this.previewSpinner) { | ||||
|                 this.previewSpinner.hide(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user