fix(ui): declutter device page header — compact tool buttons

- WinBox/RemoteWinBox/SSH: replace big accent CTAs with compact
  bordered tool buttons (text-[10px], h-3 icons, border-default)
- SimpleModeToggle: shrink from pill-button group to inline segmented
  control (text-[10px], accent-soft active state)
- Edit/Delete already icon-only ghost from previous commit
- All tool buttons now visually consistent — small, bordered, receding
- Result: header reads as a compact control strip, not a CTA row

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jason Staack
2026-03-21 12:55:02 -05:00
parent f7b95adfd2
commit 329e363b2f
4 changed files with 44 additions and 45 deletions

View File

@@ -162,26 +162,26 @@ export function RemoteWinBoxButton({ tenantId, deviceId }: RemoteWinBoxButtonPro
if (state === 'idle' || state === 'failed' || state === 'terminated') { if (state === 'idle' || state === 'failed' || state === 'terminated') {
return ( return (
<div> <div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-1">
<button <button
onClick={handleOpen} onClick={handleOpen}
disabled={createMutation.isPending} disabled={createMutation.isPending}
className="inline-flex items-center gap-2 px-4 py-2 rounded-md bg-accent text-white hover:bg-accent/90 disabled:opacity-50" className="inline-flex items-center gap-1 px-2 py-1 rounded-[var(--radius-control)] text-[10px] text-text-secondary border border-border-default hover:border-accent transition-[border-color,color] duration-[50ms] disabled:opacity-50"
title="Open Remote WinBox (browser)"
> >
{createMutation.isPending ? ( {createMutation.isPending ? (
<Loader2 className="h-4 w-4 animate-spin" /> <Loader2 className="h-3 w-3 animate-spin" />
) : ( ) : (
<Globe className="h-4 w-4" /> <Globe className="h-3 w-3" />
)} )}
{createMutation.isPending ? 'Starting...' : 'Remote WinBox'} {createMutation.isPending ? 'Starting' : 'Remote'}
</button> </button>
<button <button
onClick={handleReset} onClick={handleReset}
className="inline-flex items-center gap-2 px-4 py-2 rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground" className="inline-flex items-center px-1.5 py-1 rounded-[var(--radius-control)] text-text-muted border border-border-default hover:border-accent transition-[border-color] duration-[50ms]"
title="Reset all remote WinBox sessions for this device" title="Reset remote sessions"
> >
<RefreshCw className="h-4 w-4" /> <RefreshCw className="h-3 w-3" />
Reset
</button> </button>
</div> </div>
{state === 'failed' && error && ( {state === 'failed' && error && (

View File

@@ -162,10 +162,11 @@ export function SSHTerminal({ tenantId, deviceId, deviceName }: SSHTerminalProps
return ( return (
<button <button
onClick={handleOpen} onClick={handleOpen}
className="inline-flex items-center gap-2 px-4 py-2 rounded-md bg-accent text-white hover:bg-accent/90" className="inline-flex items-center gap-1 px-2 py-1 rounded-[var(--radius-control)] text-[10px] text-text-secondary border border-border-default hover:border-accent transition-[border-color,color] duration-[50ms]"
title="Open SSH Terminal"
> >
<TerminalIcon className="h-4 w-4" /> <TerminalIcon className="h-3 w-3" />
SSH Terminal SSH
</button> </button>
) )
} }

View File

@@ -78,14 +78,15 @@ export function WinBoxButton({ tenantId, deviceId }: WinBoxButtonProps) {
openMutation.mutate() openMutation.mutate()
}} }}
disabled={openMutation.isPending} disabled={openMutation.isPending}
className="inline-flex items-center gap-2 px-4 py-2 rounded-md bg-accent text-white hover:bg-accent/90 disabled:opacity-50" className="inline-flex items-center gap-1 px-2 py-1 rounded-[var(--radius-control)] text-[10px] text-text-secondary border border-border-default hover:border-accent transition-[border-color,color] duration-[50ms] disabled:opacity-50"
title="Open WinBox tunnel"
> >
{openMutation.isPending ? ( {openMutation.isPending ? (
<Loader2 className="h-4 w-4 animate-spin" /> <Loader2 className="h-3 w-3 animate-spin" />
) : ( ) : (
<Monitor className="h-4 w-4" /> <Monitor className="h-3 w-3" />
)} )}
{openMutation.isPending ? 'Connecting...' : 'Open WinBox'} {openMutation.isPending ? 'Connecting' : 'WinBox'}
</button> </button>
{error && <p className="mt-2 text-sm text-error">{error}</p>} {error && <p className="mt-2 text-sm text-error">{error}</p>}
</div> </div>
@@ -94,18 +95,17 @@ export function WinBoxButton({ tenantId, deviceId }: WinBoxButtonProps) {
if (state === 'ready' && tunnelInfo) { if (state === 'ready' && tunnelInfo) {
return ( return (
<div className="rounded-md border p-4 space-y-3"> <div className="rounded-sm border border-border-default bg-panel p-2.5 space-y-2">
<p className="font-medium text-sm">WinBox tunnel ready</p> <p className="text-xs text-text-primary">
<p className="text-sm text-text-muted"> Tunnel ready: <code className="font-mono text-[10px] text-text-secondary">{tunnelInfo.host}:{tunnelInfo.port}</code>
Connect to: <code className="font-mono">{tunnelInfo.host}:{tunnelInfo.port}</code>
</p> </p>
<div className="flex gap-2"> <div className="flex gap-1">
<button <button
onClick={copyAddress} onClick={copyAddress}
className="inline-flex items-center gap-2 px-3 py-1.5 text-sm rounded-md border hover:bg-accent" className="inline-flex items-center gap-1 px-2 py-0.5 text-[10px] rounded-[var(--radius-control)] border border-border-default text-text-secondary hover:border-accent transition-[border-color] duration-[50ms]"
> >
<Copy className="h-3 w-3" /> <Copy className="h-2.5 w-2.5" />
{copied ? 'Copied!' : 'Copy Address'} {copied ? 'Copied' : 'Copy'}
</button> </button>
<button <button
onClick={() => { onClick={() => {
@@ -113,15 +113,13 @@ export function WinBoxButton({ tenantId, deviceId }: WinBoxButtonProps) {
closeMutation.mutate() closeMutation.mutate()
}} }}
disabled={closeMutation.isPending} disabled={closeMutation.isPending}
className="inline-flex items-center gap-2 px-3 py-1.5 text-sm rounded-md border hover:bg-accent disabled:opacity-50" className="inline-flex items-center gap-1 px-2 py-0.5 text-[10px] rounded-[var(--radius-control)] border border-border-default text-text-muted hover:border-accent disabled:opacity-50 transition-[border-color] duration-[50ms]"
> >
<X className="h-3 w-3" /> <X className="h-2.5 w-2.5" />
Close Tunnel Close
</button> </button>
</div> </div>
<p className="text-xs text-text-muted"> <p className="text-[9px] text-text-muted">Closes after 5 min idle</p>
Tunnel closes after 5 min of inactivity
</p>
</div> </div>
) )
} }

View File

@@ -14,31 +14,31 @@ interface SimpleModeToggleProps {
export function SimpleModeToggle({ mode, onModeChange }: SimpleModeToggleProps) { export function SimpleModeToggle({ mode, onModeChange }: SimpleModeToggleProps) {
return ( return (
<div className="flex items-center gap-1 rounded-lg border border-border bg-elevated/50 p-1"> <div className="flex items-center gap-px rounded-[var(--radius-control)] border border-border-default overflow-hidden">
<Button <button
variant="ghost"
size="sm"
onClick={() => onModeChange('simple')} onClick={() => onModeChange('simple')}
className={cn( className={cn(
'gap-1.5 h-7 px-2.5 text-xs', 'flex items-center gap-1 px-1.5 py-0.5 text-[10px] transition-[background-color,color] duration-[50ms]',
mode === 'simple' && 'bg-accent/20 text-accent', mode === 'simple'
? 'bg-accent-soft text-text-primary font-medium'
: 'text-text-muted hover:text-text-secondary',
)} )}
> >
<LayoutGrid className="h-3.5 w-3.5" /> <LayoutGrid className="h-2.5 w-2.5" />
Simple Simple
</Button> </button>
<Button <button
variant="ghost"
size="sm"
onClick={() => onModeChange('standard')} onClick={() => onModeChange('standard')}
className={cn( className={cn(
'gap-1.5 h-7 px-2.5 text-xs', 'flex items-center gap-1 px-1.5 py-0.5 text-[10px] transition-[background-color,color] duration-[50ms]',
mode === 'standard' && 'bg-accent/20 text-accent', mode === 'standard'
? 'bg-accent-soft text-text-primary font-medium'
: 'text-text-muted hover:text-text-secondary',
)} )}
> >
<Sliders className="h-3.5 w-3.5" /> <Sliders className="h-2.5 w-2.5" />
Standard Standard
</Button> </button>
</div> </div>
) )
} }