mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-28 11:17:07 +00:00
fix(security): fix Security page table layouts and exploit-risk pagination (#1434)
Image scan sheet: make the finding table the single bounded scroll region (SystemSheet noScroll + flex-fill) so it no longer clips at the bottom on shorter viewports, and give the tables a phone min-width so they scroll horizontally instead of cutting off the right-hand columns. Scan history table: add the same horizontal scroll on phones. Overview "Top exploit-risk findings": render as a paginated table with column headers and top-right pagination, modeled on the dashboard stack-health table. Key the rows by rank position so recurring CVE/scan pairs no longer collide and duplicate rows when paging through. Overview severity-by-exploitability chart: label the axes (EPSS exploitability and CVSS severity) and stop the card from stretching to a taller neighbour, removing the dead space beneath the chart.
This commit is contained in:
@@ -579,6 +579,7 @@ export function VulnerabilityScanSheet({
|
||||
onTabChange={(id) => setTab(id as FindingTab)}
|
||||
footerContext={footerContext}
|
||||
size="lg"
|
||||
noScroll
|
||||
>
|
||||
{loading && !scan && (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
@@ -587,8 +588,11 @@ export function VulnerabilityScanSheet({
|
||||
)}
|
||||
|
||||
{scan && (
|
||||
<>
|
||||
<SheetSection title="Summary">
|
||||
// noScroll skips SystemSheet's default px-6 py-5 wrapper, so supply it
|
||||
// here; SheetSection's -mx-6 bleed depends on this px-6. The column lets
|
||||
// the active finding section flex to fill the sheet (single scroll box).
|
||||
<div className="flex min-h-0 flex-1 flex-col px-6 py-5">
|
||||
<SheetSection title="Summary" className="shrink-0">
|
||||
{scan.policy_evaluation?.violated && (
|
||||
<div
|
||||
role="alert"
|
||||
@@ -717,7 +721,7 @@ export function VulnerabilityScanSheet({
|
||||
</SheetSection>
|
||||
|
||||
{tab === 'vulns' && (
|
||||
<SheetSection title={`Vulnerabilities · ${totalDetails}`}>
|
||||
<SheetSection title={`Vulnerabilities · ${totalDetails}`} className="flex min-h-0 flex-1 flex-col">
|
||||
<div className="flex items-center gap-1 flex-wrap mb-3">
|
||||
{(['ALL', 'CRITICAL', 'HIGH', 'MEDIUM', 'LOW'] as SeverityFilter[]).map((s) => (
|
||||
<Button
|
||||
@@ -766,7 +770,7 @@ export function VulnerabilityScanSheet({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<ScrollArea block className="max-h-[60vh]">
|
||||
<ScrollArea block className="flex-1 min-h-0">
|
||||
{pageItems.length === 0 ? (
|
||||
<div className="text-center text-sm text-muted-foreground py-12">
|
||||
{details.length === 0
|
||||
@@ -774,7 +778,7 @@ export function VulnerabilityScanSheet({
|
||||
: 'No vulnerabilities match the selected filter.'}
|
||||
</div>
|
||||
) : (
|
||||
<Table>
|
||||
<Table className="max-md:min-w-[720px]">
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-[180px] text-[10px] uppercase tracking-[0.18em] font-mono text-stat-subtitle">CVE</TableHead>
|
||||
@@ -866,7 +870,7 @@ export function VulnerabilityScanSheet({
|
||||
)}
|
||||
|
||||
{tab === 'secrets' && (
|
||||
<SheetSection title={`Secrets · ${scan.secret_count ?? secrets.length}`}>
|
||||
<SheetSection title={`Secrets · ${scan.secret_count ?? secrets.length}`} className="flex min-h-0 flex-1 flex-col">
|
||||
{secretsNeedsPagination && (
|
||||
<div className="flex items-center gap-1 mb-3">
|
||||
<div className="flex items-center gap-1 ml-auto">
|
||||
@@ -896,13 +900,13 @@ export function VulnerabilityScanSheet({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<ScrollArea block className="max-h-[60vh]">
|
||||
<ScrollArea block className="flex-1 min-h-0">
|
||||
{secrets.length === 0 ? (
|
||||
<div className="text-center text-sm text-muted-foreground py-12">
|
||||
No secrets detected.
|
||||
</div>
|
||||
) : (
|
||||
<Table>
|
||||
<Table className="max-md:min-w-[720px]">
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-[100px] text-[10px] uppercase tracking-[0.18em] font-mono text-stat-subtitle">Severity</TableHead>
|
||||
@@ -954,7 +958,7 @@ export function VulnerabilityScanSheet({
|
||||
)}
|
||||
|
||||
{tab === 'misconfigs' && (
|
||||
<SheetSection title={`Misconfigs · ${scan.misconfig_count ?? misconfigs.length}`}>
|
||||
<SheetSection title={`Misconfigs · ${scan.misconfig_count ?? misconfigs.length}`} className="flex min-h-0 flex-1 flex-col">
|
||||
{misconfigsNeedsPagination && (
|
||||
<div className="flex items-center gap-1 mb-3">
|
||||
<div className="flex items-center gap-1 ml-auto">
|
||||
@@ -986,13 +990,13 @@ export function VulnerabilityScanSheet({
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<ScrollArea block className="max-h-[60vh]">
|
||||
<ScrollArea block className="flex-1 min-h-0">
|
||||
{misconfigs.length === 0 ? (
|
||||
<div className="text-center text-sm text-muted-foreground py-12">
|
||||
No misconfigurations detected.
|
||||
</div>
|
||||
) : (
|
||||
<Table>
|
||||
<Table className="max-md:min-w-[720px]">
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-[100px] text-[10px] uppercase tracking-[0.18em] font-mono text-stat-subtitle">Severity</TableHead>
|
||||
@@ -1080,7 +1084,7 @@ export function VulnerabilityScanSheet({
|
||||
</ScrollArea>
|
||||
</SheetSection>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
)}
|
||||
</SystemSheet>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user