From 0eee0ae49570a46b7477c6f77a1eb101fe3582c7 Mon Sep 17 00:00:00 2001 From: Julian Kepka Date: Mon, 20 Jul 2026 11:43:43 +0200 Subject: [PATCH 1/6] fix: confirm and delete button --- .../[assetVersionSlug]/advisory/[advisoryId]/page.tsx | 11 +++++------ src/components/ui/alert-dialog.tsx | 8 +++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx index e7b995b61..afccfdc12 100644 --- a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx @@ -9,8 +9,7 @@ import { Skeleton } from "@/components/ui/skeleton"; import type { SecurityAdvisory } from "@/types/api/api"; import Severity from "@/components/common/Severity"; import Markdown from "@/components/common/Markdown"; -import FormatDate from "@/components/risk-assessment/FormatDate"; -import { Button, buttonVariants } from "@/components/ui/button"; +import { Button } from "@/components/ui/button"; import { browserApiClient } from "@/services/devGuardApi"; import { AlertDialog, @@ -179,7 +178,7 @@ const Index = () => { title: "Are you sure you want to delete this advisory?", description: "This action cannot be undone. All data associated with this advisory will be deleted.", - confirmClassName: buttonVariants({ variant: "default" }), + variant: "destructive", onConfirm: handleDeleteAdvisory, }, publish: { @@ -187,7 +186,7 @@ const Index = () => { title: "Are you sure you want to publish this advisory?", description: "NOTE: This feature is still work in progress. This publishment will only add the Advisory to the CSAF report. This action cannot be undone. All data associated with this advisory will be published.", - confirmClassName: buttonVariants({ variant: "default" }), + variant: "default", onConfirm: handlePublishAdvisory, }, withdraw: { @@ -197,7 +196,7 @@ const Index = () => { title: "Are you sure you want to withdraw this advisory?", description: "This action cannot be undone. The advisory stays public but is marked as withdrawn and can no longer be changed.", - confirmClassName: buttonVariants({ variant: "destructive" }), + variant: "destructive", onConfirm: handleWithdrawAdvisory, }, } as const; @@ -418,7 +417,7 @@ const Index = () => { Cancel activeConfirm?.onConfirm()} > Confirm diff --git a/src/components/ui/alert-dialog.tsx b/src/components/ui/alert-dialog.tsx index f8974ba31..8d8c9ec56 100644 --- a/src/components/ui/alert-dialog.tsx +++ b/src/components/ui/alert-dialog.tsx @@ -3,6 +3,7 @@ import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"; import { cn } from "@/lib/utils"; import { buttonVariants } from "@/components/ui/button"; +import { type VariantProps } from "class-variance-authority"; const AlertDialog = AlertDialogPrimitive.Root; @@ -98,11 +99,12 @@ AlertDialogDescription.displayName = const AlertDialogAction = React.forwardRef< React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( + React.ComponentPropsWithoutRef & + Pick, "variant"> +>(({ className, variant = "destructive", ...props }, ref) => ( )); From 0cd474fc857cc1a884a362495cf91c6e8e4a8248 Mon Sep 17 00:00:00 2001 From: Julian Kepka Date: Mon, 20 Jul 2026 16:18:36 +0200 Subject: [PATCH 2/6] performance issues --- .../advisory/[advisoryId]/page.tsx | 22 +++++++++++++++++-- .../risk-assessment/RiskAssessmentFeed.tsx | 6 +++++ src/types/api/api.ts | 22 +++++++++++++++++-- src/utils/view.ts | 11 +++++++++- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx index afccfdc12..df220ee3d 100644 --- a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx @@ -6,7 +6,7 @@ import { fetcher } from "@/data-fetcher/fetcher"; import { useAssetMenu } from "@/hooks/useAssetMenu"; import useDecodedParams from "@/hooks/useDecodedParams"; import { Skeleton } from "@/components/ui/skeleton"; -import type { SecurityAdvisory } from "@/types/api/api"; +import type { DetailedSecurityAdvisoryDTO } from "@/types/api/api"; import Severity from "@/components/common/Severity"; import Markdown from "@/components/common/Markdown"; import { Button } from "@/components/ui/button"; @@ -37,11 +37,14 @@ import AdvisoryDialog, { } from "@/components/AdvisoryDialog"; import AuthGuard from "@/components/AuthGuard"; import { useConfig } from "@/context/ConfigContext"; +import RiskAssessmentFeed from "@/components/risk-assessment/RiskAssessmentFeed"; +import { useDeleteEvent } from "@/hooks/useDeleteEvent"; const Index = () => { const router = useRouter(); const params = useDecodedParams(); const config = useConfig(); + const deleteEvent = useDeleteEvent(); const { organizationSlug, projectSlug, @@ -129,7 +132,7 @@ const Index = () => { data: advisory, isLoading, error, - } = useSWR( + } = useSWR( organizationSlug && projectSlug && assetSlug && @@ -216,6 +219,11 @@ const Index = () => { variant: "secondary" as const, }; + const handleDeleteEvent = async (eventId: string) => { + await deleteEvent(eventId); + mutate(`${advisoryUrl}` + `/${advisoryId}/`); + }; + return ( { {advisory.description} )} + {advisory.events && advisory.events.length > 0 && ( +
+ +
+ )} {advisory.visibility === "draft" && (
diff --git a/src/components/risk-assessment/RiskAssessmentFeed.tsx b/src/components/risk-assessment/RiskAssessmentFeed.tsx index 1b597e57e..39bc649a2 100644 --- a/src/components/risk-assessment/RiskAssessmentFeed.tsx +++ b/src/components/risk-assessment/RiskAssessmentFeed.tsx @@ -43,7 +43,9 @@ import { WrenchIcon, } from "@heroicons/react/24/outline"; import { + ArrowDownToDot, Component, + Eye, GitBranchIcon, GitPullRequestCreateArrowIcon, Scale, @@ -108,6 +110,10 @@ export function EventTypeIcon({ return ; case "removedComplianceComponent": return ; + case "published": + return ; + case "withdrawn": + return ; } } diff --git a/src/types/api/api.ts b/src/types/api/api.ts index 97d4b151d..fc2552232 100644 --- a/src/types/api/api.ts +++ b/src/types/api/api.ts @@ -287,7 +287,11 @@ interface BaseVulnEventDTO { createdAt: string; id: string; vulnId: string; - vulnType: "dependencyVuln" | "firstPartyVuln" | "compliancePosture"; + vulnType: + | "dependencyVuln" + | "firstPartyVuln" + | "compliancePosture" + | "securityAdvisory"; justification: string; mechanicalJustification: string; vulnerabilityName: string | null; @@ -400,6 +404,14 @@ export interface RemovedComplianceComponentEventDTO extends BaseVulnEventDTO { }; } +export interface PublishedEventDTO extends BaseVulnEventDTO { + type: "published"; +} + +export interface WithdrawnEventDTO extends BaseVulnEventDTO { + type: "withdrawn"; +} + export type VulnEventDTO = | AcceptedEventDTO | FixedEventDTO @@ -416,7 +428,9 @@ export type VulnEventDTO = | ImplementedEventDTO | NotApplicableEventDTO | AttachedComplianceComponentEventDTO - | RemovedComplianceComponentEventDTO; + | RemovedComplianceComponentEventDTO + | PublishedEventDTO + | WithdrawnEventDTO; export interface CWE { cwe: string; @@ -1275,3 +1289,7 @@ export interface AdvisoryAffectedPackage { semverStart: string | null; semverEnd: string | null; } + +export interface DetailedSecurityAdvisoryDTO extends SecurityAdvisory { + events: VulnEventDTO[]; +} diff --git a/src/utils/view.ts b/src/utils/view.ts index 086681b40..357a3ff9f 100644 --- a/src/utils/view.ts +++ b/src/utils/view.ts @@ -12,7 +12,6 @@ // // You should have received a copy of the GNU Affero General Public License -import { UpstreamState } from "@/types/api/api"; import type { AssetDTO, ComponentRisk, @@ -181,6 +180,14 @@ export const eventTypeMessages = ( } break; } + case "published": { + message = "published " + flawName; + break; + } + case "withdrawn": { + message = "withdrew " + flawName; + break; + } } if (event.userAgent === "devguard-mcp-server") { message += " (applied by AI agent)"; @@ -205,6 +212,8 @@ export const evTypeBackground: { [key in VulnEventDTO["type"]]: string } = { licenseDecision: "bg-warning text-warning-foreground!", attachedComplianceComponent: "bg-success text-success-foreground!", removedComplianceComponent: "bg-secondary text-secondary-foreground!", + published: "bg-secondary text-secondary-foreground!", + withdrawn: "bg-destructive text-destructive-foreground!", }; export const osiLicenseHexColors: Record = { From d5d83adc12c9579b5469f18266c887e0481dc48d Mon Sep 17 00:00:00 2001 From: Julian Kepka Date: Tue, 21 Jul 2026 17:02:30 +0200 Subject: [PATCH 3/6] feat: added event feed --- .../advisory/[advisoryId]/page.tsx | 197 ++++++++++++++---- .../refs/[assetVersionSlug]/advisory/page.tsx | 2 +- .../risk-assessment/RiskAssessmentFeed.tsx | 2 + src/types/api/api.ts | 7 +- src/utils/view.ts | 7 +- 5 files changed, 172 insertions(+), 43 deletions(-) diff --git a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx index df220ee3d..1621c5424 100644 --- a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx @@ -6,10 +6,13 @@ import { fetcher } from "@/data-fetcher/fetcher"; import { useAssetMenu } from "@/hooks/useAssetMenu"; import useDecodedParams from "@/hooks/useDecodedParams"; import { Skeleton } from "@/components/ui/skeleton"; -import type { DetailedSecurityAdvisoryDTO } from "@/types/api/api"; +import type { + DetailedSecurityAdvisoryDTO, + VulnEventDTO, +} from "@/types/api/api"; import Severity from "@/components/common/Severity"; import Markdown from "@/components/common/Markdown"; -import { Button } from "@/components/ui/button"; +import { AsyncButton, Button } from "@/components/ui/button"; import { browserApiClient } from "@/services/devGuardApi"; import { AlertDialog, @@ -39,12 +42,24 @@ import AuthGuard from "@/components/AuthGuard"; import { useConfig } from "@/context/ConfigContext"; import RiskAssessmentFeed from "@/components/risk-assessment/RiskAssessmentFeed"; import { useDeleteEvent } from "@/hooks/useDeleteEvent"; +import { Card, CardContent } from "@/components/ui/card"; +import { useSession } from "@/context/SessionContext"; +import dynamic from "next/dynamic"; + +const MarkdownEditor = dynamic( + () => import("@/components/common/MarkdownEditor"), + { ssr: false }, +); const Index = () => { const router = useRouter(); const params = useDecodedParams(); const config = useConfig(); const deleteEvent = useDeleteEvent(); + const { session } = useSession(); + const [justification, setJustification] = useState( + undefined, + ); const { organizationSlug, projectSlug, @@ -80,10 +95,13 @@ const Index = () => { }; const handlePublishAdvisory = async () => { - const resp = await browserApiClient(`${advisoryUrl}` + `/${advisoryId}/`, { - method: "PATCH", - body: JSON.stringify({ visibility: "public" }), - }); + const resp = await browserApiClient( + `${advisoryUrl}` + `/${advisoryId}/events/`, + { + method: "POST", + body: JSON.stringify({ status: "published" }), + }, + ); if (resp.ok) { toast.success("Advisory published successfully"); mutate(`${advisoryUrl}` + `/${advisoryId}/`); @@ -97,10 +115,13 @@ const Index = () => { }; const handleWithdrawAdvisory = async () => { - const resp = await browserApiClient(`${advisoryUrl}` + `/${advisoryId}/`, { - method: "PATCH", - body: JSON.stringify({ visibility: "withdrawn" }), - }); + const resp = await browserApiClient( + `${advisoryUrl}` + `/${advisoryId}/events/`, + { + method: "POST", + body: JSON.stringify({ status: "withdrawn" }), + }, + ); if (resp.ok) { toast.success("Advisory withdrawn successfully"); mutate(`${advisoryUrl}` + `/${advisoryId}/`); @@ -132,6 +153,7 @@ const Index = () => { data: advisory, isLoading, error, + mutate: mutateAdvisory, } = useSWR( organizationSlug && projectSlug && @@ -165,7 +187,7 @@ const Index = () => { ? parseCvssVector(advisory.vectorString) : null; const csafYear = new Date(advisory.createdAt).getFullYear(); - const csafUrl = `${config.devguardApiUrlPublicInternet}/api/v1/organizations/${organizationSlug}/projects/${projectSlug}/assets/${assetSlug}/csaf/white/${csafYear}/dgsa-${csafYear}-${advisory.id}.json`; + const csafUrl = `${config.devguardApiUrlPublicInternet}/api/v1/organizations/${organizationSlug}/projects/${projectSlug}/assets/${assetSlug}/csaf/white/${csafYear}/dgsa-${advisory.id}.json`; const metricDefs = parsed?.version === "4.0" ? CVSS40_METRICS @@ -221,7 +243,71 @@ const Index = () => { const handleDeleteEvent = async (eventId: string) => { await deleteEvent(eventId); - mutate(`${advisoryUrl}` + `/${advisoryId}/`); + mutateAdvisory(); + }; + + const handleSubmit = async (data: { + status?: VulnEventDTO["type"]; + justification?: string; + mechanicalJustification?: string; + }): Promise => { + if (data.status === undefined || !advisory) { + return false; + } + + if (!Boolean(data.justification)) { + toast.error("Please provide a justification"); + return false; + } + + const optimisticEvent = { + type: data.status, + id: "optimistic", + createdAt: new Date().toISOString(), + justification: data.justification ?? "", + mechanicalJustification: data.mechanicalJustification ?? "", + userId: session?.identity.id ?? "", + vulnId: advisory.id, + vulnType: "securityAdvisory", + vulnerabilityName: advisory.title ?? advisory.id, + createdByVexRule: false, + } as VulnEventDTO; + + const mutatePromise = mutateAdvisory( + async (current) => { + const resp = await browserApiClient( + `${advisoryUrl}` + `/${advisoryId}/events/`, + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(data), + }, + ); + const json = await resp.json(); + + if (!json.events) { + toast.error("Failed to add comment"); + throw new Error("Failed to add comment"); + } + setJustification(""); + return { + ...current!, + ...json, + events: current!.events.concat([json.events.slice(-1)[0]]), + }; + }, + { + optimisticData: { + ...advisory, + events: advisory.events.concat([optimisticEvent]), + }, + rollbackOnError: true, + revalidate: false, + }, + ); + + mutatePromise.then(() => toast.success("Comment added")).catch(() => {}); + return true; }; return ( @@ -300,36 +386,67 @@ const Index = () => { />
)} - {advisory.visibility === "draft" && ( -
+ + - - - - -
- )} - {advisory.visibility === "public" && ( -
- - +
+
+ + +
+
+
+ {advisory.visibility === "draft" && ( + <> + + + + + )} + {advisory.visibility === "public" && ( + + )} + + handleSubmit({ status: "comment", justification }) + } + variant={"default"} + > + Comment + +
+
+
-
- )} + +
diff --git a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/page.tsx b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/page.tsx index 4e74f468a..fde467f51 100644 --- a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/page.tsx @@ -96,7 +96,7 @@ const buildColumnsDef = ( const advisory = info.row.original; if (advisory.visibility !== "public") return null; const year = new Date(advisory.createdAt).getFullYear(); - const href = `${csafBaseUrl}/csaf/white/${year}/dgsa-${year}-${advisory.id}.json`; + const href = `${csafBaseUrl}/csaf/white/${year}/dgsa-${advisory.id}.json`; return ( ; case "withdrawn": return ; + case "created": + return ; } } diff --git a/src/types/api/api.ts b/src/types/api/api.ts index fc2552232..9fbf358ba 100644 --- a/src/types/api/api.ts +++ b/src/types/api/api.ts @@ -412,6 +412,10 @@ export interface WithdrawnEventDTO extends BaseVulnEventDTO { type: "withdrawn"; } +export interface CreatedEventDTO extends BaseVulnEventDTO { + type: "created"; +} + export type VulnEventDTO = | AcceptedEventDTO | FixedEventDTO @@ -430,7 +434,8 @@ export type VulnEventDTO = | AttachedComplianceComponentEventDTO | RemovedComplianceComponentEventDTO | PublishedEventDTO - | WithdrawnEventDTO; + | WithdrawnEventDTO + | CreatedEventDTO; export interface CWE { cwe: string; diff --git a/src/utils/view.ts b/src/utils/view.ts index 357a3ff9f..b933a7d98 100644 --- a/src/utils/view.ts +++ b/src/utils/view.ts @@ -188,6 +188,10 @@ export const eventTypeMessages = ( message = "withdrew " + flawName; break; } + case "created": { + message = "created " + flawName; + break; + } } if (event.userAgent === "devguard-mcp-server") { message += " (applied by AI agent)"; @@ -212,8 +216,9 @@ export const evTypeBackground: { [key in VulnEventDTO["type"]]: string } = { licenseDecision: "bg-warning text-warning-foreground!", attachedComplianceComponent: "bg-success text-success-foreground!", removedComplianceComponent: "bg-secondary text-secondary-foreground!", - published: "bg-secondary text-secondary-foreground!", + published: "bg-info text-info-foreground!", withdrawn: "bg-destructive text-destructive-foreground!", + created: "bg-success text-success-foreground!", }; export const osiLicenseHexColors: Record = { From 81579cee5a65613735ac5b45c9a16d15acdbc19c Mon Sep 17 00:00:00 2001 From: Julian Kepka Date: Tue, 21 Jul 2026 17:07:34 +0200 Subject: [PATCH 4/6] fix: semver go fix --- .../refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx | 7 +++++-- src/services/versionCheck.ts | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx index 1621c5424..4b433621d 100644 --- a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx @@ -41,6 +41,7 @@ import AdvisoryDialog, { import AuthGuard from "@/components/AuthGuard"; import { useConfig } from "@/context/ConfigContext"; import RiskAssessmentFeed from "@/components/risk-assessment/RiskAssessmentFeed"; +import { withVPrefix } from "@/services/versionCheck"; import { useDeleteEvent } from "@/hooks/useDeleteEvent"; import { Card, CardContent } from "@/components/ui/card"; import { useSession } from "@/context/SessionContext"; @@ -358,10 +359,12 @@ const Index = () => { {pkg.packageName} - {pkg.semverStart ? `< v${pkg.semverStart}` : "—"} + {pkg.semverStart + ? `< ${withVPrefix(pkg.semverStart)}` + : "—"} - {pkg.semverEnd ? `v${pkg.semverEnd}` : "—"} + {pkg.semverEnd ? withVPrefix(pkg.semverEnd) : "—"} ))} diff --git a/src/services/versionCheck.ts b/src/services/versionCheck.ts index e0c25763a..ca89f9396 100644 --- a/src/services/versionCheck.ts +++ b/src/services/versionCheck.ts @@ -15,6 +15,10 @@ export interface VersionCheckResult { updateAvailable: boolean; } +export function withVPrefix(version: string): string { + return /^v/i.test(version) ? version : `v${version}`; +} + /** Parse a semver-style tag "v1.2.3" → [1, 2, 3]. Returns null on failure. */ function parseSemver(tag: string): [number, number, number] | null { const m = tag.match(/^v?(\d+)\.(\d+)\.(\d+)/); From 7bb33fca7f2ba36d60370fb7df34a4fafdee3b53 Mon Sep 17 00:00:00 2001 From: Julian Kepka Date: Wed, 22 Jul 2026 10:08:13 +0200 Subject: [PATCH 5/6] fix: renamed visibility and semver --- .../advisory/[advisoryId]/page.tsx | 18 +++++++++--------- .../refs/[assetVersionSlug]/advisory/page.tsx | 2 +- src/components/AdvisoryDialog.tsx | 14 +++++++------- src/types/api/api.ts | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx index 4b433621d..e118254b1 100644 --- a/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx +++ b/src/app/(loading-group)/[organizationSlug]/projects/[projectSlug]/assets/[assetSlug]/refs/[assetVersionSlug]/advisory/[advisoryId]/page.tsx @@ -236,9 +236,9 @@ const Index = () => { } as const; const visibilityBadge = visibilityConfig[ - advisory.visibility as keyof typeof visibilityConfig + advisory.state as keyof typeof visibilityConfig ] ?? { - label: advisory.visibility, + label: advisory.state, variant: "secondary" as const, }; @@ -328,7 +328,7 @@ const Index = () => { {visibilityBadge.label} - {advisory.visibility !== "draft" && ( + {advisory.state !== "draft" && ( { {pkg.packageName} - {pkg.semverStart - ? `< ${withVPrefix(pkg.semverStart)}` + {pkg.versionStart + ? `< ${withVPrefix(pkg.versionStart)}` : "—"} - {pkg.semverEnd ? withVPrefix(pkg.semverEnd) : "—"} + {pkg.versionEnd ? withVPrefix(pkg.versionEnd) : "—"} ))} @@ -405,7 +405,7 @@ const Index = () => {
- {advisory.visibility === "draft" && ( + {advisory.state === "draft" && ( <> )} - {advisory.visibility === "public" && ( + {advisory.state === "public" && (