This commit is contained in:
2025-12-20 03:47:10 +01:00
parent 8428bf9c82
commit dcba044cd6
179 changed files with 10345 additions and 786 deletions

152
frontend/js/device_detail.js Normal file → Executable file
View File

@@ -1,6 +1,6 @@
// Linux BenchTools - Device Detail Logic
const { formatDate, formatRelativeTime, formatFileSize, createScoreBadge, getScoreBadgeText, escapeHtml, showError, showEmptyState, formatTags, initTabs, openModal, showToast, formatHardwareInfo } = window.BenchUtils;
const { formatDate, formatRelativeTime, formatFileSize, createScoreBadge, getScoreBadgeText, escapeHtml, showError, showEmptyState, formatTags, initTabs, openModal, showToast, formatHardwareInfo, formatDuration, formatStorage } = window.BenchUtils;
const api = window.BenchAPI;
let currentDeviceId = null;
@@ -46,6 +46,11 @@ async function loadDeviceDetail() {
await loadDocuments();
await loadLinks();
const deleteBtn = document.getElementById('deleteDeviceBtn');
if (deleteBtn) {
deleteBtn.addEventListener('click', handleDeleteDevice);
}
} catch (error) {
console.error('Failed to load device:', error);
document.getElementById('loadingState').innerHTML =
@@ -300,7 +305,7 @@ function renderStorageDetails() {
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.75rem; font-size: 0.9rem;">
${disk.capacity_gb ? `
<div>
<strong>Capacité:</strong> ${disk.capacity_gb} GB
<strong>Capacité:</strong> ${formatStorage(disk.capacity_gb)}
</div>
` : ''}
${disk.type ? `
@@ -331,7 +336,114 @@ function renderStorageDetails() {
console.error('Failed to parse storage devices:', e);
html = '<p style="color: var(--text-danger);">Erreur lors du parsing des données de stockage</p>';
}
} else {
}
// Parse partitions
if (snapshot.partitions_json) {
try {
const partitions = typeof snapshot.partitions_json === 'string'
? JSON.parse(snapshot.partitions_json)
: snapshot.partitions_json;
if (Array.isArray(partitions) && partitions.length > 0) {
html += `
<div style="margin-top: 1.5rem;">
<h4 style="margin-bottom: 0.75rem; color: var(--text-secondary);">Partitions et volumes</h4>
<div style="overflow-x: auto;">
<table style="width: 100%; border-collapse: collapse;">
<thead>
<tr style="text-align: left; border-bottom: 1px solid var(--border-color); color: var(--text-secondary);">
<th style="padding: 0.5rem;">Partition</th>
<th style="padding: 0.5rem;">Montage</th>
<th style="padding: 0.5rem;">Type</th>
<th style="padding: 0.5rem;">Utilisé</th>
<th style="padding: 0.5rem;">Libre</th>
<th style="padding: 0.5rem;">Total</th>
</tr>
</thead>
<tbody>
${partitions.map(part => {
const used = typeof part.used_gb === 'number' ? formatStorage(part.used_gb) : 'N/A';
const free = typeof part.free_gb === 'number'
? formatStorage(part.free_gb)
: (typeof part.total_gb === 'number' && typeof part.used_gb === 'number'
? formatStorage(part.total_gb - part.used_gb)
: 'N/A');
const total = typeof part.total_gb === 'number' ? formatStorage(part.total_gb) : 'N/A';
return `
<tr style="border-bottom: 1px solid var(--border-color);">
<td style="padding: 0.5rem; font-weight: 600;">${escapeHtml(part.name || 'N/A')}</td>
<td style="padding: 0.5rem;">${part.mount_point ? escapeHtml(part.mount_point) : '<span style="color: var(--text-muted);">Non monté</span>'}</td>
<td style="padding: 0.5rem;">${part.fs_type ? escapeHtml(part.fs_type) : 'N/A'}</td>
<td style="padding: 0.5rem;">${used}</td>
<td style="padding: 0.5rem;">${free}</td>
<td style="padding: 0.5rem;">${total}</td>
</tr>
`;
}).join('')}
</tbody>
</table>
</div>
</div>
`;
}
} catch (error) {
console.error('Failed to parse partitions:', error);
html += '<p style="color: var(--color-danger); margin-top: 1rem;">Erreur lors de la lecture des partitions</p>';
}
}
if (snapshot.network_shares_json) {
try {
const shares = typeof snapshot.network_shares_json === 'string'
? JSON.parse(snapshot.network_shares_json)
: snapshot.network_shares_json;
if (Array.isArray(shares) && shares.length > 0) {
html += `
<div style="margin-top: 1.5rem;">
<h4 style="margin-bottom: 0.75rem; color: var(--text-secondary);">Partages réseau montés</h4>
<div style="overflow-x: auto;">
<table style="width: 100%; border-collapse: collapse;">
<thead>
<tr style="text-align: left; border-bottom: 1px solid var(--border-color); color: var(--text-secondary);">
<th style="padding: 0.5rem;">Source</th>
<th style="padding: 0.5rem;">Montage</th>
<th style="padding: 0.5rem;">Protocole</th>
<th style="padding: 0.5rem;">Type</th>
<th style="padding: 0.5rem;">Utilisé</th>
<th style="padding: 0.5rem;">Libre</th>
<th style="padding: 0.5rem;">Total</th>
<th style="padding: 0.5rem;">Options</th>
</tr>
</thead>
<tbody>
${shares.map(share => `
<tr style="border-bottom: 1px solid var(--border-color);">
<td style="padding: 0.5rem;">${escapeHtml(share.source || 'N/A')}</td>
<td style="padding: 0.5rem;">${escapeHtml(share.mount_point || 'N/A')}</td>
<td style="padding: 0.5rem;">${escapeHtml(share.protocol || share.fs_type || 'N/A')}</td>
<td style="padding: 0.5rem;">${share.fs_type ? escapeHtml(share.fs_type) : 'N/A'}</td>
<td style="padding: 0.5rem;">${typeof share.used_gb === 'number' ? formatStorage(share.used_gb) : 'N/A'}</td>
<td style="padding: 0.5rem;">${typeof share.free_gb === 'number' ? formatStorage(share.free_gb) : 'N/A'}</td>
<td style="padding: 0.5rem;">${typeof share.total_gb === 'number' ? formatStorage(share.total_gb) : 'N/A'}</td>
<td style="padding: 0.5rem; max-width: 200px;">${share.options ? escapeHtml(share.options) : '<span style="color: var(--text-muted);">N/A</span>'}</td>
</tr>
`).join('')}
</tbody>
</table>
</div>
</div>
`;
}
} catch (error) {
console.error('Failed to parse network shares:', error);
html += '<p style="color: var(--color-danger); margin-top: 1rem;">Erreur lors de la lecture des partages réseau</p>';
}
}
if (!html) {
html = '<p style="color: var(--text-muted);">Aucune information de stockage disponible</p>';
}
@@ -407,11 +519,25 @@ function renderOSDetails() {
return;
}
const displayServer = snapshot.display_server || snapshot.session_type || 'N/A';
const resolution = snapshot.screen_resolution || 'N/A';
const lastBoot = snapshot.last_boot_time || 'N/A';
const uptime = snapshot.uptime_seconds != null ? formatDuration(snapshot.uptime_seconds) : 'N/A';
const battery = snapshot.battery_percentage != null
? `${snapshot.battery_percentage}%${snapshot.battery_status ? ` (${snapshot.battery_status})` : ''}`
: 'N/A';
const items = [
{ label: 'Nom', value: snapshot.os_name || 'N/A' },
{ label: 'Version', value: snapshot.os_version || 'N/A' },
{ label: 'Kernel', value: snapshot.kernel_version || 'N/A' },
{ label: 'Architecture', value: snapshot.architecture || 'N/A' },
{ label: 'Environnement', value: snapshot.desktop_environment || 'N/A' },
{ label: 'Session', value: displayServer },
{ label: 'Résolution écran', value: resolution },
{ label: 'Dernier boot', value: lastBoot },
{ label: 'Uptime', value: uptime },
{ label: 'Batterie', value: battery },
{ label: 'Virtualisation', value: snapshot.virtualization_type || 'none' }
];
@@ -427,6 +553,26 @@ function renderOSDetails() {
`;
}
async function handleDeleteDevice() {
if (!currentDevice) return;
const confirmed = confirm(`Voulez-vous vraiment supprimer le device "${currentDevice.hostname}" ? Cette action est définitive.`);
if (!confirmed) {
return;
}
try {
await api.deleteDevice(currentDevice.id);
showToast('Device supprimé avec succès', 'success');
setTimeout(() => {
window.location.href = 'devices.html';
}, 800);
} catch (error) {
console.error('Failed to delete device:', error);
showToast(error.message || 'Impossible de supprimer le device', 'error');
}
}
// Render Benchmark Results
function renderBenchmarkResults() {
const bench = currentDevice.last_benchmark;