Files
KiloStar/frontend/src/App.tsx
T
zhaoxi a53ffebe0e feat: 新增工具插件、系统日志、workflow配置及前端优化
1. 新增工具插件(edit_file, python_executor, search_file, shell_executor, write_file)
2. 新增系统事件日志模块和API
3. 新增workflow配置文件和详情API
4. 前端增加SSE、错误边界、设置引导等组件
5. 优化认证加密、速率限制、配置加载等工具模块
6. 删除废弃的cluster和health API
7. 补充单元测试和集成测试

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-03 07:34:43 +00:00

135 lines
3.8 KiB
TypeScript

import { useEffect, useState } from 'react';
import i18n from './i18n';
import { TopBar } from './components/Layout/TopBar';
import { CollapsibleSidebar } from './components/Layout/CollapsibleSidebar';
import { SetupGuideModal } from './components/Layout/SetupGuideModal';
import { SettingsLayout } from './components/Settings/SettingsLayout';
import { AgentLayout } from './components/Agent/AgentLayout';
import { PluginLayout } from './components/Plugin/PluginLayout';
import { LeftPanel } from './components/Chat/LeftPanel';
import { ChatPanel } from './components/Chat/ChatPanel';
import { RightPanel } from './components/Chat/RightPanel';
import { WorkflowListView } from './components/Chat/WorkflowListView';
import { NewWorkflowDialog } from './components/Chat/NewWorkflowDialog';
import { AuthPage } from './components/Auth/AuthPage';
import { useAppStore } from './store/useAppStore';
import { useChatStore } from './store/useChatStore';
function App() {
const {
isAuthenticated,
setIsAuthenticated,
mode,
setMode,
showSettings,
workTab,
agentTab,
applyTheme,
locale,
} = useAppStore();
const { loadSessions } = useChatStore();
const [showSetupGuide, setShowSetupGuide] = useState(false);
useEffect(() => {
applyTheme();
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handler = () => applyTheme();
mediaQuery.addEventListener('change', handler);
return () => mediaQuery.removeEventListener('change', handler);
}, [applyTheme]);
useEffect(() => {
if (locale && i18n.language !== locale) {
i18n.changeLanguage(locale);
}
}, [locale]);
useEffect(() => {
const token = localStorage.getItem('token');
if (token) {
setIsAuthenticated(true);
}
}, [setIsAuthenticated]);
useEffect(() => {
if (isAuthenticated) {
loadSessions();
setShowSetupGuide(true);
}
}, [isAuthenticated, loadSessions]);
if (!isAuthenticated) {
return <AuthPage onLoginSuccess={() => setIsAuthenticated(true)} />;
}
return (
<div className="flex flex-col h-screen w-screen bg-bg-primary text-text-primary font-sans overflow-hidden">
<TopBar />
{showSetupGuide && (
<SetupGuideModal
onClose={() => setShowSetupGuide(false)}
onNavigateToAgent={() => {
setMode('agent');
}}
/>
)}
<div className="flex flex-1 overflow-hidden relative">
{showSettings ? (
<SettingsLayout />
) : (
<>
<CollapsibleSidebar />
<div className="flex-1 flex overflow-hidden">
{mode === 'work' && workTab === 'chat' && (
<div className="flex-1 flex overflow-hidden">
<LeftPanel activeTab="chats" />
<ChatPanel />
</div>
)}
{mode === 'work' && workTab === 'workflow' && <WorkflowShell />}
{mode === 'agent' && agentTab === 'agents' && <AgentLayout />}
{mode === 'agent' && agentTab === 'plugin' && <PluginLayout />}
</div>
</>
)}
</div>
</div>
);
}
function WorkflowShell() {
const { selectedWorkflow, setSelectedWorkflow } = useChatStore();
if (selectedWorkflow === 'new') {
return (
<div className="flex-1 flex overflow-hidden">
<LeftPanel activeTab="workflows" />
<NewWorkflowDialog
onClose={() => setSelectedWorkflow(null)}
onSuccess={(traceId: string) => setSelectedWorkflow(traceId)}
/>
</div>
);
}
if (selectedWorkflow) {
return (
<div className="flex-1 flex overflow-hidden">
<LeftPanel activeTab="workflows" />
<RightPanel selectedWorkflow={selectedWorkflow} />
</div>
);
}
return <WorkflowListView onSelectWorkflow={setSelectedWorkflow} />;
}
export default App;