Files
orion/static/admin/js/background-tasks.js
Samir Boulahtit 265c71f597 fix: resolve all JS architecture violations (JS-005 through JS-009)
Fixed 89 violations across vendor, admin, and shared JavaScript files:

JS-008 (raw fetch → apiClient):
- Added postFormData() and getBlob() methods to api-client.js
- Updated inventory.js, messages.js to use apiClient.postFormData()
- Added noqa for file downloads that need response headers

JS-009 (window.showToast → Utils.showToast):
- Updated admin/messages.js, notifications.js, vendor/messages.js
- Replaced alert() in customers.js

JS-006 (async error handling):
- Added try/catch to all async init() and reload() methods
- Fixed vendor: billing, dashboard, login, messages, onboarding
- Fixed shared: feature-store, upgrade-prompts
- Fixed admin: all page components

JS-005 (init guards):
- Added initialization guards to prevent duplicate init() calls
- Pattern: if (window._componentInitialized) return;

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 21:32:19 +01:00

138 lines
4.3 KiB
JavaScript

// noqa: js-006 - async init pattern is safe, loadData has try/catch
/**
* Background Tasks Monitoring Component
* Manages the background tasks monitoring page
*/
// Use centralized logger
const backgroundTasksLog = window.LogConfig.createLogger('BACKGROUND-TASKS');
function backgroundTasks() {
return {
// Extend base data
...data(),
// Set current page for navigation
currentPage: 'background-tasks',
// Page-specific data
loading: false,
error: null,
filterType: null,
pollInterval: null,
// Statistics
stats: {
total_tasks: 0,
running: 0,
completed: 0,
failed: 0,
tasks_today: 0,
avg_duration_seconds: null,
import_jobs: {},
test_runs: {}
},
// Tasks
tasks: [],
runningTasks: [],
async init() {
// Guard against multiple initialization
if (window._adminBackgroundTasksInitialized) return;
window._adminBackgroundTasksInitialized = true;
try {
backgroundTasksLog.info('Initializing background tasks monitor');
await this.loadStats();
await this.loadTasks();
await this.loadRunningTasks();
// Poll for updates every 5 seconds
this.pollInterval = setInterval(() => {
this.loadRunningTasks();
if (this.runningTasks.length > 0) {
this.loadStats();
}
}, 5000);
} catch (error) {
backgroundTasksLog.error('Failed to initialize background tasks:', error);
}
},
destroy() {
if (this.pollInterval) {
clearInterval(this.pollInterval);
}
},
async loadStats() {
try {
const stats = await apiClient.get('/admin/background-tasks/tasks/stats');
this.stats = stats;
backgroundTasksLog.info('Stats loaded:', stats);
} catch (err) {
backgroundTasksLog.error('Failed to load stats:', err);
}
},
async loadTasks() {
this.loading = true;
this.error = null;
try {
let url = '/admin/background-tasks/tasks?limit=50';
if (this.filterType) {
url += `&task_type=${this.filterType}`;
}
const tasks = await apiClient.get(url);
this.tasks = tasks;
backgroundTasksLog.info('Tasks loaded:', tasks.length);
} catch (err) {
backgroundTasksLog.error('Failed to load tasks:', err);
this.error = err.message;
if (err.message.includes('Unauthorized')) {
window.location.href = '/admin/login';
}
} finally {
this.loading = false;
}
},
async loadRunningTasks() {
try {
const running = await apiClient.get('/admin/background-tasks/tasks/running');
this.runningTasks = running;
// Update elapsed time for running tasks
const now = new Date();
this.runningTasks.forEach(task => {
if (task.started_at) {
const started = new Date(task.started_at);
task.duration_seconds = (now - started) / 1000;
}
});
} catch (err) {
backgroundTasksLog.error('Failed to load running tasks:', err);
}
},
async refresh() {
await this.loadStats();
await this.loadTasks();
await this.loadRunningTasks();
},
formatDuration(seconds) {
if (seconds === null || seconds === undefined) return 'N/A';
if (seconds < 1) return `${Math.round(seconds * 1000)}ms`;
if (seconds < 60) return `${Math.round(seconds)}s`;
const minutes = Math.floor(seconds / 60);
const secs = Math.round(seconds % 60);
return `${minutes}m ${secs}s`;
}
};
}