UX improvements.

This commit is contained in:
2026-07-12 00:40:19 +00:00
parent 994c9fbfdf
commit 43d407bf2e
9 changed files with 552 additions and 267 deletions

View File

@@ -82,8 +82,12 @@ function titleCaseScenario(s: string): string {
).join(' ');
}
function friendlyReason(reason: string): string {
if (!reason) return 'Community blocklist';
function friendlyScenario(scenario: string, origin?: string): string {
if (!scenario) {
if (origin === 'capi') return 'Community blocklist';
if (origin === 'manual' || origin === 'cscli') return 'Manual';
return origin || 'Unknown';
}
const map: Record<string, string> = {
'crowdsecurity/http-scan-classb': 'HTTP Scanner',
'crowdsecurity/ssh-slow-bruteforce': 'SSH Brute Force (slow)',
@@ -96,8 +100,8 @@ function friendlyReason(reason: string): string {
'crowdsecurity/http-bad-user-agent': 'Bad User Agent',
'crowdsecurity/iptables-scan-multi_ports': 'Port Scanner',
};
if (map[reason]) return map[reason];
const short = reason.includes('/') ? reason.split('/').slice(1).join(' ') : reason;
if (map[scenario]) return map[scenario];
const short = scenario.includes('/') ? scenario.split('/').slice(1).join(' ') : scenario;
return titleCaseScenario(short);
}
@@ -294,10 +298,10 @@ export function CrowdSecComponent() {
/>
{scenarioHubUrl(reason) ? (
<a href={scenarioHubUrl(reason)!} target="_blank" rel="noopener noreferrer" className="text-muted-foreground hover:text-foreground hover:underline">
{friendlyReason(reason)}
{friendlyScenario(reason)}
</a>
) : (
<span className="text-muted-foreground">{friendlyReason(reason)}</span>
<span className="text-muted-foreground">{friendlyScenario(reason)}</span>
)}
</div>
<span className="font-mono text-xs tabular-nums">{count.toLocaleString()}</span>
@@ -411,10 +415,10 @@ export function CrowdSecComponent() {
</div>
{scenarioHubUrl(alert.scenario) ? (
<a href={scenarioHubUrl(alert.scenario)!} target="_blank" rel="noopener noreferrer" className="text-xs text-muted-foreground whitespace-nowrap hover:text-foreground hover:underline">
{friendlyReason(alert.scenario)}
{friendlyScenario(alert.scenario)}
</a>
) : (
<span className="text-xs text-muted-foreground whitespace-nowrap">{friendlyReason(alert.scenario)}</span>
<span className="text-xs text-muted-foreground whitespace-nowrap">{friendlyScenario(alert.scenario)}</span>
)}
<span className="text-xs font-mono text-muted-foreground whitespace-nowrap">{alert.machineId?.replace(/^wc-/, '') ?? '—'}</span>
<span className="text-xs text-muted-foreground whitespace-nowrap">{formatRelativeTime(alert.createdAt)}</span>
@@ -528,7 +532,7 @@ export function CrowdSecComponent() {
}
<span className="font-mono truncate">{d.value}</span>
<Badge variant="outline" className="text-xs h-4 shrink-0">{d.type}</Badge>
<span className="text-muted-foreground truncate">{friendlyReason(d.reason)}</span>
<span className="text-muted-foreground truncate">{friendlyScenario(d.scenario, d.origin)}</span>
</div>
<div className="flex items-center gap-2 shrink-0">
{d.duration && (