dashboard: show all notifications with action taken, filter dismissals from activity

- Notifications table: show ALL (not just pending), add ACTION TAKEN column
  showing dismiss reason or pending status. Dismissed rows slightly dimmed.
- Activity section: filters out 'dismiss' entries, only shows real actions
  (reviews, comments, fixes)
This commit is contained in:
Nazim 2026-03-26 17:21:39 +00:00
parent 31ca165499
commit 27f135c921

View file

@ -271,7 +271,7 @@
const yesterday = new Date(Date.now() - 86400000).toISOString(); const yesterday = new Date(Date.now() - 86400000).toISOString();
const activity = await fetchData('activity_log', const activity = await fetchData('activity_log',
`SELECT COUNT(*) as c FROM activity_log WHERE timestamp > '${yesterday}'`); `SELECT COUNT(*) as c FROM activity_log WHERE timestamp > '${yesterday}' AND action != 'dismiss'`);
document.getElementById('activity-count').textContent = activity[0]?.c || 0; document.getElementById('activity-count').textContent = activity[0]?.c || 0;
const escalations = await fetchData('escalations', const escalations = await fetchData('escalations',
@ -287,16 +287,19 @@
`(last poll ${timeAgo(p.polled_at)} — ${p.new_count} new)`; `(last poll ${timeAgo(p.polled_at)} — ${p.new_count} new)`;
} }
// Notifications table — show pending (non-dismissed) by default // Notifications table — show ALL notifications with action taken
const notifications = await fetchData('notifications', const notifications = await fetchData('notifications',
'SELECT * FROM notifications WHERE dismissed = 0 AND processing = 0 ORDER BY seen_at DESC LIMIT 30'); `SELECT n.*, a.detail as action_detail, a.action as action_type
FROM notifications n
LEFT JOIN activity_log a ON a.github_url = n.url
ORDER BY n.seen_at DESC LIMIT 30`);
if (notifications.length === 0) { if (notifications.length === 0) {
document.getElementById('notifications-table').innerHTML = document.getElementById('notifications-table').innerHTML =
'<div class="loading">No pending notifications. ✨</div>'; '<div class="loading">No notifications yet. ✨</div>';
} else { } else {
let html = `<table> let html = `<table>
<thead><tr><th>TIME</th><th>ISSUE</th><th>REASON</th><th>TITLE</th><th>FILTER</th></tr></thead> <thead><tr><th>TIME</th><th>ISSUE</th><th>REASON</th><th>TITLE</th><th>ACTION TAKEN</th></tr></thead>
<tbody>`; <tbody>`;
for (const n of notifications) { for (const n of notifications) {
const ownTag = n.is_own_pr ? '🔵 ' : ''; const ownTag = n.is_own_pr ? '🔵 ' : '';
@ -315,22 +318,30 @@
n.reason === 'author' ? 'success' : n.reason === 'author' ? 'success' :
n.reason === 'review_requested' ? 'warning' : ''; n.reason === 'review_requested' ? 'warning' : '';
const reasonBadge = `<span class="status-badge ${reasonClass ? 'status-' + reasonClass : ''}" style="background:var(--${reasonClass || 'text-dim'}); color:#000; padding:2px 8px; border-radius:4px; font-size:0.8em">${n.reason}</span>`; const reasonBadge = `<span class="status-badge ${reasonClass ? 'status-' + reasonClass : ''}" style="background:var(--${reasonClass || 'text-dim'}); color:#000; padding:2px 8px; border-radius:4px; font-size:0.8em">${n.reason}</span>`;
const filterShort = (n.filter_reason || '').replace(/^KEEP: /, ''); // Action taken column
html += `<tr> let actionText = '';
if (n.action_detail) {
actionText = n.action_detail;
} else if (n.dismissed && n.filter_reason) {
actionText = `dismissed: ${n.filter_reason.replace(/^KEEP \(rule\): /, '')}`;
} else if (!n.dismissed) {
actionText = '<span style="color:var(--warning)">pending</span>';
}
html += `<tr style="${n.dismissed ? 'opacity:0.7' : ''}">
<td class="timestamp">${timeAgo(n.seen_at)}</td> <td class="timestamp">${timeAgo(n.seen_at)}</td>
<td>${issue}</td> <td>${issue}</td>
<td>${reasonBadge}</td> <td>${reasonBadge}</td>
<td>${ownTag}${n.title || '-'}${ciTag}</td> <td>${ownTag}${n.title || '-'}${ciTag}</td>
<td style="color:var(--text-dim);font-size:0.85em">${filterShort}</td> <td style="font-size:0.85em">${actionText}</td>
</tr>`; </tr>`;
} }
html += '</tbody></table>'; html += '</tbody></table>';
document.getElementById('notifications-table').innerHTML = html; document.getElementById('notifications-table').innerHTML = html;
} }
// Activity table // Activity table — filter out dismissals, show only real actions
const activityLog = await fetchData('activity_log', const activityLog = await fetchData('activity_log',
'SELECT * FROM activity_log ORDER BY timestamp DESC LIMIT 10'); "SELECT * FROM activity_log WHERE action != 'dismiss' ORDER BY timestamp DESC LIMIT 10");
if (activityLog.length === 0) { if (activityLog.length === 0) {
document.getElementById('activity-table').innerHTML = document.getElementById('activity-table').innerHTML =