refactor(agent-office): dashboard layout with agent columns + CEO command panel
- Restructure layout: dashboard (top, 3 columns) + office canvas (bottom, 280px) - AgentColumn: per-agent status, quick commands, approval UI, task history - CommandColumn: CEO command input with agent selector, quick shortcuts, history - Remove overlay panels (ChatPanel/DocumentPanel) - integrated into dashboard - Office canvas shrunk to compact strip at bottom Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,27 +1,27 @@
|
||||
import React, { useRef, useState, useCallback, useEffect } from 'react';
|
||||
import { useAgentManager } from './hooks/useAgentManager';
|
||||
import { useOfficeCanvas } from './hooks/useOfficeCanvas';
|
||||
import ChatPanel from './components/ChatPanel';
|
||||
import DocumentPanel from './components/DocumentPanel';
|
||||
import AgentColumn from './components/AgentColumn';
|
||||
import CommandColumn from './components/CommandColumn';
|
||||
import './AgentOffice.css';
|
||||
|
||||
const AGENT_META = {
|
||||
stock: { name: '주식 트레이더', color: '#4488cc' },
|
||||
music: { name: '음악 프로듀서', color: '#44aa88' },
|
||||
};
|
||||
|
||||
export function Component() {
|
||||
const canvasContainerRef = useRef(null);
|
||||
const [selectedAgent, setSelectedAgent] = useState(null);
|
||||
const [showDocument, setShowDocument] = useState(false);
|
||||
|
||||
const { agents, pendingTasks, connected, notifications, sendCommand, sendApproval, clearNotifications } = useAgentManager();
|
||||
|
||||
const handleAgentClick = useCallback((agentId) => {
|
||||
setSelectedAgent(prev => prev === agentId ? null : agentId);
|
||||
clearNotifications(agentId);
|
||||
}, [clearNotifications]);
|
||||
|
||||
const handleCeoClick = useCallback(() => {
|
||||
setShowDocument(prev => !prev);
|
||||
}, []);
|
||||
const handleCeoClick = useCallback(() => {}, []);
|
||||
|
||||
const { updateAgentState, moveAgent, setAgentNotification, setCeoDocBadge } = useOfficeCanvas(canvasContainerRef, handleAgentClick, handleCeoClick);
|
||||
const { updateAgentState, setAgentNotification, setCeoDocBadge } = useOfficeCanvas(canvasContainerRef, handleAgentClick, handleCeoClick);
|
||||
|
||||
useEffect(() => {
|
||||
for (const [id, info] of Object.entries(agents)) {
|
||||
@@ -53,41 +53,27 @@ export function Component() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="ao-workspace">
|
||||
<div className="ao-canvas-container" ref={canvasContainerRef} />
|
||||
|
||||
<div className="ao-agent-bar">
|
||||
{Object.entries(agents).map(([id, info]) => (
|
||||
<button
|
||||
key={id}
|
||||
className={`ao-agent-chip ${info.state === 'waiting' ? 'ao-agent-chip--alert' : ''} ${selectedAgent === id ? 'ao-agent-chip--selected' : ''}`}
|
||||
onClick={() => handleAgentClick(id)}
|
||||
>
|
||||
<span className={`ao-chip-dot ao-chip-dot--${info.state}`} />
|
||||
{id}
|
||||
{notifications[id] > 0 && (
|
||||
<span className="ao-chip-badge">{notifications[id]}</span>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
{pendingTasks.length > 0 && (
|
||||
<span className="ao-pending-count">{pendingTasks.length} pending</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{selectedAgent && (
|
||||
<ChatPanel
|
||||
agentId={selectedAgent}
|
||||
agentState={agents[selectedAgent]}
|
||||
<div className="ao-dashboard">
|
||||
{['stock', 'music'].map(id => (
|
||||
<AgentColumn
|
||||
key={id}
|
||||
agentId={id}
|
||||
meta={AGENT_META[id]}
|
||||
agentState={agents[id]}
|
||||
notification={notifications[id] || 0}
|
||||
onCommand={sendCommand}
|
||||
onApproval={sendApproval}
|
||||
onClose={() => setSelectedAgent(null)}
|
||||
onClearNotification={() => clearNotifications(id)}
|
||||
/>
|
||||
)}
|
||||
))}
|
||||
<CommandColumn
|
||||
agents={agents}
|
||||
onCommand={sendCommand}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{showDocument && (
|
||||
<DocumentPanel onClose={() => setShowDocument(false)} />
|
||||
)}
|
||||
<div className="ao-office-section">
|
||||
<div className="ao-canvas-container" ref={canvasContainerRef} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user