Skip to content

Commit 2a52b36

Browse files
committed
feat(web): 合并知识库导航入口并调整视觉细节
1 parent a62077b commit 2a52b36

15 files changed

Lines changed: 446 additions & 307 deletions

docs/develop-guides/roadmap.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
### 0.6.1
3232

3333
<!-- 0.6.1 的内容请放在这里 -->
34+
- 合并知识库导航入口:左侧导航仅保留“知识库”,文档知识库与图知识库在页面 header 中通过同一组轻量切换入口切换,保留原有列表与图谱内容区交互。
35+
- 抽象页面轻量切换 header:知识库与扩展管理页直接共用 `ViewSwitchHeader`,通过统一切换样式和 actions slot 收敛文档知识库、知识图谱、Tools、MCP、Subagents、Skills 等入口的信息层级;扩展管理各列表的刷新入口下沉到搜索框右侧,并统一搜索框与工具按钮的边框和圆角。
36+
- 调整任务中心交互:入口移动到 GitHub 按钮下方,并将右侧抽屉展示改为居中弹窗,减少对主页面布局的占用。
3437
- 调整 backend Python 工作区依赖边界:将 `backend/package/yuxi` 明确为承载核心运行依赖的业务包,根 `backend/pyproject.toml` 仅保留工作区入口与开发/测试配置,减少依赖职责混淆。
3538
-`yuxi` 从 uv workspace 成员调整为 `backend/package` 下可独立构建的本地 Python 包,backend 通过 path dependency 以已安装包形式发现依赖,移除对 `PYTHONPATH=/app/package` 的运行时耦合。
3639
- 修复沙盒 `workspace` 隔离粒度:宿主机目录从共享 `saves/threads/shared/workspace` 收敛为用户级 `saves/threads/shared/<user_id>/workspace`,并同步传递 `user_id` 到 sandbox 路径解析、provisioner 挂载与 viewer/chat 测试,保证同用户跨线程共享、不同用户隔离。

web/src/assets/css/extensions.less

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,39 @@
4141
min-width: 0;
4242
padding: 0;
4343
}
44+
45+
.search-box :deep(.ant-input-affix-wrapper) {
46+
height: 28px;
47+
padding: 0 10px;
48+
border: 1px solid var(--gray-150);
49+
border-radius: 8px;
50+
background-color: var(--gray-0);
51+
box-shadow: none;
52+
53+
&:hover,
54+
&:focus,
55+
&.ant-input-affix-wrapper-focused {
56+
border-color: var(--gray-200);
57+
box-shadow: none;
58+
}
59+
}
4460
}
4561

4662
.search-box {
4763
padding: 8px 12px 0;
4864

4965
:deep(.ant-input-affix-wrapper) {
5066
height: 28px;
51-
padding: 0 12px;
52-
// border: none;
67+
padding: 0 10px;
68+
border: 1px solid var(--gray-150);
5369
border-radius: 8px;
5470
background-color: var(--gray-0);
5571
box-shadow: none;
5672

5773
&:hover,
5874
&:focus,
5975
&.ant-input-affix-wrapper-focused {
60-
// border: none;
76+
border-color: var(--gray-200);
6177
box-shadow: none;
6278
}
6379
}
@@ -84,9 +100,9 @@
84100
color: var(--gray-500);
85101
}
86102

87-
// :deep(.ant-input-outlined) {
88-
// border: none;
89-
// }
103+
:deep(.ant-input-outlined) {
104+
border-color: var(--gray-150);
105+
}
90106
}
91107

92108
.sidebar-tool {
@@ -145,8 +161,7 @@
145161

146162
&.active {
147163
background-color: var(--gray-0);
148-
border-color: @border-color;
149-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
164+
border-color: var(--main-500);
150165
}
151166

152167
.item-header {
@@ -212,7 +227,7 @@
212227
}
213228

214229
.list-section-title {
215-
padding: 10px 14px 6px;
230+
padding: 0px 14px;
216231
color: var(--gray-500);
217232
font-size: 11px;
218233
font-weight: 600;

web/src/components/AgentConfigSidebar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ const configSwitchOptions = computed(() => {
588588
589589
if (userStore.isAdmin) {
590590
options.push({
591-
label: '新建配置',
591+
label: '+ 新建配置',
592592
value: CREATE_CONFIG_OPTION_VALUE
593593
})
594594
}

web/src/components/AgentPanel.vue

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,25 @@
22
<div ref="panelRef" class="agent-panel" :class="{ resizing: isResizing }">
33
<!-- 拖拽手柄 -->
44
<div class="resize-handle" @pointerdown="startResize"></div>
5-
<div class="panel-header">
6-
<div class="panel-title">
7-
<FolderCode :size="20" class="header-icon" />
8-
<span><strong>文件系统</strong></span>
5+
<div class="panel-header" :class="{ 'is-compact': isCompactHeader }">
6+
<div class="panel-header-main">
7+
<div class="panel-title">
8+
<span><strong>文件系统</strong></span>
9+
</div>
10+
<div class="window-actions">
11+
<button
12+
class="header-action-btn"
13+
:title="isExpanded ? '恢复高度' : '向上展开'"
14+
@click="emit('toggle-expand')"
15+
>
16+
<component :is="isExpanded ? ChevronsDownUp : ChevronsUpDown" :size="15" />
17+
</button>
18+
<button class="close-btn" @click="$emit('close')">
19+
<X :size="18" />
20+
</button>
21+
</div>
922
</div>
10-
<div class="header-actions">
23+
<div class="file-toolbar">
1124
<button
1225
class="header-action-btn"
1326
title="新建文件夹"
@@ -27,17 +40,6 @@
2740
<button class="header-action-btn" title="刷新" @click="emitRefresh">
2841
<RefreshCw :size="15" />
2942
</button>
30-
<span class="header-divider"></span>
31-
<button
32-
class="header-action-btn"
33-
:title="isExpanded ? '恢复高度' : '向上展开'"
34-
@click="emit('toggle-expand')"
35-
>
36-
<component :is="isExpanded ? ChevronsDownUp : ChevronsUpDown" :size="15" />
37-
</button>
38-
<button class="close-btn" @click="$emit('close')">
39-
<X :size="18" />
40-
</button>
4143
</div>
4244
</div>
4345
<input
@@ -166,7 +168,6 @@ import {
166168
ChevronsDownUp,
167169
ChevronsUpDown,
168170
Download,
169-
FolderCode,
170171
FolderPlus,
171172
RefreshCw,
172173
Trash2,
@@ -239,6 +240,7 @@ const expandedKeys = ref([])
239240
const deletingPaths = ref(new Set())
240241
241242
const useInlinePreview = computed(() => panelWidth.value >= INLINE_PREVIEW_MIN_WIDTH)
243+
const isCompactHeader = computed(() => panelWidth.value > 0 && panelWidth.value < 360)
242244
243245
const buildDisplayName = (fullPath) => {
244246
const normalized = String(fullPath || '').replace(/\/+$/, '')
@@ -866,10 +868,41 @@ watch(useInlinePreview, (isInline) => {
866868
display: flex;
867869
align-items: center;
868870
justify-content: space-between;
871+
gap: 8px;
869872
padding: 4px 16px;
870-
height: 56px;
873+
min-height: 56px;
871874
background: var(--gray-25);
872875
flex-shrink: 0;
876+
877+
&.is-compact {
878+
align-items: stretch;
879+
flex-direction: column;
880+
gap: 6px;
881+
padding: 8px 12px;
882+
883+
.panel-header-main {
884+
display: flex;
885+
align-items: center;
886+
justify-content: space-between;
887+
gap: 8px;
888+
min-width: 0;
889+
}
890+
891+
.file-toolbar {
892+
order: 2;
893+
width: 100%;
894+
justify-content: flex-start;
895+
padding: 4px;
896+
border-right: none;
897+
border: 1px solid var(--gray-150);
898+
border-radius: 8px;
899+
background: var(--gray-0);
900+
}
901+
}
902+
}
903+
904+
.panel-header-main {
905+
display: contents;
873906
}
874907
875908
.header-action-btn {
@@ -902,26 +935,41 @@ watch(useInlinePreview, (isInline) => {
902935
display: flex;
903936
align-items: center;
904937
gap: 12px;
938+
order: 1;
939+
flex: 1;
940+
min-width: 0;
905941
font-weight: 600;
906942
font-size: 14px;
907943
color: var(--gray-900);
908944
945+
span {
946+
overflow: hidden;
947+
text-overflow: ellipsis;
948+
white-space: nowrap;
949+
}
950+
909951
.header-icon {
952+
flex-shrink: 0;
910953
color: var(--gray-700);
911954
}
912955
}
913956
914-
.header-actions {
957+
.file-toolbar,
958+
.window-actions {
915959
display: flex;
916960
align-items: center;
917961
gap: 4px;
918962
}
919963
920-
.header-divider {
921-
width: 1px;
922-
height: 16px;
923-
background: var(--gray-300);
924-
margin: 0 4px;
964+
.file-toolbar {
965+
order: 2;
966+
padding-right: 8px;
967+
border-right: 1px solid var(--gray-300);
968+
}
969+
970+
.window-actions {
971+
order: 3;
972+
flex-shrink: 0;
925973
}
926974
927975
.hidden-file-input {

web/src/components/HeaderComponent.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ defineProps({
4343
.header-container {
4444
background-color: var(--bg-sider);
4545
backdrop-filter: blur(10px);
46-
padding: 10px 24px;
46+
padding: 8px 16px;
47+
height: 50px;
4748
border-bottom: 1px solid var(--gray-150);
4849
position: sticky;
4950
top: 0;
@@ -52,6 +53,8 @@ defineProps({
5253
5354
.header-content {
5455
display: flex;
56+
width: 100%;
57+
height: 100%;
5558
justify-content: space-between;
5659
align-items: center;
5760
gap: 10px;
@@ -71,7 +74,7 @@ defineProps({
7174
7275
h1 {
7376
margin: 0;
74-
font-size: 18px;
77+
font-size: 16px;
7578
font-weight: 500;
7679
color: var(--gray-2000);
7780
}

web/src/components/McpServersComponent.vue

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,23 @@
77
<!-- 左侧:MCP 列表 -->
88
<div class="sidebar-list">
99
<!-- 搜索框 -->
10-
<div class="search-box">
11-
<a-input
12-
v-model:value="searchQuery"
13-
placeholder="搜索 MCP..."
14-
allow-clear
15-
class="search-input"
16-
>
17-
<template #prefix><Search :size="14" class="text-muted" /></template>
18-
</a-input>
10+
<div class="sidebar-toolbar">
11+
<div class="search-box">
12+
<a-input
13+
v-model:value="searchQuery"
14+
placeholder="搜索 MCP..."
15+
allow-clear
16+
class="search-input"
17+
>
18+
<template #prefix><Search :size="14" class="text-muted" /></template>
19+
</a-input>
20+
</div>
21+
22+
<a-tooltip title="刷新 MCP">
23+
<a-button class="sidebar-tool" :disabled="loading" @click="fetchServers">
24+
<RotateCw :size="14" />
25+
</a-button>
26+
</a-tooltip>
1927
</div>
2028

2129
<!-- 统计信息 -->

web/src/components/SkillsManagerComponent.vue

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,23 @@
66
<div class="layout-wrapper" :class="{ 'content-loading': loading }">
77
<!-- 左侧:技能列表 -->
88
<div class="sidebar-list">
9-
<div class="search-box">
10-
<a-input
11-
v-model:value="searchQuery"
12-
placeholder="搜索技能..."
13-
allow-clear
14-
class="search-input"
15-
>
16-
<template #prefix><Search :size="14" class="text-muted" /></template>
17-
</a-input>
9+
<div class="sidebar-toolbar">
10+
<div class="search-box">
11+
<a-input
12+
v-model:value="searchQuery"
13+
placeholder="搜索技能..."
14+
allow-clear
15+
class="search-input"
16+
>
17+
<template #prefix><Search :size="14" class="text-muted" /></template>
18+
</a-input>
19+
</div>
20+
21+
<a-tooltip title="刷新 Skills">
22+
<a-button class="sidebar-tool" :disabled="loading" @click="fetchSkills">
23+
<RotateCw :size="14" />
24+
</a-button>
25+
</a-tooltip>
1826
</div>
1927

2028
<div class="list-container">
@@ -1211,20 +1219,17 @@ defineExpose({
12111219
.tree-container {
12121220
width: 240px;
12131221
border-right: 1px solid @border-color;
1214-
background-color: @bg-secondary;
12151222
display: flex;
12161223
flex-direction: column;
12171224
flex-shrink: 0;
12181225
12191226
.tree-header {
1220-
padding: 10px 16px;
1227+
padding: 10px 12px 0;
12211228
display: flex;
12221229
justify-content: space-between;
12231230
align-items: center;
1224-
border-bottom: 1px solid @border-color;
1225-
background-color: var(--gray-50);
12261231
.label {
1227-
font-size: 11px;
1232+
font-size: 12px;
12281233
font-weight: 600;
12291234
color: var(--gray-500);
12301235
text-transform: uppercase;
@@ -1251,7 +1256,8 @@ defineExpose({
12511256
.tree-content {
12521257
flex: 1;
12531258
overflow-y: auto;
1254-
padding: 8px;
1259+
height: 100%;
1260+
padding: 8px 0;
12551261
}
12561262
}
12571263
@@ -1264,8 +1270,7 @@ defineExpose({
12641270
min-height: 0;
12651271
12661272
.editor-header {
1267-
padding: 8px 16px;
1268-
border-bottom: 1px solid @border-color;
1273+
padding: 8px 16px 4px;
12691274
display: flex;
12701275
justify-content: space-between;
12711276
align-items: center;
@@ -1327,7 +1332,7 @@ defineExpose({
13271332
height: 100%;
13281333
border: none;
13291334
resize: none;
1330-
padding: 20px;
1335+
padding: 16px;
13311336
font-family: 'Fira Code', 'Monaco', monospace;
13321337
font-size: 13px;
13331338
line-height: 1.6;

0 commit comments

Comments
 (0)