mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-06-29 05:39:31 +00:00
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:
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 |
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue