feat: 将终端标签页移至左侧边栏

- 在 MainLayout 侧边栏添加终端标签区域
- 标签纵向排列在连接列表下方
- 点击标签自动切换到终端工作区并激活
- 简化 TerminalWorkspaceView 移除顶部标签栏和返回按钮
- 不用返回就能切换连接和打开新终端
This commit is contained in:
liumangmang
2026-03-18 23:16:54 +08:00
parent c760fbdb85
commit c01c005c07
2 changed files with 69 additions and 83 deletions

View File

@@ -1,12 +1,9 @@
<script setup lang="ts">
import { computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useTerminalTabsStore } from '../stores/terminalTabs'
import { useConnectionsStore } from '../stores/connections'
import TerminalWidget from '../components/TerminalWidget.vue'
import { ArrowLeft, X } from 'lucide-vue-next'
const router = useRouter()
const tabsStore = useTerminalTabsStore()
const connectionsStore = useConnectionsStore()
@@ -18,69 +15,16 @@ onMounted(() => {
connectionsStore.fetchConnections()
}
})
function handleTabClick(tabId: string) {
tabsStore.activate(tabId)
}
function handleTabClose(tabId: string, event: Event) {
event.stopPropagation()
tabsStore.close(tabId)
}
function goBack() {
router.push('/connections')
}
</script>
<template>
<div class="h-full flex flex-col">
<!-- 顶部导航栏 -->
<div class="flex items-center gap-4 px-4 py-3 border-b border-slate-700 bg-slate-800/50">
<button
@click="goBack"
class="p-2 rounded-lg text-slate-400 hover:bg-slate-700 hover:text-slate-100 transition-colors duration-200 cursor-pointer"
aria-label="返回"
>
<ArrowLeft class="w-5 h-5" aria-hidden="true" />
</button>
<h2 class="text-lg font-semibold text-slate-100">终端</h2>
</div>
<!-- 标签栏 -->
<div
v-if="tabs.length > 0"
class="flex items-center gap-2 px-4 py-2 border-b border-slate-700 bg-slate-900/50 overflow-x-auto"
>
<div
v-for="tab in tabs"
:key="tab.id"
@click="handleTabClick(tab.id)"
class="flex items-center gap-2 px-3 py-2 rounded-lg cursor-pointer transition-colors duration-200 whitespace-nowrap"
:class="tab.active ? 'bg-slate-700 text-slate-100' : 'bg-slate-800 text-slate-400 hover:bg-slate-700/50 hover:text-slate-200'"
>
<span class="text-sm font-medium">{{ tab.title }}</span>
<button
@click="(e) => handleTabClose(tab.id, e)"
class="p-1 rounded hover:bg-slate-600 transition-colors duration-200"
aria-label="关闭标签"
>
<X class="w-3 h-3" aria-hidden="true" />
</button>
</div>
</div>
<!-- 终端内容区 -->
<div class="flex-1 min-h-0 p-4">
<div v-if="tabs.length === 0" class="flex items-center justify-center h-full text-slate-400">
<div class="text-center">
<p class="mb-2">暂无打开的终端</p>
<button
@click="goBack"
class="px-4 py-2 rounded-lg bg-cyan-600 hover:bg-cyan-500 text-white transition-colors duration-200 cursor-pointer"
>
返回连接列表
</button>
<p class="text-lg mb-2">暂无打开的终端</p>
<p class="text-sm text-slate-500">从左侧连接列表点击"终端"按钮打开</p>
</div>
</div>
<div v-else class="h-full">