105 lines
4.1 KiB
JavaScript
105 lines
4.1 KiB
JavaScript
|
|
(() => {
|
||
|
|
const menuController = window.WarpBoxUI?.bindMenuBar?.() || { close() {} };
|
||
|
|
const dataNode = document.getElementById("activity-data");
|
||
|
|
const body = document.getElementById("activity-body");
|
||
|
|
const searchInput = document.getElementById("activity-search");
|
||
|
|
const severityFilter = document.getElementById("activity-severity");
|
||
|
|
const kindFilter = document.getElementById("activity-kind");
|
||
|
|
const statusLeft = document.getElementById("activity-status-left");
|
||
|
|
const toast = document.getElementById("toast");
|
||
|
|
|
||
|
|
if (!dataNode || !body || !searchInput) return;
|
||
|
|
const events = parseData();
|
||
|
|
|
||
|
|
function parseData() {
|
||
|
|
try {
|
||
|
|
return JSON.parse(dataNode.textContent || "[]");
|
||
|
|
} catch (_) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function showToast(message, type = "info", duration = 1800) {
|
||
|
|
window.WarpBoxUI?.toast?.(message, type, { target: toast, duration });
|
||
|
|
}
|
||
|
|
|
||
|
|
function renderKindFilter() {
|
||
|
|
const kinds = new Set(events.map((event) => event.kind || "unknown"));
|
||
|
|
Array.from(kinds).sort().forEach((kind) => {
|
||
|
|
const option = document.createElement("option");
|
||
|
|
option.value = kind;
|
||
|
|
option.textContent = kind;
|
||
|
|
kindFilter.appendChild(option);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function createdLabel(value) {
|
||
|
|
const parsed = new Date(value);
|
||
|
|
if (Number.isNaN(parsed.getTime())) return "-";
|
||
|
|
return parsed.toISOString().replace("T", " ").slice(0, 16) + " UTC";
|
||
|
|
}
|
||
|
|
|
||
|
|
function filtered() {
|
||
|
|
const query = searchInput.value.trim().toLowerCase();
|
||
|
|
const severity = severityFilter.value;
|
||
|
|
const kind = kindFilter.value;
|
||
|
|
return events.filter((event) => {
|
||
|
|
const haystack = [event.kind, event.message, event.ip, event.path, event.method].join(" ").toLowerCase();
|
||
|
|
const matchesQuery = !query || haystack.includes(query);
|
||
|
|
const matchesSeverity = severity === "all" || event.severity === severity;
|
||
|
|
const matchesKind = kind === "all" || event.kind === kind;
|
||
|
|
return matchesQuery && matchesSeverity && matchesKind;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
function render() {
|
||
|
|
const rows = filtered();
|
||
|
|
body.innerHTML = "";
|
||
|
|
rows.forEach((event) => {
|
||
|
|
const row = document.createElement("tr");
|
||
|
|
row.innerHTML = `
|
||
|
|
<td>${createdLabel(event.created_at)}</td>
|
||
|
|
<td>${escapeHtml(event.kind || "-")}</td>
|
||
|
|
<td>${escapeHtml(event.severity || "-")}</td>
|
||
|
|
<td>${escapeHtml(event.ip || "-")}</td>
|
||
|
|
<td>${escapeHtml(event.method || "-")}</td>
|
||
|
|
<td title="${escapeHtml(event.path || "-")}">${escapeHtml(event.path || "-")}</td>
|
||
|
|
<td title="${escapeHtml(event.message || "-")}">${escapeHtml(event.message || "-")}</td>
|
||
|
|
`;
|
||
|
|
body.appendChild(row);
|
||
|
|
});
|
||
|
|
statusLeft.textContent = `${rows.length} activity event(s) visible`;
|
||
|
|
}
|
||
|
|
|
||
|
|
function escapeHtml(value) {
|
||
|
|
return window.WarpBoxUI?.htmlEscape?.(value) || String(value ?? "");
|
||
|
|
}
|
||
|
|
|
||
|
|
[searchInput, severityFilter, kindFilter].forEach((element) => {
|
||
|
|
element.addEventListener(element.tagName === "INPUT" ? "input" : "change", render);
|
||
|
|
});
|
||
|
|
|
||
|
|
document.querySelectorAll("[data-command]").forEach((button) => {
|
||
|
|
button.addEventListener("click", () => {
|
||
|
|
menuController.close();
|
||
|
|
if (button.dataset.command === "refresh") {
|
||
|
|
window.location.reload();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (button.dataset.command === "export") {
|
||
|
|
const blob = new Blob([JSON.stringify(filtered(), null, 2)], { type: "application/json;charset=utf-8" });
|
||
|
|
const url = URL.createObjectURL(blob);
|
||
|
|
const anchor = document.createElement("a");
|
||
|
|
anchor.href = url;
|
||
|
|
anchor.download = `warpbox-activity-${new Date().toISOString().replaceAll(":", "-")}.json`;
|
||
|
|
anchor.click();
|
||
|
|
URL.revokeObjectURL(url);
|
||
|
|
showToast("Visible activity exported");
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
renderKindFilter();
|
||
|
|
render();
|
||
|
|
})();
|