"use client"; import { ArrowDown, ArrowUp, ArrowUpDown, ChevronLeft, ChevronRight, ExternalLink, RefreshCw } from "lucide-react"; import { useState } from "react"; import { WorkflowRunResponseSchema } from "@/client/types.gen"; import { FilterBuilder } from "@/components/filters/FilterBuilder"; import { MediaPreviewButton, MediaPreviewDialog } from "@/components/MediaPreviewDialog"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { ActiveFilter, FilterAttribute } from "@/types/filters"; export interface WorkflowRunsTableProps { // Data runs: WorkflowRunResponseSchema[]; loading: boolean; error: string | null; // Pagination currentPage: number; totalPages: number; totalCount: number; onPageChange: (page: number) => void; // Filters availableAttributes: FilterAttribute[]; activeFilters: ActiveFilter[]; onFiltersChange: (filters: ActiveFilter[]) => void; onApplyFilters: () => void; onClearFilters: () => void; isExecutingFilters: boolean; hasAppliedFilters?: boolean; // Sorting sortBy?: string | null; sortOrder?: 'asc' | 'desc'; onSort?: (field: string) => void; // Navigation & Actions workflowId: number; // Reload onReload?: () => void; // Optional customization title?: string; subtitle?: string; showFilters?: boolean; emptyMessage?: string; } export function WorkflowRunsTable({ runs, loading, error, currentPage, totalPages, totalCount, onPageChange, availableAttributes, activeFilters, onFiltersChange, onApplyFilters, onClearFilters, isExecutingFilters, hasAppliedFilters = false, sortBy, sortOrder = 'desc', onSort, workflowId, onReload, title = "Workflow Run History", subtitle, showFilters = true, emptyMessage = "No workflow runs found", }: WorkflowRunsTableProps) { const [selectedRowId, setSelectedRowId] = useState(null); // Media preview dialog const mediaPreview = MediaPreviewDialog(); const formatDate = (dateString: string) => new Date(dateString).toLocaleString(); const handleRowClick = (runId: number) => { window.open(`/workflow/${workflowId}/run/${runId}`, '_blank'); }; return (
{/* Title and Filters */} {showFilters && (

{title}

)} {/* Loading State */} {loading ? (
Loading workflow runs...
) : error ? (
{error}
) : runs.length === 0 ? (

{emptyMessage}

) : (
Workflow Runs {subtitle || `Showing ${runs.length} of ${totalCount} total runs`}
{onReload && ( )}
ID Status Created At Call Type onSort?.('duration')} >
Duration {sortBy === 'duration' ? ( sortOrder === 'asc' ? : ) : ( )}
Disposition Actions
{runs.map((run) => ( handleRowClick(run.id)} > #{run.id} {run.is_completed ? "Completed" : "In Progress"} {formatDate(run.created_at)} {run.call_type === 'inbound' ? 'Inbound' : 'Outbound'} {typeof run.cost_info?.call_duration_seconds === 'number' ? `${run.cost_info.call_duration_seconds.toFixed(1)}s` : "-"} {run.gathered_context?.mapped_call_disposition ? ( {run.gathered_context.mapped_call_disposition as string} ) : ( - )}
e.stopPropagation()}>
))}
{/* Pagination */} {totalPages > 1 && (

Page {currentPage} of {totalPages}

)}
)} {/* Media Preview Dialog */} {mediaPreview.dialog}
); }