Merge claude/1

This commit is contained in:
librelad 2026-06-18 16:15:15 +01:00
commit f4784b5fc1

View File

@ -282,8 +282,7 @@ class ServicesManager {
_renderRichDetail(info) { _renderRichDetail(info) {
if (!info || !info.detail) return ''; if (!info || !info.detail) return '';
const d = info.detail; const d = info.detail;
const fmt = window.SystemFmt; const fmt = window.SystemFmt || SVC_FMT;
if (!fmt) return '';
const lim = d.limits || {}; const lim = d.limits || {};
const memLimit = lim.memory || 0; const memLimit = lim.memory || 0;
const cpuLimit = lim.nano_cpus const cpuLimit = lim.nano_cpus
@ -350,7 +349,7 @@ class ServicesManager {
const stats = info?.stats; const stats = info?.stats;
const detail = info?.detail; const detail = info?.detail;
const memLimit = detail?.limits?.memory || 0; const memLimit = detail?.limits?.memory || 0;
const fmt = window.SystemFmt; const fmt = window.SystemFmt || SVC_FMT;
const cpuEl = item.querySelector('[data-svc-live="cpu"]'); const cpuEl = item.querySelector('[data-svc-live="cpu"]');
const memEl = item.querySelector('[data-svc-live="mem"]'); const memEl = item.querySelector('[data-svc-live="mem"]');
if (cpuEl) cpuEl.textContent = stats ? `${(stats.cpu_percent ?? 0).toFixed(1)}% CPU` : '—'; if (cpuEl) cpuEl.textContent = stats ? `${(stats.cpu_percent ?? 0).toFixed(1)}% CPU` : '—';
@ -411,7 +410,7 @@ class ServicesManager {
const stats = info.stats; const stats = info.stats;
const detail = info.detail; const detail = info.detail;
const memLimit = detail?.limits?.memory || 0; const memLimit = detail?.limits?.memory || 0;
const fmt = window.SystemFmt; const fmt = window.SystemFmt || SVC_FMT;
const cpuTxt = stats ? `${(stats.cpu_percent ?? 0).toFixed(1)}% CPU` : '—'; const cpuTxt = stats ? `${(stats.cpu_percent ?? 0).toFixed(1)}% CPU` : '—';
const memUsed = stats?.memory?.used ?? 0; const memUsed = stats?.memory?.used ?? 0;
const memPct = memLimit > 0 ? (memUsed / memLimit) * 100 : (stats?.memory?.percent ?? 0); const memPct = memLimit > 0 ? (memUsed / memLimit) * 100 : (stats?.memory?.percent ?? 0);
@ -804,6 +803,34 @@ class ServicesManager {
// Tiny helpers ---------------------------------------------------------- // Tiny helpers ----------------------------------------------------------
// Number/time formatters for the rich detail panel + live stat chips. Mirrors
// the admin System page's window.SystemFmt, but owned here so the Services tab
// renders its advanced detail even when that page module hasn't loaded — it's
// lazy, so visiting /admin/system must NOT be a prerequisite for this tab.
// Prefer window.SystemFmt when present so both surfaces share one implementation.
const SVC_FMT = {
bytes(n) {
n = Number(n) || 0;
const u = ['B', 'KB', 'MB', 'GB', 'TB']; let i = 0;
while (n >= 1024 && i < u.length - 1) { n /= 1024; i++; }
return `${n.toFixed(i ? 1 : 0)} ${u[i]}`;
},
rate(n) { return `${this.bytes(n)}/s`; },
timeAgo(unixSec) {
if (!unixSec) return '';
const diff = Math.floor(Date.now() / 1000) - unixSec;
if (diff < 60) return `${diff}s ago`;
if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;
return `${Math.floor(diff / 86400)}d ago`;
},
timeAgoIso(iso) {
if (!iso) return '';
const t = Math.floor(new Date(iso).getTime() / 1000);
return Number.isFinite(t) && t > 0 ? this.timeAgo(t) : '';
},
};
function escapeHtml(s) { function escapeHtml(s) {
return String(s ?? '') return String(s ?? '')
.replace(/&/g, '&amp;') .replace(/&/g, '&amp;')