mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
design: reorganize header buttons and move clear to bottom
This commit is contained in:
parent
74bdcfe185
commit
d7f0846b5a
2 changed files with 67 additions and 61 deletions
|
|
@ -43,12 +43,17 @@ export class FullHeader extends HeaderBase {
|
||||||
|
|
||||||
<div class="flex flex-col sm:flex-row gap-3 sm:items-center">
|
<div class="flex flex-col sm:flex-row gap-3 sm:items-center">
|
||||||
<div class="flex gap-2 items-center">
|
<div class="flex gap-2 items-center">
|
||||||
|
<notification-status
|
||||||
|
@open-settings=${() =>
|
||||||
|
this.dispatchEvent(new CustomEvent('open-notification-settings'))}
|
||||||
|
></notification-status>
|
||||||
|
${this.renderActionButtons(exitedSessions, runningSessions)}
|
||||||
<button
|
<button
|
||||||
class="btn-secondary font-mono text-xs px-4 py-2"
|
class="btn-secondary font-mono text-sm px-5 py-2.5"
|
||||||
@click=${() => this.dispatchEvent(new CustomEvent('open-file-browser'))}
|
@click=${() => this.dispatchEvent(new CustomEvent('open-file-browser'))}
|
||||||
title="Browse Files (⌘O)"
|
title="Browse Files (⌘O)"
|
||||||
>
|
>
|
||||||
<span class="flex items-center gap-1">
|
<span class="flex items-center gap-2">
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
|
||||||
<path
|
<path
|
||||||
d="M1.75 1h5.5c.966 0 1.75.784 1.75 1.75v1h4c.966 0 1.75.784 1.75 1.75v7.75A1.75 1.75 0 0113 15H3a1.75 1.75 0 01-1.75-1.75V2.75C1.25 1.784 1.784 1 1.75 1zM2.75 2.5v10.75c0 .138.112.25.25.25h10a.25.25 0 00.25-.25V5.5a.25.25 0 00-.25-.25H8.75v-2.5a.25.25 0 00-.25-.25h-5.5a.25.25 0 00-.25.25z"
|
d="M1.75 1h5.5c.966 0 1.75.784 1.75 1.75v1h4c.966 0 1.75.784 1.75 1.75v7.75A1.75 1.75 0 0113 15H3a1.75 1.75 0 01-1.75-1.75V2.75C1.25 1.784 1.784 1 1.75 1zM2.75 2.5v10.75c0 .138.112.25.25.25h10a.25.25 0 00.25-.25V5.5a.25.25 0 00-.25-.25H8.75v-2.5a.25.25 0 00-.25-.25h-5.5a.25.25 0 00-.25.25z"
|
||||||
|
|
@ -57,12 +62,8 @@ export class FullHeader extends HeaderBase {
|
||||||
Browse
|
Browse
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<notification-status
|
|
||||||
@open-settings=${() =>
|
|
||||||
this.dispatchEvent(new CustomEvent('open-notification-settings'))}
|
|
||||||
></notification-status>
|
|
||||||
<button
|
<button
|
||||||
class="btn-primary font-mono text-sm px-6 py-2 vt-create-button"
|
class="btn-primary font-mono text-sm px-5 py-2.5 vt-create-button"
|
||||||
@click=${this.handleCreateSession}
|
@click=${this.handleCreateSession}
|
||||||
>
|
>
|
||||||
Create Session
|
Create Session
|
||||||
|
|
@ -70,65 +71,19 @@ export class FullHeader extends HeaderBase {
|
||||||
${this.renderUserMenu()}
|
${this.renderUserMenu()}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col sm:flex-row gap-2 sm:items-center">
|
|
||||||
${this.renderExitedToggleButton(exitedSessions)}
|
|
||||||
${this.renderActionButtons(exitedSessions, runningSessions)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderExitedToggleButton(exitedSessions: Session[]) {
|
private renderActionButtons(_exitedSessions: Session[], runningSessions: Session[]) {
|
||||||
if (exitedSessions.length === 0) return '';
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<button
|
|
||||||
class="relative font-mono text-xs px-4 py-2 rounded-lg border transition-all duration-200 ${
|
|
||||||
this.hideExited
|
|
||||||
? 'border-dark-border bg-dark-bg-tertiary text-dark-text hover:border-accent-green-darker'
|
|
||||||
: 'border-accent-green bg-accent-green text-dark-bg hover:bg-accent-green-darker'
|
|
||||||
}"
|
|
||||||
@click=${this.handleHideExitedToggle}
|
|
||||||
>
|
|
||||||
<div class="flex items-center gap-3">
|
|
||||||
<span>Show Exited (${exitedSessions.length})</span>
|
|
||||||
<div
|
|
||||||
class="w-8 h-4 rounded-full transition-colors duration-200 ${
|
|
||||||
this.hideExited ? 'bg-dark-border' : 'bg-dark-bg'
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="w-3 h-3 rounded-full transition-transform duration-200 mt-0.5 ${
|
|
||||||
this.hideExited ? 'translate-x-0.5 bg-dark-text-muted' : 'translate-x-4 bg-dark-bg'
|
|
||||||
}"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private renderActionButtons(exitedSessions: Session[], runningSessions: Session[]) {
|
|
||||||
return html`
|
|
||||||
${
|
|
||||||
!this.hideExited && exitedSessions.length > 0
|
|
||||||
? html`
|
|
||||||
<button
|
|
||||||
class="btn-ghost font-mono text-xs px-4 py-2 text-status-warning"
|
|
||||||
@click=${this.handleCleanExited}
|
|
||||||
>
|
|
||||||
Clean Exited (${exitedSessions.length})
|
|
||||||
</button>
|
|
||||||
`
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
${
|
${
|
||||||
runningSessions.length > 0 && !this.killingAll
|
runningSessions.length > 0 && !this.killingAll
|
||||||
? html`
|
? html`
|
||||||
<button
|
<button
|
||||||
class="btn-ghost font-mono text-xs px-4 py-2 text-status-error"
|
class="btn-secondary font-mono text-sm px-5 py-2.5 text-status-error border-status-error hover:bg-status-error hover:text-dark-bg"
|
||||||
@click=${this.handleKillAll}
|
@click=${this.handleKillAll}
|
||||||
>
|
>
|
||||||
Kill All (${runningSessions.length})
|
Kill All (${runningSessions.length})
|
||||||
|
|
@ -139,11 +94,11 @@ export class FullHeader extends HeaderBase {
|
||||||
${
|
${
|
||||||
this.killingAll
|
this.killingAll
|
||||||
? html`
|
? html`
|
||||||
<div class="flex items-center gap-2 px-4 py-2">
|
<div class="flex items-center gap-2 px-5 py-2.5">
|
||||||
<div
|
<div
|
||||||
class="w-4 h-4 border-2 border-status-error border-t-transparent rounded-full animate-spin"
|
class="w-4 h-4 border-2 border-status-error border-t-transparent rounded-full animate-spin"
|
||||||
></div>
|
></div>
|
||||||
<span class="text-status-error font-mono text-xs">Killing...</span>
|
<span class="text-status-error font-mono text-sm">Killing...</span>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ''
|
: ''
|
||||||
|
|
@ -157,7 +112,7 @@ export class FullHeader extends HeaderBase {
|
||||||
return html`
|
return html`
|
||||||
<div class="user-menu-container relative">
|
<div class="user-menu-container relative">
|
||||||
<button
|
<button
|
||||||
class="btn-ghost font-mono text-xs text-dark-text flex items-center gap-1"
|
class="btn-secondary font-mono text-sm px-5 py-2.5 text-dark-text border-dark-border hover:bg-dark-bg-tertiary hover:border-accent-green flex items-center gap-2"
|
||||||
@click=${this.toggleUserMenu}
|
@click=${this.toggleUserMenu}
|
||||||
title="User menu"
|
title="User menu"
|
||||||
>
|
>
|
||||||
|
|
@ -176,15 +131,15 @@ export class FullHeader extends HeaderBase {
|
||||||
this.showUserMenu
|
this.showUserMenu
|
||||||
? html`
|
? html`
|
||||||
<div
|
<div
|
||||||
class="absolute right-0 top-full mt-1 bg-dark-surface border border-dark-border rounded shadow-lg py-1 z-50 min-w-32"
|
class="absolute right-0 top-full mt-1 bg-dark-surface border border-dark-border rounded-lg shadow-lg py-1 z-50 min-w-36"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="px-3 py-2 text-xs text-dark-text-muted border-b border-dark-border"
|
class="px-3 py-2 text-sm text-dark-text-muted border-b border-dark-border"
|
||||||
>
|
>
|
||||||
${this.authMethod || 'authenticated'}
|
${this.authMethod || 'authenticated'}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="w-full text-left px-3 py-2 text-xs font-mono text-status-warning hover:bg-dark-bg-secondary hover:text-status-error"
|
class="w-full text-left px-3 py-2 text-sm font-mono text-status-warning hover:bg-dark-bg-secondary hover:text-status-error"
|
||||||
@click=${this.handleLogout}
|
@click=${this.handleLogout}
|
||||||
>
|
>
|
||||||
Logout
|
Logout
|
||||||
|
|
|
||||||
|
|
@ -377,6 +377,57 @@ export class SessionList extends LitElement {
|
||||||
@error=${(e: CustomEvent) =>
|
@error=${(e: CustomEvent) =>
|
||||||
this.dispatchEvent(new CustomEvent('error', { detail: e.detail }))}
|
this.dispatchEvent(new CustomEvent('error', { detail: e.detail }))}
|
||||||
></session-create-form>
|
></session-create-form>
|
||||||
|
|
||||||
|
${this.renderExitedControls()}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderExitedControls() {
|
||||||
|
const exitedSessions = this.sessions.filter((session) => session.status === 'exited');
|
||||||
|
|
||||||
|
if (exitedSessions.length === 0) return '';
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="flex justify-center items-center gap-4 mt-8 pb-4">
|
||||||
|
<button
|
||||||
|
class="font-mono text-sm px-6 py-2 rounded-lg border transition-all duration-200 ${
|
||||||
|
this.hideExited
|
||||||
|
? 'border-dark-border bg-dark-bg-secondary text-dark-text-muted hover:bg-dark-bg-tertiary hover:text-dark-text'
|
||||||
|
: 'border-dark-border bg-dark-bg-tertiary text-dark-text hover:bg-dark-bg-secondary'
|
||||||
|
}"
|
||||||
|
@click=${() => this.dispatchEvent(new CustomEvent('hide-exited-change', { detail: !this.hideExited }))}
|
||||||
|
>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span>${this.hideExited ? 'Show' : 'Hide'} Exited (${exitedSessions.length})</span>
|
||||||
|
<div
|
||||||
|
class="w-8 h-4 rounded-full transition-colors duration-200 ${
|
||||||
|
this.hideExited ? 'bg-dark-surface' : 'bg-dark-bg'
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="w-3 h-3 rounded-full transition-transform duration-200 mt-0.5 ${
|
||||||
|
this.hideExited
|
||||||
|
? 'translate-x-0.5 bg-dark-text-muted'
|
||||||
|
: 'translate-x-4 bg-accent-green'
|
||||||
|
}"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
${
|
||||||
|
!this.hideExited && exitedSessions.length > 0
|
||||||
|
? html`
|
||||||
|
<button
|
||||||
|
class="font-mono text-sm px-6 py-2 rounded-lg border transition-all duration-200 border-dark-border bg-dark-bg-secondary text-status-warning hover:bg-dark-bg-tertiary hover:border-status-warning"
|
||||||
|
@click=${this.handleCleanupExited}
|
||||||
|
?disabled=${this.cleaningExited}
|
||||||
|
>
|
||||||
|
${this.cleaningExited ? 'Cleaning...' : `Clean Exited (${exitedSessions.length})`}
|
||||||
|
</button>
|
||||||
|
`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue