feat: rich ratelimited log viewer table

Renders ratelimited log entries as a structured table instead of raw
JSON, showing: timestamp, sender (header_from), recipient, subject,
IP address, rate-limit rule name (orange badge, tooltip with rl_info),
and queue ID.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-27 09:47:49 +01:00
parent dbaf3b330b
commit 332efe59eb

View File

@@ -913,6 +913,45 @@
}
});
// ── Ratelimited log renderer ──────────────────────────────────────────
const renderRatelimitLog = (entries) => {
let html = `<div class="woocow-log-toolbar">
<strong>Rate-Limited Messages</strong>
<span style="color:#666;font-size:12px">${entries.length} entries</span>
</div>
<table class="wp-list-table widefat fixed striped woocow-table">
<thead><tr>
<th style="width:130px">Time</th>
<th>Sender</th>
<th>Recipient</th>
<th>Subject</th>
<th style="width:110px">IP</th>
<th style="width:120px">Rate Limit Rule</th>
<th style="width:110px">Queue ID</th>
</tr></thead><tbody>`;
entries.forEach(e => {
const dt = e.time ? new Date(e.time * 1000).toLocaleString() : '—';
const sender = e.header_from || e.from || '—';
const subject = e.header_subject || '—';
html += `<tr>
<td style="font-size:11px;white-space:nowrap">${esc(dt)}</td>
<td style="font-size:11px">${esc(sender)}</td>
<td style="font-size:11px">${esc(e.rcpt || '—')}</td>
<td style="font-size:12px">${esc(subject)}</td>
<td><code style="font-size:11px">${esc(e.ip || '—')}</code></td>
<td>
<span class="woocow-badge woocow-badge-orange" title="${esc(e.rl_info || '')}">${esc(e.rl_name || '—')}</span>
</td>
<td><code style="font-size:11px">${esc(e.qid || '—')}</code></td>
</tr>`;
});
html += '</tbody></table>';
$('#wc-log-wrap').html(html);
};
// ── Log load ──────────────────────────────────────────────────────────
$('#wc-log-load').on('click', () => {
@@ -931,10 +970,8 @@
return;
}
if (type === 'rspamd-history') {
renderRspamdLog(entries);
return;
}
if (type === 'rspamd-history') { renderRspamdLog(entries); return; }
if (type === 'ratelimited') { renderRatelimitLog(entries); return; }
// Plain text log
const typeLabel = $('#wc-log-type option:selected').text();