diff --git a/web/js/admin.js b/web/js/admin.js
index e48c0985..405251ed 100644
--- a/web/js/admin.js
+++ b/web/js/admin.js
@@ -47,7 +47,6 @@
edit: ({ promptId }) => this.editPrompt(promptId),
delete: ({ promptId }) => this.deletePrompt(promptId),
"open-film": ({ promptId, index }) => this.openFilmStripViewer(promptId, index),
- "download-log": ({ filename }) => this.downloadLogFile(filename),
"remove-review-tag": ({ index }) => this.removeReviewTag(index),
"pick-tag-suggestion": ({ tag }) => this.pickTagSuggestion(tag),
};
@@ -128,14 +127,12 @@
document.getElementById("exportBtn").addEventListener("click", () => this.exportPrompts());
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());
document.getElementById("backupBtn").addEventListener("click", () => this.backupDatabase());
document.getElementById("restoreBtn").addEventListener("click", () => this.showRestoreModal());
document.getElementById("scanBtn").addEventListener("click", () => this.showScanModal());
document.getElementById("autoTagBtn").addEventListener("click", () => this.showAutoTagModal());
document.getElementById("addPromptBtn").addEventListener("click", () => this.showAddPromptModal());
- document.getElementById("logsBtn").addEventListener("click", () => this.showLogsModal());
document.getElementById("metadataBtn").addEventListener("click", () => this.openMetadataViewer());
document.getElementById("galleryBtn").addEventListener("click", () => this.openGallery());
@@ -215,10 +212,6 @@
document.getElementById("confirmRestore").addEventListener("click", () => this.confirmRestore());
document.getElementById("cancelRestore").addEventListener("click", () => this.hideModal("restoreModal"));
- // Diagnostics modal
- 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());
@@ -230,12 +223,6 @@
document.getElementById("scanPill").addEventListener("click", () => this.showScanModal());
document.getElementById("quickBackupBtn").addEventListener("click", () => this.quickBackup());
- // Logs modal
- document.getElementById("refreshLogsBtn").addEventListener("click", () => this.refreshLogs());
- document.getElementById("downloadLogsBtn").addEventListener("click", () => this.downloadLogs());
- document.getElementById("clearLogsBtn").addEventListener("click", () => this.clearLogs());
- document.getElementById("updateLogConfigBtn").addEventListener("click", () => this.updateLogConfig());
-
// Auto Tag modals
document.getElementById("startAutoTagBtn").addEventListener("click", () => this.startAutoTag());
document.getElementById("startReviewBtn").addEventListener("click", () => this.startReview());
@@ -1801,15 +1788,6 @@
return `${size.toFixed(1)} ${units[unitIndex]}`;
}
- // Diagnostics functionality
- showDiagnosticsModal() {
- this.showModal("diagnosticsModal");
- }
-
- closeDiagnostics() {
- this.hideModal("diagnosticsModal");
- }
-
// Maintenance functionality
showMaintenanceModal() {
this.showModal("maintenanceModal");
@@ -1981,160 +1959,6 @@
resultsContainer.innerHTML = html;
}
- async runDiagnostics() {
- const content = document.getElementById("diagnosticsContent");
- content.innerHTML = `
-
-
-
Running diagnostics...
-
- `;
-
- try {
- const response = await ApiClient.fetchUrl('/prompt_manager/diagnostics');
- if (response.ok) {
- const data = await response.json();
- if (data.success) {
- this.renderDiagnostics(data.diagnostics);
- } else {
- throw new Error(data.error || 'Diagnostics failed');
- }
- } else {
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
- }
- } catch (error) {
- console.error('Diagnostics error:', error);
- content.innerHTML = `
-
-
โ Diagnostics Failed
-
${escapeHtml(error.message)}
-
- `;
- }
- }
-
- renderDiagnostics(diagnostics) {
- const content = document.getElementById("diagnosticsContent");
-
- let html = '
';
-
- // Summary
- html += '
';
- html += '
๐ Diagnostic Summary
';
- html += '
';
-
- for (const [category, result] of Object.entries(diagnostics)) {
- const status = result.status === 'ok' ? 'โ
PASS' : (result.status === 'warning' ? 'โ ๏ธ WARNING' : 'โ FAIL');
- const statusColor = result.status === 'ok' ? 'text-pm-success' : (result.status === 'warning' ? 'text-pm-warning' : 'text-pm-error');
-
- html += `
-
- ${escapeHtml(category)}
- ${status}
-
- `;
- }
-
- html += '
';
-
- // Detailed results
- for (const [category, result] of Object.entries(diagnostics)) {
- const bgColor = result.status === 'ok' ? 'bg-pm-success-tint border-pm-success' :
- (result.status === 'warning' ? 'bg-pm-warning/20 border-pm-warning' : 'bg-pm-error-tint border-pm-error');
-
- html += `
`;
- html += `
${escapeHtml(category)}
`;
-
- if (result.message) {
- html += `
${escapeHtml(result.message)}
`;
- }
-
- // Show specific details based on category
- if (category === 'database' && result.status === 'ok') {
- html += `
`;
- html += `
Prompts: ${escapeHtml(result.prompt_count || 0)}
`;
- html += `
Images table: ${result.has_images_table ? 'Yes' : 'No'}
`;
- html += `
`;
- }
-
- if (category === 'images_table' && result.status === 'ok') {
- html += `
`;
- html += `
Images: ${escapeHtml(result.image_count || 0)}
`;
- if (result.recent_images && result.recent_images.length > 0) {
- html += `
Recent images:
`;
- html += `
`;
- result.recent_images.slice(0, 3).forEach(img => {
- html += `- ${escapeHtml(img.filename)} โ Prompt ${escapeHtml(img.prompt_id)}
`;
- });
- html += `
`;
- }
- html += `
`;
- }
-
- if (category === 'comfyui_output' && result.output_dirs) {
- html += `
`;
- html += `
Output directories found:
`;
- html += `
`;
- result.output_dirs.forEach(dir => {
- html += `- ${escapeHtml(dir)}
`;
- });
- html += `
`;
- html += `
`;
- }
-
- if (category === 'dependencies' && result.dependencies) {
- html += `
`;
- for (const [dep, available] of Object.entries(result.dependencies)) {
- const status = available ? 'โ
' : 'โ';
- html += `
${status} ${escapeHtml(dep)}
`;
- }
- html += `
`;
- }
-
- html += '
';
- }
-
- html += '
';
- content.innerHTML = html;
- }
-
- async testImageLink() {
- if (this.prompts.length === 0) {
- this.showNotification('No prompts available for testing', 'warning');
- return;
- }
-
- // Use the first prompt for testing
- const testPrompt = this.prompts[0];
-
- try {
- const response = await ApiClient.fetchUrl('/prompt_manager/diagnostics/test-link', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({
- prompt_id: testPrompt.id,
- image_path: '/test/fake/image.png'
- })
- });
-
- if (response.ok) {
- const data = await response.json();
- if (data.success) {
- this.showNotification('โ
Test image link created successfully!', 'success');
- // Refresh the gallery to show the test image
- setTimeout(() => this.refreshList(), 1000);
- } else {
- throw new Error(data.result?.message || 'Test failed');
- }
- } else {
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
- }
- } catch (error) {
- console.error('Test link error:', error);
- this.showNotification(`โ Test failed: ${error.message}`, 'error');
- }
- }
-
// Database backup and restore functionality
async backupDatabase() {
try {
@@ -2497,273 +2321,6 @@
this.showNotification(`Scan failed: ${state.message}`, "error");
}
- // Logs functionality
- showLogsModal() {
- this.showModal("logsModal");
- this.loadLogStats();
- this.loadLogFiles();
- this.loadLogConfig();
- }
-
- closeLogs() {
- this.hideModal("logsModal");
- }
-
- async loadLogStats() {
- try {
- const response = await ApiClient.fetchUrl('/prompt_manager/logs/stats');
- const data = await response.json();
-
- if (data.success) {
- const stats = data.stats;
- document.getElementById("logStatsTotal").textContent = stats.buffer_count || 0;
- document.getElementById("logStatsErrors").textContent = stats.level_counts?.ERROR || 0;
- document.getElementById("logStatsWarnings").textContent = stats.level_counts?.WARNING || 0;
- document.getElementById("logStatsLevel").textContent = stats.current_level || "INFO";
- document.getElementById("logStatsSize").textContent = this.formatBytes(stats.total_log_size || 0);
- }
- } catch (error) {
- console.error("Failed to load log stats:", error);
- }
- }
-
- async loadLogConfig() {
- try {
- const response = await ApiClient.fetchUrl('/prompt_manager/logs/config');
- const data = await response.json();
-
- if (data.success) {
- const config = data.config;
- document.getElementById("setLogLevel").value = config.level || "INFO";
- document.getElementById("consoleLogging").checked = config.console_logging !== false;
- }
- } catch (error) {
- console.error("Failed to load log config:", error);
- }
- }
-
- async loadLogFiles() {
- try {
- const response = await ApiClient.fetchUrl('/prompt_manager/logs/files');
- const data = await response.json();
-
- if (data.success) {
- const container = document.getElementById("logFilesList");
-
- if (data.files.length === 0) {
- container.innerHTML = '
No log files found
';
- return;
- }
-
- container.innerHTML = data.files.map(file => `
-
-
- ${escapeHtml(file.filename)}
- ${file.is_main ? 'Active' : ''}
-
-
- Size: ${this.formatBytes(file.size)} | Modified: ${new Date(file.modified).toLocaleString()}
-
-
-
- `).join('');
- }
- } catch (error) {
- console.error("Failed to load log files:", error);
- }
- }
-
- async refreshLogs() {
- const level = document.getElementById("logLevel").value;
- const limit = parseInt(document.getElementById("logLimit").value);
-
- try {
- const url = new URL(ApiClient.resolveUrl('/prompt_manager/logs'), window.location.origin);
- if (level) url.searchParams.set('level', level);
- url.searchParams.set('limit', limit.toString());
-
- const response = await ApiClient.fetchUrl(url);
- const data = await response.json();
-
- if (data.success) {
- this.displayLogs(data.logs);
- this.showNotification(`Loaded ${data.logs.length} log entries`, "success");
- } else {
- this.showNotification(`Failed to load logs: ${data.error}`, "error");
- }
- } catch (error) {
- console.error("Failed to refresh logs:", error);
- this.showNotification("Failed to refresh logs", "error");
- }
- }
-
- displayLogs(logs) {
- const container = document.getElementById("logsContainer");
-
- if (logs.length === 0) {
- container.innerHTML = '
No logs found
';
- return;
- }
-
- container.innerHTML = logs.map(log => {
- const levelColors = {
- DEBUG: 'text-pm-secondary',
- INFO: 'text-pm-accent',
- WARNING: 'text-pm-warning',
- ERROR: 'text-pm-error',
- CRITICAL: 'text-pm-error'
- };
-
- const levelColor = levelColors[log.level] || 'text-pm-secondary';
- const timestamp = new Date(log.timestamp).toLocaleString();
-
- return `
-
-
- ${escapeHtml(timestamp.split(' ')[1])}
- ${escapeHtml(log.level)}
- ${escapeHtml(log.logger)}
- ${escapeHtml(log.message)}
-
-
- ${escapeHtml(log.filename)}:${escapeHtml(log.lineno)}
-
-
- `;
- }).join('');
-
- // Auto-scroll to bottom
- container.scrollTop = container.scrollHeight;
- }
-
- async downloadLogs() {
- const level = document.getElementById("logLevel").value;
- const limit = parseInt(document.getElementById("logLimit").value);
-
- try {
- const url = new URL(ApiClient.resolveUrl('/prompt_manager/logs'), window.location.origin);
- if (level) url.searchParams.set('level', level);
- url.searchParams.set('limit', limit.toString());
-
- const response = await ApiClient.fetchUrl(url);
- const data = await response.json();
-
- if (data.success) {
- const logText = data.logs.map(log =>
- `${log.timestamp} [${log.level}] ${log.logger}: ${log.message} (${log.filename}:${log.lineno})`
- ).join('\n');
-
- const blob = new Blob([logText], { type: 'text/plain' });
- const url2 = URL.createObjectURL(blob);
- const a = document.createElement('a');
- a.href = url2;
- a.download = `prompt_manager_logs_${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.txt`;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url2);
-
- this.showNotification("Logs downloaded successfully", "success");
- } else {
- this.showNotification(`Failed to download logs: ${data.error}`, "error");
- }
- } catch (error) {
- console.error("Failed to download logs:", error);
- this.showNotification("Failed to download logs", "error");
- }
- }
-
- async downloadLogFile(filename) {
- try {
- const response = await ApiClient.fetchUrl(`/prompt_manager/logs/download/${encodeURIComponent(filename)}`);
-
- if (response.ok) {
- const blob = await response.blob();
- const url = URL.createObjectURL(blob);
- const a = document.createElement('a');
- a.href = url;
- a.download = filename;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url);
-
- this.showNotification(`Downloaded ${filename}`, "success");
- } else {
- this.showNotification(`Failed to download ${filename}`, "error");
- }
- } catch (error) {
- console.error("Failed to download log file:", error);
- this.showNotification("Failed to download log file", "error");
- }
- }
-
- async clearLogs() {
- if (!confirm("Are you sure you want to clear all log files? This cannot be undone.")) {
- return;
- }
-
- try {
- const response = await ApiClient.fetchUrl('/prompt_manager/logs/truncate', {
- method: 'POST'
- });
- const data = await response.json();
-
- if (data.success) {
- this.showNotification(data.message, "success");
- this.refreshLogs();
- this.loadLogStats();
- this.loadLogFiles();
- } else {
- this.showNotification(`Failed to clear logs: ${data.error}`, "error");
- }
- } catch (error) {
- console.error("Failed to clear logs:", error);
- this.showNotification("Failed to clear logs", "error");
- }
- }
-
- async updateLogConfig() {
- const level = document.getElementById("setLogLevel").value;
- const consoleLogging = document.getElementById("consoleLogging").checked;
-
- try {
- const response = await ApiClient.fetchUrl('/prompt_manager/logs/config', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify({
- level: level,
- console_logging: consoleLogging
- })
- });
-
- const data = await response.json();
-
- if (data.success) {
- this.showNotification("Log configuration updated", "success");
- this.loadLogStats();
- } else {
- this.showNotification(`Failed to update config: ${data.error}`, "error");
- }
- } catch (error) {
- console.error("Failed to update log config:", error);
- this.showNotification("Failed to update log configuration", "error");
- }
- }
-
- formatBytes(bytes) {
- if (bytes === 0) return '0 B';
- const k = 1024;
- const sizes = ['B', 'KB', 'MB', 'GB'];
- const i = Math.floor(Math.log(bytes) / Math.log(k));
- return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
- }
-
// Pagination methods
updatePaginationControls() {
const { currentPage, totalPages, total, limit } = this.pagination;