feat: 更新Dashboard页面布局和样式
- 将Dashboard顶部的卡片改为CPU、内存、Active Agents三个卡片 - 移除Active MCP Servers和Active Models卡片 - 增强Element Plus下拉框暗色主题样式 - 修复旧HTML文件导致的Tailwind冲突问题 - 统一下拉框样式与输入框风格 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -36,27 +36,49 @@ html.dark .el-select {
|
||||
--el-select-input-focus-border-color: #ff9500;
|
||||
}
|
||||
|
||||
html.dark .el-select .el-input__wrapper {
|
||||
background-color: #1a1c25;
|
||||
box-shadow: 0 0 0 1px #2a2c36 inset;
|
||||
html.dark .el-select .el-input__wrapper,
|
||||
html.dark .el-select .el-select__wrapper {
|
||||
background-color: #1a1c25 !important;
|
||||
border: 1px solid #2a2c36;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease;
|
||||
padding: 2px 11px;
|
||||
min-height: 42px;
|
||||
}
|
||||
|
||||
html.dark .el-select.el-select--large .el-input__wrapper {
|
||||
padding: 5px 11px;
|
||||
min-height: 46px;
|
||||
}
|
||||
|
||||
html.dark .el-select .el-input__wrapper:hover {
|
||||
box-shadow: 0 0 0 1px #ff9500 inset;
|
||||
border-color: #ff9500;
|
||||
}
|
||||
|
||||
html.dark .el-select .el-input__wrapper.is-focus {
|
||||
box-shadow: 0 0 0 1px #ff9500 inset;
|
||||
border-color: #ff9500;
|
||||
}
|
||||
|
||||
html.dark .el-select .el-input__inner {
|
||||
color: #ffffff;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
html.dark .el-select .el-input__wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
html.dark .el-select .el-select__wrapper {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
html.dark .el-select .el-select__wrapper .el-select__selected-item {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
html.dark .el-select .el-input__inner::placeholder {
|
||||
color: #71717a;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
/* 下拉箭头 */
|
||||
@@ -78,21 +100,22 @@ html.dark .el-select .el-input__suffix .el-select__caret:hover {
|
||||
}
|
||||
|
||||
/* 下拉菜单 */
|
||||
.el-select-dropdown.el-popper,
|
||||
html.dark .el-select-dropdown {
|
||||
background-color: #171922;
|
||||
border: 1px solid #2a2c36;
|
||||
background-color: #1a1c25 !important;
|
||||
border: 1px solid #2a2c36 !important;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
html.dark .el-select-dropdown__item {
|
||||
color: #ffffff;
|
||||
color: #ffffff !important;
|
||||
padding: 8px 12px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
html.dark .el-select-dropdown__item:hover {
|
||||
background-color: #1a1c25;
|
||||
background-color: #1a1c25 !important;
|
||||
}
|
||||
|
||||
html.dark .el-select-dropdown__item.is-selected {
|
||||
@@ -118,23 +141,34 @@ html.dark .el-select-dropdown__empty {
|
||||
}
|
||||
|
||||
/* popper 箭头 */
|
||||
.el-popper.is-light,
|
||||
html.dark .el-popper.is-light {
|
||||
background: #171922;
|
||||
border: 1px solid #2a2c36;
|
||||
background: #1a1c25 !important;
|
||||
border: 1px solid #2a2c36 !important;
|
||||
}
|
||||
|
||||
.el-popper.is-light .el-popper__arrow::before,
|
||||
html.dark .el-popper.is-light .el-popper__arrow::before {
|
||||
background: #171922;
|
||||
border-color: #2a2c36;
|
||||
background: #1a1c25 !important;
|
||||
border-color: #2a2c36 !important;
|
||||
}
|
||||
|
||||
/* 输入框尺寸 */
|
||||
html.dark .el-select.el-select--large .el-input__wrapper {
|
||||
padding: 4px 11px;
|
||||
/* 选中项文字居中 */
|
||||
html.dark .el-select .el-select__wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
html.dark .el-select.el-select--default .el-input__wrapper {
|
||||
padding: 3px 10px;
|
||||
html.dark .el-select .el-select__selected-item,
|
||||
html.dark .el-select .el-select__placeholder {
|
||||
line-height: 20px !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
html.dark .el-select .el-select__selected-item > span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 多选标签 */
|
||||
|
||||
@@ -3,9 +3,9 @@ import { ref, onMounted } from 'vue'
|
||||
|
||||
// 显示的数字(用于动画)
|
||||
const displayStats = ref({
|
||||
cpu: 0,
|
||||
memory: 0,
|
||||
activeAgents: 0,
|
||||
activeMCP: 0,
|
||||
activeModels: 0,
|
||||
requests: 0,
|
||||
agentsCalls: 0,
|
||||
mcpCalls: 0,
|
||||
@@ -14,9 +14,9 @@ const displayStats = ref({
|
||||
|
||||
// 目标数字
|
||||
const targetStats = {
|
||||
cpu: 45,
|
||||
memory: 72,
|
||||
activeAgents: 3,
|
||||
activeMCP: 21,
|
||||
activeModels: 13,
|
||||
requests: 36,
|
||||
agentsCalls: 3,
|
||||
mcpCalls: 21,
|
||||
@@ -47,9 +47,9 @@ const animateNumber = (key: keyof typeof displayStats.value, target: number) =>
|
||||
|
||||
onMounted(() => {
|
||||
// 页面加载后依次动画每个数字
|
||||
setTimeout(() => animateNumber('activeAgents', targetStats.activeAgents), 0)
|
||||
setTimeout(() => animateNumber('activeMCP', targetStats.activeMCP), 300)
|
||||
setTimeout(() => animateNumber('activeModels', targetStats.activeModels), 600)
|
||||
setTimeout(() => animateNumber('cpu', targetStats.cpu), 0)
|
||||
setTimeout(() => animateNumber('memory', targetStats.memory), 200)
|
||||
setTimeout(() => animateNumber('activeAgents', targetStats.activeAgents), 400)
|
||||
// deployment insights 数字动画(延迟900ms,在顶部stats之后)
|
||||
setTimeout(() => animateNumber('requests', targetStats.requests), 900)
|
||||
setTimeout(() => animateNumber('agentsCalls', targetStats.agentsCalls), 1000)
|
||||
@@ -64,20 +64,6 @@ const agents = ref([
|
||||
{ name: 'template-openai-api', count: 1, color: 'bg-primary-purple', status: 'error' },
|
||||
])
|
||||
|
||||
// MCP Servers列表
|
||||
const mcpServers = ref([
|
||||
{ name: 'linear-demo', count: 15, color: 'bg-primary-yellow' },
|
||||
{ name: 'google-maps', count: 4, color: 'bg-primary-cyan' },
|
||||
{ name: 'explorer-mcp', count: 2, color: 'bg-primary-purple' },
|
||||
])
|
||||
|
||||
// Models列表
|
||||
const models = ref([
|
||||
{ name: 'gpt-40-2024-08-12', count: 2, color: 'bg-primary-yellow' },
|
||||
{ name: 'cerebras-sandbox', count: 6, color: 'bg-primary-cyan' },
|
||||
{ name: 'sandbox-openai', count: 5, color: 'bg-primary-purple' },
|
||||
])
|
||||
|
||||
// 图表数据
|
||||
const chartData = ref([
|
||||
{ time: '3:02 PM', agents: 1, mcp: 2, models: 1.5 },
|
||||
@@ -121,8 +107,6 @@ const recentRequests = ref([
|
||||
|
||||
// 开关状态
|
||||
const agentErrorEnabled = ref(true)
|
||||
const mcpErrorEnabled = ref(false)
|
||||
const modelErrorEnabled = ref(false)
|
||||
|
||||
// Top requests标签切换
|
||||
const topRequestsTab = ref<'general' | 'errors'>('general')
|
||||
@@ -152,6 +136,56 @@ const topRequestsTab = ref<'general' | 'errors'>('general')
|
||||
<!-- 卡片网格布局 -->
|
||||
<div class="grid grid-cols-3 gap-6">
|
||||
<!-- 第一行:3个状态卡片 -->
|
||||
<!-- CPU 占用卡片 -->
|
||||
<div class="bg-dark-700 rounded-xl p-5">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h3 class="font-semibold text-lg">CPU Usage</h3>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-sm text-gray-400">Live</span>
|
||||
<span class="w-2 h-2 rounded-full bg-primary-success animate-pulse"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-4xl font-bold mb-2">{{ displayStats.cpu }}<span class="text-xl text-gray-400">%</span></div>
|
||||
<!-- 进度条 -->
|
||||
<div class="w-full h-2 rounded-full bg-dark-500 overflow-hidden mb-4 relative">
|
||||
<div
|
||||
class="absolute left-0 top-0 h-full bg-gradient-to-r from-primary-orange to-red-500 progress-bar"
|
||||
:style="{ '--target-width': displayStats.cpu + '%' }"
|
||||
></div>
|
||||
</div>
|
||||
<!-- 使用情况 -->
|
||||
<div class="flex justify-between text-sm text-gray-400">
|
||||
<span>0%</span>
|
||||
<span>50%</span>
|
||||
<span>100%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 内存占用卡片 -->
|
||||
<div class="bg-dark-700 rounded-xl p-5">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h3 class="font-semibold text-lg">Memory Usage</h3>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-sm text-gray-400">Live</span>
|
||||
<span class="w-2 h-2 rounded-full bg-primary-success animate-pulse"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-4xl font-bold mb-2">{{ displayStats.memory }}<span class="text-xl text-gray-400">%</span></div>
|
||||
<!-- 进度条 -->
|
||||
<div class="w-full h-2 rounded-full bg-dark-500 overflow-hidden mb-4 relative">
|
||||
<div
|
||||
class="absolute left-0 top-0 h-full bg-gradient-to-r from-primary-cyan to-blue-500 progress-bar"
|
||||
:style="{ '--target-width': displayStats.memory + '%' }"
|
||||
></div>
|
||||
</div>
|
||||
<!-- 使用情况 -->
|
||||
<div class="flex justify-between text-sm text-gray-400">
|
||||
<span>0%</span>
|
||||
<span>50%</span>
|
||||
<span>100%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Active Agents 卡片 -->
|
||||
<div class="bg-dark-700 rounded-xl p-5">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
@@ -172,13 +206,10 @@ const topRequestsTab = ref<'general' | 'errors'>('general')
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-4xl font-bold mb-4">{{ displayStats.activeAgents }}</div>
|
||||
<!-- 进度条 - 三个同时动画 -->
|
||||
<!-- 进度条 -->
|
||||
<div class="w-full h-2 rounded-full bg-dark-500 overflow-hidden mb-4 relative">
|
||||
<!-- 黄色 -->
|
||||
<div class="absolute left-0 top-0 h-full bg-primary-yellow progress-bar" style="--target-width: 33%"></div>
|
||||
<!-- 蓝色 -->
|
||||
<div class="absolute top-0 h-full bg-primary-cyan progress-bar" style="left: 33%; --target-width: 33%"></div>
|
||||
<!-- 紫色 -->
|
||||
<div class="absolute top-0 h-full bg-primary-purple progress-bar" style="left: 66%; --target-width: 34%"></div>
|
||||
</div>
|
||||
<!-- 明细列表 -->
|
||||
@@ -194,80 +225,6 @@ const topRequestsTab = ref<'general' | 'errors'>('general')
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Active MCP Servers 卡片 -->
|
||||
<div class="bg-dark-700 rounded-xl p-5">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h3 class="font-semibold text-lg">Active MCP Servers</h3>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-sm text-gray-400">Errors</span>
|
||||
<div
|
||||
class="w-10 h-5 rounded-full relative cursor-pointer transition-colors"
|
||||
:class="mcpErrorEnabled ? 'bg-primary-orange' : 'bg-dark-500'"
|
||||
@click="mcpErrorEnabled = !mcpErrorEnabled"
|
||||
>
|
||||
<div
|
||||
class="absolute top-0.5 w-4 h-4 rounded-full transition-transform"
|
||||
:class="mcpErrorEnabled ? 'right-0.5 bg-white' : 'left-0.5 bg-gray-400'"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-4xl font-bold mb-4">{{ displayStats.activeMCP }}</div>
|
||||
<!-- 进度条 - 三个同时动画 -->
|
||||
<div class="w-full h-2 rounded-full bg-dark-500 overflow-hidden mb-4 relative">
|
||||
<div class="absolute left-0 top-0 h-full bg-primary-yellow progress-bar" style="--target-width: 71%"></div>
|
||||
<div class="absolute top-0 h-full bg-primary-cyan progress-bar" style="left: 71%; --target-width: 19%"></div>
|
||||
<div class="absolute top-0 h-full bg-primary-purple progress-bar" style="left: 90%; --target-width: 10%"></div>
|
||||
</div>
|
||||
<!-- 明细列表 -->
|
||||
<ul class="space-y-2">
|
||||
<li v-for="server in mcpServers" :key="server.name" class="flex justify-between items-center">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="w-3 h-3 rounded-sm" :class="server.color"></span>
|
||||
<span class="text-sm text-gray-300">{{ server.name }}</span>
|
||||
</div>
|
||||
<span class="text-sm">{{ server.count }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Active Models 卡片 -->
|
||||
<div class="bg-dark-700 rounded-xl p-5">
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h3 class="font-semibold text-lg">Active Models</h3>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-sm text-gray-400">Errors</span>
|
||||
<div
|
||||
class="w-10 h-5 rounded-full relative cursor-pointer transition-colors"
|
||||
:class="modelErrorEnabled ? 'bg-primary-orange' : 'bg-dark-500'"
|
||||
@click="modelErrorEnabled = !modelErrorEnabled"
|
||||
>
|
||||
<div
|
||||
class="absolute top-0.5 w-4 h-4 rounded-full transition-transform"
|
||||
:class="modelErrorEnabled ? 'right-0.5 bg-white' : 'left-0.5 bg-gray-400'"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-4xl font-bold mb-4">{{ displayStats.activeModels }}</div>
|
||||
<!-- 进度条 - 三个同时动画 -->
|
||||
<div class="w-full h-2 rounded-full bg-dark-500 overflow-hidden mb-4 relative">
|
||||
<div class="absolute left-0 top-0 h-full bg-primary-yellow progress-bar" style="--target-width: 46%"></div>
|
||||
<div class="absolute top-0 h-full bg-primary-cyan progress-bar" style="left: 46%; --target-width: 15%"></div>
|
||||
<div class="absolute top-0 h-full bg-primary-purple progress-bar" style="left: 61%; --target-width: 39%"></div>
|
||||
</div>
|
||||
<!-- 明细列表 -->
|
||||
<ul class="space-y-2">
|
||||
<li v-for="model in models" :key="model.name" class="flex justify-between items-center">
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="w-3 h-3 rounded-sm" :class="model.color"></span>
|
||||
<span class="text-sm text-gray-300">{{ model.name }}</span>
|
||||
</div>
|
||||
<span class="text-sm">{{ model.count }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 第二行 -->
|
||||
<!-- All deployment request Insights 卡片(跨2列) -->
|
||||
<div class="bg-dark-700 rounded-xl p-5 col-span-2">
|
||||
|
||||
@@ -8,5 +8,10 @@ export default defineConfig({
|
||||
alias: {
|
||||
'@': resolve(__dirname, 'src')
|
||||
}
|
||||
},
|
||||
server: {
|
||||
fs: {
|
||||
allow: ['..']
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user