fix(ui): fix device header layout for narrow viewports

Two-row layout: top row is identity (breadcrumb › dot hostname status),
bottom row is metadata left + actions right. Hostname truncates instead
of wrapping. Metadata truncates. Actions stay on one line and push
against the right edge. No overlap at any width.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-21 13:18:32 -05:00
parent 2fd98fece0
commit 814cf3b1e7

View File

@@ -433,54 +433,47 @@ function DeviceDetailPage() {
<div className={cn('space-y-4', mode === 'simple' ? 'max-w-5xl' : 'max-w-3xl')} data-testid="device-detail"> <div className={cn('space-y-4', mode === 'simple' ? 'max-w-5xl' : 'max-w-3xl')} data-testid="device-detail">
{/* Device workspace header */} {/* Device workspace header */}
<div className="bg-sidebar border border-border-default rounded-sm px-3 py-1.5"> <div className="bg-sidebar border border-border-default rounded-sm px-3 py-1.5">
<div className="flex justify-between items-center"> {/* Top row: device identity */}
<div className="min-w-0"> <div className="flex items-center gap-1.5 min-w-0">
{/* Breadcrumb */} <Link
<div className="mb-px"> to="/tenants/$tenantId/devices"
<Link params={{ tenantId }}
to="/tenants/$tenantId/devices" className="text-[8px] text-text-muted hover:text-text-secondary transition-[color] duration-[50ms] flex-shrink-0"
params={{ tenantId }} >
className="text-[8px] text-text-muted hover:text-text-secondary transition-[color] duration-[50ms]" Devices
> </Link>
Devices <span className="text-[8px] text-text-muted flex-shrink-0">&rsaquo;</span>
</Link> <div className={cn(
<span className="text-[8px] text-text-muted mx-1">&rsaquo;</span> 'w-1.5 h-1.5 rounded-full flex-shrink-0',
<span className="text-[8px] text-text-secondary">{device.hostname}</span> device.status === 'online' ? 'bg-online' :
</div> device.status === 'degraded' ? 'bg-warning' : 'bg-offline'
{/* Device name + status dot + label */} )} />
<div className="flex items-center gap-1.5"> <h1 className="text-[13px] font-semibold text-text-primary truncate" data-testid="device-hostname">
<div className={cn( {device.hostname}
'w-1.5 h-1.5 rounded-full flex-shrink-0', </h1>
device.status === 'online' ? 'bg-online' : <span className={cn(
device.status === 'degraded' ? 'bg-warning' : 'bg-offline' 'text-[9px] flex-shrink-0',
)} /> device.status === 'online' ? 'text-online' :
<h1 className="text-[13px] font-semibold text-text-primary truncate" data-testid="device-hostname"> device.status === 'degraded' ? 'text-warning' : 'text-offline'
{device.hostname} )}>
</h1> {device.status}
<span className={cn( </span>
'text-[9px] flex-shrink-0', <TlsSecurityBadge tlsMode={device.tls_mode} />
device.status === 'online' ? 'text-online' : </div>
device.status === 'degraded' ? 'text-warning' : 'text-offline' {/* Metadata + actions row */}
)}> <div className="flex items-center justify-between mt-0.5 gap-2">
{device.status} <div className="text-[9px] text-text-secondary truncate pl-[9px]">
</span> {device.model ?? device.board_name ?? '\u2014'}
<TlsSecurityBadge tlsMode={device.tls_mode} /> {' \u00b7 '}
</div> <span className="font-mono text-[8px]">{device.ip_address}</span>
{/* Metadata */} {device.routeros_version && (
<div className="text-[9px] text-text-secondary mt-px pl-[9px]"> <>
{device.model ?? device.board_name ?? '\u2014'} {' \u00b7 '}
{' \u00b7 '} <span className="font-mono text-[8px]">v{device.routeros_version}</span>
<span className="font-mono text-[8px]">{device.ip_address}</span> </>
{device.routeros_version && ( )}
<>
{' \u00b7 '}
<span className="font-mono text-[8px]">v{device.routeros_version}</span>
</>
)}
</div>
</div> </div>
{/* Actions */} <div className="flex items-center gap-1 flex-shrink-0">
<div className="flex items-center gap-1 flex-shrink-0 ml-3">
<SimpleModeToggle mode={mode} onModeChange={toggleMode} /> <SimpleModeToggle mode={mode} onModeChange={toggleMode} />
{user?.role !== 'viewer' && device.routeros_version !== null && ( {user?.role !== 'viewer' && device.routeros_version !== null && (
<> <>