Improve Arc-style sidebar UI for better space utilization

- Put Browse Files and Kill buttons on the same line in sidebar header
- Remove "running" text from session status, keep only the colored dot
- Apply home directory path filtering (~/...) for better readability
- Import and use formatPathForDisplay from path-utils

These changes maximize usable space in the vertical tabs sidebar.
This commit is contained in:
Peter Steinberger 2025-06-24 04:32:36 +02:00
parent b72e038786
commit 763d9ce8f0
4 changed files with 79 additions and 44 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 795 B

View file

@ -434,6 +434,45 @@ private struct ServerConfigurationSection: View {
} header: {
Text("Server Configuration")
.font(.headline)
} footer: {
// Dashboard URL display
if accessMode == .localhost {
HStack(spacing: 5) {
Text("Dashboard available at")
.font(.caption)
.foregroundStyle(.secondary)
if let url = URL(string: "http://127.0.0.1:\(serverPort)") {
Link(url.absoluteString, destination: url)
.font(.caption)
.foregroundStyle(.blue)
}
}
.frame(maxWidth: .infinity)
.multilineTextAlignment(.center)
} else if accessMode == .network {
if let ip = localIPAddress {
HStack(spacing: 5) {
Text("Dashboard available at")
.font(.caption)
.foregroundStyle(.secondary)
if let url = URL(string: "http://\(ip):\(serverPort)") {
Link(url.absoluteString, destination: url)
.font(.caption)
.foregroundStyle(.blue)
}
}
.frame(maxWidth: .infinity)
.multilineTextAlignment(.center)
} else {
Text("Fetching local IP address...")
.font(.caption)
.foregroundStyle(.secondary)
.frame(maxWidth: .infinity)
.multilineTextAlignment(.center)
}
}
}
}
}
@ -646,6 +685,7 @@ private struct NgrokIntegrationSection: View {
} footer: {
Text("ngrok creates secure tunnels to your dashboard from anywhere.")
.font(.caption)
.frame(maxWidth: .infinity)
.multilineTextAlignment(.center)
}
}

View file

@ -24,6 +24,7 @@ import type { AuthClient } from '../services/auth-client.js';
import './session-create-form.js';
import './session-card.js';
import { createLogger } from '../utils/logger.js';
import { formatPathForDisplay } from '../utils/path-utils.js';
const logger = createLogger('session-list');
@ -281,22 +282,16 @@ export class SessionList extends LitElement {
${session.name || session.command}
</div>
<div class="text-xs text-dark-text-muted truncate">
${session.workingDir}
${formatPathForDisplay(session.workingDir)}
</div>
</div>
<div class="flex items-center gap-2 flex-shrink-0">
<span
class="${session.status === 'running'
? 'text-status-success'
: 'text-status-warning'} text-xs flex items-center gap-1"
>
<div
class="w-2 h-2 rounded-full ${session.status === 'running'
? 'bg-status-success'
: 'bg-status-warning'}"
></div>
${session.status}
</span>
<div
class="w-2 h-2 rounded-full ${session.status === 'running'
? 'bg-status-success'
: 'bg-status-warning'}"
title="${session.status}"
></div>
${session.status === 'running' || session.status === 'exited'
? html`
<button

View file

@ -51,15 +51,18 @@ export class SidebarHeader extends HeaderBase {
</button>
<div class="flex flex-col gap-1 w-full max-w-[200px]">
<button
class="btn-ghost font-mono text-xs px-3 py-1.5 w-full"
@click=${this.handleOpenFileBrowser}
title="Browse files"
>
Browse Files
</button>
${this.renderUtilityAndKillButtons(runningSessions)}
${this.renderExitedToggleButton(exitedSessions, true)}
${this.renderActionButtons(exitedSessions, runningSessions, true)}
${!this.hideExited && exitedSessions.length > 0
? html`
<button
class="btn-ghost font-mono text-xs px-3 py-1.5 w-full text-status-warning"
@click=${this.handleCleanExited}
>
Clean Exited (${exitedSessions.length})
</button>
`
: ''}
</div>
</div>
</div>
@ -113,30 +116,27 @@ export class SidebarHeader extends HeaderBase {
`;
}
private renderActionButtons(
exitedSessions: Session[],
runningSessions: Session[],
compact: boolean
) {
const buttonClass = compact
? 'btn-ghost font-mono text-xs px-3 py-1.5 w-full'
: 'btn-ghost font-mono text-xs px-4 py-2';
private renderUtilityAndKillButtons(runningSessions: Session[]) {
return html`
${!this.hideExited && exitedSessions.length > 0
? html`
<button class="${buttonClass} text-status-warning" @click=${this.handleCleanExited}>
Clean Exited (${exitedSessions.length})
</button>
`
: ''}
${runningSessions.length > 0 && !this.killingAll
? html`
<button class="${buttonClass} text-status-error" @click=${this.handleKillAll}>
Kill (${runningSessions.length})
</button>
`
: ''}
<div class="flex gap-1 w-full">
<button
class="btn-ghost font-mono text-xs px-3 py-1.5 flex-1"
@click=${this.handleOpenFileBrowser}
title="Browse files"
>
Browse Files
</button>
${runningSessions.length > 0 && !this.killingAll
? html`
<button
class="btn-ghost font-mono text-xs px-3 py-1.5 flex-1 text-status-error"
@click=${this.handleKillAll}
>
Kill (${runningSessions.length})
</button>
`
: ''}
</div>
`;
}
}