@@ -437,6 +534,7 @@
document.getElementById("settingsBtn").addEventListener("click", () => this.showSettingsModal());
document.getElementById("statsBtn").addEventListener("click", () => this.showStats());
document.getElementById("diagnosticsBtn").addEventListener("click", () => this.showDiagnosticsModal());
+ document.getElementById("maintenanceBtn").addEventListener("click", () => this.showMaintenanceModal());
// Modals
this.bindModalEvents();
@@ -464,6 +562,11 @@
document.getElementById("runDiagnosticsBtn").addEventListener("click", () => this.runDiagnostics());
document.getElementById("testImageLinkBtn").addEventListener("click", () => this.testImageLink());
+ // Maintenance modal
+ document.getElementById("runMaintenanceBtn").addEventListener("click", () => this.runMaintenance());
+ document.getElementById("selectAllMaintenanceBtn").addEventListener("click", () => this.selectAllMaintenance());
+ document.getElementById("clearAllMaintenanceBtn").addEventListener("click", () => this.clearAllMaintenance());
+
// Close modals on backdrop click
document.querySelectorAll("[id$='Modal']").forEach((modal) => {
modal.addEventListener("click", (e) => {
@@ -1329,6 +1432,175 @@
this.hideModal("diagnosticsModal");
}
+ // Maintenance functionality
+ showMaintenanceModal() {
+ this.showModal("maintenanceModal");
+ }
+
+ closeMaintenance() {
+ this.hideModal("maintenanceModal");
+ }
+
+ selectAllMaintenance() {
+ document.querySelectorAll('.maintenance-option').forEach(checkbox => {
+ checkbox.checked = true;
+ });
+ }
+
+ clearAllMaintenance() {
+ document.querySelectorAll('.maintenance-option').forEach(checkbox => {
+ checkbox.checked = false;
+ });
+ }
+
+ async runMaintenance() {
+ const resultsContainer = document.getElementById("maintenanceResults");
+ const runButton = document.getElementById("runMaintenanceBtn");
+
+ // Get selected operations
+ const selectedOps = Array.from(document.querySelectorAll('.maintenance-option:checked'))
+ .map(checkbox => checkbox.id);
+
+ if (selectedOps.length === 0) {
+ this.showNotification('Please select at least one maintenance operation', 'warning');
+ return;
+ }
+
+ // Show loading state
+ runButton.disabled = true;
+ runButton.innerHTML = '🔄 Running...';
+ resultsContainer.innerHTML = `
+
+
+
Running maintenance operations...
+
Operations: ${selectedOps.map(op => op.replace(/_/g, ' ')).join(', ')}
+
+ `;
+
+ try {
+ const response = await fetch('/prompt_manager/maintenance', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ operations: selectedOps })
+ });
+
+ if (response.ok) {
+ const data = await response.json();
+ if (data.success) {
+ this.renderMaintenanceResults(data);
+
+ // Show overall success notification
+ if (data.all_successful) {
+ this.showNotification('✅ All maintenance operations completed successfully!', 'success');
+ } else {
+ this.showNotification('⚠️ Some maintenance operations had issues', 'warning');
+ }
+
+ // Refresh stats after maintenance
+ setTimeout(() => this.loadStatistics(), 1000);
+ } else {
+ throw new Error(data.error || 'Maintenance failed');
+ }
+ } else {
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
+ }
+ } catch (error) {
+ console.error('Maintenance error:', error);
+ resultsContainer.innerHTML = `
+
+
❌ Maintenance Failed
+
${error.message}
+
+ `;
+ this.showNotification('❌ Maintenance failed', 'error');
+ } finally {
+ runButton.disabled = false;
+ runButton.innerHTML = '🔧 Run Maintenance';
+ }
+ }
+
+ renderMaintenanceResults(data) {
+ const resultsContainer = document.getElementById("maintenanceResults");
+
+ let html = '
';
+
+ // Summary
+ html += '
';
+ html += '
📋 Maintenance Summary
';
+ html += '
';
+ html += `
+
+ Operations Completed
+ ${data.operations_completed}
+
+ `;
+ html += `
+
+ Overall Success
+
+ ${data.all_successful ? '✅ ALL PASSED' : '⚠️ SOME ISSUES'}
+
+
+ `;
+ html += '
';
+
+ // Detailed results
+ for (const [operation, result] of Object.entries(data.results)) {
+ const bgColor = result.success ? 'bg-green-900/20 border-green-600' : 'bg-red-900/20 border-red-600';
+ const statusIcon = result.success ? '✅' : '❌';
+ const statusText = result.success ? 'SUCCESS' : 'FAILED';
+
+ html += `
`;
+ html += `
`;
+ html += `${statusIcon}`;
+ html += `${operation.replace(/_/g, ' ')}`;
+ html += `${statusText}`;
+ html += `
`;
+
+ if (result.message) {
+ html += `
${result.message}
`;
+ }
+
+ // Show specific details
+ if (result.removed_count !== undefined) {
+ html += `
Items removed: ${result.removed_count}
`;
+ }
+
+ if (result.duplicate_hashes !== undefined) {
+ html += `
Duplicate hash groups found: ${result.duplicate_hashes}
`;
+ }
+
+ if (result.issues_found !== undefined) {
+ html += `
Issues found: ${result.issues_found}
`;
+ if (result.issues && result.issues.length > 0) {
+ html += `
`;
+ result.issues.forEach(issue => {
+ html += `- ${issue}
`;
+ });
+ html += `
`;
+ }
+ }
+
+ if (result.info) {
+ html += `
`;
+ html += `
Total prompts: ${result.info.total_prompts || 'N/A'}
`;
+ html += `
Database size: ${result.info.database_size_bytes ? this.formatFileSize(result.info.database_size_bytes) : 'N/A'}
`;
+ html += `
`;
+ }
+
+ if (result.error) {
+ html += `
`;
+ html += `Error: ${result.error}`;
+ html += `
`;
+ }
+
+ html += '
';
+ }
+
+ html += '
';
+ resultsContainer.innerHTML = html;
+ }
+
async runDiagnostics() {
const content = document.getElementById("diagnosticsContent");
content.innerHTML = `