feat(ui): show the attack path in the Issues panel and rename the menu entry (#13195)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Alejandro BailoandClaude Opus 5.5 authored and GitHub committed 2026-10-29 10:43:42 +01:00
1 parent 814ae54d6a
commit ca6ed48664
20 files changed
+461 -109

No files matched your search

+2 -2
View File
@@ -13,8 +13,8 @@ vi.mock("@/actions/issues", () => ({ getIssue }));
vi.mock("@/components/shadcn/content-layout", () => ({
ContentLayout: ({ children }: { children: ReactNode }) => children,
}));
vi.mock("@/components/shared/feature-flag-gate", () => ({
FeatureFlagGate: ({ children }: { children: ReactNode }) => children,
vi.mock("@/components/shared/feature-flag-route", () => ({
FeatureFlagRoute: ({ children }: { children: ReactNode }) => children,
}));
vi.mock("@/components/issues/issue-detail", () => ({
IssueDetail: ({ scanId }: { scanId?: string }) => (
+3 -10
View File
@@ -9,7 +9,7 @@ import { Button } from "@/components/shadcn/button/button";
import { Card } from "@/components/shadcn/card/card";
import { ContentLayout } from "@/components/shadcn/content-layout";
import { EntityInfo } from "@/components/shadcn/entities";
import { FeatureFlagGate } from "@/components/shared/feature-flag-gate";
import { FeatureFlagRoute } from "@/components/shared/feature-flag-route";
import { FEATURE_FLAG } from "@/lib/feature-flags";
import { VERDICTS } from "@/lib/issues/verdicts";
import { isCloud } from "@/lib/shared/env";
@@ -34,14 +34,7 @@ export default async function IssuePage({
return (
<ContentLayout title="Issue" icon={<ShieldAlert />}>
<FeatureFlagGate
flag={FEATURE_FLAG.ISSUES}
fallback={
<p className="text-text-neutral-tertiary text-sm">
Issues is not available for this account yet.
</p>
}
>
<FeatureFlagRoute flag={FEATURE_FLAG.ISSUES}>
<div className="flex min-w-0 flex-col gap-4">
<Button asChild variant="link" size="link-sm" className="self-start">
<Link href="/issues">← All issues</Link>
@@ -70,7 +63,7 @@ export default async function IssuePage({
/>
</Card>
</div>
</FeatureFlagGate>
</FeatureFlagRoute>
</ContentLayout>
);
}
+5 -12
View File
@@ -7,7 +7,7 @@ import { getAllProviders } from "@/actions/providers";
import { ProviderAccountSelectors } from "@/components/filters/provider-account-selectors";
import { ProviderGroupSelector } from "@/components/filters/provider-group-selector";
import { ContentLayout } from "@/components/shadcn/content-layout";
import { FeatureFlagGate } from "@/components/shared/feature-flag-gate";
import { FeatureFlagRoute } from "@/components/shared/feature-flag-route";
import { FEATURE_FLAG } from "@/lib/feature-flags";
import { isCloud } from "@/lib/shared/env";
import { SearchParamsProps } from "@/types";
@@ -29,16 +29,9 @@ export default async function Issues({
return (
<ContentLayout title="Issues" icon={<ShieldAlert />}>
{/* Deployment gate above (notFound); per-account rollout here. The route
stays reachable by URL, so the off state explains itself. */}
<FeatureFlagGate
flag={FEATURE_FLAG.ISSUES}
fallback={
<p className="text-text-neutral-tertiary text-sm">
Issues is not available for this account yet.
</p>
}
>
{/* Deployment gate above (notFound); per-account rollout here, also a
redirect to the overview when off, like the hidden menu entry. */}
<FeatureFlagRoute flag={FEATURE_FLAG.ISSUES}>
<Suspense
fallback={
<p className="text-text-neutral-tertiary text-sm">
@@ -62,7 +55,7 @@ export default async function Issues({
}
/>
</Suspense>
</FeatureFlagGate>
</FeatureFlagRoute>
</ContentLayout>
);
}