From 2725d2fe200766b173fd608f4736eadd26dfa01b Mon Sep 17 00:00:00 2001 From: Xin Wang Date: Sat, 7 Feb 2026 14:28:54 +0800 Subject: [PATCH] Improve web ui --- web/App.tsx | 28 ++++++-- web/components/UI.tsx | 38 +++++++++-- web/pages/Assistants.tsx | 130 +++++++++++++++++++++++++++++++++---- web/pages/CallLogs.tsx | 9 +-- web/pages/History.tsx | 102 ++++++++++++++--------------- web/pages/LLMLibrary.tsx | 2 +- web/pages/ToolLibrary.tsx | 4 +- web/pages/VoiceLibrary.tsx | 2 +- web/services/mockData.ts | 4 +- web/types.ts | 7 +- 10 files changed, 232 insertions(+), 94 deletions(-) diff --git a/web/App.tsx b/web/App.tsx index 71afd91..c13b9c9 100644 --- a/web/App.tsx +++ b/web/App.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import { HashRouter as Router, Routes, Route, Link, useLocation } from 'react-router-dom'; -import { Bot, Book, User, LayoutDashboard, Mic2, Video, GitBranch, Zap, PanelLeftClose, PanelLeftOpen, History as HistoryIcon, ChevronDown, ChevronRight, Box, Wand2, Wrench, BrainCircuit, AudioLines } from 'lucide-react'; +import { Bot, Book, User, LayoutDashboard, Mic2, Video, GitBranch, Zap, PanelLeftClose, PanelLeftOpen, History as HistoryIcon, ChevronDown, ChevronRight, Box, Wand2, Wrench, BrainCircuit, AudioLines, Activity } from 'lucide-react'; import { AssistantsPage } from './pages/Assistants'; import { KnowledgeBasePage } from './pages/KnowledgeBase'; @@ -124,18 +124,32 @@ const AppLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => { { path: '/workflows', label: '工作流', icon: }, ] }, - { path: '/history', label: '历史记录', icon: }, - { path: '/auto-test', label: '测试助手', icon: }, + { + path: '#observation', + label: '观察记录', + icon: , + children: [ + { path: '/history', label: '历史记录', icon: }, + ] + }, + { + path: '#testing', + label: '自动化测试', + icon: , + children: [ + { path: '/auto-test', label: '测试助手', icon: }, + ] + }, { path: '#components', label: '组件库', icon: , children: [ - { path: '/llms', label: '大模型库', icon: }, + { path: '/llms', label: '模型接入', icon: }, { path: '/asr', label: '语音识别', icon: }, - { path: '/voices', label: '声音库', icon: }, + { path: '/voices', label: '声音资源', icon: }, { path: '/knowledge', label: '知识库', icon: }, - { path: '/tools', label: '工具库', icon: }, + { path: '/tools', label: '工具与插件', icon: }, ] }, { path: '/profile', label: '个人中心', icon: }, @@ -227,4 +241,4 @@ const App: React.FC = () => { ); }; -export default App; \ No newline at end of file +export default App; diff --git a/web/components/UI.tsx b/web/components/UI.tsx index 2eb30d1..8ffb110 100644 --- a/web/components/UI.tsx +++ b/web/components/UI.tsx @@ -53,14 +53,23 @@ export const Input: React.FC = ({ className = '', ...props }) => { }; // Card - Glassmorphism style, very subtle border -export const Card: React.FC<{ children: React.ReactNode; className?: string }> = ({ children, className = '' }) => ( -
+interface CardProps extends React.HTMLAttributes { + children: React.ReactNode; + className?: string; +} +export const Card: React.FC = ({ children, className = '', ...props }) => ( +
{children}
); // Badge -export const Badge: React.FC<{ children: React.ReactNode; variant?: 'default' | 'success' | 'warning' | 'outline' }> = ({ children, variant = 'default' }) => { +interface BadgeProps { + children: React.ReactNode; + variant?: 'default' | 'success' | 'warning' | 'outline'; + className?: string; +} +export const Badge: React.FC = ({ children, variant = 'default', className = '' }) => { const styles = { default: "border-transparent bg-primary/20 text-primary hover:bg-primary/30 border border-primary/20", success: "border-transparent bg-green-500/20 text-green-400 border border-green-500/20", @@ -68,7 +77,7 @@ export const Badge: React.FC<{ children: React.ReactNode; variant?: 'default' | outline: "text-foreground border border-white/10 hover:bg-accent hover:text-accent-foreground", }; return ( -
+
{children}
); @@ -76,9 +85,24 @@ export const Badge: React.FC<{ children: React.ReactNode; variant?: 'default' | // Table - Subtle borders export const TableHeader: React.FC<{ children: React.ReactNode }> = ({ children }) => {children}; -export const TableRow: React.FC<{ children: React.ReactNode; className?: string }> = ({ children, className = '' }) => {children}; -export const TableHead: React.FC<{ children: React.ReactNode; className?: string }> = ({ children, className = '' }) => {children}; -export const TableCell: React.FC<{ children: React.ReactNode; className?: string }> = ({ children, className = '' }) => {children}; + +interface TableRowProps extends React.HTMLAttributes { + children: React.ReactNode; + className?: string; +} +export const TableRow: React.FC = ({ children, className = '', ...props }) => {children}; + +interface TableHeadProps extends React.ThHTMLAttributes { + children: React.ReactNode; + className?: string; +} +export const TableHead: React.FC = ({ children, className = '', ...props }) => {children}; + +interface TableCellProps extends React.TdHTMLAttributes { + children: React.ReactNode; + className?: string; +} +export const TableCell: React.FC = ({ children, className = '', ...props }) => {children}; // Drawer (Side Sheet) interface DrawerProps { diff --git a/web/pages/Assistants.tsx b/web/pages/Assistants.tsx index a22ce32..a7cd5ed 100644 --- a/web/pages/Assistants.tsx +++ b/web/pages/Assistants.tsx @@ -1,8 +1,8 @@ import React, { useState, useEffect, useRef } from 'react'; -import { Plus, Search, Play, Copy, Trash2, Edit2, Mic, MessageSquare, Save, Video, PhoneOff, Camera, ArrowLeftRight, Send, Phone, MoreHorizontal, Rocket, AlertTriangle, PhoneCall, CameraOff, Image, Images, CloudSun, Calendar, TrendingUp, Coins, Wrench, Globe, Terminal, X, ClipboardCheck, Sparkles, Volume2, Timer, ChevronDown, Link as LinkIcon, Database, Server, Zap, ExternalLink, Key } from 'lucide-react'; +import { Plus, Search, Play, Copy, Trash2, Edit2, Mic, MessageSquare, Save, Video, PhoneOff, Camera, ArrowLeftRight, Send, Phone, MoreHorizontal, Rocket, AlertTriangle, PhoneCall, CameraOff, Image, Images, CloudSun, Calendar, TrendingUp, Coins, Wrench, Globe, Terminal, X, ClipboardCheck, Sparkles, Volume2, Timer, ChevronDown, Link as LinkIcon, Database, Server, Zap, ExternalLink, Key, BrainCircuit, Ear, Book, Filter } from 'lucide-react'; import { Button, Input, Card, Badge, Drawer, Dialog } from '../components/UI'; -import { mockAssistants, mockKnowledgeBases, mockVoices } from '../services/mockData'; +import { mockAssistants, mockKnowledgeBases, mockVoices, mockLLMModels, mockASRModels } from '../services/mockData'; import { Assistant, TabValue } from '../types'; import { GoogleGenAI } from "@google/genai"; @@ -63,6 +63,10 @@ export const AssistantsPage: React.FC = () => { tools: [], interruptionSensitivity: 500, configMode: 'platform', + llmModelId: '', + asrModelId: '', + embeddingModelId: '', + rerankModelId: '', }; setAssistants([...assistants, newAssistant]); setSelectedId(newId); @@ -363,6 +367,12 @@ export const AssistantsPage: React.FC = () => { > 工具配置 + ) : ( <> @@ -435,6 +445,26 @@ export const AssistantsPage: React.FC = () => { {activeTab === TabValue.GLOBAL && selectedAssistant.configMode === 'platform' && (
+
+ +
+ + +
+

选择用于驱动该助手对话的大语言模型。

+
+
+
+ )} + + {activeTab === TabValue.KNOWLEDGE && selectedAssistant.configMode === 'platform' && ( +
+
+ +
+ + +
+

用于将文本转换为向量的嵌入模型。

+
- - + +
+ + +
+

可选配置。重排模型可优化检索结果的相关性排序。

+
+ +
+ +
+ + +
+

选择助手回答问题时参考的私有知识库。

)} {activeTab === TabValue.VOICE && !isNoneConfig && (
+
+ +
+ + +
+

+ 选择用于识别用户语音输入的模型。 +

+
+