/** * TeamList - Sidebar Team List Component * * Displays a compact list of teams for the sidebar navigation. * * @module components/TeamList */ import { useEffect, useState } from 'react'; import { useTeamStore } from '../store/teamStore'; import { useAgentStore } from '../store/agentStore'; import { useChatStore } from '../store/chatStore'; import { Users, Plus, Activity, CheckCircle, AlertTriangle, X, Bot } from 'lucide-react'; import type { TeamMemberRole } from '../types/team'; interface TeamListProps { onSelectTeam?: (teamId: string) => void; selectedTeamId?: string; } export function TeamList({ onSelectTeam, selectedTeamId }: TeamListProps) { const { teams, loadTeams, setActiveTeam, createTeam, isLoading } = useTeamStore(); const clones = useAgentStore((s) => s.clones); const { agents } = useChatStore(); const [showCreateModal, setShowCreateModal] = useState(false); const [teamName, setTeamName] = useState(''); const [teamDescription, setTeamDescription] = useState(''); const [teamPattern, setTeamPattern] = useState<'sequential' | 'parallel' | 'pipeline'>('sequential'); const [selectedAgents, setSelectedAgents] = useState([]); const [isCreating, setIsCreating] = useState(false); useEffect(() => { try { loadTeams(); } catch (err) { console.error('[TeamList] Failed to load teams:', err); } }, [loadTeams]); const handleSelectTeam = (teamId: string) => { const team = teams.find(t => t.id === teamId); if (team) { setActiveTeam(team); onSelectTeam?.(teamId); } }; const handleCreateTeam = async () => { if (!teamName.trim() || selectedAgents.length === 0) return; setIsCreating(true); try { const roleAssignments: { agentId: string; role: TeamMemberRole }[] = selectedAgents.map((agentId, index) => ({ agentId, role: (index === 0 ? 'orchestrator' : index === 1 ? 'reviewer' : 'worker') as TeamMemberRole, })); const team = await createTeam({ name: teamName.trim(), description: teamDescription.trim() || undefined, pattern: teamPattern, memberAgents: roleAssignments, }); if (team) { setShowCreateModal(false); setTeamName(''); setTeamDescription(''); setSelectedAgents([]); setTeamPattern('sequential'); setActiveTeam(team); onSelectTeam?.(team.id); } } finally { setIsCreating(false); } }; const toggleAgentSelection = (agentId: string) => { setSelectedAgents(prev => prev.includes(agentId) ? prev.filter(id => id !== agentId) : [...prev, agentId] ); }; const getStatusIcon = (status: string) => { switch (status) { case 'active': return ; case 'paused': return ; case 'completed': return ; default: return ; } }; // Merge clones and agents for display - normalize to common type with defensive checks const availableAgents: Array<{ id: string; name: string; role?: string }> = (clones && clones.length > 0) ? clones.map(c => ({ id: c.id, name: c.name, role: c.role })) : (agents && agents.length > 0) ? agents.map(a => ({ id: a.id, name: a.name, role: '默认助手', })) : []; return (
{/* Header */}

团队

{/* Create Team Modal */} {showCreateModal && (

创建团队

{/* Team Name */}
setTeamName(e.target.value)} placeholder="例如:开发团队 Alpha" className="w-full px-3 py-2 text-sm border border-gray-200 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-gray-400" />
{/* Team Description */}