feat: integrate DevQALoop into TeamOrchestrator and add integration test checklist
- Add Review tab to TeamOrchestrator with DevQALoopPanel integration - Create comprehensive integration test checklist (22 test cases) - Document component integration status analysis - Update progress documentation Key findings: - Most "low integration" components were actually integrated via indirect paths - DevQALoop was the only truly unintegrated component, now fixed Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,8 @@
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useTeamStore } from '../store/teamStore';
|
||||
import { useGatewayStore } from '../store/gatewayStore';
|
||||
import { useAgentStore } from '../store/agentStore';
|
||||
import { DevQALoopPanel } from './DevQALoop';
|
||||
import type {
|
||||
TeamMember,
|
||||
TeamTask,
|
||||
@@ -20,7 +21,7 @@ import type {
|
||||
import {
|
||||
Users, Plus, Trash2, X,
|
||||
Bot, Clock, AlertTriangle, CheckCircle,
|
||||
Play, UserPlus, FileText,
|
||||
Play, UserPlus, FileText, RefreshCw,
|
||||
} from 'lucide-react';
|
||||
|
||||
// === Sub-Components ===
|
||||
@@ -206,7 +207,7 @@ interface TeamOrchestratorProps {
|
||||
}
|
||||
|
||||
export function TeamOrchestrator({ isOpen, onClose }: TeamOrchestratorProps) {
|
||||
const [view, setView] = useState<'teams' | 'tasks' | 'members'>('teams');
|
||||
const [view, setView] = useState<'teams' | 'tasks' | 'members' | 'review'>('teams');
|
||||
const [isCreating, setIsCreating] = useState(false);
|
||||
const [newTeamName, setNewTeamName] = useState('');
|
||||
const [newTeamPattern, setNewTeamPattern] = useState<CollaborationPattern>('sequential');
|
||||
@@ -230,9 +231,10 @@ export function TeamOrchestrator({ isOpen, onClose }: TeamOrchestratorProps) {
|
||||
updateMemberRole,
|
||||
setSelectedTask,
|
||||
setSelectedMember,
|
||||
startDevQALoop,
|
||||
} = useTeamStore();
|
||||
|
||||
const { clones } = useGatewayStore();
|
||||
const clones = useAgentStore((s) => s.clones);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
@@ -405,6 +407,22 @@ export function TeamOrchestrator({ isOpen, onClose }: TeamOrchestratorProps) {
|
||||
>
|
||||
Members
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setView('review')}
|
||||
className={`px-3 py-1.5 rounded-lg text-sm font-medium flex items-center gap-1 ${
|
||||
view === 'review'
|
||||
? 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-300'
|
||||
: 'text-gray-500 hover:text-gray-700 dark:text-gray-400'
|
||||
}`}
|
||||
>
|
||||
<RefreshCw className="w-4 h-4" />
|
||||
Review
|
||||
{activeTeam.activeLoops.length > 0 && (
|
||||
<span className="ml-1 px-1.5 py-0.5 text-xs bg-yellow-200 dark:bg-yellow-800 rounded-full">
|
||||
{activeTeam.activeLoops.length}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Tasks View */}
|
||||
@@ -484,6 +502,62 @@ export function TeamOrchestrator({ isOpen, onClose }: TeamOrchestratorProps) {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Review View - Dev↔QA Loop */}
|
||||
{view === 'review' && (
|
||||
<div className="flex-1 p-6 overflow-y-auto">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="font-semibold text-gray-900 dark:text-white">Dev↔QA Review Loops</h3>
|
||||
<button
|
||||
onClick={async () => {
|
||||
// Start a new Dev↔QA loop with the first available task and members
|
||||
if (activeTeam.tasks.length > 0 && activeTeam.members.length >= 2) {
|
||||
const devMember = activeTeam.members.find(m => m.role === 'developer');
|
||||
const reviewerMember = activeTeam.members.find(m => m.role === 'reviewer');
|
||||
if (devMember && reviewerMember) {
|
||||
const task = activeTeam.tasks.find(t => t.status === 'pending' || t.status === 'in_progress');
|
||||
if (task) {
|
||||
await startDevQALoop(activeTeam.id, task.id, devMember.id, reviewerMember.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
disabled={activeTeam.tasks.length === 0 || activeTeam.members.length < 2}
|
||||
className="flex items-center gap-1 px-3 py-1.5 text-sm bg-yellow-500 text-white rounded-lg hover:bg-yellow-600 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
<Plus className="w-4 h-4" />
|
||||
Start Review Loop
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{activeTeam.activeLoops.length === 0 ? (
|
||||
<div className="text-center py-8 text-gray-500 dark:text-gray-400">
|
||||
<RefreshCw className="w-12 h-12 mx-auto mb-4 text-gray-300 dark:text-gray-600" />
|
||||
<p>No active review loops.</p>
|
||||
<p className="text-sm mt-2">Add tasks and members, then start a Dev↔QA loop.</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
{activeTeam.activeLoops.map(loop => {
|
||||
const task = activeTeam.tasks.find(t => t.id === loop.taskId);
|
||||
const developer = activeTeam.members.find(m => m.id === loop.developerId);
|
||||
const reviewer = activeTeam.members.find(m => m.id === loop.reviewerId);
|
||||
|
||||
return (
|
||||
<DevQALoopPanel
|
||||
key={loop.id}
|
||||
loop={loop}
|
||||
teamId={activeTeam.id}
|
||||
developerName={developer?.name || 'Unknown Developer'}
|
||||
reviewerName={reviewer?.name || 'Unknown Reviewer'}
|
||||
taskTitle={task?.title || 'Unknown Task'}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex-1 flex items-center justify-center text-gray-500 dark:text-gray-400">
|
||||
|
||||
Reference in New Issue
Block a user