maj
This commit is contained in:
@@ -1,20 +1,60 @@
|
||||
// Linux BenchTools - Dashboard Logic
|
||||
|
||||
const { formatDate, formatRelativeTime, createScoreBadge, getScoreBadgeText, escapeHtml, showError, showEmptyState, copyToClipboard, showToast } = window.BenchUtils;
|
||||
const { formatDate, formatRelativeTime, createScoreBadge, getScoreBadgeText, escapeHtml, showError, showEmptyState, copyToClipboard, showToast, debounce } = window.BenchUtils;
|
||||
const api = window.BenchAPI;
|
||||
|
||||
// Global state
|
||||
let allDevices = [];
|
||||
let isLoading = false;
|
||||
|
||||
// Load dashboard data
|
||||
async function loadDashboard() {
|
||||
if (isLoading) return;
|
||||
|
||||
isLoading = true;
|
||||
updateRefreshButton(true);
|
||||
|
||||
try {
|
||||
await Promise.all([
|
||||
loadStats(),
|
||||
loadTopDevices()
|
||||
]);
|
||||
|
||||
// Update last refresh time
|
||||
updateLastRefreshTime();
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to load dashboard:', error);
|
||||
showToast('Erreur lors du chargement des données', 'error');
|
||||
} finally {
|
||||
isLoading = false;
|
||||
updateRefreshButton(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Update refresh button state
|
||||
function updateRefreshButton(loading) {
|
||||
const btn = document.getElementById('refreshBtn');
|
||||
if (!btn) return;
|
||||
|
||||
if (loading) {
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '⏳ Chargement...';
|
||||
} else {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '🔄 Actualiser';
|
||||
}
|
||||
}
|
||||
|
||||
// Update last refresh time
|
||||
function updateLastRefreshTime() {
|
||||
const element = document.getElementById('lastUpdate');
|
||||
if (!element) return;
|
||||
|
||||
const now = new Date();
|
||||
element.textContent = `Mis à jour: ${now.toLocaleTimeString('fr-FR')}`;
|
||||
}
|
||||
|
||||
// Load statistics
|
||||
async function loadStats() {
|
||||
try {
|
||||
@@ -72,48 +112,74 @@ async function loadTopDevices() {
|
||||
|
||||
if (!data.items || data.items.length === 0) {
|
||||
showEmptyState(container, 'Aucun device trouvé. Exécutez un benchmark sur une machine pour commencer.', '📊');
|
||||
allDevices = [];
|
||||
return;
|
||||
}
|
||||
|
||||
// Store all devices for filtering
|
||||
allDevices = data.items;
|
||||
|
||||
// Sort by global_score descending
|
||||
const sortedDevices = data.items.sort((a, b) => {
|
||||
const sortedDevices = allDevices.sort((a, b) => {
|
||||
const scoreA = a.last_benchmark?.global_score ?? -1;
|
||||
const scoreB = b.last_benchmark?.global_score ?? -1;
|
||||
return scoreB - scoreA;
|
||||
});
|
||||
|
||||
// Generate table HTML
|
||||
container.innerHTML = `
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Hostname</th>
|
||||
<th>Description</th>
|
||||
<th>Score Global</th>
|
||||
<th>CPU</th>
|
||||
<th>MEM</th>
|
||||
<th>DISK</th>
|
||||
<th>NET</th>
|
||||
<th>GPU</th>
|
||||
<th>Dernier Bench</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${sortedDevices.map((device, index) => createDeviceRow(device, index + 1)).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
`;
|
||||
// Render devices
|
||||
renderDevicesTable(sortedDevices);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to load devices:', error);
|
||||
showError(container, 'Impossible de charger les devices. Vérifiez que le backend est accessible.');
|
||||
container.innerHTML = `
|
||||
<div class="error" style="text-align: center;">
|
||||
<p style="margin-bottom: 1rem;">❌ Impossible de charger les devices</p>
|
||||
<p style="font-size: 0.9rem; margin-bottom: 1rem;">${escapeHtml(error.message)}</p>
|
||||
<button class="btn btn-primary btn-sm" onclick="loadTopDevices()">🔄 Réessayer</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
// Render devices table
|
||||
function renderDevicesTable(devices) {
|
||||
const container = document.getElementById('devicesTable');
|
||||
|
||||
if (devices.length === 0) {
|
||||
container.innerHTML = `
|
||||
<div style="text-align: center; padding: 2rem; color: var(--text-secondary);">
|
||||
<p>Aucun device trouvé avec ces critères de recherche.</p>
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
container.innerHTML = `
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Hostname</th>
|
||||
<th>Description</th>
|
||||
<th>Score Global</th>
|
||||
<th>CPU</th>
|
||||
<th>MEM</th>
|
||||
<th>DISK</th>
|
||||
<th>NET</th>
|
||||
<th>GPU</th>
|
||||
<th>Dernier Bench</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${devices.map((device, index) => createDeviceRow(device, index + 1)).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Create device row HTML
|
||||
function createDeviceRow(device, rank) {
|
||||
const bench = device.last_benchmark;
|
||||
@@ -167,13 +233,69 @@ async function copyBenchCommand() {
|
||||
}
|
||||
}
|
||||
|
||||
// Filter devices based on search query
|
||||
function filterDevices(query) {
|
||||
if (!query || query.trim() === '') {
|
||||
renderDevicesTable(allDevices);
|
||||
return;
|
||||
}
|
||||
|
||||
const lowerQuery = query.toLowerCase();
|
||||
const filtered = allDevices.filter(device => {
|
||||
const hostname = (device.hostname || '').toLowerCase();
|
||||
const description = (device.description || '').toLowerCase();
|
||||
const location = (device.location || '').toLowerCase();
|
||||
|
||||
return hostname.includes(lowerQuery) ||
|
||||
description.includes(lowerQuery) ||
|
||||
location.includes(lowerQuery);
|
||||
});
|
||||
|
||||
renderDevicesTable(filtered);
|
||||
}
|
||||
|
||||
// Debounced search
|
||||
const debouncedSearch = debounce((query) => {
|
||||
filterDevices(query);
|
||||
}, 300);
|
||||
|
||||
// Handle search input
|
||||
function handleSearch(event) {
|
||||
const query = event.target.value;
|
||||
debouncedSearch(query);
|
||||
}
|
||||
|
||||
// Clear search
|
||||
function clearSearch() {
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
if (searchInput) {
|
||||
searchInput.value = '';
|
||||
filterDevices('');
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh dashboard manually
|
||||
function refreshDashboard() {
|
||||
if (!isLoading) {
|
||||
loadDashboard();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize dashboard on page load
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
loadDashboard();
|
||||
|
||||
// Setup search input listener
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
if (searchInput) {
|
||||
searchInput.addEventListener('input', handleSearch);
|
||||
}
|
||||
|
||||
// Refresh every 30 seconds
|
||||
setInterval(loadDashboard, 30000);
|
||||
});
|
||||
|
||||
// Make copyBenchCommand available globally
|
||||
// Make functions available globally
|
||||
window.copyBenchCommand = copyBenchCommand;
|
||||
window.clearSearch = clearSearch;
|
||||
window.refreshDashboard = refreshDashboard;
|
||||
|
||||
Reference in New Issue
Block a user