fix(frontend): align project types with backend enums
- Fix ProjectStatus: use 'active' instead of 'in_progress' - Fix AgentStatus: remove 'active'/'pending'/'error', add 'waiting' - Fix SprintStatus: add 'in_review' - Rename IssueSummary to IssueCountSummary - Update all components to use correct enum values 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -126,7 +126,7 @@ function AgentListItem({
|
|||||||
<DropdownMenuItem onClick={() => onAction(agent.id, 'view')}>
|
<DropdownMenuItem onClick={() => onAction(agent.id, 'view')}>
|
||||||
View Details
|
View Details
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
{agent.status === 'active' || agent.status === 'working' ? (
|
{agent.status === 'working' || agent.status === 'waiting' ? (
|
||||||
<DropdownMenuItem onClick={() => onAction(agent.id, 'pause')}>
|
<DropdownMenuItem onClick={() => onAction(agent.id, 'pause')}>
|
||||||
Pause Agent
|
Pause Agent
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
@@ -196,7 +196,7 @@ export function AgentPanel({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const activeAgentCount = agents.filter(
|
const activeAgentCount = agents.filter(
|
||||||
(a) => a.status === 'active' || a.status === 'working'
|
(a) => a.status === 'working' || a.status === 'waiting'
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -14,21 +14,17 @@ const statusConfig: Record<AgentStatus, { color: string; label: string }> = {
|
|||||||
color: 'bg-yellow-500',
|
color: 'bg-yellow-500',
|
||||||
label: 'Idle',
|
label: 'Idle',
|
||||||
},
|
},
|
||||||
active: {
|
|
||||||
color: 'bg-green-500',
|
|
||||||
label: 'Active',
|
|
||||||
},
|
|
||||||
working: {
|
working: {
|
||||||
color: 'bg-green-500 animate-pulse',
|
color: 'bg-green-500 animate-pulse',
|
||||||
label: 'Working',
|
label: 'Working',
|
||||||
},
|
},
|
||||||
pending: {
|
waiting: {
|
||||||
color: 'bg-gray-400',
|
color: 'bg-blue-500',
|
||||||
label: 'Pending',
|
label: 'Waiting',
|
||||||
},
|
},
|
||||||
error: {
|
paused: {
|
||||||
color: 'bg-red-500',
|
color: 'bg-gray-400',
|
||||||
label: 'Error',
|
label: 'Paused',
|
||||||
},
|
},
|
||||||
terminated: {
|
terminated: {
|
||||||
color: 'bg-gray-600',
|
color: 'bg-gray-600',
|
||||||
@@ -49,7 +45,7 @@ export function AgentStatusIndicator({
|
|||||||
showLabel = false,
|
showLabel = false,
|
||||||
className,
|
className,
|
||||||
}: AgentStatusIndicatorProps) {
|
}: AgentStatusIndicatorProps) {
|
||||||
const config = statusConfig[status] || statusConfig.pending;
|
const config = statusConfig[status] || statusConfig.idle;
|
||||||
|
|
||||||
const sizeClasses = {
|
const sizeClasses = {
|
||||||
sm: 'h-2 w-2',
|
sm: 'h-2 w-2',
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import {
|
|||||||
} from '@/components/ui/card';
|
} from '@/components/ui/card';
|
||||||
import { Separator } from '@/components/ui/separator';
|
import { Separator } from '@/components/ui/separator';
|
||||||
import { Skeleton } from '@/components/ui/skeleton';
|
import { Skeleton } from '@/components/ui/skeleton';
|
||||||
import type { IssueSummary as IssueSummaryType } from './types';
|
import type { IssueCountSummary } from './types';
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Types
|
// Types
|
||||||
@@ -32,7 +32,7 @@ import type { IssueSummary as IssueSummaryType } from './types';
|
|||||||
|
|
||||||
interface IssueSummaryProps {
|
interface IssueSummaryProps {
|
||||||
/** Issue summary data */
|
/** Issue summary data */
|
||||||
summary: IssueSummaryType | null;
|
summary: IssueCountSummary | null;
|
||||||
/** Whether data is loading */
|
/** Whether data is loading */
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
/** Callback when "View All Issues" is clicked */
|
/** Callback when "View All Issues" is clicked */
|
||||||
@@ -171,8 +171,8 @@ export function IssueSummary({
|
|||||||
<StatusRow
|
<StatusRow
|
||||||
icon={CheckCircle2}
|
icon={CheckCircle2}
|
||||||
iconColor="text-green-500"
|
iconColor="text-green-500"
|
||||||
label="Completed"
|
label="Closed"
|
||||||
count={summary.done}
|
count={summary.closed}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{onViewAllIssues && (
|
{onViewAllIssues && (
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import type {
|
|||||||
AgentInstance,
|
AgentInstance,
|
||||||
Sprint,
|
Sprint,
|
||||||
BurndownDataPoint,
|
BurndownDataPoint,
|
||||||
IssueSummary as IssueSummaryType,
|
IssueCountSummary,
|
||||||
ActivityItem,
|
ActivityItem,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ const mockProject: Project = {
|
|||||||
id: 'proj-001',
|
id: 'proj-001',
|
||||||
name: 'E-Commerce Platform Redesign',
|
name: 'E-Commerce Platform Redesign',
|
||||||
description: 'Complete redesign of the e-commerce platform with modern UI/UX',
|
description: 'Complete redesign of the e-commerce platform with modern UI/UX',
|
||||||
status: 'in_progress',
|
status: 'active',
|
||||||
autonomy_level: 'milestone',
|
autonomy_level: 'milestone',
|
||||||
current_sprint_id: 'sprint-003',
|
current_sprint_id: 'sprint-003',
|
||||||
created_at: '2025-01-15T00:00:00Z',
|
created_at: '2025-01-15T00:00:00Z',
|
||||||
@@ -66,7 +66,7 @@ const mockAgents: AgentInstance[] = [
|
|||||||
project_id: 'proj-001',
|
project_id: 'proj-001',
|
||||||
name: 'Product Owner',
|
name: 'Product Owner',
|
||||||
role: 'product_owner',
|
role: 'product_owner',
|
||||||
status: 'active',
|
status: 'working',
|
||||||
current_task: 'Reviewing user story acceptance criteria',
|
current_task: 'Reviewing user story acceptance criteria',
|
||||||
last_activity_at: new Date(Date.now() - 2 * 60 * 1000).toISOString(),
|
last_activity_at: new Date(Date.now() - 2 * 60 * 1000).toISOString(),
|
||||||
spawned_at: '2025-01-15T00:00:00Z',
|
spawned_at: '2025-01-15T00:00:00Z',
|
||||||
@@ -102,7 +102,7 @@ const mockAgents: AgentInstance[] = [
|
|||||||
project_id: 'proj-001',
|
project_id: 'proj-001',
|
||||||
name: 'Frontend Engineer',
|
name: 'Frontend Engineer',
|
||||||
role: 'frontend_engineer',
|
role: 'frontend_engineer',
|
||||||
status: 'active',
|
status: 'working',
|
||||||
current_task: 'Implementing product catalog component',
|
current_task: 'Implementing product catalog component',
|
||||||
last_activity_at: new Date(Date.now() - 1 * 60 * 1000).toISOString(),
|
last_activity_at: new Date(Date.now() - 1 * 60 * 1000).toISOString(),
|
||||||
spawned_at: '2025-01-15T00:00:00Z',
|
spawned_at: '2025-01-15T00:00:00Z',
|
||||||
@@ -114,7 +114,7 @@ const mockAgents: AgentInstance[] = [
|
|||||||
project_id: 'proj-001',
|
project_id: 'proj-001',
|
||||||
name: 'QA Engineer',
|
name: 'QA Engineer',
|
||||||
role: 'qa_engineer',
|
role: 'qa_engineer',
|
||||||
status: 'pending',
|
status: 'waiting',
|
||||||
current_task: 'Preparing test cases for Sprint 3',
|
current_task: 'Preparing test cases for Sprint 3',
|
||||||
last_activity_at: new Date(Date.now() - 30 * 60 * 1000).toISOString(),
|
last_activity_at: new Date(Date.now() - 30 * 60 * 1000).toISOString(),
|
||||||
spawned_at: '2025-01-15T00:00:00Z',
|
spawned_at: '2025-01-15T00:00:00Z',
|
||||||
@@ -148,12 +148,12 @@ const mockBurndownData: BurndownDataPoint[] = [
|
|||||||
{ day: 8, remaining: 20, ideal: 24 },
|
{ day: 8, remaining: 20, ideal: 24 },
|
||||||
];
|
];
|
||||||
|
|
||||||
const mockIssueSummary: IssueSummaryType = {
|
const mockIssueSummary: IssueCountSummary = {
|
||||||
open: 12,
|
open: 12,
|
||||||
in_progress: 8,
|
in_progress: 8,
|
||||||
in_review: 3,
|
in_review: 3,
|
||||||
blocked: 2,
|
blocked: 2,
|
||||||
done: 45,
|
closed: 45,
|
||||||
total: 70,
|
total: 70,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -392,7 +392,7 @@ export function ProjectDashboard({ projectId, className }: ProjectDashboardProps
|
|||||||
<ProjectHeader
|
<ProjectHeader
|
||||||
project={project}
|
project={project}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
canPause={project.status === 'in_progress'}
|
canPause={project.status === 'active'}
|
||||||
canStart={true}
|
canStart={true}
|
||||||
onStartSprint={handleStartSprint}
|
onStartSprint={handleStartSprint}
|
||||||
onPauseProject={handlePauseProject}
|
onPauseProject={handlePauseProject}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export function ProjectHeader({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const showPauseButton = canPause && project.status === 'in_progress';
|
const showPauseButton = canPause && project.status === 'active';
|
||||||
const showStartButton = canStart && project.status !== 'completed' && project.status !== 'archived';
|
const showStartButton = canStart && project.status !== 'completed' && project.status !== 'archived';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -16,12 +16,8 @@ import type { ProjectStatus, AutonomyLevel } from './types';
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
const projectStatusConfig: Record<ProjectStatus, { label: string; className: string }> = {
|
const projectStatusConfig: Record<ProjectStatus, { label: string; className: string }> = {
|
||||||
draft: {
|
active: {
|
||||||
label: 'Draft',
|
label: 'Active',
|
||||||
className: 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-200',
|
|
||||||
},
|
|
||||||
in_progress: {
|
|
||||||
label: 'In Progress',
|
|
||||||
className: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200',
|
className: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200',
|
||||||
},
|
},
|
||||||
paused: {
|
paused: {
|
||||||
@@ -32,10 +28,6 @@ const projectStatusConfig: Record<ProjectStatus, { label: string; className: str
|
|||||||
label: 'Completed',
|
label: 'Completed',
|
||||||
className: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
className: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
|
||||||
},
|
},
|
||||||
blocked: {
|
|
||||||
label: 'Blocked',
|
|
||||||
className: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
|
|
||||||
},
|
|
||||||
archived: {
|
archived: {
|
||||||
label: 'Archived',
|
label: 'Archived',
|
||||||
className: 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400',
|
className: 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400',
|
||||||
@@ -48,7 +40,7 @@ interface ProjectStatusBadgeProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ProjectStatusBadge({ status, className }: ProjectStatusBadgeProps) {
|
export function ProjectStatusBadge({ status, className }: ProjectStatusBadgeProps) {
|
||||||
const config = projectStatusConfig[status] || projectStatusConfig.draft;
|
const config = projectStatusConfig[status] || projectStatusConfig.active;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Badge variant="outline" className={cn(config.className, className)}>
|
<Badge variant="outline" className={cn(config.className, className)}>
|
||||||
|
|||||||
@@ -11,7 +11,10 @@
|
|||||||
// Project Types
|
// Project Types
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
export type ProjectStatus = 'draft' | 'in_progress' | 'paused' | 'completed' | 'blocked' | 'archived';
|
/**
|
||||||
|
* Matches backend: ProjectStatus enum in app/models/syndarix/enums.py
|
||||||
|
*/
|
||||||
|
export type ProjectStatus = 'active' | 'paused' | 'completed' | 'archived';
|
||||||
|
|
||||||
export type AutonomyLevel = 'full_control' | 'milestone' | 'autonomous';
|
export type AutonomyLevel = 'full_control' | 'milestone' | 'autonomous';
|
||||||
|
|
||||||
@@ -31,7 +34,10 @@ export interface Project {
|
|||||||
// Agent Types
|
// Agent Types
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
export type AgentStatus = 'idle' | 'active' | 'working' | 'pending' | 'error' | 'terminated';
|
/**
|
||||||
|
* Matches backend: AgentStatus enum in app/models/syndarix/enums.py
|
||||||
|
*/
|
||||||
|
export type AgentStatus = 'idle' | 'working' | 'waiting' | 'paused' | 'terminated';
|
||||||
|
|
||||||
export interface AgentInstance {
|
export interface AgentInstance {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -50,7 +56,10 @@ export interface AgentInstance {
|
|||||||
// Sprint Types
|
// Sprint Types
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
export type SprintStatus = 'planning' | 'active' | 'review' | 'completed';
|
/**
|
||||||
|
* Matches backend: SprintStatus enum in app/models/syndarix/enums.py
|
||||||
|
*/
|
||||||
|
export type SprintStatus = 'planned' | 'active' | 'in_review' | 'completed' | 'cancelled';
|
||||||
|
|
||||||
export interface Sprint {
|
export interface Sprint {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -78,7 +87,10 @@ export interface BurndownDataPoint {
|
|||||||
// Issue Types
|
// Issue Types
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
export type IssueStatus = 'open' | 'in_progress' | 'in_review' | 'blocked' | 'done' | 'closed';
|
/**
|
||||||
|
* Matches backend: IssueStatus enum in app/models/syndarix/enums.py
|
||||||
|
*/
|
||||||
|
export type IssueStatus = 'open' | 'in_progress' | 'in_review' | 'blocked' | 'closed';
|
||||||
|
|
||||||
export type IssuePriority = 'low' | 'medium' | 'high' | 'critical';
|
export type IssuePriority = 'low' | 'medium' | 'high' | 'critical';
|
||||||
|
|
||||||
@@ -96,12 +108,12 @@ export interface Issue {
|
|||||||
labels?: string[];
|
labels?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IssueSummary {
|
export interface IssueCountSummary {
|
||||||
open: number;
|
open: number;
|
||||||
in_progress: number;
|
in_progress: number;
|
||||||
in_review: number;
|
in_review: number;
|
||||||
blocked: number;
|
blocked: number;
|
||||||
done: number;
|
closed: number;
|
||||||
total: number;
|
total: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user