diff --git a/src/Web/autopilot-monitor-web/app/admin/components/VulnerabilityDataSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/VulnerabilityDataSection.tsx index a255adb3..21d02454 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/VulnerabilityDataSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/VulnerabilityDataSection.tsx @@ -4,6 +4,7 @@ import { useCallback, useEffect, useState } from "react"; import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import SaveResetBar from "../../settings/components/SaveResetBar"; +import VulnerabilityExposurePanel from "@/components/VulnerabilityExposurePanel"; import type { AdminConfiguration } from "@/types/adminConfig"; interface VulnerabilityTopCve { @@ -325,19 +326,6 @@ export function VulnerabilityDataSection({ } }, [getAccessToken, setError, onAdminConfigUpdated, refreshSyncStatus]); - const severityChipClass = (sev: string): string => { - switch (sev.toLowerCase()) { - case "critical": - return "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300 border-red-300 dark:border-red-700"; - case "high": - return "bg-orange-100 text-orange-800 dark:bg-orange-900/30 dark:text-orange-300 border-orange-300 dark:border-orange-700"; - case "medium": - return "bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-300 border-amber-300 dark:border-amber-700"; - default: - return "bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600"; - } - }; - const formatTimestamp = (ts: string | undefined): string => { if (!ts) return "Never"; try { @@ -587,134 +575,16 @@ export function VulnerabilityDataSection({ {/* Fleet Vulnerability Exposure (read-only cross-tenant overview) */} -
- No vulnerability findings in the last {summary?.windowDays ?? summaryDays} days. - {!vulnerabilityCorrelationEnabled && " Correlation is currently disabled."} -
- )} -| toggleSort("appName")}>App {sortIndicator("appName")} | +toggleSort("totalInstalls")}>Installs {sortIndicator("totalInstalls")} | +toggleSort("succeeded")}>Succeeded {sortIndicator("succeeded")} | +toggleSort("failed")}>Failed {sortIndicator("failed")} | +toggleSort("failureRate")}>Failure Rate {sortIndicator("failureRate")} | +toggleSort("avgDurationSeconds")}>Avg Duration {sortIndicator("avgDurationSeconds")} | +toggleSort("trend")}>Trend {sortIndicator("trend")} | +
|---|---|---|---|---|---|---|
| + {row.appName} + {appTypeBadge(row.appType)} + | +{row.totalInstalls} | +{row.succeeded} | +{row.failed} | ++ = 20 ? "text-red-700 font-semibold" : row.failureRate >= 5 ? "text-amber-700" : "text-gray-700"}> + {row.failureRate.toFixed(1)}% + + | +{formatDuration(row.avgDurationSeconds, "—")} | +{trendBadge(row)} | +
| Software | +Version | +Publisher | +Sessions | +Last seen | +CPE | +
|---|---|---|---|---|---|
| {row.displayName || row.normalizedName} | +{row.normalizedVersion || "—"} | +{row.publisher || "—"} | +{row.sessionCount} | +{formatDate(row.lastSeenAt)} | ++ {row.cpeUri ? ( + mapped + ) : ( + unmatched + )} + | +
+ App installs, the installed-software inventory, and vulnerability exposure across enrollments. +
+- All apps observed across enrollments, sortable by failure rate, duration, and trend. -
-| toggleSort("appName")} - > - App {sortIndicator("appName")} - | -toggleSort("totalInstalls")} - > - Installs {sortIndicator("totalInstalls")} - | -toggleSort("succeeded")} - > - Succeeded {sortIndicator("succeeded")} - | -toggleSort("failed")} - > - Failed {sortIndicator("failed")} - | -toggleSort("failureRate")} - > - Failure Rate {sortIndicator("failureRate")} - | -toggleSort("avgDurationSeconds")} - > - Avg Duration {sortIndicator("avgDurationSeconds")} - | -toggleSort("trend")} - > - Trend {sortIndicator("trend")} - | -
|---|---|---|---|---|---|---|
| - {row.appName} - {appTypeBadge(row.appType)} - | -{row.totalInstalls} | -{row.succeeded} | -{row.failed} | -- = 20 - ? "text-red-700 font-semibold" - : row.failureRate >= 5 - ? "text-amber-700" - : "text-gray-700" - } - > - {row.failureRate.toFixed(1)}% - - | -- {formatDuration(row.avgDurationSeconds)} - | -{trendBadge(row)} | -