chore: 提交所有工作进度 — SaaS 后端增强、Admin UI、桌面端集成
包含大量 SaaS 平台改进、Admin 管理后台更新、桌面端集成完善、 文档同步、测试文件重构等内容。为 QA 测试准备干净工作树。
This commit is contained in:
@@ -365,7 +365,7 @@ export function RightPanel() {
|
||||
onClick={handleCancelEdit}
|
||||
aria-label="Cancel edit"
|
||||
>
|
||||
Cancel
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
@@ -373,7 +373,7 @@ export function RightPanel() {
|
||||
onClick={() => { handleSaveAgent().catch(silentErrorHandler('RightPanel')); }}
|
||||
aria-label="Save edit"
|
||||
>
|
||||
Save
|
||||
保存
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
@@ -383,7 +383,7 @@ export function RightPanel() {
|
||||
onClick={handleStartEdit}
|
||||
aria-label="Edit Agent"
|
||||
>
|
||||
Edit
|
||||
编辑
|
||||
</Button>
|
||||
)
|
||||
) : null}
|
||||
@@ -395,20 +395,20 @@ export function RightPanel() {
|
||||
transition={defaultTransition}
|
||||
className="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-4 shadow-sm"
|
||||
>
|
||||
<div className="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-3">About Me</div>
|
||||
<div className="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-3">关于我</div>
|
||||
{isEditingAgent && agentDraft ? (
|
||||
<div className="space-y-2">
|
||||
<AgentInput label="Name" value={agentDraft.name} onChange={(value) => setAgentDraft({ ...agentDraft, name: value })} />
|
||||
<AgentInput label="Role" value={agentDraft.role} onChange={(value) => setAgentDraft({ ...agentDraft, role: value })} />
|
||||
<AgentInput label="Nickname" value={agentDraft.nickname} onChange={(value) => setAgentDraft({ ...agentDraft, nickname: value })} />
|
||||
<AgentInput label="Model" value={agentDraft.model} onChange={(value) => setAgentDraft({ ...agentDraft, model: value })} />
|
||||
<AgentInput label="名称" value={agentDraft.name} onChange={(value) => setAgentDraft({ ...agentDraft, name: value })} />
|
||||
<AgentInput label="角色" value={agentDraft.role} onChange={(value) => setAgentDraft({ ...agentDraft, role: value })} />
|
||||
<AgentInput label="昵称" value={agentDraft.nickname} onChange={(value) => setAgentDraft({ ...agentDraft, nickname: value })} />
|
||||
<AgentInput label="模型" value={agentDraft.model} onChange={(value) => setAgentDraft({ ...agentDraft, model: value })} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-3 text-sm">
|
||||
<AgentRow label="Role" value={selectedClone?.role || '全能型 AI 助手'} />
|
||||
<AgentRow label="Nickname" value={selectedClone?.nickname || '小龙'} />
|
||||
<AgentRow label="Model" value={selectedClone?.model || currentModel} />
|
||||
<AgentRow label="Emoji" value={selectedClone?.emoji || '🦞'} />
|
||||
<AgentRow label="角色" value={selectedClone?.role || '全能型 AI 助手'} />
|
||||
<AgentRow label="昵称" value={selectedClone?.nickname || '小龙'} />
|
||||
<AgentRow label="模型" value={selectedClone?.model || currentModel} />
|
||||
<AgentRow label="表情" value={selectedClone?.emoji || '🦞'} />
|
||||
</div>
|
||||
)}
|
||||
</motion.div>
|
||||
@@ -418,33 +418,33 @@ export function RightPanel() {
|
||||
transition={defaultTransition}
|
||||
className="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-4 shadow-sm"
|
||||
>
|
||||
<div className="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-3">You in My Eyes</div>
|
||||
<div className="text-sm font-semibold text-gray-900 dark:text-gray-100 mb-3">我眼中的你</div>
|
||||
{isEditingAgent && agentDraft ? (
|
||||
<div className="space-y-2">
|
||||
<AgentInput label="Name" value={agentDraft.userName} onChange={(value) => setAgentDraft({ ...agentDraft, userName: value })} />
|
||||
<AgentInput label="Role" value={agentDraft.userRole} onChange={(value) => setAgentDraft({ ...agentDraft, userRole: value })} />
|
||||
<AgentInput label="Scenarios" value={agentDraft.scenarios} onChange={(value) => setAgentDraft({ ...agentDraft, scenarios: value })} placeholder="coding, research" />
|
||||
<AgentInput label="Workspace" value={agentDraft.workspaceDir} onChange={(value) => setAgentDraft({ ...agentDraft, workspaceDir: value })} />
|
||||
<AgentToggle label="File Restriction" checked={agentDraft.restrictFiles} onChange={(value) => setAgentDraft({ ...agentDraft, restrictFiles: value })} />
|
||||
<AgentToggle label="Opt-in Program" checked={agentDraft.privacyOptIn} onChange={(value) => setAgentDraft({ ...agentDraft, privacyOptIn: value })} />
|
||||
<AgentInput label="你的名称" value={agentDraft.userName} onChange={(value) => setAgentDraft({ ...agentDraft, userName: value })} />
|
||||
<AgentInput label="你的角色" value={agentDraft.userRole} onChange={(value) => setAgentDraft({ ...agentDraft, userRole: value })} />
|
||||
<AgentInput label="场景" value={agentDraft.scenarios} onChange={(value) => setAgentDraft({ ...agentDraft, scenarios: value })} placeholder="编程, 研究" />
|
||||
<AgentInput label="工作区" value={agentDraft.workspaceDir} onChange={(value) => setAgentDraft({ ...agentDraft, workspaceDir: value })} />
|
||||
<AgentToggle label="文件限制" checked={agentDraft.restrictFiles} onChange={(value) => setAgentDraft({ ...agentDraft, restrictFiles: value })} />
|
||||
<AgentToggle label="隐私计划" checked={agentDraft.privacyOptIn} onChange={(value) => setAgentDraft({ ...agentDraft, privacyOptIn: value })} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-3 text-sm">
|
||||
<AgentRow label="Name" value={userNameDisplay} />
|
||||
<AgentRow label="Addressing" value={userAddressing} />
|
||||
<AgentRow label="Timezone" value={localTimezone} />
|
||||
<AgentRow label="你的名称" value={userNameDisplay} />
|
||||
<AgentRow label="称呼方式" value={userAddressing} />
|
||||
<AgentRow label="时区" value={localTimezone} />
|
||||
<div className="flex gap-4">
|
||||
<div className="w-16 text-gray-500 dark:text-gray-400">Focus</div>
|
||||
<div className="w-16 text-gray-500 dark:text-gray-400">专注</div>
|
||||
<div className="flex-1 flex flex-wrap gap-2">
|
||||
{focusAreas.map((item) => (
|
||||
<Badge key={item} variant="default">{item}</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<AgentRow label="Workspace" value={selectedClone?.workspaceDir || workspaceInfo?.path || '~/.zclaw/zclaw-workspace'} />
|
||||
<AgentRow label="Resolved" value={selectedClone?.workspaceResolvedPath || workspaceInfo?.resolvedPath || '-'} />
|
||||
<AgentRow label="File Restriction" value={selectedClone?.restrictFiles ? 'Enabled' : 'Disabled'} />
|
||||
<AgentRow label="Opt-in" value={selectedClone?.privacyOptIn ? 'Joined' : 'Not joined'} />
|
||||
<AgentRow label="工作区" value={selectedClone?.workspaceDir || workspaceInfo?.path || '~/.zclaw/zclaw-workspace'} />
|
||||
<AgentRow label="已解析" value={selectedClone?.workspaceResolvedPath || workspaceInfo?.resolvedPath || '-'} />
|
||||
<AgentRow label="文件限制" value={selectedClone?.restrictFiles ? '已开启' : '已关闭'} />
|
||||
<AgentRow label="隐私计划" value={selectedClone?.privacyOptIn ? '已加入' : '未加入'} />
|
||||
</div>
|
||||
)}
|
||||
</motion.div>
|
||||
@@ -455,9 +455,9 @@ export function RightPanel() {
|
||||
className="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-4 shadow-sm"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<div className="text-sm font-semibold text-gray-900 dark:text-gray-100">Bootstrap Files</div>
|
||||
<div className="text-sm font-semibold text-gray-900 dark:text-gray-100">引导文件</div>
|
||||
<Badge variant={selectedClone?.bootstrapReady ? 'success' : 'default'}>
|
||||
{selectedClone?.bootstrapReady ? 'Generated' : 'Not generated'}
|
||||
{selectedClone?.bootstrapReady ? '已生成' : '未生成'}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="space-y-2 text-sm">
|
||||
@@ -466,13 +466,13 @@ export function RightPanel() {
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<span className="font-medium text-gray-800 dark:text-gray-200">{file.name}</span>
|
||||
<Badge variant={file.exists ? 'success' : 'error'}>
|
||||
{file.exists ? 'Exists' : 'Missing'}
|
||||
{file.exists ? '已存在' : '缺失'}
|
||||
</Badge>
|
||||
</div>
|
||||
<div className="mt-1 text-xs text-gray-500 dark:text-gray-400 break-all">{file.path}</div>
|
||||
</div>
|
||||
)) : (
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">No bootstrap files generated for this Agent.</p>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400">该 Agent 尚未生成引导文件。</p>
|
||||
)}
|
||||
</div>
|
||||
</motion.div>
|
||||
@@ -497,7 +497,7 @@ export function RightPanel() {
|
||||
<WifiOff className="w-4 h-4 text-gray-500 dark:text-gray-400" />
|
||||
)}
|
||||
<Badge variant={connected ? 'success' : 'default'}>
|
||||
Gateway {connected ? 'Connected' : connectionState === 'connecting' ? 'Connecting...' : connectionState === 'reconnecting' ? 'Reconnecting...' : 'Disconnected'}
|
||||
Gateway {connected ? '已连接' : connectionState === 'connecting' ? '连接中...' : connectionState === 'reconnecting' ? '重连中...' : '未连接'}
|
||||
</Badge>
|
||||
</div>
|
||||
{connected && (
|
||||
@@ -506,8 +506,8 @@ export function RightPanel() {
|
||||
size="sm"
|
||||
onClick={() => { loadUsageStats(); loadPluginStatus(); loadClones(); }}
|
||||
className="p-1 text-gray-500 hover:text-orange-500"
|
||||
title="Refresh data"
|
||||
aria-label="Refresh data"
|
||||
title="刷新数据"
|
||||
aria-label="刷新数据"
|
||||
>
|
||||
<RefreshCw className="w-3.5 h-3.5" />
|
||||
</Button>
|
||||
@@ -537,7 +537,7 @@ export function RightPanel() {
|
||||
onClick={handleReconnect}
|
||||
className="w-full"
|
||||
>
|
||||
Connect Gateway
|
||||
连接 Gateway
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user