refactor: Move Start/Restart/Clear to nav bar popup outside terminal
- Titlebar only keeps toggle and close buttons - Toggle button wider to use freed space - Nav bar opens as popup below terminal (no internal space change) - Added Start/Restart agent buttons to TerminalNavButtons - Backdrop blur on popup bar
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
defineProps<{
|
defineProps<{
|
||||||
waitingForToken?: boolean
|
waitingForToken?: boolean
|
||||||
|
showStart?: boolean
|
||||||
|
showRestart?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
defineEmits<{
|
defineEmits<{
|
||||||
@@ -10,6 +12,7 @@ defineEmits<{
|
|||||||
runClaudeResume: []
|
runClaudeResume: []
|
||||||
clearBuffer: []
|
clearBuffer: []
|
||||||
refresh: []
|
refresh: []
|
||||||
|
restart: []
|
||||||
sendKey: [key: string]
|
sendKey: [key: string]
|
||||||
scroll: [direction: 'up' | 'down' | 'end']
|
scroll: [direction: 'up' | 'down' | 'end']
|
||||||
}>()
|
}>()
|
||||||
@@ -17,6 +20,16 @@ defineEmits<{
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="tnb-bar">
|
<div class="tnb-bar">
|
||||||
|
<!-- Agent lifecycle -->
|
||||||
|
<button v-if="showStart" class="tnb-btn start" title="Start Agent" @click="$emit('restart')">
|
||||||
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
||||||
|
<span class="tnb-label">Start</span>
|
||||||
|
</button>
|
||||||
|
<button v-if="showRestart" class="tnb-btn restart" title="Restart Agent" @click="$emit('restart')">
|
||||||
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
|
||||||
|
<span class="tnb-label">Restart</span>
|
||||||
|
</button>
|
||||||
|
<span v-if="showStart || showRestart" class="tnb-sep"></span>
|
||||||
<!-- Action buttons -->
|
<!-- Action buttons -->
|
||||||
<button class="tnb-btn mcp" :class="{ waiting: waitingForToken }" title="Connect MCP" @click="$emit('requestToken')">
|
<button class="tnb-btn mcp" :class="{ waiting: waitingForToken }" title="Connect MCP" @click="$emit('requestToken')">
|
||||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
|
||||||
@@ -129,6 +142,12 @@ defineEmits<{
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Agent lifecycle */
|
||||||
|
.tnb-btn.start { color: #10b981; border-color: rgba(16, 185, 129, 0.2); }
|
||||||
|
.tnb-btn.start:hover { background: rgba(16, 185, 129, 0.2); border-color: rgba(16, 185, 129, 0.3); color: #34d399; }
|
||||||
|
.tnb-btn.restart { color: rgba(245, 158, 11, 0.8); border-color: rgba(245, 158, 11, 0.2); }
|
||||||
|
.tnb-btn.restart:hover { background: rgba(245, 158, 11, 0.2); border-color: rgba(245, 158, 11, 0.3); color: #f59e0b; }
|
||||||
|
|
||||||
/* Action button variants */
|
/* Action button variants */
|
||||||
.tnb-btn.mcp:hover { background: rgba(236, 72, 153, 0.2); border-color: rgba(236, 72, 153, 0.3); color: #ec4899; }
|
.tnb-btn.mcp:hover { background: rgba(236, 72, 153, 0.2); border-color: rgba(236, 72, 153, 0.3); color: #ec4899; }
|
||||||
.tnb-btn.mcp.waiting { background: rgba(16, 185, 129, 0.2); border-color: #10b981; color: #10b981; animation: tnb-pulse 0.8s infinite; }
|
.tnb-btn.mcp.waiting { background: rgba(16, 185, 129, 0.2); border-color: #10b981; color: #10b981; animation: tnb-pulse 0.8s infinite; }
|
||||||
|
|||||||
@@ -265,29 +265,6 @@ onBeforeUnmount(() => {
|
|||||||
<span v-else-if="terminalState === 'crashed'" class="at-status-text crashed">Crashed</span>
|
<span v-else-if="terminalState === 'crashed'" class="at-status-text crashed">Crashed</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="window-controls">
|
<div class="window-controls">
|
||||||
<button
|
|
||||||
v-if="terminalState === 'crashed' || terminalState === 'off'"
|
|
||||||
class="wc-btn start"
|
|
||||||
title="Start Agent"
|
|
||||||
@click.stop="handleRestart"
|
|
||||||
>
|
|
||||||
<svg width="10" height="10" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
v-if="agentRunning"
|
|
||||||
class="wc-btn restart"
|
|
||||||
title="Restart Agent"
|
|
||||||
@click.stop="handleRestart"
|
|
||||||
>
|
|
||||||
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="wc-btn"
|
|
||||||
title="Clear Buffer"
|
|
||||||
@click.stop="clearBuffer"
|
|
||||||
>
|
|
||||||
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2m3 0v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6h14"/></svg>
|
|
||||||
</button>
|
|
||||||
<button
|
<button
|
||||||
class="wc-btn nav-toggle"
|
class="wc-btn nav-toggle"
|
||||||
:class="{ active: showNavButtons }"
|
:class="{ active: showNavButtons }"
|
||||||
@@ -302,19 +279,6 @@ onBeforeUnmount(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Nav buttons bar -->
|
|
||||||
<TerminalNavButtons
|
|
||||||
v-if="showNavButtons"
|
|
||||||
@request-token="agentTerminal.sendInput('genera token usando tu mcp')"
|
|
||||||
@run-claude="navRunClaude"
|
|
||||||
@run-claude-continue="navRunClaudeContinue"
|
|
||||||
@run-claude-resume="navRunClaudeResume"
|
|
||||||
@clear-buffer="clearBuffer"
|
|
||||||
@refresh="navRefresh"
|
|
||||||
@send-key="navSendKey"
|
|
||||||
@scroll="navScroll"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- Terminal content -->
|
<!-- Terminal content -->
|
||||||
<div class="at-content" :style="{ background: agentBg }">
|
<div class="at-content" :style="{ background: agentBg }">
|
||||||
<div ref="terminalContainer" class="at-term"></div>
|
<div ref="terminalContainer" class="at-term"></div>
|
||||||
@@ -341,6 +305,23 @@ onBeforeUnmount(() => {
|
|||||||
<!-- Resize handle -->
|
<!-- Resize handle -->
|
||||||
<div class="at-resize" @mousedown="startResize"></div>
|
<div class="at-resize" @mousedown="startResize"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Nav buttons bar (outside terminal, hangs from bottom) -->
|
||||||
|
<TerminalNavButtons
|
||||||
|
v-if="showNavButtons"
|
||||||
|
class="at-nav-popup"
|
||||||
|
:show-start="terminalState === 'crashed' || terminalState === 'off'"
|
||||||
|
:show-restart="agentRunning"
|
||||||
|
@request-token="agentTerminal.sendInput('genera token usando tu mcp')"
|
||||||
|
@run-claude="navRunClaude"
|
||||||
|
@run-claude-continue="navRunClaudeContinue"
|
||||||
|
@run-claude-resume="navRunClaudeResume"
|
||||||
|
@clear-buffer="clearBuffer"
|
||||||
|
@refresh="navRefresh"
|
||||||
|
@restart="handleRestart"
|
||||||
|
@send-key="navSendKey"
|
||||||
|
@scroll="navScroll"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
@@ -442,9 +423,7 @@ onBeforeUnmount(() => {
|
|||||||
}
|
}
|
||||||
.wc-btn:hover { background: rgba(255, 255, 255, 0.5); }
|
.wc-btn:hover { background: rgba(255, 255, 255, 0.5); }
|
||||||
.wc-btn.x:hover { background: linear-gradient(180deg, #e66 0%, #c33 100%); border-color: #a22; color: #fff; }
|
.wc-btn.x:hover { background: linear-gradient(180deg, #e66 0%, #c33 100%); border-color: #a22; color: #fff; }
|
||||||
.wc-btn.start { color: #0a0; }
|
.wc-btn.nav-toggle { width: 44px; }
|
||||||
.wc-btn.start:hover { background: rgba(16, 185, 129, 0.3); }
|
|
||||||
.wc-btn.restart:hover { background: rgba(245, 158, 11, 0.3); color: #a80; }
|
|
||||||
.wc-btn.nav-toggle.active { background: rgba(99, 102, 241, 0.3); border-color: rgba(99, 102, 241, 0.4); color: #818cf8; }
|
.wc-btn.nav-toggle.active { background: rgba(99, 102, 241, 0.3); border-color: rgba(99, 102, 241, 0.4); color: #818cf8; }
|
||||||
.wc-btn.nav-toggle:hover { background: rgba(99, 102, 241, 0.2); color: #818cf8; }
|
.wc-btn.nav-toggle:hover { background: rgba(99, 102, 241, 0.2); color: #818cf8; }
|
||||||
|
|
||||||
@@ -513,6 +492,20 @@ onBeforeUnmount(() => {
|
|||||||
.agent-terminal.resizing { user-select: none; }
|
.agent-terminal.resizing { user-select: none; }
|
||||||
.agent-terminal.resizing .at-term { pointer-events: none; }
|
.agent-terminal.resizing .at-term { pointer-events: none; }
|
||||||
|
|
||||||
|
.at-nav-popup {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 100%;
|
||||||
|
border-radius: 0 0 6px 6px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
border-top: none;
|
||||||
|
backdrop-filter: blur(14px) saturate(1.3);
|
||||||
|
-webkit-backdrop-filter: blur(14px) saturate(1.3);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.at-slide-enter-active, .at-slide-leave-active { transition: all 0.15s ease; }
|
.at-slide-enter-active, .at-slide-leave-active { transition: all 0.15s ease; }
|
||||||
.at-slide-enter-from, .at-slide-leave-to { opacity: 0; transform: translateY(16px) scale(0.98); }
|
.at-slide-enter-from, .at-slide-leave-to { opacity: 0; transform: translateY(16px) scale(0.98); }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user