DesignX
Agent Ops@paxeer/agent-ops/run-timelineimplemented

Run timeline

Vertical run event timeline with Separator.

Install

$pnpm exec designx add @paxeer/agent-ops/run-timeline

Preview

Loading preview...

Source code

components/designx/agent-ops/run-timeline.tsxtsx
import { Badge, Card, CardContent, CardHeader, CardTitle, Separator, StatusChip } from "@paxeer/core";

export type TimelineTone = "primary" | "secondary" | "tertiary" | "error" | "surface";

export interface TimelineEvent {
  id: string;
  time: string;
  title: string;
  detail?: string;
  tone?: TimelineTone;
}

export interface RunTimelineProps {
  runId?: string;
  events: TimelineEvent[];
}

export function RunTimeline({ runId = "run-latest", events }: RunTimelineProps) {
  return (
    <Card className="gap-3 py-4" data-slot="run-timeline">
      <CardHeader className="flex-row items-center justify-between px-4">
        <CardTitle className="text-[length:var(--md-sys-typescale-label-large-size)]">
          Run timeline
        </CardTitle>
        <Badge variant="outline">{runId}</Badge>
      </CardHeader>
      <CardContent className="px-4">
        {events.length === 0 ? (
          <p className="text-[length:var(--md-sys-typescale-body-small-size)] text-on-surface-variant">
            This run has not emitted events yet.
          </p>
        ) : (
          <ol className="flex flex-col">
            {events.map((event, index) => (
              <li key={event.id} className="flex flex-col gap-2">
                <div className="flex flex-wrap items-center gap-2">
                  <time className="font-[family-name:var(--md-ref-typeface-mono)] text-[length:var(--md-sys-typescale-label-small-size)] text-on-surface-variant">
                    {event.time}
                  </time>
                  <StatusChip tone={event.tone ?? "secondary"}>{event.title}</StatusChip>
                </div>
                {event.detail ? (
                  <p className="text-[length:var(--md-sys-typescale-body-small-size)] text-on-surface-variant">
                    {event.detail}
                  </p>
                ) : null}
                {index < events.length - 1 ? <Separator className="my-2" /> : null}
              </li>
            ))}
          </ol>
        )}
      </CardContent>
    </Card>
  );
}