periplon 0.2.0

Rust SDK for building multi-agent AI workflows and automation
Documentation
'use client'

import { useQuery } from '@tanstack/react-query'
import Link from 'next/link'
import { apiClient } from '@/lib/api-client'
import { Card, CardContent } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { formatDate, formatDuration, getStatusColor } from '@/lib/utils'
import { Eye, XCircle } from 'lucide-react'

export default function ExecutionsPage() {
  const { data: executions, isLoading } = useQuery({
    queryKey: ['executions'],
    queryFn: () => apiClient.listExecutions(),
    refetchInterval: 5000, // Refresh every 5 seconds for real-time updates
  })

  const getExecutionDuration = (execution: any) => {
    if (!execution.started_at) return null
    const end = execution.completed_at
      ? new Date(execution.completed_at)
      : new Date()
    const start = new Date(execution.started_at)
    return end.getTime() - start.getTime()
  }

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-3xl font-bold">Executions</h1>
        <p className="text-muted-foreground">
          Monitor workflow execution status and history
        </p>
      </div>

      {isLoading ? (
        <div>Loading...</div>
      ) : executions && executions.length > 0 ? (
        <div className="space-y-3">
          {executions.map((execution) => {
            const duration = getExecutionDuration(execution)
            return (
              <Card key={execution.id} className="hover:shadow-md transition-shadow">
                <CardContent className="p-4">
                  <div className="flex items-center justify-between">
                    <div className="flex-1 space-y-2">
                      <div className="flex items-center gap-3">
                        <Badge className={getStatusColor(execution.status)}>
                          {execution.status}
                        </Badge>
                        <span className="font-medium text-sm">
                          {execution.workflow_id}
                        </span>
                        <span className="text-xs text-muted-foreground">
                          v{execution.workflow_version}
                        </span>
                      </div>

                      <div className="flex items-center gap-4 text-sm text-muted-foreground">
                        <span>{formatDate(execution.created_at)}</span>
                        {duration && (
                          <span>Duration: {formatDuration(duration)}</span>
                        )}
                        <span>Trigger: {execution.trigger_type}</span>
                        {execution.triggered_by && (
                          <span>By: {execution.triggered_by}</span>
                        )}
                      </div>

                      {execution.error && (
                        <div className="text-sm text-destructive">
                          Error: {execution.error}
                        </div>
                      )}
                    </div>

                    <div className="flex gap-2">
                      <Button variant="outline" size="sm" asChild>
                        <Link href={`/executions/${execution.id}`}>
                          <Eye className="h-3 w-3 mr-1" />
                          View
                        </Link>
                      </Button>
                      {execution.status === 'running' && (
                        <Button
                          variant="destructive"
                          size="sm"
                          onClick={() => apiClient.cancelExecution(execution.id)}
                        >
                          <XCircle className="h-3 w-3 mr-1" />
                          Cancel
                        </Button>
                      )}
                    </div>
                  </div>
                </CardContent>
              </Card>
            )
          })}
        </div>
      ) : (
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-12">
            <p className="text-muted-foreground">No executions yet</p>
          </CardContent>
        </Card>
      )}
    </div>
  )
}