Files
sencho/frontend/src/lib/severityStyles.ts
T
Anso 0066887cee feat(security): reflow the node Security page for mobile (#1372)
* feat(security): reflow the node Security page for mobile

Below the md breakpoint the Security page now reads as a phone surface
instead of a squeezed desktop, with no change to the desktop layout.

- Masthead stat cluster moves into a full-width 3-cell strip
  (critical / high / last scan) below the tab strip, since the masthead
  hides its inline cluster on a phone.
- The eight-section tab strip becomes a horizontally scrollable mono row
  with an edge mask-fade and a cyan underline on the active tab; every
  section stays reachable by scroll.
- The six totals render as a 3x2 hairline-divided grid instead of the
  640px-wide rail that forced a horizontal scroll.
- The Images tab becomes a filterable, scrollable list (severity dot,
  truncated ref, freshness, critical/high count tags) with a chip row,
  in place of the desktop table.
- A freshness footer band states scan recency and scanner version.

All mobile treatment is gated by useIsMobile() or max-md: utilities, so
the desktop view is byte-identical. Charts are reused full-width.

* feat(security): make the mobile Security page a bespoke masthead-led screen

On a phone the Security page now drops the global top bar and leads with
its masthead (the notifications + more-menu cluster moves into the
masthead's right slot), matching Home and Fleet so the mobile shell is
continuous across pages. The view is reclassified bespoke and rendered
through the masthead-led path; the desktop layout is unchanged.

The mobile "more" menu now lists every destination instead of omitting
the bottom-tab views, so the same menu opens the same set on every
screen rather than changing contents from page to page.
2026-06-14 21:28:13 -04:00

54 lines
2.3 KiB
TypeScript

import type { ScanSummary, VulnSeverity } from '@/types/security';
export type SeverityKey = VulnSeverity | 'CLEAN' | 'FINDINGS';
/** Image-list filter value: any severity key, the "all" sentinel, or the
* phone-only FIXABLE pseudo-filter (images with at least one fixable finding). */
export type ImageFilterValue = 'all' | SeverityKey | 'FIXABLE';
/**
* The display "key" for a scan summary: its highest vulnerability severity, or
* `FINDINGS` when the scan has only secrets/misconfigurations (stored
* highest_severity is derived from CVEs alone), or `CLEAN` when nothing was
* found. Shared so the badge, sorting, and filtering all classify identically.
*/
export function getSeverityKey(summary: ScanSummary): SeverityKey {
const hasNonVulnFindings = (summary.secret_count ?? 0) > 0 || (summary.misconfig_count ?? 0) > 0;
return summary.highest_severity ?? (hasNonVulnFindings ? 'FINDINGS' : 'CLEAN');
}
export const SEVERITY_ROW_TINT: Record<VulnSeverity, string> = {
CRITICAL: 'bg-destructive/10 border-l-[3px] border-destructive/70',
HIGH: 'bg-warning/10 border-l-[3px] border-warning/70',
MEDIUM: 'border-l-[3px] border-info/40',
LOW: 'border-l-[3px] border-transparent',
UNKNOWN: 'border-l-[3px] border-transparent',
};
/**
* Border/background/text classes for a severity pill. `CLEAN` is the all-zero
* state; `FINDINGS` is the amber "not clean but no vulnerability severity"
* state for a scan that has secrets or misconfigurations but zero CVEs (the
* stored highest_severity is derived from vulnerabilities only).
*/
export const SEVERITY_BADGE_CLASSES: Record<SeverityKey, string> = {
CRITICAL: 'border-destructive/25 bg-destructive/8 text-destructive',
HIGH: 'border-warning/25 bg-warning/8 text-warning',
MEDIUM: 'border-warning/25 bg-warning/8 text-warning',
LOW: 'border-border bg-muted/30 text-muted-foreground',
UNKNOWN: 'border-border bg-muted/20 text-muted-foreground',
CLEAN: 'border-success/25 bg-success/8 text-success',
FINDINGS: 'border-warning/25 bg-warning/8 text-warning',
};
/** Leading state-dot color for a severity pill. */
export const SEVERITY_DOT_CLASSES: Record<SeverityKey, string> = {
CRITICAL: 'bg-destructive',
HIGH: 'bg-warning',
MEDIUM: 'bg-warning',
LOW: 'bg-muted-foreground/60',
UNKNOWN: 'bg-muted-foreground/40',
CLEAN: 'bg-success',
FINDINGS: 'bg-warning',
};