import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { formatDistanceToNow } from 'date-fns'; import { X, CheckCircle, XCircle, Clock, AlertCircle, Play, Pause, HelpCircle, Ban, Timer, GitBranch, User, ExternalLink } from 'lucide-react'; import { WorkflowRun } from '../types/github'; import { ApiService } from '../services/api'; interface WorkflowRunsModalProps { isOpen: boolean; onClose: () => void; repository: { owner: string; name: string; } | null; } const getStatusIcon = (status: string, conclusion: string | null) => { switch (status) { case 'in_progress': return ; case 'queued': case 'requested': case 'pending': return ; case 'waiting': return ; case 'completed': switch (conclusion) { case 'success': return ; case 'failure': return ; case 'cancelled': return ; case 'action_required': return ; case 'neutral': return ; case 'skipped': return ; case 'stale': return ; case 'timed_out': return ; default: return ; } default: return ; } }; const getStatusText = (status: string, conclusion: string | null) => { if (status === 'completed' && conclusion) { return conclusion.charAt(0).toUpperCase() + conclusion.slice(1); } return status.charAt(0).toUpperCase() + status.slice(1); }; export const WorkflowRunsModal: React.FC = ({ isOpen, onClose, repository }) => { const [runs, setRuns] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const apiService = useMemo(() => new ApiService(), []); const handleBackdropClick = (e: React.MouseEvent) => { if (e.target === e.currentTarget) { onClose(); } }; const fetchWorkflowRuns = useCallback(async () => { if (!repository) return; setLoading(true); setError(null); try { const response = await apiService.getRepositoryWorkflowRuns(repository.owner, repository.name); setRuns(response); } catch (error) { console.error('Error fetching workflow runs:', error); setError('Failed to fetch workflow runs'); } finally { setLoading(false); } }, [repository, apiService]); useEffect(() => { if (isOpen && repository) { fetchWorkflowRuns(); } }, [isOpen, repository, fetchWorkflowRuns]); if (!isOpen) return null; return (

{repository?.owner}/{repository?.name}

Recent workflow runs

{loading ? (
) : error ? (

{error}

) : runs.length === 0 ? (

No workflow runs found

) : (
{runs.map((run) => (
{getStatusIcon(run.status, run.conclusion)}

{run.display_title}

{getStatusText(run.status, run.conclusion)} • #{run.run_number}

Branch: {run.head_branch}
Author: {run.actor.login}

Commit:

{run.head_commit && ( <> {run.head_commit.id.substring(0, 7)} {run.head_commit.message} )}
{formatDistanceToNow(new Date(run.created_at), { addSuffix: true })}
))}
)}
); };