cc工作前备份
This commit is contained in:
@@ -1,103 +1,214 @@
|
||||
import { FileText, User, Target, CheckSquare } from 'lucide-react';
|
||||
import { useEffect } from 'react';
|
||||
import { useGatewayStore } from '../store/gatewayStore';
|
||||
import { useChatStore } from '../store/chatStore';
|
||||
import {
|
||||
Wifi, WifiOff, Bot, BarChart3, Plug, RefreshCw,
|
||||
MessageSquare, Cpu, Activity,
|
||||
} from 'lucide-react';
|
||||
|
||||
export function RightPanel() {
|
||||
const {
|
||||
connectionState, gatewayVersion, error, clones, usageStats, pluginStatus,
|
||||
connect, loadClones, loadUsageStats, loadPluginStatus,
|
||||
} = useGatewayStore();
|
||||
const { messages, currentModel } = useChatStore();
|
||||
|
||||
const connected = connectionState === 'connected';
|
||||
|
||||
// Load data when connected
|
||||
useEffect(() => {
|
||||
if (connected) {
|
||||
loadClones();
|
||||
loadUsageStats();
|
||||
loadPluginStatus();
|
||||
}
|
||||
}, [connected]);
|
||||
|
||||
const handleReconnect = () => {
|
||||
connect().catch(() => {});
|
||||
};
|
||||
|
||||
const userMsgCount = messages.filter(m => m.role === 'user').length;
|
||||
const assistantMsgCount = messages.filter(m => m.role === 'assistant').length;
|
||||
const toolCallCount = messages.filter(m => m.role === 'tool').length;
|
||||
|
||||
return (
|
||||
<aside className="w-80 bg-white border-l border-gray-200 flex flex-col flex-shrink-0">
|
||||
{/* 顶部工具栏 */}
|
||||
<aside className="w-72 bg-white border-l border-gray-200 flex flex-col flex-shrink-0">
|
||||
{/* 顶部 */}
|
||||
<div className="h-14 border-b border-gray-100 flex items-center justify-between px-4 flex-shrink-0">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-center gap-1 text-gray-600">
|
||||
<Target className="w-4 h-4" />
|
||||
<span className="font-medium">2268</span>
|
||||
</div>
|
||||
<button className="text-xs text-orange-600 hover:underline">去购买</button>
|
||||
<div className="flex items-center gap-2">
|
||||
<Activity className="w-4 h-4 text-gray-500" />
|
||||
<span className="font-medium text-gray-700 text-sm">系统状态</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 text-gray-500">
|
||||
<button className="hover:text-gray-700 flex items-center gap-1 text-xs">
|
||||
<FileText className="w-4 h-4" />
|
||||
<span>文件</span>
|
||||
{connected && (
|
||||
<button
|
||||
onClick={() => { loadUsageStats(); loadPluginStatus(); loadClones(); }}
|
||||
className="p-1 text-gray-400 hover:text-orange-500 rounded transition-colors"
|
||||
title="刷新数据"
|
||||
>
|
||||
<RefreshCw className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
<button className="hover:text-gray-700 flex items-center gap-1 text-xs">
|
||||
<User className="w-4 h-4" />
|
||||
<span>Agent</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 内容区 */}
|
||||
<div className="flex-1 overflow-y-auto custom-scrollbar p-4">
|
||||
{/* 任务进度 */}
|
||||
<div className="bg-gray-50 rounded-lg border border-gray-100 mb-6 overflow-hidden">
|
||||
<div className="p-3">
|
||||
<div className="flex justify-between text-xs mb-2">
|
||||
<span className="text-gray-600">任务进度</span>
|
||||
<span className="font-medium text-gray-900">65%</span>
|
||||
</div>
|
||||
<div className="w-full bg-gray-200 rounded-full h-2">
|
||||
<div className="bg-orange-500 h-2 rounded-full transition-all" style={{ width: '65%' }}></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-t border-gray-100 divide-y divide-gray-100 text-xs">
|
||||
<div className="py-2 px-3 flex justify-between">
|
||||
<span className="text-gray-600">远程执行</span>
|
||||
<span className="text-green-600">✅ 完成</span>
|
||||
</div>
|
||||
<div className="py-2 px-3 flex justify-between">
|
||||
<span className="text-gray-600">任务编排</span>
|
||||
<span className="text-orange-600">🔄 进行中</span>
|
||||
</div>
|
||||
<div className="py-2 px-3 flex justify-between">
|
||||
<span className="text-gray-600">多 Agent 协作</span>
|
||||
<span className="text-gray-400">⏳ 待开始</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 今日统计 */}
|
||||
<div className="mb-6">
|
||||
<h3 className="font-bold text-gray-900 mb-3 text-sm">今日统计</h3>
|
||||
<div className="bg-gray-50 rounded-lg border border-gray-100 p-3">
|
||||
<div className="space-y-2 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">任务数</span>
|
||||
<span className="font-medium text-gray-900">8 个</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">成功</span>
|
||||
<span className="font-medium text-green-600">6 个</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">进行中</span>
|
||||
<span className="font-medium text-orange-600">2 个</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 下一步行动 */}
|
||||
<div>
|
||||
<h3 className="font-bold text-gray-900 mb-3 text-sm flex items-center gap-2">
|
||||
<span className="w-5 h-5 bg-orange-500 rounded-full flex items-center justify-center text-white text-xs">
|
||||
<Target className="w-3 h-3" />
|
||||
<div className="flex-1 overflow-y-auto custom-scrollbar p-4 space-y-4">
|
||||
{/* Gateway 连接状态 */}
|
||||
<div className={`rounded-lg border p-3 ${connected ? 'bg-green-50 border-green-200' : 'bg-gray-50 border-gray-200'}`}>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
{connected ? (
|
||||
<Wifi className="w-4 h-4 text-green-600" />
|
||||
) : (
|
||||
<WifiOff className="w-4 h-4 text-gray-400" />
|
||||
)}
|
||||
<span className={`text-xs font-semibold ${connected ? 'text-green-700' : 'text-gray-600'}`}>
|
||||
Gateway {connected ? '已连接' : connectionState === 'connecting' ? '连接中...' : connectionState === 'reconnecting' ? '重连中...' : '未连接'}
|
||||
</span>
|
||||
下一步行动
|
||||
</div>
|
||||
<div className="space-y-1 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">地址</span>
|
||||
<span className="text-gray-700 font-mono">127.0.0.1:18789</span>
|
||||
</div>
|
||||
{gatewayVersion && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">版本</span>
|
||||
<span className="text-gray-700">{gatewayVersion}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">当前模型</span>
|
||||
<span className="text-orange-600 font-medium">{currentModel}</span>
|
||||
</div>
|
||||
</div>
|
||||
{!connected && connectionState !== 'connecting' && (
|
||||
<button
|
||||
onClick={handleReconnect}
|
||||
className="mt-2 w-full text-xs bg-orange-500 text-white rounded py-1.5 hover:bg-orange-600 transition-colors"
|
||||
>
|
||||
连接 Gateway
|
||||
</button>
|
||||
)}
|
||||
{error && (
|
||||
<p className="mt-2 text-xs text-red-500 truncate" title={error}>{error}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 当前会话 */}
|
||||
<div className="bg-gray-50 rounded-lg border border-gray-100 p-3">
|
||||
<h3 className="text-xs font-semibold text-gray-700 mb-2 flex items-center gap-1.5">
|
||||
<MessageSquare className="w-3.5 h-3.5" />
|
||||
当前会话
|
||||
</h3>
|
||||
<div className="ml-7 space-y-2">
|
||||
<h4 className="text-xs font-semibold text-gray-900 mb-2">立即执行 (今天)</h4>
|
||||
<ul className="space-y-2">
|
||||
<li className="flex items-start gap-2 text-xs text-gray-600">
|
||||
<div className="w-3 h-3 border border-gray-300 rounded-sm mt-0.5 flex-shrink-0"></div>
|
||||
<span>初始化项目结构</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2 text-xs text-gray-600">
|
||||
<div className="w-3 h-3 border border-gray-300 rounded-sm mt-0.5 flex-shrink-0"></div>
|
||||
<span>创建核心系统代码</span>
|
||||
</li>
|
||||
<li className="flex items-start gap-2 text-xs text-gray-600">
|
||||
<div className="w-3 h-3 border border-gray-300 rounded-sm mt-0.5 flex-shrink-0"></div>
|
||||
<span>集成 OpenClaw SDK</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="space-y-1.5 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">用户消息</span>
|
||||
<span className="font-medium text-gray-900">{userMsgCount}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">助手回复</span>
|
||||
<span className="font-medium text-gray-900">{assistantMsgCount}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">工具调用</span>
|
||||
<span className="font-medium text-gray-900">{toolCallCount}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">总消息数</span>
|
||||
<span className="font-medium text-orange-600">{messages.length}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 分身 */}
|
||||
<div className="bg-gray-50 rounded-lg border border-gray-100 p-3">
|
||||
<h3 className="text-xs font-semibold text-gray-700 mb-2 flex items-center gap-1.5">
|
||||
<Bot className="w-3.5 h-3.5" />
|
||||
分身
|
||||
</h3>
|
||||
{clones.length > 0 ? (
|
||||
<div className="space-y-1.5">
|
||||
{clones.slice(0, 5).map(c => (
|
||||
<div key={c.id} className="flex items-center gap-2 text-xs">
|
||||
<div className="w-5 h-5 bg-gradient-to-br from-orange-400 to-red-500 rounded-md flex items-center justify-center text-white text-[10px]">
|
||||
<Bot className="w-3 h-3" />
|
||||
</div>
|
||||
<span className="text-gray-700 truncate">{c.name}</span>
|
||||
</div>
|
||||
))}
|
||||
{clones.length > 5 && (
|
||||
<p className="text-xs text-gray-400">+{clones.length - 5} 个分身</p>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-xs text-gray-400">
|
||||
{connected ? '暂无分身,在左侧栏创建' : '连接后可用'}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 用量统计 */}
|
||||
{usageStats && (
|
||||
<div className="bg-gray-50 rounded-lg border border-gray-100 p-3">
|
||||
<h3 className="text-xs font-semibold text-gray-700 mb-2 flex items-center gap-1.5">
|
||||
<BarChart3 className="w-3.5 h-3.5" />
|
||||
用量统计
|
||||
</h3>
|
||||
<div className="space-y-1.5 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">总会话数</span>
|
||||
<span className="font-medium text-gray-900">{usageStats.totalSessions}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">总消息数</span>
|
||||
<span className="font-medium text-gray-900">{usageStats.totalMessages}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">总 Token</span>
|
||||
<span className="font-medium text-gray-900">{usageStats.totalTokens.toLocaleString()}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 插件状态 */}
|
||||
{pluginStatus.length > 0 && (
|
||||
<div className="bg-gray-50 rounded-lg border border-gray-100 p-3">
|
||||
<h3 className="text-xs font-semibold text-gray-700 mb-2 flex items-center gap-1.5">
|
||||
<Plug className="w-3.5 h-3.5" />
|
||||
插件 ({pluginStatus.length})
|
||||
</h3>
|
||||
<div className="space-y-1 text-xs">
|
||||
{pluginStatus.map((p: any, i: number) => (
|
||||
<div key={i} className="flex justify-between">
|
||||
<span className="text-gray-600 truncate">{p.name || p.id}</span>
|
||||
<span className={p.status === 'active' ? 'text-green-600' : 'text-gray-400'}>
|
||||
{p.status === 'active' ? '运行中' : '已停止'}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 系统信息 */}
|
||||
<div className="bg-gray-50 rounded-lg border border-gray-100 p-3">
|
||||
<h3 className="text-xs font-semibold text-gray-700 mb-2 flex items-center gap-1.5">
|
||||
<Cpu className="w-3.5 h-3.5" />
|
||||
系统信息
|
||||
</h3>
|
||||
<div className="space-y-1.5 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">ZCLAW 版本</span>
|
||||
<span className="text-gray-700">v0.2.0</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">协议版本</span>
|
||||
<span className="text-gray-700">Gateway v3</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-500">平台</span>
|
||||
<span className="text-gray-700">Tauri 2.0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user