(() => { const menuController = window.WarpBoxUI?.bindMenuBar?.() || { close() { document.querySelectorAll(".menu-item.is-open").forEach((item) => { item.classList.remove("is-open"); item.querySelector(".menu-button")?.setAttribute("aria-expanded", "false"); }); } }; const toast = document.getElementById("toast"); const searchInput = document.getElementById("search-input"); const severityFilter = document.getElementById("severity-filter"); const statusFilter = document.getElementById("status-filter"); const sourceFilter = document.getElementById("source-filter"); const sortFilter = document.getElementById("sort-filter"); const alertsBody = document.getElementById("alerts-body"); const selectedCountEl = document.getElementById("selected-count"); const openCountEl = document.querySelector("[data-open-count]"); const highCountEl = document.querySelector("[data-high-count]"); const ackCountEl = document.querySelector("[data-ack-count]"); const closedCountEl = document.querySelector("[data-closed-count]"); const selectAll = document.getElementById("select-all"); const detailEls = { title: document.getElementById("detail-title"), severity: document.getElementById("detail-severity"), status: document.getElementById("detail-status"), code: document.getElementById("detail-code"), trace: document.getElementById("detail-trace"), time: document.getElementById("detail-time"), description: document.getElementById("detail-description"), metadata: document.getElementById("detail-metadata") }; if (!alertsBody || !searchInput || !statusFilter || !selectedCountEl) return; function showToast(message, type = "info", duration = 1800) { if (window.WarpBoxUI) { window.WarpBoxUI.toast(message, type, { target: toast, duration }); return; } if (!toast) return; toast.textContent = message; toast.classList.add("is-visible"); window.setTimeout(() => toast.classList.remove("is-visible"), duration); } function allRows() { return Array.from(alertsBody.querySelectorAll("tr")); } function visibleRows() { return allRows().filter((row) => row.style.display !== "none"); } function selectedRows() { return allRows().filter((row) => row.querySelector(".row-check")?.checked && row.style.display !== "none"); } function updateSelectedCount() { selectedCountEl.textContent = `Selected: ${selectedRows().length}`; } function updateSummaryCounts() { const rows = visibleRows(); openCountEl.textContent = String(rows.filter((row) => row.dataset.status === "open").length); highCountEl.textContent = String(rows.filter((row) => row.dataset.severity === "high" && row.dataset.status !== "closed").length); ackCountEl.textContent = String(rows.filter((row) => row.dataset.status === "acked").length); closedCountEl.textContent = String(rows.filter((row) => row.dataset.status === "closed").length); } function updateDetails(row) { if (!row) return; allRows().forEach((item) => item.classList.remove("is-selected")); row.classList.add("is-selected"); detailEls.title.textContent = row.dataset.title || ""; detailEls.severity.textContent = row.dataset.severity || ""; detailEls.status.textContent = row.dataset.status || ""; detailEls.code.textContent = row.dataset.code || ""; detailEls.trace.textContent = row.dataset.trace || ""; detailEls.time.textContent = row.dataset.time || ""; detailEls.description.textContent = row.dataset.description || ""; try { detailEls.metadata.textContent = JSON.stringify(JSON.parse(row.dataset.metadata || "{}"), null, 2); } catch (_) { detailEls.metadata.textContent = row.dataset.metadata || "{}"; } } function applyFilters() { const search = searchInput.value.trim().toLowerCase(); const severity = severityFilter.value; const status = statusFilter.value; const group = sourceFilter.value; allRows().forEach((row) => { const haystack = [ row.dataset.title, row.dataset.description, row.dataset.code, row.dataset.trace, row.dataset.group ].join(" ").toLowerCase(); const matchesSearch = !search || haystack.includes(search); const matchesSeverity = severity === "all" || row.dataset.severity === severity; const matchesStatus = status === "all" || row.dataset.status === status; const matchesGroup = group === "all" || row.dataset.group === group; row.style.display = matchesSearch && matchesSeverity && matchesStatus && matchesGroup ? "" : "none"; }); const order = { high: 3, medium: 2, low: 1 }; visibleRows().sort((a, b) => { if (sortFilter.value === "severity") return order[b.dataset.severity] - order[a.dataset.severity]; if (sortFilter.value === "oldest") return Number(a.dataset.id) - Number(b.dataset.id); return Number(b.dataset.id) - Number(a.dataset.id); }).forEach((row) => alertsBody.appendChild(row)); const selectedVisible = visibleRows().find((row) => row.classList.contains("is-selected")); if (!selectedVisible && visibleRows()[0]) updateDetails(visibleRows()[0]); updateSelectedCount(); updateSummaryCounts(); } function setRowStatus(row, nextStatus) { row.dataset.status = nextStatus; const statusCell = row.children[3]?.querySelector(".alerts-pill"); if (!statusCell) return; statusCell.className = `alerts-pill ${nextStatus}`; statusCell.textContent = nextStatus; } function changeSelectedStatus(nextStatus) { const rows = selectedRows(); if (!rows.length) { showToast("Select one or more alerts first", "warning"); return; } rows.forEach((row) => { setRowStatus(row, nextStatus); row.querySelector(".row-check").checked = false; }); if (selectAll) selectAll.checked = false; updateSelectedCount(); updateSummaryCounts(); const currentRow = visibleRows().find((row) => row.classList.contains("is-selected")) || visibleRows()[0]; if (currentRow) updateDetails(currentRow); showToast(nextStatus === "acked" ? "Selected alerts acknowledged" : "Selected alerts closed"); } const commandMessages = { refresh: "Alerts refreshed in mock view", export: "Visible alerts exported in mock view", "copy-meta": "Metadata copied in mock view", "help-codes": "Each alert code maps to a unique trigger point and trace identifier.", "help-meta": "Metadata explains why the alert happened and includes extra context." }; function runCommand(command) { switch (command) { case "ack": changeSelectedStatus("acked"); return; case "close": changeSelectedStatus("closed"); return; case "open-only": statusFilter.value = "open"; applyFilters(); showToast("Showing open alerts only"); return; default: showToast(commandMessages[command] || `Mock action: ${command}`); } } [searchInput, severityFilter, statusFilter, sourceFilter, sortFilter].forEach((control) => { control.addEventListener(control.tagName === "INPUT" ? "input" : "change", applyFilters); }); allRows().forEach((row) => { row.addEventListener("click", (event) => { if (event.target.closest("button") || event.target.closest("input")) return; updateDetails(row); }); row.querySelector(".row-open")?.addEventListener("click", () => updateDetails(row)); row.querySelector(".row-check")?.addEventListener("change", updateSelectedCount); }); selectAll?.addEventListener("change", () => { visibleRows().forEach((row) => { const checkbox = row.querySelector(".row-check"); if (checkbox) checkbox.checked = selectAll.checked; }); updateSelectedCount(); }); document.querySelectorAll("[data-command]").forEach((button) => { button.addEventListener("click", () => { menuController.close(); runCommand(button.dataset.command); }); }); document.addEventListener("keydown", (event) => { if (event.key === "Escape") menuController.close(); if (event.key === "F5") { event.preventDefault(); runCommand("refresh"); } }); applyFilters(); updateDetails(allRows()[0]); })();