mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-10-28 08:20:49 +08:00
新增经典、悬浮和侧栏布局,保存用户偏好,并调整工具栏、状态摘要及窄屏交互。 统一控制台弹层外观、焦点行为和中英文文案。 根据虚拟磁盘文件访问能力显示浏览入口、容量信息和不可用状态。 验证:npm run build 通过(vue-tsc 类型检查和 Vite 生产构建)。
57 lines
3.1 KiB
Vue
57 lines
3.1 KiB
Vue
<script setup lang="ts">
|
|
import { ref } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { BarChart3, Bot, Settings, Terminal, MoreHorizontal } from 'lucide-vue-next'
|
|
import { Button } from '@/components/ui/button'
|
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'
|
|
|
|
defineProps<{
|
|
showStats: boolean
|
|
showTerminal: boolean
|
|
terminalRunning: boolean
|
|
showComputerUse: boolean
|
|
}>()
|
|
const emit = defineEmits<{
|
|
(e: 'openStats'): void
|
|
(e: 'openTerminal'): void
|
|
(e: 'openComputerUse'): void
|
|
}>()
|
|
const router = useRouter()
|
|
const { t } = useI18n()
|
|
const menuOpen = ref(false)
|
|
function openFromMenu(action: () => void) {
|
|
menuOpen.value = false
|
|
window.setTimeout(action, 50)
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="console-header-actions flex shrink-0 items-center gap-1">
|
|
<div class="hidden items-center gap-1 md:flex">
|
|
<Button v-if="showStats" variant="ghost" size="sm" class="gap-1.5 rounded-lg text-xs" :aria-label="t('actionbar.stats')" :title="t('actionbar.stats')" @click="emit('openStats')">
|
|
<BarChart3 class="size-4" /><span class="hidden lg:inline">{{ t('actionbar.stats') }}</span>
|
|
</Button>
|
|
<Button v-if="showTerminal" variant="ghost" size="sm" class="gap-1.5 rounded-lg text-xs" :aria-label="t('actionbar.webTerminal')" :title="t('actionbar.webTerminal')" :disabled="!terminalRunning" @click="emit('openTerminal')">
|
|
<Terminal class="size-4" /><span class="hidden lg:inline">{{ t('actionbar.webTerminal') }}</span>
|
|
</Button>
|
|
<Button v-if="showComputerUse" variant="ghost" size="sm" class="gap-1.5 rounded-lg text-xs" :aria-label="t('computerUse.title')" :title="t('computerUse.title')" @click="emit('openComputerUse')">
|
|
<Bot class="size-4" /><span class="hidden lg:inline">AI</span>
|
|
</Button>
|
|
</div>
|
|
<DropdownMenu v-if="showStats || showTerminal || showComputerUse" v-model:open="menuOpen">
|
|
<DropdownMenuTrigger as-child class="md:hidden">
|
|
<Button variant="ghost" size="icon-sm" :aria-label="t('actionbar.more')"><MoreHorizontal class="size-4" /></Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end" class="w-48">
|
|
<DropdownMenuItem v-if="showStats" @select="openFromMenu(() => emit('openStats'))"><BarChart3 class="size-4" />{{ t('actionbar.stats') }}</DropdownMenuItem>
|
|
<DropdownMenuItem v-if="showTerminal" :disabled="!terminalRunning" @select="openFromMenu(() => emit('openTerminal'))"><Terminal class="size-4" />{{ t('actionbar.webTerminal') }}</DropdownMenuItem>
|
|
<DropdownMenuItem v-if="showComputerUse" @select="openFromMenu(() => emit('openComputerUse'))"><Bot class="size-4" />{{ t('computerUse.title') }}</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
<Button variant="ghost" size="sm" class="gap-1.5 rounded-lg px-2 text-xs" :aria-label="t('actionbar.settings')" :title="t('actionbar.settings')" @click="router.push('/settings')">
|
|
<Settings class="size-4" /><span class="hidden lg:inline">{{ t('actionbar.settings') }}</span>
|
|
</Button>
|
|
</div>
|
|
</template>
|