feat(desktop): simple mode UI — ChatArea compact + SimpleSidebar + RightPanel dual-mode

Adapt ChatArea for compact/butler mode:
- Add onOpenDetail prop for expanding to full view
- Remove inline export dialog (moved to detail view)
- Replace SquarePen with ClipboardList icon

Add SimpleSidebar component for butler simple mode:
- Two tabs: 对话 / 行业资讯
- Quick suggestion buttons
- Minimal navigation

RightPanel refactoring for dual-mode support:
- Detect simple vs professional mode
- Conditional rendering based on butler mode state
This commit is contained in:
iven
2026-04-09 17:48:18 +08:00
parent 4b15ead8e7
commit 2f25316e83
3 changed files with 213 additions and 93 deletions

View File

@@ -85,7 +85,11 @@ import { Button, Badge } from './ui';
import { getPersonalityById } from '../lib/personality-presets';
import { silentErrorHandler } from '../lib/error-utils';
export function RightPanel() {
interface RightPanelProps {
simpleMode?: boolean;
}
export function RightPanel({ simpleMode = false }: RightPanelProps) {
// Connection store
const connectionState = useConnectionStore((s) => s.connectionState);
const gatewayVersion = useConnectionStore((s) => s.gatewayVersion);
@@ -271,60 +275,85 @@ export function RightPanel() {
<aside className="w-full bg-white dark:bg-gray-900 flex flex-col">
{/* 顶部工具栏 - Tab 栏 */}
<div className="border-b border-gray-200 dark:border-gray-700 flex-shrink-0">
{/* 主 Tab 行 */}
<div className="flex items-center px-2 pt-2 gap-1">
<TabButton
active={activeTab === 'status'}
onClick={() => setActiveTab('status')}
icon={<Activity className="w-4 h-4" />}
label="状态"
/>
<TabButton
active={activeTab === 'agent'}
onClick={() => setActiveTab('agent')}
icon={<User className="w-4 h-4" />}
label="Agent"
/>
<TabButton
active={activeTab === 'files'}
onClick={() => setActiveTab('files')}
icon={<FileText className="w-4 h-4" />}
label="文件"
/>
<TabButton
active={activeTab === 'memory'}
onClick={() => setActiveTab('memory')}
icon={<Brain className="w-4 h-4" />}
label="记忆"
/>
</div>
{/* 第二行 Tab */}
<div className="flex items-center px-2 pb-2 gap-1">
<TabButton
active={activeTab === 'reflection'}
onClick={() => setActiveTab('reflection')}
icon={<Sparkles className="w-4 h-4" />}
label="反思"
/>
<TabButton
active={activeTab === 'autonomy'}
onClick={() => setActiveTab('autonomy')}
icon={<Shield className="w-4 h-4" />}
label="自主"
/>
<TabButton
active={activeTab === 'evolution'}
onClick={() => setActiveTab('evolution')}
icon={<Dna className="w-4 h-4" />}
label="演化"
/>
<TabButton
active={activeTab === 'butler'}
onClick={() => setActiveTab('butler')}
icon={<ConciergeBell className="w-4 h-4" />}
label="管家"
/>
</div>
{simpleMode ? (
/* 简洁模式: 仅 状态 / Agent / 管家 */
<div className="flex items-center px-2 py-2 gap-1">
<TabButton
active={activeTab === 'status'}
onClick={() => setActiveTab('status')}
icon={<Activity className="w-4 h-4" />}
label="状态"
/>
<TabButton
active={activeTab === 'agent'}
onClick={() => setActiveTab('agent')}
icon={<User className="w-4 h-4" />}
label="Agent"
/>
<TabButton
active={activeTab === 'butler'}
onClick={() => setActiveTab('butler')}
icon={<ConciergeBell className="w-4 h-4" />}
label="管家"
/>
</div>
) : (
<>
{/* 专业模式: 全部 8 个 Tab */}
<div className="flex items-center px-2 pt-2 gap-1">
<TabButton
active={activeTab === 'status'}
onClick={() => setActiveTab('status')}
icon={<Activity className="w-4 h-4" />}
label="状态"
/>
<TabButton
active={activeTab === 'agent'}
onClick={() => setActiveTab('agent')}
icon={<User className="w-4 h-4" />}
label="Agent"
/>
<TabButton
active={activeTab === 'files'}
onClick={() => setActiveTab('files')}
icon={<FileText className="w-4 h-4" />}
label="文件"
/>
<TabButton
active={activeTab === 'memory'}
onClick={() => setActiveTab('memory')}
icon={<Brain className="w-4 h-4" />}
label="记忆"
/>
</div>
<div className="flex items-center px-2 pb-2 gap-1">
<TabButton
active={activeTab === 'reflection'}
onClick={() => setActiveTab('reflection')}
icon={<Sparkles className="w-4 h-4" />}
label="反思"
/>
<TabButton
active={activeTab === 'autonomy'}
onClick={() => setActiveTab('autonomy')}
icon={<Shield className="w-4 h-4" />}
label="自主"
/>
<TabButton
active={activeTab === 'evolution'}
onClick={() => setActiveTab('evolution')}
icon={<Dna className="w-4 h-4" />}
label="演化"
/>
<TabButton
active={activeTab === 'butler'}
onClick={() => setActiveTab('butler')}
icon={<ConciergeBell className="w-4 h-4" />}
label="管家"
/>
</div>
</>
)}
</div>
{/* 消息统计 */}