Files
intrusion-detection/app/templates/dashboard.html
T

103 lines
2.8 KiB
HTML

{% extends "base.html" %} {% block title %}Dashboard — Intrusion Detection{%
endblock %} {% block content %}
<h1>Dashboard</h1>
<p class="muted">
Localhost-only control panel for the intrusion detection scanner.
</p>
<div class="cards" id="status-cards"></div>
<div class="panel">
<div class="panel-head">
<h2>Latest scans</h2>
<a class="btn ghost" href="/scan">Run a scan →</a>
</div>
<table class="table">
<thead>
<tr>
<th>Job</th>
<th>Kind</th>
<th>State</th>
<th>Started</th>
<th>Finished</th>
<th class="num">Blocked</th>
</tr>
</thead>
<tbody id="latest-scans"></tbody>
</table>
</div>
{% endblock %} {% block scripts %}
<script>
async function loadDashboard() {
try {
const s = await api("/api/status");
renderCards(s);
renderScans(s.latest_scans || []);
} catch (e) {
toast(e.message, "error");
}
}
function renderCards(s) {
const cards = [
{
label: "Scan running",
value: s.scan_running ? "Yes" : "No",
tone: s.scan_running ? "warn" : "ok",
},
{ label: "Blocklist IPv4", value: s.blocklist_ipv4_count ?? "—" },
{ label: "Blocklist IPv6", value: s.blocklist_ipv6_count ?? "—" },
{
label: "Firewall snapshot",
value:
s.firewall_snapshot && s.firewall_snapshot.exists
? "Present"
: "None",
tone:
s.firewall_snapshot && s.firewall_snapshot.exists ? "ok" : "muted",
},
];
const box = document.getElementById("status-cards");
box.innerHTML = "";
for (const c of cards) {
box.append(
el(
"div",
{ class: "card" },
el("div", { class: "card-label", text: c.label }),
el("div", { class: `card-value ${c.tone || ""}`, text: c.value }),
),
);
}
}
function renderScans(scans) {
const body = document.getElementById("latest-scans");
body.innerHTML = "";
if (!scans.length) {
body.innerHTML =
'<tr><td colspan="6" class="muted">No scans yet — run one from the Scan page.</td></tr>';
return;
}
for (const j of scans) {
const r = j.result || {};
body.append(
el(
"tr",
el("td", { class: "mono", text: j.job_id }),
el("td", { text: j.kind }),
el("td", {}, badge(j.state)),
el("td", { text: fmtTime(j.started) }),
el("td", { text: fmtTime(j.finished) }),
el("td", { class: "num", text: r.blocked_targets ?? "—" }),
),
);
}
}
loadDashboard();
// Keep the latest-scans table fresh without hammering /api/scan/status.
setInterval(loadDashboard, 15000);
</script>
{% endblock %}