refactor: 优化组件样式和结构,移除多余的代码,增强可读性

This commit is contained in:
Wenjie Zhang 2026-03-19 18:32:14 +08:00
parent fb7fd6fae5
commit a2ffbb04ba
7 changed files with 177 additions and 317 deletions

View File

@ -1,6 +1,7 @@
@border-color: var(--gray-150);
@bg-secondary: var(--gray-10);
@radius: 8px;
@mono-font: 'Monaco', 'Consolas', monospace;
// Root container for extension pages to ensure 100% height
.extension-page-root {
@ -43,7 +44,7 @@
padding: 12px;
display: flex;
flex-direction: column;
gap: 4px;
gap: 8px;
}
}
@ -52,16 +53,18 @@
border-radius: @radius;
cursor: pointer;
transition: all 0.2s;
border: 1px solid transparent;
border: 1px solid var(--gray-50);
background-color: var(--gray-0);
&:hover {
background-color: var(--gray-100);
border-color: @border-color;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
&.active {
background-color: var(--gray-0);
border-color: @border-color;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
.item-header {
@ -93,6 +96,20 @@
}
}
.item-details {
display: flex;
flex-direction: column;
gap: 4px;
}
.item-desc {
font-size: 12px;
color: var(--gray-400);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&.active {
.item-icon,
@ -106,12 +123,20 @@
}
}
.list-item .item-details-inline {
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 8px;
}
.item-meta {
font-size: 12px;
color: var(--gray-500);
}
.list-separator {
height: 1px;
background-color: var(--gray-150);
margin: 2px 12px;
opacity: 0.8; // Deepened from 0.5 to 0.8
flex-shrink: 0;
display: none;
}
/* Main Panel */
@ -155,6 +180,36 @@
align-items: center;
gap: 10px;
}
.panel-title-row {
min-height: 32px;
}
.panel-title-stack {
min-height: 32px;
display: flex;
flex-direction: column;
justify-content: center;
}
.panel-title-meta {
font-size: 12px;
color: var(--gray-500);
border-radius: 4px;
margin-top: 4px;
display: inline-block;
user-select: text;
}
.panel-title-icon {
color: var(--gray-700);
flex-shrink: 0;
}
.panel-actions {
display: flex;
align-items: center;
}
}
}
@ -192,6 +247,22 @@
}
}
.detail-tabs {
.tab-content {
padding: 16px;
min-height: 300px;
height: 100%;
overflow: auto;
}
.empty-tab {
display: flex;
align-items: center;
justify-content: center;
min-height: 200px;
}
}
.tab-title {
display: flex;
align-items: center;
@ -199,6 +270,76 @@
font-size: 14px;
}
.info-grid {
display: grid;
gap: 16px;
.info-item {
display: flex;
flex-direction: column;
gap: 4px;
label {
font-size: 12px;
color: var(--gray-500);
font-weight: 500;
}
> span {
font-size: 14px;
color: var(--gray-900);
}
}
}
.extension-form {
.form-item {
margin-bottom: 16px;
}
}
.mono-text {
font-family: @mono-font;
}
.code-inline {
font-family: @mono-font;
font-size: 13px;
background: var(--gray-50);
padding: 8px 12px;
border-radius: 4px;
}
.code-pre {
font-family: @mono-font;
font-size: 12px;
background: var(--gray-50);
padding: 12px;
border-radius: 4px;
margin: 0;
overflow-x: auto;
}
.code-panel {
background: var(--gray-50);
border: 1px solid var(--gray-150);
border-radius: @radius;
padding: 16px;
}
.code-panel-pre {
margin: 0;
font-family: @mono-font;
font-size: 13px;
white-space: pre-wrap;
word-break: break-word;
color: var(--gray-700);
}
.text-break-all {
word-break: break-all;
}
/* Common helpers */
.text-muted {
color: var(--gray-400);

View File

@ -1,26 +0,0 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<!-- Center agent -->
<circle cx="12" cy="12" r="3" />
<!-- Sub-agents -->
<circle cx="5" cy="5" r="2" />
<circle cx="19" cy="5" r="2" />
<circle cx="5" cy="19" r="2" />
<circle cx="19" cy="19" r="2" />
<!-- Connections -->
<line x1="9.5" y1="9.5" x2="6.5" y2="6.5" />
<line x1="14.5" y1="9.5" x2="17.5" y2="6.5" />
<line x1="9.5" y1="14.5" x2="6.5" y2="17.5" />
<line x1="14.5" y1="14.5" x2="17.5" y2="17.5" />
</svg>

Before

Width:  |  Height:  |  Size: 645 B

View File

@ -67,7 +67,7 @@
<template v-else>
<div class="panel-top-bar">
<h2 style="min-height: 32px">
<h2 class="panel-title-row">
<span class="server-icon-lg">{{ currentServer.icon || '🔌' }}</span>
<span
><strong>{{ currentServer.name }}</strong></span
@ -146,14 +146,14 @@
>
<div class="info-item" v-if="currentServer.url">
<label>服务器 URL</label>
<span class="url-text">{{ currentServer.url }}</span>
<span class="code-inline text-break-all">{{ currentServer.url }}</span>
</div>
<div
class="info-item"
v-if="currentServer.headers && Object.keys(currentServer.headers).length > 0"
>
<label>请求头</label>
<pre class="headers-pre">{{
<pre class="code-pre">{{
JSON.stringify(currentServer.headers, null, 2)
}}</pre>
</div>
@ -171,7 +171,7 @@
<template v-if="currentServer.transport === 'stdio'">
<div class="info-item" v-if="currentServer.command">
<label>命令</label>
<span class="command-text">{{ currentServer.command }}</span>
<span class="code-inline">{{ currentServer.command }}</span>
</div>
<div
class="info-item"
@ -189,7 +189,7 @@
v-if="currentServer.env && Object.keys(currentServer.env).length > 0"
>
<label>环境变量</label>
<pre class="headers-pre">{{
<pre class="code-pre">{{
JSON.stringify(currentServer.env, null, 2)
}}</pre>
</div>
@ -351,7 +351,7 @@
</div>
<!-- 表单模式 -->
<a-form v-if="formMode === 'form'" layout="vertical" class="server-form">
<a-form v-if="formMode === 'form'" layout="vertical" class="extension-form">
<a-form-item label="服务器名称" required class="form-item">
<a-input
v-model:value="form.name"
@ -953,97 +953,6 @@ defineExpose({
.server-icon {
font-size: 18px;
}
.item-details {
display: flex;
flex-direction: column;
gap: 4px;
.transport-tag {
background: var(--gray-100);
border: none;
color: var(--gray-600);
border-radius: 4px;
font-size: 11px;
width: fit-content;
}
.item-desc {
font-size: 12px;
color: var(--gray-400);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
/* 右侧面板 */
.main-panel {
.detail-tabs {
.tab-content {
padding: 16px;
min-height: 300px;
height: 100%;
overflow: scroll;
}
.empty-tab {
display: flex;
align-items: center;
justify-content: center;
min-height: 200px;
}
}
}
.info-grid {
display: grid;
gap: 16px;
.info-item {
display: flex;
flex-direction: column;
gap: 4px;
label {
font-size: 12px;
color: var(--gray-500);
font-weight: 500;
}
span {
font-size: 14px;
color: var(--gray-900);
}
.url-text {
font-family: 'Monaco', 'Consolas', monospace;
font-size: 13px;
word-break: break-all;
background: var(--gray-50);
padding: 8px 12px;
border-radius: 4px;
}
.command-text {
font-family: 'Monaco', 'Consolas', monospace;
font-size: 13px;
background: var(--gray-50);
padding: 8px 12px;
border-radius: 4px;
}
.headers-pre {
font-family: 'Monaco', 'Consolas', monospace;
font-size: 12px;
background: var(--gray-50);
padding: 12px;
border-radius: 4px;
margin: 0;
overflow-x: auto;
}
}
}
/* 工具列表样式 */
@ -1153,7 +1062,7 @@ defineExpose({
font-weight: 500;
font-size: 13px;
color: var(--gray-900);
font-family: 'Monaco', 'Consolas', monospace;
font-family: @mono-font;
}
.param-required {
font-size: 11px;
@ -1168,7 +1077,7 @@ defineExpose({
background: var(--gray-100);
padding: 1px 6px;
border-radius: 3px;
font-family: 'Monaco', 'Consolas', monospace;
font-family: @mono-font;
}
}
@ -1189,14 +1098,9 @@ defineExpose({
margin-bottom: 16px;
text-align: right;
}
.server-form {
.form-item {
margin-bottom: 16px;
}
}
.json-mode {
.json-textarea {
font-family: 'Monaco', 'Consolas', monospace;
font-family: @mono-font;
font-size: 13px;
}
.json-actions {

View File

@ -28,11 +28,11 @@
@click="selectSkill(skill)"
>
<div class="item-header">
<Box :size="16" class="item-icon" />
<BookMarked :size="16" class="item-icon" />
<span class="item-name">{{ skill.name }}</span>
</div>
<div class="item-details">
<span class="item-slug">{{ skill.slug }}</span>
<div class="item-details item-details-inline">
<span class="item-slug item-meta mono-text">{{ skill.slug }}</span>
<div class="item-badges">
<span
v-if="skill.tool_dependencies?.length"
@ -63,7 +63,7 @@
<template v-else>
<div class="panel-top-bar">
<div class="skill-summary">
<div class="panel-title-stack">
<h2>{{ currentSkill.name }}</h2>
<!-- <code>{{ currentSkill.slug }}</code> -->
</div>
@ -279,7 +279,7 @@ import {
FolderPlus,
File,
Search,
Box,
BookMarked,
FileCode,
Eye,
Edit3
@ -655,14 +655,6 @@ defineExpose({
.list-item {
.item-details {
display: flex;
justify-content: space-between;
align-items: center;
.item-slug {
font-size: 12px;
color: var(--gray-400);
font-family: monospace;
}
.item-badges {
display: flex;
gap: 4px;
@ -681,27 +673,6 @@ defineExpose({
}
}
/* 右侧面板 */
.main-panel {
.panel-top-bar {
.skill-summary {
min-height: 32px;
display: flex;
flex-direction: column;
justify-content: center;
code {
font-size: 12px;
color: var(--gray-500);
background: @bg-secondary;
padding: 2px 6px;
border-radius: 4px;
margin-top: 4px;
display: inline-block;
}
}
}
}
.workspace {
display: flex;
flex: 1;

View File

@ -33,7 +33,7 @@
@click="selectAgent(agent)"
>
<div class="item-header">
<img :src="subagentsIcon" alt="SubAgent" class="agent-icon-svg" />
<Bot :size="16" class="item-icon" />
<span class="item-name">{{ agent.name }}</span>
</div>
<div class="item-details">
@ -56,8 +56,8 @@
<template v-else>
<div class="panel-top-bar">
<h2 style="min-height: 32px">
<img :src="subagentsIcon" alt="SubAgent" class="agent-icon-lg-svg" />
<h2 class="panel-title-row">
<Bot :size="18" class="panel-title-icon" />
<span
><strong>{{ currentAgent.name }}</strong></span
>
@ -138,8 +138,8 @@
<span class="tab-title"><MessageSquare :size="14" />系统提示词</span>
</template>
<div class="tab-content">
<div class="prompt-display">
<pre>{{ currentAgent.system_prompt }}</pre>
<div class="code-panel">
<pre class="code-panel-pre">{{ currentAgent.system_prompt }}</pre>
</div>
</div>
</a-tab-pane>
@ -157,9 +157,8 @@
@cancel="formModalVisible = false"
:maskClosable="false"
width="600px"
class="subagent-modal"
>
<a-form layout="vertical" class="subagent-form">
<a-form layout="vertical" class="extension-form">
<a-form-item label="名称" required class="form-item">
<a-input
v-model:value="form.name"
@ -212,7 +211,6 @@ import { Search, Bot, Pencil, Trash2, Info, MessageSquare } from 'lucide-vue-nex
import { subagentApi } from '@/apis/subagent_api'
import { toolApi } from '@/apis/tool_api'
import { formatFullDateTime } from '@/utils/time'
import subagentsIcon from '@/assets/icons/subagents.svg'
import ModelSelectorComponent from '@/components/ModelSelectorComponent.vue'
//
@ -453,45 +451,6 @@ defineExpose({
<style lang="less" scoped>
@import '@/assets/css/extensions.less';
.list-item {
.agent-icon-svg {
width: 16px;
height: 16px;
color: var(--gray-500);
flex-shrink: 0;
}
.item-details {
display: flex;
flex-direction: column;
gap: 4px;
.builtin-tag {
background: var(--color-primary-50);
border: none;
color: var(--color-primary-600);
border-radius: 4px;
font-size: 11px;
width: fit-content;
}
.item-desc {
font-size: 12px;
color: var(--gray-400);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.agent-icon-lg-svg {
width: 18px;
height: 18px;
color: var(--gray-700);
flex-shrink: 0;
}
.model-override-row {
display: flex;
align-items: center;
@ -506,62 +465,4 @@ defineExpose({
}
}
/* 右侧面板 */
.main-panel {
.detail-tabs {
.tab-content {
padding: 16px;
min-height: 300px;
height: 100%;
overflow: scroll;
}
}
}
.info-grid {
display: grid;
gap: 16px;
.info-item {
display: flex;
flex-direction: column;
gap: 4px;
label {
font-size: 12px;
color: var(--gray-500);
font-weight: 500;
}
span {
font-size: 14px;
color: var(--gray-900);
}
}
}
.prompt-display {
background: var(--gray-50);
border: 1px solid var(--gray-150);
border-radius: 8px;
padding: 16px;
pre {
margin: 0;
font-family: 'Monaco', 'Consolas', monospace;
font-size: 13px;
white-space: pre-wrap;
word-break: break-word;
color: var(--gray-700);
}
}
/* 模态框样式 */
.subagent-modal {
.subagent-form {
.form-item {
margin-bottom: 16px;
}
}
}
</style>

View File

@ -45,8 +45,8 @@
<Wrench :size="16" class="item-icon" />
<span class="item-name">{{ tool.name }}</span>
</div>
<div class="item-details">
<span class="item-category">{{
<div class="item-details item-details-inline">
<span class="item-category item-meta">{{
categoryLabels[tool.category] || tool.category
}}</span>
<div class="item-tags">
@ -72,9 +72,9 @@
<template v-else>
<div class="panel-top-bar">
<div class="tool-summary">
<div class="panel-title-stack">
<h2>{{ currentTool.name }}</h2>
<code>{{ currentTool.id }}</code>
<code class="panel-title-meta">{{ currentTool.id }}</code>
</div>
</div>
@ -221,13 +221,6 @@ defineExpose({
.list-item {
.item-details {
display: flex;
justify-content: space-between;
align-items: center;
.item-category {
font-size: 12px;
color: var(--gray-600);
}
.item-tags {
display: flex;
gap: 2px;
@ -245,26 +238,6 @@ defineExpose({
}
}
/* 右侧面板 */
.main-panel {
.panel-top-bar {
.tool-summary {
min-height: 32px;
display: flex;
flex-direction: column;
justify-content: center;
code {
font-size: 12px;
color: var(--gray-500);
border-radius: 4px;
margin-top: 4px;
display: inline-block;
user-select: text;
}
}
}
}
.tool-detail {
padding: 16px;
flex: 1;

View File

@ -1,5 +1,5 @@
<template>
<div class="extensions-view">
<div class="extensions-view extension-page-root">
<div class="extensions-header">
<a-tabs v-model:activeKey="activeTab" class="extensions-tabs">
<a-tab-pane key="tools" tab="工具" />
@ -213,13 +213,9 @@ const handleImportUpload = async ({ file, onSuccess, onError }) => {
</script>
<style scoped lang="less">
.extensions-view {
height: 100%;
min-height: 0;
display: flex;
flex-direction: column;
background-color: var(--gray-0);
@import '@/assets/css/extensions.less';
.extensions-view {
.extensions-header {
display: flex;
justify-content: space-between;