mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-31 20:58:04 +00:00
feat(security): scan comparison UI (#648)
Side-by-side vulnerability scan comparison with two entry points: - Compare button plus inline baseline picker inside the scan drawer. - New Scan History page reachable from the Resources Hub, grouping completed scans by image with a checkbox selection flow. The comparison sheet shows a severity delta ribbon, Added/Removed/Unchanged filters, and a paginated CVE table. Cross-image comparisons are allowed but flagged with a warning. Compare access is gated to Skipper and Admiral tiers; the underlying /security/compare endpoint is unchanged.
This commit is contained in:
@@ -17,10 +17,11 @@ import { Switch } from "@/components/ui/switch";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||
import { apiFetch } from '@/lib/api';
|
||||
import { toast } from '@/components/ui/toast-store';
|
||||
import { Trash2, HardDrive, Network, PackageMinus, MonitorX, MoreVertical, AlertTriangle, ShieldCheck, Plus, Eye, Copy, Container, Loader2 } from 'lucide-react';
|
||||
import { Trash2, HardDrive, Network, PackageMinus, MonitorX, MoreVertical, AlertTriangle, ShieldCheck, Plus, Eye, Copy, Container, Loader2, History } from 'lucide-react';
|
||||
import { CursorProvider, CursorContainer, Cursor, CursorFollow } from '@/components/animate-ui/primitives/animate/cursor';
|
||||
import { useTrivyStatus } from '@/hooks/useTrivyStatus';
|
||||
import { VulnerabilityScanSheet } from './VulnerabilityScanSheet';
|
||||
import { SENCHO_NAVIGATE_EVENT, type SenchoNavigateDetail } from './NodeManager';
|
||||
import type { ScanSummary, VulnSeverity } from '@/types/security';
|
||||
import { useNodes } from '@/context/NodeContext';
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
@@ -705,6 +706,22 @@ export default function ResourcesView() {
|
||||
{activeNode?.type === 'remote' && (
|
||||
<span className="text-sm text-muted-foreground">- {activeNode.name}</span>
|
||||
)}
|
||||
{trivy.available && isPaid && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="ml-auto border-border"
|
||||
onClick={() => {
|
||||
window.dispatchEvent(new CustomEvent<SenchoNavigateDetail>(SENCHO_NAVIGATE_EVENT, {
|
||||
detail: { view: 'security-history' },
|
||||
}));
|
||||
}}
|
||||
title="View completed vulnerability scans and compare them"
|
||||
>
|
||||
<History className="w-4 h-4 mr-2" strokeWidth={1.5} />
|
||||
Scan history
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Top row: Footprint + Quick Clean */}
|
||||
@@ -1473,6 +1490,7 @@ export default function ResourcesView() {
|
||||
onClose={() => setInspectScanId(null)}
|
||||
onRescan={(imageRef) => { setInspectScanId(null); handleScanImage(imageRef, true); }}
|
||||
canGenerateSbom={isPaid}
|
||||
canCompare={isPaid}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user