Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"use client";

import { usePathname, useSearchParams } from "next/navigation";
import { groupBy, shuffle } from "lodash";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { useEffect, useMemo } from "react";
import useSWR from "swr";
import { QueryArtifactSelector } from "../../../../../../components/ArtifactSelector";
Expand All @@ -14,7 +15,7 @@ import CVERainbowBadge from "../../../../../../components/CVERainbowBadge";
import Page from "../../../../../../components/Page";
import { RiskHistoryDistributionDiagram } from "../../../../../../components/RiskHistoryDistributionDiagram";
import SeverityCard from "../../../../../../components/SeverityCard";
import { Button } from "../../../../../../components/ui/button";
import { AsyncButton, Button } from "../../../../../../components/ui/button";
import {
Card,
CardContent,
Expand Down Expand Up @@ -54,6 +55,11 @@ import {
} from "../../../../../../utils/view";
import useRouterQuery from "../../../../../../hooks/useRouterQuery";
import Link from "next/link";
import { toast } from "sonner";
import { useActiveProject } from "@/hooks/useActiveProject";
import { useActiveAsset } from "@/hooks/useActiveAsset";
import { useActiveAssetVersion } from "@/hooks/useActiveAssetVersion";
Comment on lines +59 to +61
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The imports 'useActiveProject', 'useActiveAsset', and 'useActiveAssetVersion' are added but never used in the component. These unused imports should be removed to keep the code clean and avoid confusion.

Suggested change
import { useActiveProject } from "@/hooks/useActiveProject";
import { useActiveAsset } from "@/hooks/useActiveAsset";
import { useActiveAssetVersion } from "@/hooks/useActiveAssetVersion";

Copilot uses AI. Check for mistakes.
import { browserApiClient } from "../../../../../../services/devGuardApi";

const OverviewPage = () => {
const search = useSearchParams();
Expand Down Expand Up @@ -185,6 +191,8 @@ const OverviewPage = () => {
const [mode, setMode] = useViewMode("devguard-view-mode");
const activeOrg = useActiveOrg();
const projectMenu = useProjectMenu();
const asset = useActiveAsset();
const assetVersion = useActiveAssetVersion();
const router = useRouter();
const contentTree = useOrganization().contentTree;

Expand Down Expand Up @@ -258,6 +266,35 @@ const OverviewPage = () => {
return latestRiskHistory.sort(sorter).slice(0, 7);
}, [completeRiskHistory, mode]);

const selectedArtifact = useSearchParams()?.get("artifact") || undefined;
const pathname = usePathname();
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable 'pathname' is declared using usePathname() but is never used in the component. Consider removing it to avoid confusion.

Copilot uses AI. Check for mistakes.

const downloadSBOMReport = async () => {
try {
const response = await browserApiClient(
`/organizations/${organizationSlug}/projects/${projectSlug}/releases/${releaseId}/sbom.json/`,
{ method: "GET", signal: AbortSignal.timeout(60 * 8 * 1000) },
);
if (!response.ok) {
toast.error(
"Failed to download SBOM report. Please try again later.",
);
return;
}
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
// add download attribute to the link
link.download = `${releaseId}.json`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (error) {
toast.error("Failed to download SBOM. Please try again later.");
}
};

if (releases?.data.length === 0) {
return (
<Page title={project.name} Menu={projectMenu} Title={<ProjectTitle />}>
Expand All @@ -282,10 +319,21 @@ const OverviewPage = () => {

return (
<Page title={project.name} Menu={projectMenu} Title={<ProjectTitle />}>
<div className="mb-4">
<QueryArtifactSelector
artifacts={releases?.data?.map((r) => r.name) || []}
/>
<div className="mb-4 flex flex-row items-start justify-between">
<div className="flex items-center gap-2">
<QueryArtifactSelector
artifacts={releases?.data?.map((r) => r.name) || []}
/>
</div>
<div className="flex relative flex-col">
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CSS class 'relative' appears unnecessary in this context as there are no absolutely positioned child elements. Consider removing it unless it serves a specific purpose.

Suggested change
<div className="flex relative flex-col">
<div className="flex flex-col">

Copilot uses AI. Check for mistakes.
<AsyncButton
disabled={selectedArtifact === undefined}
onClick={downloadSBOMReport}
variant={"secondary"}
>
Download SBOM
</AsyncButton>
</div>
</div>

<Section
Expand Down