Dashboard admin : split stats/disk + preload disk au warmup + wc -l (1.85s -> 40ms)

This commit is contained in:
unfr
2026-04-24 08:48:29 +02:00
parent bd8e4e5228
commit 54b6cc453e
4 changed files with 100 additions and 72 deletions

View File

@@ -72,22 +72,62 @@ function setRefreshStatus(text) {
$('#refresh-status').textContent = text;
}
function renderDisk(disk) {
const max = Math.max(
disk.movie_b,
disk.tv_b,
disk.justwatch_movie_b,
disk.justwatch_tv_b,
disk.ratings_b,
1,
);
const rows = [
['Films (détails TMDB)', disk.movie_b, ''],
['Séries (détails TMDB)', disk.tv_b, 'tv'],
['Providers films', disk.justwatch_movie_b, 'jwmovie'],
['Providers séries', disk.justwatch_tv_b, 'jwtv'],
['IMDb ratings', disk.ratings_b, 'ratings'],
];
$('#disk-bars').innerHTML = `${rows
.map(
([label, b, cls]) => `
<div class="disk-row">
<span class="label">${label}</span>
<div class="disk-bar ${cls}"><span style="width:${(b / max) * 100}%"></span></div>
<span class="size">${fmtBytes(b)}</span>
</div>`,
)
.join('')}
<div class="disk-row" style="margin-top:6px;border-top:1px solid var(--border);padding-top:10px">
<span class="label" style="color:var(--text)">Total</span><div></div>
<span class="size" style="color:var(--text);font-weight:600">${fmtBytes(disk.total_b)}</span>
</div>`;
}
// ---- Dashboard ------------------------------------------------------------
async function loadStats() {
setRefreshStatus('Chargement…');
// Fast endpoint first; disk runs in parallel and fills in once ready.
const statsP = fetch('/admin/api/stats').then((r) => {
if (r.status === 401) {
location.reload();
throw new Error('auth');
}
return r.json();
});
const diskP = fetch('/admin/api/disk').then((r) => (r.ok ? r.json() : null));
let data;
try {
const res = await fetch('/admin/api/stats');
if (res.status === 401) {
location.reload();
return;
}
data = await res.json();
data = await statsP;
} catch (err) {
setRefreshStatus(`Erreur : ${err.message}`);
if (err.message !== 'auth') setRefreshStatus(`Erreur : ${err.message}`);
return;
}
// Schedule disk render independently (don't block the rest of the UI).
diskP.then((disk) => disk && renderDisk(disk)).catch(() => {});
$('#disk-bars').innerHTML =
'<div class="status loading" style="padding:20px">Calcul des tailles disque…</div>';
// Cron card
const cronEl = $('#cron-status');
@@ -120,39 +160,7 @@ async function loadStats() {
$('#process-uptime').textContent = `Uptime : ${fmtUptime(data.process.uptime_s)}`;
$('#process-node').textContent = `Node ${data.process.node} · pid ${data.process.pid}`;
// Disk bars
const disk = data.data.disk;
const max = Math.max(
disk.movie_b,
disk.tv_b,
disk.justwatch_movie_b,
disk.justwatch_tv_b,
disk.ratings_b,
1,
);
const rows = [
['Films (détails TMDB)', disk.movie_b, ''],
['Séries (détails TMDB)', disk.tv_b, 'tv'],
['Providers films', disk.justwatch_movie_b, 'jwmovie'],
['Providers séries', disk.justwatch_tv_b, 'jwtv'],
['IMDb ratings', disk.ratings_b, 'ratings'],
];
$('#disk-bars').innerHTML =
rows
.map(
([label, b, cls]) => `
<div class="disk-row">
<span class="label">${label}</span>
<div class="disk-bar ${cls}"><span style="width:${(b / max) * 100}%"></span></div>
<span class="size">${fmtBytes(b)}</span>
</div>
`,
)
.join('') +
`<div class="disk-row" style="margin-top:6px;border-top:1px solid var(--border);padding-top:10px">
<span class="label" style="color:var(--text)">Total</span><div></div>
<span class="size" style="color:var(--text);font-weight:600">${fmtBytes(disk.total_b)}</span>
</div>`;
// (disk handled in renderDisk via diskP)
// Cron summary
const sum = data.cron.log_summary;