From: Stefan Gasser Date: Fri, 16 Jan 2026 13:30:11 +0000 (+0100) Subject: feat(dashboard): display secrets detection in logs table (#30) X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=b2116e82aa1d1d3a9ea099dda7bff885e9d3c5d6;p=sgasser-llm-shield.git feat(dashboard): display secrets detection in logs table (#30) Add Secrets column to the Recent Requests table showing detected secret types (e.g., OPENSSH_PRIVATE_KEY, PEM_PRIVATE_KEY) as red badges. The data was already available from the API but not displayed. - Add Secrets column header between PII Entities and Scan Time - Parse secrets_types and secrets_detected from API response - Display secret types as error-colored badges - Add CSS utilities for error color variants - Update colspan values for detail rows Closes #20 --- diff --git a/src/views/dashboard/page.tsx b/src/views/dashboard/page.tsx index 1a99b2a..a0c7e3f 100644 --- a/src/views/dashboard/page.tsx +++ b/src/views/dashboard/page.tsx @@ -95,12 +95,15 @@ const DashboardPage: FC = () => { .bg-success { background: var(--color-success); } .bg-success\\/10 { background: rgba(22, 163, 74, 0.1); } .bg-teal { background: var(--color-teal); } + .bg-error { background: var(--color-error); } + .bg-error\\/10 { background: rgba(220, 38, 38, 0.1); } /* Border utilities */ .border-border { border-color: var(--color-border); } .border-border-subtle { border-color: var(--color-border-subtle); } .border-accent\\/20 { border-color: rgba(180, 83, 9, 0.2); } .border-success\\/20 { border-color: rgba(22, 163, 74, 0.2); } + .border-error\\/20 { border-color: rgba(220, 38, 38, 0.2); } /* Text utilities */ .text-text-primary { color: var(--color-text-primary); } @@ -110,6 +113,7 @@ const DashboardPage: FC = () => { .text-info { color: var(--color-info); } .text-success { color: var(--color-success); } .text-teal { color: var(--color-teal); } + .text-error { color: var(--color-error); } /* Border radius */ .rounded-sm { border-radius: var(--radius-sm); } @@ -381,6 +385,9 @@ const LogsSection: FC = () => ( PII Entities + + Secrets + Scan Time @@ -388,7 +395,7 @@ const LogsSection: FC = () => ( - +
@@ -547,13 +554,15 @@ async function fetchLogs() { const tbody = document.getElementById('logs-body'); if (data.logs.length === 0) { - tbody.innerHTML = '
📋
No requests yet
'; + tbody.innerHTML = '
📋
No requests yet
'; return; } tbody.innerHTML = data.logs.map((log, index) => { const time = new Date(log.timestamp).toLocaleTimeString(); const entities = log.entities ? log.entities.split(',').filter(e => e.trim()) : []; + const secretsTypes = log.secrets_types ? log.secrets_types.split(',').filter(s => s.trim()) : []; + const secretsDetected = log.secrets_detected === 1; const lang = log.language || 'en'; const detectedLang = log.detected_language; @@ -583,12 +592,17 @@ async function fetchLogs() { ? '
' + entities.map(e => '' + e.trim() + '').join('') + '
' : '—') + '' + + '' + + (secretsDetected + ? '
' + (secretsTypes.length > 0 ? secretsTypes.map(s => '' + s.trim() + '').join('') : 'DETECTED') + '
' + : '—') + + '' + '' + log.scan_time_ms + 'ms' + ''; const detailRow = '' + - '' + + '' + '
' + '
' + formatMaskedPreview(log.masked_content, entities) + '
' + '
' +