This commit is contained in:
2026-06-18 09:37:29 +03:00
parent 21fb4704a6
commit db5f174ef3
20 changed files with 534 additions and 10 deletions
+93
View File
@@ -39,6 +39,7 @@ $$(".tab").forEach(tab => {
tab.classList.add("active");
$("#tab-" + tab.dataset.tab).classList.add("active");
if (tab.dataset.tab === "network") loadNetwork();
if (tab.dataset.tab === "system") loadSystem();
if (tab.dataset.tab === "update") loadUpdateStatus();
});
});
@@ -278,6 +279,98 @@ $("#net-apply")?.addEventListener("click", async () => {
} catch (e) { flash(e.message, true); }
});
// ---------- System ----------
let systemPollTimer = null;
function formatKb(kb) {
if (kb >= 1 << 20) return (kb / (1 << 20)).toFixed(1) + " ГБ";
if (kb >= 1 << 10) return (kb / (1 << 10)).toFixed(0) + " МБ";
return kb + " КБ";
}
function renderSystemStats(s) {
const el = $("#sys-stats");
if (!el) return;
const cpu = s.cpu_percent != null ? s.cpu_percent + "%" : "—";
const mem = s.memory || {};
el.innerHTML = `
<div class="sys-grid">
<div class="sys-tile"><span>Часы</span><strong>${s.clock || "—"}</strong></div>
<div class="sys-tile"><span>Аптайм</span><strong>${s.uptime || "—"}</strong></div>
<div class="sys-tile"><span>CPU</span><strong>${cpu}</strong></div>
<div class="sys-tile"><span>Память</span><strong>${mem.used_percent ?? "—"}%</strong>
<small>${formatKb(mem.used_kb || 0)} / ${formatKb(mem.total_kb || 0)}</small></div>
</div>`;
const clockEl = $("#sys-clock");
if (clockEl && s.clock) clockEl.textContent = "Текущее время: " + s.clock;
}
function renderButtonLog(entries) {
const body = $("#sys-log-body");
if (!body) return;
if (!entries || !entries.length) {
body.innerHTML = '<tr><td colspan="6" class="empty-cell">Нажатий пока нет</td></tr>';
return;
}
body.innerHTML = entries.map(e => {
const ok = e.ok;
const result = ok
? (e.http ? `OK ${e.http}` : "OK") + (e.message ? `${e.message}` : "")
: (e.http ? `ERR ${e.http}` : "ERR") + (e.message ? `${e.message}` : "");
return `
<tr>
<td>${e.ts || "—"}</td>
<td>${e.label || "—"}</td>
<td>${e.method || "—"}</td>
<td class="log-path" title="${e.url || ""}">${e.url || "—"}</td>
<td class="${ok ? "log-ok" : "log-err"}">${result}</td>
<td>${e.ms != null ? e.ms : "—"}</td>
</tr>`;
}).join("");
}
async function loadSystem() {
try {
const [stats, blog] = await Promise.all([
api("GET", "/api/system/stats"),
api("GET", "/api/system/button-log"),
]);
renderSystemStats(stats);
renderButtonLog(blog.entries);
const dtInput = $("#sys-datetime");
if (dtInput && stats.clock && !dtInput.dataset.touched) {
dtInput.value = stats.clock.replace(" ", "T").slice(0, 16);
}
} catch (e) {
const el = $("#sys-stats");
if (el) el.textContent = e.message;
}
if (!systemPollTimer) {
systemPollTimer = setInterval(() => {
if ($("#tab-system")?.classList.contains("active")) loadSystem();
}, 3000);
}
}
$("#sys-datetime")?.addEventListener("input", (e) => {
e.target.dataset.touched = "1";
});
$("#sys-set-time")?.addEventListener("click", async () => {
const raw = $("#sys-datetime")?.value;
if (!raw) { flash("Укажите дату и время", true); return; }
const dt = raw.replace("T", " ") + ":00";
try {
const r = await api("POST", "/api/system/time", { datetime: dt });
flash("Время установлено: " + r.datetime);
const dtInput = $("#sys-datetime");
if (dtInput) delete dtInput.dataset.touched;
loadSystem();
} catch (e) { flash(e.message, true); }
});
$("#sys-refresh")?.addEventListener("click", loadSystem);
// ---------- Update / OTA ----------
let updatePollTimer = null;