feat(agent-office): notification badges + CEO desk document panel + telegram test
- Add notification state management with badge counts in useAgentManager - Render exclamation badge on agent sprites (separate from status icons) - Add CEO desk document icon with click-to-open activity panel - Create DocumentPanel with unified activity feed + per-agent detail tabs - Add telegram test button to stock agent ChatPanel - Remove TaskHistory + bottom toolbar (replaced by DocumentPanel) - Add getActivityFeed API helper Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,21 +2,26 @@ import React, { useRef, useState, useCallback, useEffect } from 'react';
|
||||
import { useAgentManager } from './hooks/useAgentManager';
|
||||
import { useOfficeCanvas } from './hooks/useOfficeCanvas';
|
||||
import ChatPanel from './components/ChatPanel';
|
||||
import TaskHistory from './components/TaskHistory';
|
||||
import DocumentPanel from './components/DocumentPanel';
|
||||
import './AgentOffice.css';
|
||||
|
||||
export function Component() {
|
||||
const canvasContainerRef = useRef(null);
|
||||
const [selectedAgent, setSelectedAgent] = useState(null);
|
||||
const [showHistory, setShowHistory] = useState(null);
|
||||
const [showDocument, setShowDocument] = useState(false);
|
||||
|
||||
const { agents, pendingTasks, connected, sendCommand, sendApproval } = useAgentManager();
|
||||
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 { updateAgentState, moveAgent } = useOfficeCanvas(canvasContainerRef, handleAgentClick);
|
||||
const { updateAgentState, moveAgent, setAgentNotification, setCeoDocBadge } = useOfficeCanvas(canvasContainerRef, handleAgentClick, handleCeoClick);
|
||||
|
||||
useEffect(() => {
|
||||
for (const [id, info] of Object.entries(agents)) {
|
||||
@@ -24,6 +29,20 @@ export function Component() {
|
||||
}
|
||||
}, [agents, updateAgentState]);
|
||||
|
||||
useEffect(() => {
|
||||
for (const [id, count] of Object.entries(notifications)) {
|
||||
setAgentNotification(id, count);
|
||||
}
|
||||
for (const id of Object.keys(agents)) {
|
||||
if (!notifications[id]) setAgentNotification(id, 0);
|
||||
}
|
||||
}, [notifications, agents, setAgentNotification]);
|
||||
|
||||
useEffect(() => {
|
||||
const total = Object.values(notifications).reduce((s, n) => s + n, 0);
|
||||
setCeoDocBadge(total);
|
||||
}, [notifications, setCeoDocBadge]);
|
||||
|
||||
return (
|
||||
<div className="ao-page">
|
||||
<div className="ao-header">
|
||||
@@ -46,7 +65,9 @@ export function Component() {
|
||||
>
|
||||
<span className={`ao-chip-dot ao-chip-dot--${info.state}`} />
|
||||
{id}
|
||||
{info.state === 'waiting' && <span className="ao-chip-badge">!</span>}
|
||||
{notifications[id] > 0 && (
|
||||
<span className="ao-chip-badge">{notifications[id]}</span>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
{pendingTasks.length > 0 && (
|
||||
@@ -64,22 +85,10 @@ export function Component() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{showHistory && (
|
||||
<TaskHistory
|
||||
agentId={showHistory}
|
||||
onClose={() => setShowHistory(null)}
|
||||
/>
|
||||
{showDocument && (
|
||||
<DocumentPanel onClose={() => setShowDocument(false)} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="ao-toolbar">
|
||||
{Object.keys(agents).map(id => (
|
||||
<button key={id} className="ao-tool-btn"
|
||||
onClick={() => setShowHistory(prev => prev === id ? null : id)}>
|
||||
📋 {id} 이력
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user