(options = {})
| 6550 | listEl.innerHTML = '<p class="text-xs text-gray-500">No alerts at this severity. Findings appear here as the running watchers emit them.</p>'; |
| 6551 | return; |
| 6552 | } |
| 6553 | listEl.innerHTML = alerts.map(a => { |
| 6554 | const [cls] = _WT_SEV_STYLE[a.severity] || _WT_SEV_STYLE.info; |
| 6555 | const t = a.ts ? new Date(a.ts * 1000).toLocaleString() : ''; |
| 6556 | const codes = (a.codes || []).join(', '); |
| 6557 | const ep = [a.src, a.target].filter(Boolean).map(escapeHtml).join(' → '); |
| 6558 | return `<div class="rounded-lg border ${cls} px-3 py-2"> |
| 6559 | <div class="flex items-start justify-between gap-3"> |
| 6560 | <div class="min-w-0"> |
| 6561 | <span class="text-xs uppercase tracking-wide opacity-80">${escapeHtml(a.label || a.source)}</span> |
| 6562 | <span class="text-sm ml-1">${escapeHtml(a.title || '')}</span> |
| 6563 | </div> |
| 6564 | <span class="text-[10px] uppercase font-semibold shrink-0">${escapeHtml(a.severity)}</span> |
| 6565 | </div> |
| 6566 | <div class="text-xs opacity-70 mt-0.5">${codes ? escapeHtml(codes) + ' · ' : ''}${ep ? ep + ' · ' : ''}${escapeHtml(t)}</div> |
| 6567 | </div>`; |
| 6568 | }).join(''); |
| 6569 | } |
| 6570 | async function watchtowerRefresh() { |
| 6571 | const sev = (document.getElementById('watchtower-minsev') || {}).value || ''; |
no test coverage detected