diff --git a/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.test.tsx b/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.test.tsx index 1b95b18748..663cabf732 100644 --- a/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.test.tsx +++ b/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.test.tsx @@ -408,7 +408,7 @@ const mockFinding: ResourceDrawerFinding = { }; describe("ResourceDetailDrawerContent — resource navigation", () => { - it("should not render resource navigation from the recommendation drawer", () => { + it("should render a View Resource link below the resource actions menu", () => { // Given render( { />, ); + // When + const viewResourceLink = screen.getByRole("link", { + name: "View Resource", + }); + const resourceActionsMenu = screen.getByRole("menu", { + name: "Resource actions", + }); + // Then + expect(viewResourceLink).toHaveAttribute( + "href", + "/resources?resourceId=res-1", + ); + expect(viewResourceLink).toHaveAttribute("target", "_blank"); + expect(viewResourceLink).toHaveAttribute("rel", "noopener noreferrer"); expect( - screen.queryByRole("link", { name: "View Resource" }), - ).not.toBeInTheDocument(); + resourceActionsMenu.compareDocumentPosition(viewResourceLink) & + Node.DOCUMENT_POSITION_FOLLOWING, + ).not.toBe(0); }); }); const mockResourceRow: FindingResourceRow = { diff --git a/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.tsx b/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.tsx index 94d071ad91..f9ab4fe130 100644 --- a/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.tsx +++ b/ui/components/findings/table/resource-detail-drawer/resource-detail-drawer-content.tsx @@ -304,6 +304,12 @@ function buildComplianceDetailHref({ return `/compliance/${encodeURIComponent(framework)}?${params.toString()}`; } +function buildResourceDetailHref(resourceId: string): string { + const params = new URLSearchParams(); + params.set("resourceId", resourceId); + return `/resources?${params.toString()}`; +} + interface ResourceDetailDrawerContentProps { isLoading: boolean; isNavigating: boolean; @@ -421,6 +427,9 @@ export function ResourceDetailDrawerContent({ const nativeIacConfig = resolveNativeIacConfig(providerType); const showOverviewCheckMetaContent = showCheckMetaContent; const showOverviewFindingContent = Boolean(f); + const resourceDetailHref = f?.resourceId + ? buildResourceDetailHref(f.resourceId) + : null; const findingRecommendationUrl = f?.remediation.recommendation.url; const checkRecommendationUrl = checkMeta.remediation.recommendation.url; const recommendationUrl = isNonEmptyString(findingRecommendationUrl) @@ -775,6 +784,21 @@ export function ResourceDetailDrawerContent({ )} + + {resourceDetailHref && ( +
+ +
+ )} )}