fix: differentiate security action links and add suppression editing (#1500)

Security page UX fixes:

- Stop the CVSS x EPSS scatter chart from painting a full-plot "white
  rectangle" cursor on click (cursor disabled), and prevent click-drag
  selection on charts.
- Differentiate the overview action links: "fixable" links (masthead primary
  action, review-queue blocker, and the Fixable signal tile) now open the
  Images tab pre-filtered to fixable findings; the Stale and Failed signal
  tiles link to the History tab where those scans are listed; Secrets and
  Misconfigs tiles link to their tabs. The Images tab accepts an initialFilter
  and exposes a Fixable option in the severity dropdown.
- Fix the "Secrets / misconfigs" option wrapping and misaligning in the
  severity dropdown (single-line option labels, wider trigger).
- Add Edit for CVE suppressions and misconfig acknowledgements (reason, scope
  pattern, expiry), reusing the existing dialog and the existing PUT endpoints;
  the CVE/rule identity stays fixed.
This commit is contained in:
Anso
2026-06-28 06:17:47 -04:00
committed by GitHub
parent ba57c67048
commit 083442d5ea
15 changed files with 316 additions and 115 deletions
@@ -133,12 +133,12 @@ describe('derivePostureReasons', () => {
knownExploited: 1,
secrets: 2,
}));
expect(primaryAction).toEqual({ label: 'Update affected images', targetTab: 'images' });
expect(primaryAction).toEqual({ label: 'Update affected images', targetTab: 'images', kind: 'fixable_cve' });
});
it('falls through to the next blocker when the first is absent', () => {
const { primaryAction } = derivePostureReasons(facts({ secrets: 1 }));
expect(primaryAction).toEqual({ label: 'Review detected secrets', targetTab: 'secrets' });
expect(primaryAction).toEqual({ label: 'Review detected secrets', targetTab: 'secrets', kind: 'secret' });
});
it('returns null primaryAction when no blockers exist', () => {
+8 -5
View File
@@ -60,6 +60,9 @@ export interface PostureReason {
export interface PostureAction {
label: string;
targetTab: SecurityPostureTargetTab;
/** The reason kind that produced this action, so the UI can target the
* affected items precisely (e.g. filter Images to fixable findings). */
kind: PostureReasonKind;
}
export interface SecurityPostureFacts {
@@ -123,7 +126,7 @@ export function derivePostureReasons(f: SecurityPostureFacts): {
targetTab: 'images',
};
reasons.push(r);
if (!primaryAction) primaryAction = { label: 'Update affected images', targetTab: 'images' };
if (!primaryAction) primaryAction = { label: 'Update affected images', targetTab: r.targetTab, kind: r.kind };
}
if (f.knownExploited > 0) {
@@ -136,7 +139,7 @@ export function derivePostureReasons(f: SecurityPostureFacts): {
targetTab: 'images',
};
reasons.push(r);
if (!primaryAction) primaryAction = { label: 'Review exploited findings', targetTab: 'images' };
if (!primaryAction) primaryAction = { label: 'Review exploited findings', targetTab: r.targetTab, kind: r.kind };
}
if (f.secrets > 0) {
@@ -149,7 +152,7 @@ export function derivePostureReasons(f: SecurityPostureFacts): {
targetTab: 'secrets',
};
reasons.push(r);
if (!primaryAction) primaryAction = { label: 'Review detected secrets', targetTab: 'secrets' };
if (!primaryAction) primaryAction = { label: 'Review detected secrets', targetTab: r.targetTab, kind: r.kind };
}
if (f.dangerousCompose > 0) {
@@ -162,7 +165,7 @@ export function derivePostureReasons(f: SecurityPostureFacts): {
targetTab: 'compose',
};
reasons.push(r);
if (!primaryAction) primaryAction = { label: 'Review Compose risks', targetTab: 'compose' };
if (!primaryAction) primaryAction = { label: 'Review Compose risks', targetTab: r.targetTab, kind: r.kind };
}
if (f.exposedBlocker > 0) {
@@ -175,7 +178,7 @@ export function derivePostureReasons(f: SecurityPostureFacts): {
targetTab: 'images',
};
reasons.push(r);
if (!primaryAction) primaryAction = { label: 'Review public exposure', targetTab: 'images' };
if (!primaryAction) primaryAction = { label: 'Review public exposure', targetTab: r.targetTab, kind: r.kind };
}
// Review items. These appear in-page but do not force a red masthead.