Files
orion/app/modules/monitoring/static/admin/js/logs.js
Samir Boulahtit 0b4291d893 refactor(js): migrate JavaScript files to module directories
Move 47 JS files from static/{admin,vendor,shared}/js/ to their
respective module directories app/modules/*/static/*/js/:

- Orders: orders.js, order-detail.js
- Catalog: products.js (renamed from vendor-products.js), product-*.js
- Inventory: inventory.js (admin & vendor)
- Customers: customers.js, users.js, user-*.js
- Billing: billing-history.js, subscriptions.js, subscription-tiers.js,
  billing.js, invoices.js, feature-store.js, upgrade-prompts.js
- Messaging: messages.js, notifications.js, email-templates.js
- Marketplace: marketplace*.js, letzshop*.js, onboarding.js
- Monitoring: monitoring.js, background-tasks.js, imports.js, logs.js
- Dev Tools: testing-*.js, code-quality-*.js

Update 39 templates to reference new module static paths using
url_for('{module}_static', path='...') pattern.

Files staying in static/ (platform core):
- admin: dashboard, login, platforms, vendors, companies, admin-users,
  settings, components, init-alpine, module-config
- vendor: dashboard, login, profile, settings, team, media, init-alpine
- shared: api-client, utils, money, icons, log-config, vendor-selector,
  media-picker

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:08:20 +01:00

249 lines
8.0 KiB
JavaScript

// noqa: js-006 - async init pattern is safe, loadData has try/catch
// static/admin/js/logs.js
// noqa: JS-003 - Uses ...baseData which is data() with safety check
const logsLog = window.LogConfig?.loggers?.logs || console;
function adminLogs() {
// Get base data with safety check for standalone usage
const baseData = typeof data === 'function' ? data() : {};
return {
// Inherit base layout functionality from init-alpine.js
...baseData,
// Logs-specific state
currentPage: 'logs',
loading: true,
error: null,
successMessage: null,
logSource: 'database',
logs: [],
stats: {
total_count: 0,
warning_count: 0,
error_count: 0,
critical_count: 0
},
selectedLog: null,
filters: {
level: '',
module: '',
search: ''
},
pagination: {
page: 1,
per_page: 20,
total: 0,
pages: 0
},
logFiles: [],
selectedFile: '',
fileContent: null,
// Computed: Total pages
get totalPages() {
return this.pagination.pages;
},
// Computed: Start index for pagination display
get startIndex() {
if (this.pagination.total === 0) return 0;
return (this.pagination.page - 1) * this.pagination.per_page + 1;
},
// Computed: End index for pagination display
get endIndex() {
const end = this.pagination.page * this.pagination.per_page;
return end > this.pagination.total ? this.pagination.total : end;
},
// Computed: Page numbers for pagination
get pageNumbers() {
const pages = [];
const totalPages = this.totalPages;
const current = this.pagination.page;
if (totalPages <= 7) {
for (let i = 1; i <= totalPages; i++) {
pages.push(i);
}
} else {
pages.push(1);
if (current > 3) {
pages.push('...');
}
const start = Math.max(2, current - 1);
const end = Math.min(totalPages - 1, current + 1);
for (let i = start; i <= end; i++) {
pages.push(i);
}
if (current < totalPages - 2) {
pages.push('...');
}
pages.push(totalPages);
}
return pages;
},
async init() {
// Guard against multiple initialization
if (window._adminLogsInitialized) {
logsLog.warn('Already initialized, skipping');
return;
}
window._adminLogsInitialized = true;
logsLog.info('=== LOGS PAGE INITIALIZING ===');
// Load platform settings for rows per page
if (window.PlatformSettings) {
this.pagination.per_page = await window.PlatformSettings.getRowsPerPage();
}
await this.loadStats();
await this.loadLogs();
},
async refresh() {
this.error = null;
this.successMessage = null;
await this.loadStats();
if (this.logSource === 'database') {
await this.loadLogs();
} else {
await this.loadFileLogs();
}
},
async loadStats() {
try {
const data = await apiClient.get('/admin/logs/statistics?days=7');
this.stats = data;
logsLog.info('Log statistics loaded:', this.stats);
} catch (error) {
logsLog.error('Failed to load log statistics:', error);
}
},
async loadLogs() {
this.loading = true;
this.error = null;
try {
const params = new URLSearchParams();
if (this.filters.level) params.append('level', this.filters.level);
if (this.filters.module) params.append('module', this.filters.module);
if (this.filters.search) params.append('search', this.filters.search);
params.append('skip', (this.pagination.page - 1) * this.pagination.per_page);
params.append('limit', this.pagination.per_page);
const data = await apiClient.get(`/admin/logs/database?${params}`);
this.logs = data.logs;
this.pagination.total = data.total;
this.pagination.pages = Math.ceil(this.pagination.total / this.pagination.per_page);
logsLog.info(`Loaded ${this.logs.length} logs (total: ${this.pagination.total})`);
} catch (error) {
logsLog.error('Failed to load logs:', error);
this.error = error.response?.data?.detail || 'Failed to load logs';
} finally {
this.loading = false;
}
},
async loadFileLogs() {
this.loading = true;
this.error = null;
try {
const data = await apiClient.get('/admin/logs/files');
this.logFiles = data.files;
if (this.logFiles.length > 0 && !this.selectedFile) {
this.selectedFile = this.logFiles[0].filename;
await this.loadFileContent();
}
logsLog.info(`Loaded ${this.logFiles.length} log files`);
} catch (error) {
logsLog.error('Failed to load log files:', error);
this.error = error.response?.data?.detail || 'Failed to load log files';
} finally {
this.loading = false;
}
},
async loadFileContent() {
if (!this.selectedFile) return;
this.loading = true;
this.error = null;
try {
const data = await apiClient.get(`/admin/logs/files/${this.selectedFile}?lines=500`);
this.fileContent = data;
logsLog.info(`Loaded file content for ${this.selectedFile}`);
} catch (error) {
logsLog.error('Failed to load file content:', error);
this.error = error.response?.data?.detail || 'Failed to load file content';
} finally {
this.loading = false;
}
},
async downloadLogFile() {
if (!this.selectedFile) return;
try {
const token = localStorage.getItem('admin_token');
// Note: window.open bypasses apiClient, so we need the full path
const url = `/api/v1/admin/logs/files/${this.selectedFile}/download`;
window.open(`${url}?token=${token}`, '_blank'); // noqa: sec-022
} catch (error) {
logsLog.error('Failed to download log file:', error);
this.error = 'Failed to download log file';
}
},
resetFilters() {
this.filters = {
level: '',
module: '',
search: ''
};
this.pagination.page = 1;
this.loadLogs();
},
previousPage() {
if (this.pagination.page > 1) {
this.pagination.page--;
this.loadLogs();
}
},
nextPage() {
if (this.pagination.page < this.totalPages) {
this.pagination.page++;
this.loadLogs();
}
},
goToPage(pageNum) {
if (pageNum !== '...' && pageNum >= 1 && pageNum <= this.totalPages) {
this.pagination.page = pageNum;
this.loadLogs();
}
},
showLogDetail(log) {
this.selectedLog = log;
},
formatTimestamp(timestamp) {
return new Date(timestamp).toLocaleString();
}
};
}
logsLog.info('Logs module loaded');