Update app.js

This commit is contained in:
oliver
2026-06-15 09:12:22 -03:00
parent 9448cef053
commit 145079e344
+62 -19
View File
@@ -8,6 +8,7 @@ const ROUTES = {
instances: "/admin/instance", instances: "/admin/instance",
backup: "/admin/backup-repo", backup: "/admin/backup-repo",
servers: "/admin/server", servers: "/admin/server",
seats: "/server",
keys: "/admin/key", keys: "/admin/key",
crm: "/crm", crm: "/crm",
}; };
@@ -918,6 +919,31 @@ async function serversLoadData() {
} }
}) })
.filter(Boolean); .filter(Boolean);
/* ─── Fetch seat data ─────────────────────────────────────── */
let seatMap = {};
try {
const seatRes = await fetch("https://n8n.derez.ai/webhook/server");
if (seatRes.ok) {
const seatJson = await seatRes.json();
const seatArr = Array.isArray(seatJson)
? Array.isArray(seatJson[0]?.data)
? seatJson[0].data
: seatJson
: [];
for (const s of seatArr) {
if (s.server) seatMap[s.server.toLowerCase().trim()] = s;
}
}
} catch (_) {
/* seat data is optional */
}
/* ─── Merge seats into server data ─────────────────────────── */
for (const sv of serversData) {
const key = (sv.server?.name ?? "").toLowerCase().trim();
sv.seats = seatMap[key] || null;
}
if (serversData.length === 0) throw new Error("No server data in response"); if (serversData.length === 0) throw new Error("No server data in response");
currentServerIdx = 0; currentServerIdx = 0;
serversRenderTabs(); serversRenderTabs();
@@ -1090,9 +1116,6 @@ function serversRenderDashboard(idx) {
<div style="font-size:11px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.07em;margin-top:3px">Score</div> <div style="font-size:11px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.07em;margin-top:3px">Score</div>
</div> </div>
</div> </div>
<p style="font-size:13px;color:var(--text-muted);line-height:1.65;border-top:1px solid var(--border);padding-top:12px;margin:0">
${escHtml(summary.short_summary)}
</p>
</div> </div>
<!-- ─ CPU / Memory / Disk ───────────────────────────────── --> <!-- ─ CPU / Memory / Disk ───────────────────────────────── -->
@@ -1174,26 +1197,46 @@ function serversRenderDashboard(idx) {
<div style="font-size:11px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.07em;margin-bottom:6px">Exposed Ports</div> <div style="font-size:11px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.07em;margin-bottom:6px">Exposed Ports</div>
<div>${portsHtml}</div> <div>${portsHtml}</div>
<div style="font-size:12px;color:var(--text-muted);margin-top:8px">Vuln score: ${security.vulnerability_score ?? "—"}</div> <div style="font-size:12px;color:var(--text-muted);margin-top:8px">Vuln score: ${security.vulnerability_score ?? "—"}</div>
</div>
</div> </div>
</div> </div>
${
security.risk_flags?.length
? `
<div style="margin-top:12px;padding-top:10px;border-top:1px solid var(--border);display:flex;gap:6px;flex-wrap:wrap">
${security.risk_flags.map((f) => `<span class="badge badge-medium">${escHtml(f)}</span>`).join("")}
</div>`
: ""
}
</div>
<div class="card"> <div class="card">
<div class="card-title" style="margin-bottom:14px"> <div class="card-title" style="margin-bottom:14px">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/> <rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 3v18"/>
<polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/> </svg>
</svg> Seats
Containers </div>
${
s.seats
? `
<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;margin-bottom:14px">
<div>
<div class="dash-stat">${s.seats.Seats ?? "—"}</div>
<div class="dash-stat-sub">Total</div>
</div>
<div>
<div class="dash-stat">${s.seats["Seats taken"] ?? "—"}</div>
<div class="dash-stat-sub">Taken</div>
</div>
<div>
<div class="dash-stat" style="color:${(s.seats["Seats Available"] ?? 0) < 2 ? "var(--danger)" : (s.seats["Seats Available"] ?? 0) < 10 ? "var(--warning)" : "var(--success)"}">${s.seats["Seats Available"] ?? "—"}</div>
<div class="dash-stat-sub">Available</div>
</div>
</div>`
: `<div class="text-muted" style="font-size:13px;padding:8px 0">No seat data available</div>`
}
</div> </div>
<div class="card">
<div class="card-title" style="margin-bottom:14px">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/>
<polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/>
</svg>
Containers
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:14px"> <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:14px">
<div> <div>
<div class="dash-stat" style="color:${containers.running > 0 ? "var(--success)" : "var(--text-muted)"}">${containers.running}</div> <div class="dash-stat" style="color:${containers.running > 0 ? "var(--success)" : "var(--text-muted)"}">${containers.running}</div>