refactor(ui): 优化调试模式实现并改进界面样式
- 将调试模式状态管理移至 infoStore 实现全局统一控制 - 移除各组件中分散的调试模式状态管理代码 - 调整侧边栏和头部组件的边框和背景颜色 - 优化按钮和交互元素的悬停效果 - 更新文档中的 changelog 记录待办事项
This commit is contained in:
parent
95b084ec69
commit
d6dfa2b5e3
@ -9,6 +9,8 @@
|
||||
- [x] 将现在的 graphview.vue 文件中 GraphContainer相关的代码分离到一个单独的组件中,然后 actions 和 footer 都是作为 slot top/bottom 提供的
|
||||
- [x] 然后应用到 web/src/components/ToolCallingResult/KnowledgeGraphResult.vue 中,替换现有的 GraphContainer。
|
||||
- [ ] 知识图谱的上传和可视化,支持属性,标签的展示
|
||||
- [ ] 集成智能体评估,首先使用命令行来实现,然后考虑放在 UI 里面展示
|
||||
- [ ] 开发与生产环境隔离
|
||||
|
||||
🐛**BUGs**
|
||||
- [x] LlightRAG 知识库中,点击边,没有显示,但是在全屏的时候却又能够显示出来。
|
||||
|
||||
@ -100,7 +100,6 @@
|
||||
:message="message"
|
||||
:key="msgIndex"
|
||||
:is-processing="isProcessing && conv.status === 'streaming' && msgIndex === conv.messages.length - 1"
|
||||
:debug-mode="state.debug_mode"
|
||||
:show-refs="showMsgRefs(message)"
|
||||
@retry="retryMessage(message)"
|
||||
>
|
||||
@ -207,7 +206,6 @@ const threadMessages = ref({});
|
||||
|
||||
const uiState = reactive({
|
||||
...props.state,
|
||||
debug_mode: computed(() => props.state.debug_mode ?? false),
|
||||
isSidebarOpen: localStorage.getItem('chat_sidebar_open', 'true') === 'true',
|
||||
isInitialRender: true,
|
||||
showRenameButton: false,
|
||||
@ -1004,8 +1002,8 @@ watch(conversations, () => {
|
||||
|
||||
.example-chip {
|
||||
padding: 6px 12px;
|
||||
background: var(--gray-100);
|
||||
border: 1px solid var(--gray-200);
|
||||
background: var(--gray-25);
|
||||
// border: 1px solid var(--gray-100);
|
||||
border-radius: 16px;
|
||||
cursor: pointer;
|
||||
font-size: 0.8rem;
|
||||
@ -1017,11 +1015,10 @@ watch(conversations, () => {
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:hover {
|
||||
background: var(--main-50);
|
||||
// background: var(--main-25);
|
||||
border-color: var(--main-200);
|
||||
color: var(--main-700);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 0px 4px rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
&:active {
|
||||
|
||||
@ -21,11 +21,6 @@
|
||||
<div class="agent-info" v-if="selectedAgent">
|
||||
<div class="agent-basic-info">
|
||||
<p class="agent-description">{{ selectedAgent.description }}</p>
|
||||
<!-- <div class="debug-toggle" v-if="selectedAgent.name">
|
||||
<span class="debug-text">调试信息</span>
|
||||
<a-switch v-model:checked="debugMode" size="small" />
|
||||
</div>
|
||||
<pre v-if="debugMode && selectedAgent.name" class="debug-info">{{ selectedAgent }}</pre> -->
|
||||
</div>
|
||||
|
||||
<a-divider />
|
||||
@ -334,7 +329,6 @@ const {
|
||||
// console.log(availableTools.value)
|
||||
|
||||
// 本地状态
|
||||
const debugMode = ref(false);
|
||||
const toolsModalOpen = ref(false);
|
||||
const selectedTools = ref([]);
|
||||
const toolsSearchText = ref('');
|
||||
@ -362,10 +356,6 @@ const closeSidebar = () => {
|
||||
emit('close');
|
||||
};
|
||||
|
||||
const toggleDebugMode = () => {
|
||||
debugMode.value = !debugMode.value;
|
||||
};
|
||||
|
||||
const getConfigLabel = (key, value) => {
|
||||
// console.log(configurableItems)
|
||||
if (value.description && value.name !== key) {
|
||||
@ -648,30 +638,6 @@ watch(() => props.isOpen, (newVal) => {
|
||||
color: var(--gray-700);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.debug-toggle {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
cursor: pointer;
|
||||
|
||||
.debug-text {
|
||||
font-size: 13px;
|
||||
color: var(--gray-600);
|
||||
}
|
||||
}
|
||||
|
||||
.debug-info {
|
||||
margin-top: 12px;
|
||||
padding: 12px;
|
||||
background: var(--gray-50);
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
color: var(--gray-700);
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
<!-- 错误消息 -->
|
||||
</div>
|
||||
|
||||
<div v-if="debugMode" class="status-info">{{ message }}</div>
|
||||
<div v-if="infoStore.debugMode" class="status-info">{{ message }}</div>
|
||||
|
||||
<!-- 自定义内容 -->
|
||||
<slot></slot>
|
||||
@ -85,6 +85,7 @@ import RefsComponent from '@/components/RefsComponent.vue'
|
||||
import { Loader, CircleCheckBig } from 'lucide-vue-next';
|
||||
import { ToolResultRenderer } from '@/components/ToolCallingResult'
|
||||
import { useAgentStore } from '@/stores/agent'
|
||||
import { useInfoStore } from '@/stores/info'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
|
||||
@ -112,12 +113,13 @@ const props = defineProps({
|
||||
type: [Array, Boolean],
|
||||
default: () => false
|
||||
},
|
||||
debugMode: {
|
||||
// 是否为最新消息
|
||||
isLatestMessage: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 是否为最新消息
|
||||
isLatestMessage: {
|
||||
// 是否显示调试信息 (已废弃,使用 infoStore.debugMode)
|
||||
debugMode: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
@ -133,6 +135,7 @@ const expandedToolCalls = ref(new Set()); // 展开的工具调用集合
|
||||
|
||||
// 引入智能体 store
|
||||
const agentStore = useAgentStore();
|
||||
const infoStore = useInfoStore();
|
||||
const { availableTools } = storeToRefs(agentStore);
|
||||
|
||||
// 工具相关方法
|
||||
|
||||
@ -244,7 +244,7 @@ const openAgentModal = () => {
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 16px;
|
||||
border-bottom: 1px solid var(--gray-200);
|
||||
border-bottom: 1px solid var(--gray-50);
|
||||
flex-shrink: 0;
|
||||
|
||||
.header-title {
|
||||
@ -261,6 +261,7 @@ const openAgentModal = () => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
// color: var(--gray-600);
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,10 +361,10 @@ const openAgentModal = () => {
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--gray-50);
|
||||
background-color: var(--gray-25);
|
||||
|
||||
.actions-mask {
|
||||
background: linear-gradient(to right, transparent, var(--gray-100) 20px);
|
||||
background: linear-gradient(to right, transparent, var(--gray-25) 20px);
|
||||
}
|
||||
|
||||
.actions-mask, .conversation-actions {
|
||||
@ -372,14 +373,14 @@ const openAgentModal = () => {
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: var(--gray-100);
|
||||
background-color: var(--gray-50);
|
||||
|
||||
.conversation-title {
|
||||
color: var(--main-600);
|
||||
font-weight: 500;
|
||||
}
|
||||
.actions-mask {
|
||||
background: linear-gradient(to right, transparent, var(--gray-100) 20px);
|
||||
background: linear-gradient(to right, transparent, var(--gray-50) 20px);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -415,20 +416,25 @@ const openAgentModal = () => {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
color: var(--gray-500);
|
||||
// padding: 0.5rem;
|
||||
transition: background-color 0.3s;
|
||||
&:hover {
|
||||
color: var(--main-color);
|
||||
|
||||
svg {
|
||||
stroke: var(--gray-600);
|
||||
}
|
||||
|
||||
&:hover svg {
|
||||
stroke: var(--main-color);
|
||||
}
|
||||
}
|
||||
|
||||
// 智能体选择器样式
|
||||
.agent-selector {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-size: 15px;
|
||||
color: var(--gray-900);
|
||||
transition: color 0.2s ease;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
color: var(--main-500);
|
||||
|
||||
@ -22,6 +22,10 @@
|
||||
<template #icon><RobotOutlined /></template>
|
||||
智能体配置
|
||||
</a-button>
|
||||
<a-button @click="toggleDebugMode" :type="infoStore.debugMode ? 'primary' : 'default'">
|
||||
<template #icon><BugOutlined /></template>
|
||||
Debug 模式: {{ infoStore.debugMode ? '开启' : '关闭' }}
|
||||
</a-button>
|
||||
<a-button @click="toggleFullscreen">
|
||||
<template #icon>
|
||||
<FullscreenOutlined v-if="!state.isFullscreen" />
|
||||
@ -99,6 +103,7 @@ import { useConfigStore } from '@/stores/config';
|
||||
import { useUserStore } from '@/stores/user';
|
||||
import { useDatabaseStore } from '@/stores/database';
|
||||
import { useAgentStore } from '@/stores/agent';
|
||||
import { useInfoStore } from '@/stores/info';
|
||||
import { useThrottleFn } from '@vueuse/core';
|
||||
import { message } from 'ant-design-vue';
|
||||
import {
|
||||
@ -112,7 +117,8 @@ import {
|
||||
PlusCircleOutlined,
|
||||
UserOutlined,
|
||||
DatabaseOutlined,
|
||||
RobotOutlined
|
||||
RobotOutlined,
|
||||
BugOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { configApi } from '@/apis/system_api';
|
||||
@ -122,6 +128,7 @@ const configStore = useConfigStore()
|
||||
const userStore = useUserStore();
|
||||
const databaseStore = useDatabaseStore();
|
||||
const agentStore = useAgentStore();
|
||||
const infoStore = useInfoStore();
|
||||
const config = configStore.config;
|
||||
|
||||
|
||||
@ -366,6 +373,12 @@ const printDatabaseInfo = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 切换Debug模式
|
||||
const toggleDebugMode = () => {
|
||||
if (!checkAdminPermission()) return;
|
||||
infoStore.toggleDebugMode();
|
||||
};
|
||||
|
||||
// 打印智能体配置
|
||||
const printAgentConfig = async () => {
|
||||
if (!checkAdminPermission()) return;
|
||||
|
||||
@ -245,7 +245,7 @@ div.header, #app-router-view {
|
||||
background-color: var(--main-10);
|
||||
height: 100%;
|
||||
width: var(--header-width);
|
||||
border-right: 1px solid var(--gray-300);
|
||||
border-right: 1px solid var(--gray-100);
|
||||
|
||||
.nav {
|
||||
display: flex;
|
||||
|
||||
@ -7,6 +7,7 @@ export const useInfoStore = defineStore('info', () => {
|
||||
const infoConfig = ref({})
|
||||
const isLoading = ref(false)
|
||||
const isLoaded = ref(false)
|
||||
const debugMode = ref(false)
|
||||
|
||||
// 计算属性 - 组织信息
|
||||
const organization = computed(() => infoConfig.value.organization || {
|
||||
@ -41,6 +42,14 @@ export const useInfoStore = defineStore('info', () => {
|
||||
isLoaded.value = true
|
||||
}
|
||||
|
||||
function setDebugMode(enabled) {
|
||||
debugMode.value = enabled
|
||||
}
|
||||
|
||||
function toggleDebugMode() {
|
||||
debugMode.value = !debugMode.value
|
||||
}
|
||||
|
||||
async function loadInfoConfig(force = false) {
|
||||
// 如果已经加载过且不强制刷新,则不重新加载
|
||||
if (isLoaded.value && !force) {
|
||||
@ -93,6 +102,7 @@ export const useInfoStore = defineStore('info', () => {
|
||||
infoConfig,
|
||||
isLoading,
|
||||
isLoaded,
|
||||
debugMode,
|
||||
|
||||
// 计算属性
|
||||
organization,
|
||||
@ -102,6 +112,8 @@ export const useInfoStore = defineStore('info', () => {
|
||||
|
||||
// 方法
|
||||
setInfoConfig,
|
||||
setDebugMode,
|
||||
toggleDebugMode,
|
||||
loadInfoConfig,
|
||||
reloadInfoConfig
|
||||
}
|
||||
|
||||
@ -2,19 +2,19 @@
|
||||
<div class="agent-view">
|
||||
<div class="agent-view-header">
|
||||
<div class="header-left">
|
||||
<div class="header-item">
|
||||
<span class="brandname">{{ infoStore.branding?.title }}</span>
|
||||
</div>
|
||||
<div class="header-item">
|
||||
<a-button class="header-button" @click="openAgentModal">
|
||||
<Bot size="18" stroke-width="1.75" />
|
||||
选择:{{ selectedAgent?.name || '选择智能体' }}
|
||||
</a-button>
|
||||
<span class="brandname">{{ infoStore.branding?.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="header-item">
|
||||
<a-button class="header-button" @click="openAgentModal">
|
||||
<Bot size="18" stroke-width="1.75" />
|
||||
切换智能体
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="header-item">
|
||||
<a-button class="header-button" @click="toggleConf" :icon="h(SettingOutlined)"> 配置 </a-button>
|
||||
</div>
|
||||
@ -118,7 +118,6 @@ const {
|
||||
configurableItems,
|
||||
} = storeToRefs(agentStore);
|
||||
const state = reactive({
|
||||
debug_mode: false,
|
||||
agentModalOpen: false,
|
||||
isConfigSidebarOpen: false,
|
||||
isEmptyConfig: computed(() =>
|
||||
@ -217,11 +216,6 @@ const goToAgentPage = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const toggleDebugMode = () => {
|
||||
state.debug_mode = !state.debug_mode;
|
||||
console.log("debug_mode", state.debug_mode);
|
||||
};
|
||||
|
||||
const toggleConf = () => {
|
||||
state.isConfigSidebarOpen = !state.isConfigSidebarOpen
|
||||
}
|
||||
@ -240,7 +234,7 @@ const toggleConf = () => {
|
||||
.agent-view-header {
|
||||
height: var(--agent-view-header-height);
|
||||
background-color: var(--bg-sider);
|
||||
border-bottom: 1px solid var(--gray-200);
|
||||
border-bottom: 1px solid var(--gray-100);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@ -260,7 +254,7 @@ const toggleConf = () => {
|
||||
gap: 10px;
|
||||
|
||||
span.brandname {
|
||||
font-size: 17px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-right: 16px;
|
||||
@ -271,6 +265,7 @@ const toggleConf = () => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
border-color: var(--gray-100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user