feat(sidebar): 分组模式统一顶部对话类型切换器,列表切换改推挤动画
- 分段控件(普通对话/多智能体)在分组模式下也显示在搜索框下方,移除工作区标题行单字切换按钮 - 列表切换移除 Transition out-in(消除空白期),改为同步推挤滑动:新面板绝对定位从侧边滑入顶出旧面板,去掉 opacity 淡入淡出 - 切换时重置列表滚动位置;同步更新 AGENTS.md 描述
This commit is contained in:
parent
9fff41650d
commit
d3ec94e7e8
@ -374,7 +374,7 @@ AI 执行以下流程时,每一步都要向用户说明在做什么:
|
||||
- `newConversationType`(同上):空对话时输入栏待创建类型(`'agent' | 'multi_agent'`),localStorage 持久化(`agents_new_conversation_type`),由输入栏底行 `+` 右侧的类型选择器修改(`InputComposer.vue` 的 `agent-type-switcher`)。
|
||||
- `sidebarConversationType`(`stores/conversation.ts`):侧边栏列表过滤器(`'normal' | 'multi_agent'`),localStorage 持久化(`agents_sidebar_conversation_type`),驱动列表/搜索的 `multi_agent_mode=0|1` 请求参数与侧边栏新建按钮的对话类型。
|
||||
- `stores/conversation.ts` 的 `multiAgentMode` 字段保留,但语义已变为「当前对话是否多智能体」,仅由 `enterConversation`(meta 落地)与空对话 watcher(复位 false)写入——`stores/subAgent.ts` 的读取点依赖它,不得删除。
|
||||
- 侧边栏类型切换 UI:平铺模式在「搜索对话」下方显示分段控件;分组模式在工作区标题行新建/更多按钮左侧显示单字切换按钮;列表区域用 `<Transition mode="out-in">` 做左右滑动动画(切多智能体向左滑出,切回反向)。
|
||||
- 侧边栏类型切换 UI:分段控件统一显示在「搜索对话」下方(平铺/分组模式位置一致,搜索时隐藏);列表区域用 `<Transition>` 推挤式同步滑动动画(无 out-in,新面板绝对定位从侧边滑入把旧面板顶出,切多智能体向左,切回反向;切换时重置列表滚动位置)。
|
||||
- 发送消息创建对话时按 `newConversationType` 选择 `/api/conversations` 或 `/api/multiagent/conversations`(`message/send.ts`);侧边栏新建按 `sidebarConversationType` 选择(`conversation/action.ts`)。
|
||||
|
||||
### 11.1 角色与实例
|
||||
|
||||
@ -113,7 +113,7 @@
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div v-if="!searchActive && !isGroupByWorkspaceActive" class="conversation-type-switch">
|
||||
<div v-if="!searchActive" class="conversation-type-switch">
|
||||
<button
|
||||
type="button"
|
||||
class="conversation-type-option"
|
||||
@ -132,8 +132,8 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="conversation-list">
|
||||
<Transition :name="slideTransitionName" mode="out-in">
|
||||
<div ref="conversationListEl" class="conversation-list">
|
||||
<Transition :name="slideTransitionName">
|
||||
<div :key="sidebarType" class="conversation-list-pane">
|
||||
<div v-if="runningTaskItems.length && !searchActive && !isGroupByWorkspaceActive" class="running-task-section">
|
||||
<div class="running-task-section-title">运行中的任务</div>
|
||||
@ -203,15 +203,6 @@
|
||||
class="workspace-group-actions"
|
||||
:class="{ visible: hoverWorkspaceId === String(ws.workspace_id || '') || openWorkspaceMenuId === String(ws.workspace_id || '') }"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="workspace-type-btn"
|
||||
:title="sidebarType === 'multi_agent' ? '当前:多智能体对话(点击切换为普通对话)' : '当前:普通对话(点击切换为多智能体对话)'"
|
||||
:aria-label="sidebarType === 'multi_agent' ? '切换为普通对话' : '切换为多智能体对话'"
|
||||
@click.stop="toggleSidebarType"
|
||||
>
|
||||
<span class="workspace-type-btn-label">{{ sidebarType === 'multi_agent' ? '多' : '单' }}</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="workspace-new-btn"
|
||||
@ -774,16 +765,16 @@ const slideTransitionName = computed(() =>
|
||||
sidebarType.value === 'multi_agent' ? 'type-slide-left' : 'type-slide-right'
|
||||
);
|
||||
|
||||
/** 列表容器:切换类型时重置滚动位置,保证推挤动画从顶部开始 */
|
||||
const conversationListEl = ref<HTMLElement | null>(null);
|
||||
|
||||
const setSidebarType = (type: 'normal' | 'multi_agent') => {
|
||||
if (conversationStore.sidebarConversationType === type) return;
|
||||
if (conversationListEl.value) conversationListEl.value.scrollTop = 0;
|
||||
conversationStore.setSidebarConversationType(type);
|
||||
emit('conversation-type-change', type);
|
||||
};
|
||||
|
||||
const toggleSidebarType = () => {
|
||||
setSidebarType(sidebarType.value === 'multi_agent' ? 'normal' : 'multi_agent');
|
||||
};
|
||||
|
||||
const { sidebarCollapsed: collapsed } = storeToRefs(uiStore);
|
||||
const {
|
||||
searchQuery,
|
||||
|
||||
@ -211,6 +211,8 @@
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
padding-top: 8px;
|
||||
/* 为对话类型切换推挤动画提供绝对定位上下文 */
|
||||
position: relative;
|
||||
scrollbar-width: none !important;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
@ -808,7 +810,6 @@ body[data-theme='dark'] .workspace-group-header.search-result-group-header:hover
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.workspace-type-btn,
|
||||
.workspace-new-btn,
|
||||
.workspace-more-btn {
|
||||
width: 28px;
|
||||
@ -825,7 +826,6 @@ body[data-theme='dark'] .workspace-group-header.search-result-group-header:hover
|
||||
color 140ms ease;
|
||||
}
|
||||
|
||||
.workspace-type-btn:hover,
|
||||
.workspace-new-btn:hover,
|
||||
.workspace-more-btn:hover,
|
||||
.workspace-group-actions.visible .workspace-more-btn[aria-expanded='true'] {
|
||||
@ -833,12 +833,6 @@ body[data-theme='dark'] .workspace-group-header.search-result-group-header:hover
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.workspace-type-btn-label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.workspace-more-btn span {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
@ -1153,7 +1147,8 @@ body[data-theme='dark'] .conversation-sidebar .load-more-btn:hover:not(:disabled
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 列表区域整体左右滑动切换动画 */
|
||||
/* 列表区域整体左右滑动切换动画(推挤式:新面板从侧边滑入把旧面板顶出去,
|
||||
无 out-in 空白期;两面板同速同幅滑动,边缘始终相接) */
|
||||
.conversation-list-pane {
|
||||
min-height: 0;
|
||||
}
|
||||
@ -1162,27 +1157,31 @@ body[data-theme='dark'] .conversation-sidebar .load-more-btn:hover:not(:disabled
|
||||
.type-slide-left-leave-active,
|
||||
.type-slide-right-enter-active,
|
||||
.type-slide-right-leave-active {
|
||||
transition:
|
||||
transform 200ms ease,
|
||||
opacity 200ms ease;
|
||||
transition: transform 220ms ease;
|
||||
}
|
||||
|
||||
/* 进入面板绝对定位覆盖在容器上,与流内滑出的旧面板同步推移;
|
||||
padding-top 对齐 .conversation-list 的 padding-top,避免垂直错位 */
|
||||
.type-slide-left-enter-active,
|
||||
.type-slide-right-enter-active {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
padding-top: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.type-slide-left-enter-from {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.type-slide-left-leave-to {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.type-slide-right-enter-from {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.type-slide-right-leave-to {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user