'use client'; import { Archive, Check, Folder as FolderIcon, FolderInput, Inbox, Pencil, RotateCcw, } from 'lucide-react'; import { useRouter } from 'next/navigation'; import { useState, useTransition } from 'react'; import { toast } from 'sonner'; import { moveWorkflowToFolderApiV1WorkflowWorkflowIdFolderPut, updateWorkflowStatusApiV1WorkflowWorkflowIdStatusPut, } from '@/client/sdk.gen'; import type { FolderResponse } from '@/client/types.gen'; import { Button } from '@/components/ui/button'; import { Card, CardContent } from '@/components/ui/card'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; interface Workflow { id: number; name: string; status: string; created_at: string; total_runs?: number | null; folder_id?: number | null; } interface WorkflowTableProps { workflows: Workflow[]; showArchived: boolean; /** * When provided, each row gets a "Move to folder" action listing these * folders. Omit it (e.g. for the archived list) to hide the control. */ folders?: FolderResponse[]; /** The folder this table is rendered under; null means "Uncategorized". */ currentFolderId?: number | null; } export function WorkflowTable({ workflows, showArchived, folders, currentFolderId = null, }: WorkflowTableProps) { const router = useRouter(); const [isPending, startTransition] = useTransition(); const [loadingWorkflowId, setLoadingWorkflowId] = useState(null); const [movingWorkflowId, setMovingWorkflowId] = useState(null); const handleEdit = (id: number) => { router.push(`/workflow/${id}`); }; const handleArchiveToggle = async (id: number, currentStatus: string) => { const newStatus = currentStatus === 'active' ? 'archived' : 'active'; const action = currentStatus === 'active' ? 'Archive' : 'Restore'; setLoadingWorkflowId(id); try { const response = await updateWorkflowStatusApiV1WorkflowWorkflowIdStatusPut({ path: { workflow_id: id, }, body: { status: newStatus, }, }); if (response.data) { toast.success(`Workflow ${action.toLowerCase()}d successfully`); startTransition(() => { router.refresh(); }); } } catch (error) { console.error(`Error ${action.toLowerCase()}ing workflow:`, error); toast.error(`Failed to ${action.toLowerCase()} workflow`); } finally { setLoadingWorkflowId(null); } }; const handleMove = async (id: number, folderId: number | null) => { setMovingWorkflowId(id); try { const response = await moveWorkflowToFolderApiV1WorkflowWorkflowIdFolderPut({ path: { workflow_id: id }, body: { folder_id: folderId }, }); if (response.error) { throw new Error('Failed to move agent'); } toast.success( folderId === null ? 'Moved to Uncategorized' : 'Agent moved', ); startTransition(() => { router.refresh(); }); } catch (error) { console.error('Error moving workflow:', error); toast.error('Failed to move agent'); } finally { setMovingWorkflowId(null); } }; return ( ID Agent Name Created At Total Runs Actions {workflows.map((workflow) => ( {workflow.id} {workflow.name} {new Date(workflow.created_at).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric', })} {workflow.total_runs || 0}
{folders && ( Move to folder handleMove(workflow.id, null)} > Uncategorized {currentFolderId === null && ( )} {folders.map((folder) => ( handleMove(workflow.id, folder.id)} > {folder.name} {folder.id === currentFolderId && ( )} ))} )}
))}
); }