script
This commit is contained in:
@@ -36,6 +36,7 @@ async function loadDeviceDetail() {
|
||||
renderDeviceHeader();
|
||||
renderHardwareSummary();
|
||||
renderLastBenchmark();
|
||||
renderNetworkDetails();
|
||||
await loadBenchmarkHistory();
|
||||
await loadDocuments();
|
||||
await loadLinks();
|
||||
@@ -86,9 +87,27 @@ function renderHardwareSummary() {
|
||||
return;
|
||||
}
|
||||
|
||||
// RAM usage info
|
||||
const ramTotalGB = Math.round((snapshot.ram_total_mb || 0) / 1024);
|
||||
const ramUsedMB = snapshot.ram_used_mb || 0;
|
||||
const ramFreeMB = snapshot.ram_free_mb || 0;
|
||||
const ramSharedMB = snapshot.ram_shared_mb || 0;
|
||||
|
||||
let ramValue = `${ramTotalGB} GB`;
|
||||
if (ramUsedMB > 0 || ramFreeMB > 0) {
|
||||
const usagePercent = ramTotalGB > 0 ? Math.round((ramUsedMB / (snapshot.ram_total_mb || 1)) * 100) : 0;
|
||||
ramValue = `${ramTotalGB} GB (${usagePercent}% utilisé)<br><small>Utilisée: ${Math.round(ramUsedMB / 1024)}GB • Libre: ${Math.round(ramFreeMB / 1024)}GB`;
|
||||
if (ramSharedMB > 0) {
|
||||
ramValue += ` • Partagée: ${Math.round(ramSharedMB / 1024)}GB`;
|
||||
}
|
||||
ramValue += `<br>${snapshot.ram_slots_used || '?'} / ${snapshot.ram_slots_total || '?'} slots</small>`;
|
||||
} else {
|
||||
ramValue += `<br><small>${snapshot.ram_slots_used || '?'} / ${snapshot.ram_slots_total || '?'} slots</small>`;
|
||||
}
|
||||
|
||||
const hardwareItems = [
|
||||
{ label: 'CPU', icon: '🔲', value: `${snapshot.cpu_model || 'N/A'}<br><small>${snapshot.cpu_cores || 0}C / ${snapshot.cpu_threads || 0}T @ ${snapshot.cpu_max_freq_ghz || snapshot.cpu_base_freq_ghz || '?'} GHz</small>` },
|
||||
{ label: 'RAM', icon: '💾', value: `${Math.round((snapshot.ram_total_mb || 0) / 1024)} GB<br><small>${snapshot.ram_slots_used || '?'} / ${snapshot.ram_slots_total || '?'} slots</small>` },
|
||||
{ label: 'RAM', icon: '💾', value: ramValue },
|
||||
{ label: 'GPU', icon: '🎮', value: snapshot.gpu_model || snapshot.gpu_summary || 'N/A' },
|
||||
{ label: 'Stockage', icon: '💿', value: snapshot.storage_summary || 'N/A' },
|
||||
{ label: 'Réseau', icon: '🌐', value: snapshot.network_interfaces_json ? `${JSON.parse(snapshot.network_interfaces_json).length} interface(s)` : 'N/A' },
|
||||
@@ -141,6 +160,126 @@ function renderLastBenchmark() {
|
||||
`;
|
||||
}
|
||||
|
||||
// Render network details
|
||||
function renderNetworkDetails() {
|
||||
const container = document.getElementById('networkDetails');
|
||||
const snapshot = currentDevice.last_hardware_snapshot;
|
||||
const bench = currentDevice.last_benchmark;
|
||||
|
||||
if (!snapshot || !snapshot.network_interfaces_json) {
|
||||
container.innerHTML = '<p style="color: var(--text-muted);">Aucune information réseau disponible</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const interfaces = JSON.parse(snapshot.network_interfaces_json);
|
||||
|
||||
if (!interfaces || interfaces.length === 0) {
|
||||
container.innerHTML = '<p style="color: var(--text-muted);">Aucune interface réseau détectée</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '<div style="display: grid; gap: 1rem;">';
|
||||
|
||||
// Interface details
|
||||
interfaces.forEach(iface => {
|
||||
const typeIcon = iface.type === 'ethernet' ? '🔌' : (iface.type === 'wifi' ? '📡' : '🌐');
|
||||
const wol = iface.wake_on_lan;
|
||||
const wolBadge = wol === true
|
||||
? '<span class="badge badge-success" style="margin-left: 0.5rem;">WoL ✓</span>'
|
||||
: (wol === false ? '<span class="badge badge-muted" style="margin-left: 0.5rem;">WoL ✗</span>' : '');
|
||||
|
||||
html += `
|
||||
<div class="hardware-item" style="border: 1px solid var(--border-color); border-radius: 8px; padding: 1rem;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 0.75rem;">
|
||||
<div>
|
||||
<div style="font-weight: 600; color: var(--color-primary);">${typeIcon} ${escapeHtml(iface.name)}</div>
|
||||
<div style="color: var(--text-secondary); font-size: 0.9rem; margin-top: 0.25rem;">${escapeHtml(iface.type || 'unknown')}</div>
|
||||
</div>
|
||||
<div>${wolBadge}</div>
|
||||
</div>
|
||||
|
||||
<div style="display: grid; gap: 0.5rem; font-size: 0.9rem;">
|
||||
${iface.ip ? `<div><strong>IP:</strong> ${escapeHtml(iface.ip)}</div>` : ''}
|
||||
${iface.mac ? `<div><strong>MAC:</strong> <code>${escapeHtml(iface.mac)}</code></div>` : ''}
|
||||
${iface.speed_mbps ? `<div><strong>Vitesse:</strong> ${iface.speed_mbps} Mbps</div>` : ''}
|
||||
${iface.driver ? `<div><strong>Driver:</strong> ${escapeHtml(iface.driver)}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
// Network benchmark results (iperf3)
|
||||
if (bench && bench.network_score !== null && bench.network_score !== undefined) {
|
||||
let netBenchHtml = '<div style="border: 2px solid var(--color-info); border-radius: 8px; padding: 1rem; margin-top: 1rem;">';
|
||||
netBenchHtml += '<div style="font-weight: 600; color: var(--color-info); margin-bottom: 0.75rem;">📈 Résultats Benchmark Réseau (iperf3)</div>';
|
||||
netBenchHtml += '<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1rem;">';
|
||||
|
||||
// Try to parse network_results_json if available
|
||||
let uploadMbps = null;
|
||||
let downloadMbps = null;
|
||||
let pingMs = null;
|
||||
|
||||
if (bench.network_results_json) {
|
||||
try {
|
||||
const netResults = typeof bench.network_results_json === 'string'
|
||||
? JSON.parse(bench.network_results_json)
|
||||
: bench.network_results_json;
|
||||
uploadMbps = netResults.upload_mbps;
|
||||
downloadMbps = netResults.download_mbps;
|
||||
pingMs = netResults.ping_ms;
|
||||
} catch (e) {
|
||||
console.warn('Failed to parse network_results_json:', e);
|
||||
}
|
||||
}
|
||||
|
||||
if (uploadMbps !== null && uploadMbps !== undefined) {
|
||||
netBenchHtml += `
|
||||
<div style="text-align: center;">
|
||||
<div style="font-size: 1.5rem; font-weight: 600; color: var(--color-success);">↑ ${uploadMbps.toFixed(2)}</div>
|
||||
<div style="color: var(--text-secondary); font-size: 0.85rem;">Upload Mbps</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
if (downloadMbps !== null && downloadMbps !== undefined) {
|
||||
netBenchHtml += `
|
||||
<div style="text-align: center;">
|
||||
<div style="font-size: 1.5rem; font-weight: 600; color: var(--color-info);">↓ ${downloadMbps.toFixed(2)}</div>
|
||||
<div style="color: var(--text-secondary); font-size: 0.85rem;">Download Mbps</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
if (pingMs !== null && pingMs !== undefined) {
|
||||
netBenchHtml += `
|
||||
<div style="text-align: center;">
|
||||
<div style="font-size: 1.5rem; font-weight: 600; color: var(--color-warning);">${typeof pingMs === 'number' ? pingMs.toFixed(2) : pingMs}</div>
|
||||
<div style="color: var(--text-secondary); font-size: 0.85rem;">Ping ms</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
netBenchHtml += `
|
||||
<div style="text-align: center;">
|
||||
<div style="font-size: 1.5rem; font-weight: 600; color: var(--color-primary);">${bench.network_score.toFixed(2)}</div>
|
||||
<div style="color: var(--text-secondary); font-size: 0.85rem;">Score</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
netBenchHtml += '</div></div>';
|
||||
html += netBenchHtml;
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
container.innerHTML = html;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to parse network interfaces:', error);
|
||||
container.innerHTML = '<p style="color: var(--text-danger);">Erreur lors du parsing des données réseau</p>';
|
||||
}
|
||||
}
|
||||
|
||||
// Load benchmark history
|
||||
async function loadBenchmarkHistory() {
|
||||
const container = document.getElementById('benchmarkHistory');
|
||||
|
||||
Reference in New Issue
Block a user