new-ui #1

Merged
liamjd merged 2 commits from new-ui into main 2026-07-27 20:11:23 +01:00
Owner

UI based on Claude Design, two pane/accordion panels.

UI based on Claude Design, two pane/accordion panels.
Replaces the two-tab tables with the component-first layout from Claude
Design project 909bf096: dark brand bar carrying BOM metadata, severity
stat strip, a 400px component list ordered worst-first, and a detail pane
of vulnerability cards for the selected component. Search, severity chips
and row selection are live — they were static in the mock.

The design's data was hand-written, so four fields have no CycloneDX
equivalent. findings.ts owns those mappings so components stay free of
format knowledge:

- status pill: analysis.state (a VEX statement) outranks the per-version
  affects status, and neither being present reads as Unconfirmed rather
  than asserting the component is affected;
- headline: there is no title field, so a description accompanied by
  detail becomes the headline and otherwise its first sentence is
  promoted — past 240 characters no headline is emitted, because Trivy's
  lodash finding otherwise rendered as a wall of bold;
- "Fixed in": only from ranges explicitly marked unaffected, hidden
  otherwise, with recommendation shown separately since that is where
  scanners actually put fix guidance;
- advisory links: absent from the design, but dropping them from a
  security tool loses too much, so they render as hostname chips with the
  tail collapsed behind a disclosure.

Runtime-varying classes resolve through whole-string lookups in
design/styles.ts because Tailwind only sees literal class names.

Two deliberate losses: dark mode goes, the design being light-only by
intent, and there is no longer a view of every finding at once — each is
reached through the component it affects.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The design drew components only, so after implementing it there was no way
to see every finding at once — each was reachable solely through the
component it affects, which is wrong for triage across a whole BOM.

The side pane now has two modes sharing one shell: SidePane owns the
toggle, search and severity chips and renders rows as a snippet, so the
lists differ only in their rows and detail pane. Severity chips are
derived per mode, since a component's severity is that of its worst
finding and the two sets do not always match.

The modes cross-link — a finding card opens the finding, an affected-
component row opens the component — and both jumps clear the search and
filter first, or the target could land outside the list it just switched
to. Selection stays fallback-resolved, so switching mode with a stale id
lands on the first visible row rather than an empty pane.

Advisory links move to AdvisoryLinks.svelte now that both detail panes
render them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
liamjd merged commit 004962bf0d into main 2026-07-27 20:11:23 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
liamjd/SBOMViewer!1
No description provided.