++ fix grafico
This commit is contained in:
@@ -35,16 +35,22 @@
|
||||
|
||||
<section class="log-panel mt-4 p-3 p-md-4">
|
||||
<div class="d-flex align-items-center justify-content-between mb-3">
|
||||
<h2 class="h4 mb-0">Attivita Recenti</h2>
|
||||
<span class="pill">UTC</span>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<h2 class="h4 mb-0">Attivita Recenti</h2>
|
||||
<span id="liveIndicator" class="live-dot d-none"></span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<span id="logCount" class="pill">0 eventi</span>
|
||||
<span class="pill">UTC</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<div class="log-scroll">
|
||||
<table class="table table-dark table-borderless align-middle mb-0" id="logsTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ora</th>
|
||||
<th>Livello</th>
|
||||
<th>Job</th>
|
||||
<th style="width:160px">Ora</th>
|
||||
<th style="width:90px">Livello</th>
|
||||
<th style="width:130px">Job</th>
|
||||
<th>Messaggio</th>
|
||||
<th>Dettagli</th>
|
||||
</tr>
|
||||
@@ -69,15 +75,20 @@
|
||||
return new Date(value).toLocaleString();
|
||||
}
|
||||
|
||||
function fmtSummary(summary) {
|
||||
if (!summary || Object.keys(summary).length === 0) {
|
||||
return 'Nessuna esecuzione';
|
||||
function fmtSummary(summary, running) {
|
||||
if (running) {
|
||||
return '<span class="sync-in-progress">▶ Sincronizzazione in corso…</span>';
|
||||
}
|
||||
if (!summary || Object.keys(summary).length === 0) {
|
||||
return '<span class="text-secondary">Nessuna esecuzione ancora</span>';
|
||||
}
|
||||
const labels = { downloaded: 'scaricati', kept: 'invariati', deleted: 'eliminati', errors: 'errori', trigger: 'avviato da', error: 'errore' };
|
||||
const parts = [];
|
||||
for (const [key, val] of Object.entries(summary)) {
|
||||
parts.push(`${key}: ${val}`);
|
||||
const label = labels[key] || key;
|
||||
parts.push(`<span class="summary-kv"><span class="summary-key">${label}</span> ${val}</span>`);
|
||||
}
|
||||
return parts.join(' | ');
|
||||
return parts.join('');
|
||||
}
|
||||
|
||||
function statusClass(status, running) {
|
||||
@@ -112,7 +123,7 @@
|
||||
<div>Ultima fine: ${fmtDate(job.last_end)}</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 summary-box mono small">${fmtSummary(job.last_summary)}</div>
|
||||
<div class="mt-3 summary-box mono small">${fmtSummary(job.last_summary, job.running)}</div>
|
||||
|
||||
<div class="mt-3 d-flex gap-2">
|
||||
<button class="btn btn-outline-light btn-sm" data-job="${job.name}">Avvia ora</button>
|
||||
@@ -135,21 +146,37 @@
|
||||
});
|
||||
}
|
||||
|
||||
let prevLogTime = null;
|
||||
|
||||
function renderLogs(logs) {
|
||||
const tbody = document.querySelector('#logsTable tbody');
|
||||
tbody.innerHTML = '';
|
||||
const entries = logs.slice(0, 200);
|
||||
const newTopTime = entries.length > 0 ? entries[0].time : null;
|
||||
const hasNew = newTopTime && newTopTime !== prevLogTime;
|
||||
prevLogTime = newTopTime;
|
||||
|
||||
logs.slice(0, 120).forEach((entry) => {
|
||||
tbody.innerHTML = '';
|
||||
entries.forEach((entry, i) => {
|
||||
const tr = document.createElement('tr');
|
||||
if (hasNew && i < 3) tr.classList.add('row-new');
|
||||
tr.innerHTML = `
|
||||
<td class="mono small">${fmtDate(entry.time)}</td>
|
||||
<td><span class="pill level-${entry.level.toLowerCase()}">${entry.level}</span></td>
|
||||
<td class="mono small">${entry.job || '-'}</td>
|
||||
<td>${entry.message}</td>
|
||||
<td class="mono small">${JSON.stringify(entry.details || {})}</td>
|
||||
<td class="mono small text-truncate" style="max-width:260px" title="${encodeURIComponent(JSON.stringify(entry.details || {})).replace(/'/g,"'").replace(/%/g,'%')}">` +
|
||||
JSON.stringify(entry.details || {}) +
|
||||
`</td>
|
||||
`;
|
||||
tbody.appendChild(tr);
|
||||
});
|
||||
|
||||
document.getElementById('logCount').textContent = entries.length + ' eventi';
|
||||
|
||||
if (hasNew) {
|
||||
const scroll = document.querySelector('.log-scroll');
|
||||
scroll.scrollTop = 0;
|
||||
}
|
||||
}
|
||||
|
||||
async function reload() {
|
||||
@@ -158,6 +185,13 @@
|
||||
document.getElementById('serverTime').textContent = `Server UTC: ${fmtDate(data.server_time)}`;
|
||||
renderJobs(data.jobs || []);
|
||||
renderLogs(data.logs || []);
|
||||
const anyRunning = (data.jobs || []).some(j => j.running);
|
||||
const dot = document.getElementById('liveIndicator');
|
||||
if (anyRunning) {
|
||||
dot.classList.remove('d-none');
|
||||
} else {
|
||||
dot.classList.add('d-none');
|
||||
}
|
||||
} catch (err) {
|
||||
document.getElementById('serverTime').textContent = `Errore: ${err.message}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user