style(cluster): one header row in the docked pane

The pane drew its own title bar above the grid's toolbar, so the cluster spent
two lines on headers where Recent QSOs beside it spent one — in a pane often
only a few spots tall. The grid's toolbar now takes what the caller wants on its
left, and the pane passes its title, live count and Filters button there.
Reported by VK4DX.
This commit is contained in:
2026-08-28 13:15:41 +02:00
parent f7b9aa2181
commit 30f74583ff
3 changed files with 24 additions and 9 deletions
+11 -5
View File
@@ -6236,13 +6236,19 @@ export default function App() {
case 'cluster':
return (
<div className="h-full w-full min-h-0 flex flex-col bg-card border border-border rounded-lg overflow-hidden">
<div className="flex items-center justify-between px-2 py-1 border-b border-border/60 shrink-0">
<span className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground">Cluster</span>
{clusterFiltersToggleBtn}
</div>
<div className="flex-1 min-h-0 flex">
<div className="flex-1 min-w-0 flex flex-col min-h-0">
<ClusterGrid key={`clg-${activeProfileId ?? 'x'}`} rows={clusterRenderedRows as any} spotStatus={spotStatus} onSpotClick={handleSpotClick} onSpotSelect={handleSpotSelect} />
{/* Title, count and Filters ride INSIDE the grid's toolbar: two
header rows cost a pane that is often only a few spots tall
one of the few lines it has. */}
<ClusterGrid key={`clg-${activeProfileId ?? 'x'}`} rows={clusterRenderedRows as any} spotStatus={spotStatus} onSpotClick={handleSpotClick} onSpotSelect={handleSpotSelect}
headerLeft={(
<>
<span className="text-[11px] font-semibold uppercase tracking-wider text-muted-foreground shrink-0">DX Cluster</span>
<Badge variant="secondary" className="text-[10px] shrink-0">{spots.length} live</Badge>
{clusterFiltersToggleBtn}
</>
)} />
</div>
{clusterShowFilters && renderClusterFilters()}
</div>