feat(ui): 新增暗色模式支持并调整智能体选择器位置
将智能体选择器从侧边栏移动到主聊天界面头部 调整相关样式以匹配新的布局
This commit is contained in:
parent
0ff771dc19
commit
fb3b864565
@ -11,7 +11,7 @@
|
|||||||
- 开发与生产环境隔离,构建生产镜像 <Badge type="info" text="0.4" />
|
- 开发与生产环境隔离,构建生产镜像 <Badge type="info" text="0.4" />
|
||||||
- 集成 LangFuse (观望) 添加用户日志与用户反馈模块,可以在 AgentView 中查看信息
|
- 集成 LangFuse (观望) 添加用户日志与用户反馈模块,可以在 AgentView 中查看信息
|
||||||
- 集成 neo4j mcp (或者自己构建工具)
|
- 集成 neo4j mcp (或者自己构建工具)
|
||||||
- 文档解析部分的 markdown 中的图片替换为内部可访问的链接
|
- 文档解析部分的 markdown 中的图片替换为内部可访问的链接 (2/4)
|
||||||
|
|
||||||
### Bugs
|
### Bugs
|
||||||
- 部分异常状态下,智能体的模型名称出现重叠[#279](https://github.com/xerrors/Yuxi-Know/issues/279)
|
- 部分异常状态下,智能体的模型名称出现重叠[#279](https://github.com/xerrors/Yuxi-Know/issues/279)
|
||||||
@ -28,6 +28,7 @@
|
|||||||
- 新增基于知识库文件生成示例问题功能([#335](https://github.com/xerrors/Yuxi-Know/pull/335#issuecomment-3530976425))
|
- 新增基于知识库文件生成示例问题功能([#335](https://github.com/xerrors/Yuxi-Know/pull/335#issuecomment-3530976425))
|
||||||
- 新增知识库支持文件夹/压缩包上传的功能([#335](https://github.com/xerrors/Yuxi-Know/pull/335#issuecomment-3530976425))
|
- 新增知识库支持文件夹/压缩包上传的功能([#335](https://github.com/xerrors/Yuxi-Know/pull/335#issuecomment-3530976425))
|
||||||
- 新增自定义模型支持、新增 dashscope rerank/embeddings 模型的支持
|
- 新增自定义模型支持、新增 dashscope rerank/embeddings 模型的支持
|
||||||
|
- 新增暗色模式支持并调整整体 UI([#343](https://github.com/xerrors/Yuxi-Know/pull/343))
|
||||||
|
|
||||||
### 修复
|
### 修复
|
||||||
- 修复重排序模型实际未生效的问题
|
- 修复重排序模型实际未生效的问题
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
<div type="button" class="agent-nav-btn" v-if="!chatUIStore.isSidebarOpen" @click="toggleSidebar">
|
<div type="button" class="agent-nav-btn" v-if="!chatUIStore.isSidebarOpen" @click="toggleSidebar">
|
||||||
<PanelLeftOpen class="nav-btn-icon" size="18"/>
|
<PanelLeftOpen class="nav-btn-icon" size="18"/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
type="button"
|
type="button"
|
||||||
class="agent-nav-btn"
|
class="agent-nav-btn"
|
||||||
v-if="!chatUIStore.isSidebarOpen"
|
v-if="!chatUIStore.isSidebarOpen"
|
||||||
@ -41,6 +41,15 @@
|
|||||||
<MessageCirclePlus v-else class="nav-btn-icon" size="18"/>
|
<MessageCirclePlus v-else class="nav-btn-icon" size="18"/>
|
||||||
<span class="text" :class="{'hide-text': isMediumContainer}">新对话</span>
|
<span class="text" :class="{'hide-text': isMediumContainer}">新对话</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="!props.singleMode"
|
||||||
|
class="agent-nav-btn"
|
||||||
|
@click="openAgentModal"
|
||||||
|
>
|
||||||
|
<span class="text">{{ currentAgentName || '选择智能体' }}</span>
|
||||||
|
<ChevronDown size="16" class="switch-icon" />
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="header__right">
|
<div class="header__right">
|
||||||
<!-- AgentState 显示按钮 - 只在智能体支持 todo 或 files 能力时显示 -->
|
<!-- AgentState 显示按钮 - 只在智能体支持 todo 或 files 能力时显示 -->
|
||||||
@ -234,7 +243,7 @@ import AgentMessageComponent from '@/components/AgentMessageComponent.vue'
|
|||||||
import ImagePreviewComponent from '@/components/ImagePreviewComponent.vue'
|
import ImagePreviewComponent from '@/components/ImagePreviewComponent.vue'
|
||||||
import ChatSidebarComponent from '@/components/ChatSidebarComponent.vue'
|
import ChatSidebarComponent from '@/components/ChatSidebarComponent.vue'
|
||||||
import RefsComponent from '@/components/RefsComponent.vue'
|
import RefsComponent from '@/components/RefsComponent.vue'
|
||||||
import { PanelLeftOpen, MessageCirclePlus, LoaderCircle, Layers } from 'lucide-vue-next';
|
import { PanelLeftOpen, MessageCirclePlus, LoaderCircle, Layers, ChevronDown } from 'lucide-vue-next';
|
||||||
import { handleChatError, handleValidationError } from '@/utils/errorHandler';
|
import { handleChatError, handleValidationError } from '@/utils/errorHandler';
|
||||||
import { ScrollController } from '@/utils/scrollController';
|
import { ScrollController } from '@/utils/scrollController';
|
||||||
import { AgentValidator } from '@/utils/agentValidator';
|
import { AgentValidator } from '@/utils/agentValidator';
|
||||||
@ -1432,10 +1441,19 @@ watch(conversations, () => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 1rem 8px;
|
padding: 1rem 8px;
|
||||||
|
|
||||||
.header__left, .header__right, .header__center {
|
.header__left, .header__right {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.switch-icon {
|
||||||
|
color: var(--gray-500);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-nav-btn:hover .switch-icon {
|
||||||
|
color: var(--main-500);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
<p class="agent-description">{{ selectedAgent.description }}</p>
|
<p class="agent-description">{{ selectedAgent.description }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-divider />
|
<!-- <a-divider /> -->
|
||||||
|
|
||||||
<div v-if="selectedAgentId && configurableItems" class="config-form-content">
|
<div v-if="selectedAgentId && configurableItems" class="config-form-content">
|
||||||
<!-- 配置表单 -->
|
<!-- 配置表单 -->
|
||||||
@ -357,7 +357,8 @@ const closeSidebar = () => {
|
|||||||
const getConfigLabel = (key, value) => {
|
const getConfigLabel = (key, value) => {
|
||||||
// console.log(configurableItems)
|
// console.log(configurableItems)
|
||||||
if (value.description && value.name !== key) {
|
if (value.description && value.name !== key) {
|
||||||
return `${value.name}(${key})`;
|
return `${value.name}`;
|
||||||
|
// return `${value.name}(${key})`;
|
||||||
}
|
}
|
||||||
return key;
|
return key;
|
||||||
};
|
};
|
||||||
@ -695,7 +696,14 @@ watch(() => props.isOpen, (newVal) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.config-item {
|
.config-item {
|
||||||
margin: 30px 0;
|
background-color: var(--gray-50);
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0px 1px 1px var(--shadow-2);
|
||||||
|
|
||||||
|
:deep(label.form_item_model) {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
.config-description {
|
.config-description {
|
||||||
margin: 4px 0 8px 0;
|
margin: 4px 0 8px 0;
|
||||||
|
|||||||
@ -2,15 +2,7 @@
|
|||||||
<div class="chat-sidebar" :class="{'sidebar-open': chatUIStore.isSidebarOpen, 'no-transition': isInitialRender}">
|
<div class="chat-sidebar" :class="{'sidebar-open': chatUIStore.isSidebarOpen, 'no-transition': isInitialRender}">
|
||||||
<div class="sidebar-content">
|
<div class="sidebar-content">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<div class="header-title" v-if="singleMode">{{ selectedAgentName }}</div>
|
<div class="header-title">{{ branding.name }}</div>
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
class="agent-selector"
|
|
||||||
@click="openAgentModal"
|
|
||||||
>
|
|
||||||
<span class="agent-name">{{ selectedAgentName || '选择智能体' }}</span>
|
|
||||||
<ChevronDown size="16" class="switch-icon" />
|
|
||||||
</div>
|
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<div class="toggle-sidebar nav-btn" v-if="chatUIStore.isSidebarOpen" @click="toggleCollapse">
|
<div class="toggle-sidebar nav-btn" v-if="chatUIStore.isSidebarOpen" @click="toggleCollapse">
|
||||||
<PanelLeftClose size="20" color="var(--gray-800)"/>
|
<PanelLeftClose size="20" color="var(--gray-800)"/>
|
||||||
@ -73,12 +65,17 @@ import {
|
|||||||
MoreOutlined
|
MoreOutlined
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
import { message, Modal } from 'ant-design-vue';
|
import { message, Modal } from 'ant-design-vue';
|
||||||
import { PanelLeftClose, MessageSquarePlus, ChevronDown, LoaderCircle } from 'lucide-vue-next';
|
import { PanelLeftClose, MessageSquarePlus, LoaderCircle } from 'lucide-vue-next';
|
||||||
import dayjs, { parseToShanghai } from '@/utils/time';
|
import dayjs, { parseToShanghai } from '@/utils/time';
|
||||||
import { useChatUIStore } from '@/stores/chatUI';
|
import { useChatUIStore } from '@/stores/chatUI';
|
||||||
|
import { useInfoStore } from '@/stores/info';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
|
||||||
// 使用 chatUI store
|
// 使用 chatUI store
|
||||||
const chatUIStore = useChatUIStore();
|
const chatUIStore = useChatUIStore();
|
||||||
|
const infoStore = useInfoStore();
|
||||||
|
|
||||||
|
const { branding } = storeToRefs(infoStore);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
currentAgentId: {
|
currentAgentId: {
|
||||||
@ -113,13 +110,7 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emit = defineEmits(['create-chat', 'select-chat', 'delete-chat', 'rename-chat', 'toggle-sidebar', 'open-agent-modal']);
|
const emit = defineEmits(['create-chat', 'select-chat', 'delete-chat', 'rename-chat', 'toggle-sidebar', 'open-agent-modal']);
|
||||||
|
|
||||||
const selectedAgentName = computed(() => {
|
|
||||||
if (props.selectedAgentId && props.agents && props.agents.length > 0) {
|
|
||||||
const agent = props.agents.find(a => a.id === props.selectedAgentId);
|
|
||||||
return agent ? agent.name : '';
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
const groupedChats = computed(() => {
|
const groupedChats = computed(() => {
|
||||||
const groups = {
|
const groups = {
|
||||||
@ -221,16 +212,14 @@ const toggleCollapse = () => {
|
|||||||
emit('toggle-sidebar');
|
emit('toggle-sidebar');
|
||||||
};
|
};
|
||||||
|
|
||||||
const openAgentModal = () => {
|
|
||||||
emit('open-agent-modal');
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.chat-sidebar {
|
.chat-sidebar {
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: var(--gray-25);
|
background-color: var(--gray-0);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -280,7 +269,7 @@ const openAgentModal = () => {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
.header-title {
|
.header-title {
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: var(--gray-900);
|
color: var(--gray-900);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@ -479,34 +468,5 @@ const openAgentModal = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 智能体选择器样式
|
|
||||||
.agent-selector {
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 15px;
|
|
||||||
color: var(--gray-900);
|
|
||||||
transition: color 0.2s ease;
|
|
||||||
font-weight: 500;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
|
|
||||||
.agent-name {
|
|
||||||
transition: color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.switch-icon {
|
|
||||||
color: var(--gray-500);
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.agent-name {
|
|
||||||
color: var(--main-500);
|
|
||||||
}
|
|
||||||
.switch-icon {
|
|
||||||
color: var(--main-500);
|
|
||||||
transform: translateY(1px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -202,7 +202,7 @@ const mainList = [{
|
|||||||
</RouterLink>
|
</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-mobile">
|
<div class="header-mobile">
|
||||||
<RouterLink to="/chat" class="nav-item" active-class="active">对话</RouterLink>
|
<RouterLink to="/agent" class="nav-item" active-class="active">对话</RouterLink>
|
||||||
<RouterLink to="/database" class="nav-item" active-class="active">知识</RouterLink>
|
<RouterLink to="/database" class="nav-item" active-class="active">知识</RouterLink>
|
||||||
<RouterLink to="/setting" class="nav-item" active-class="active">设置</RouterLink>
|
<RouterLink to="/setting" class="nav-item" active-class="active">设置</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user