Skip to content

Timeline View

The timeline view renders a vertical event log — useful for audit trails, activity feeds, deployment histories, or any ordered sequence of events.

Preview
  • PR #42 mergedsuccess2 hours ago

    Merged feature/auth-refactor into main after CI passed

  • Deploy to stagingwarning5 hours ago

    Deployed v2.3.1-rc1 — smoke tests pending

  • Review requestedyesterday

    Alice requested review from Bob and Carol

Spec
typescript
TimelineView.events(events).title('Deployment History').build()

How it works

The SPA navigates to #/{resource}/timeline (or #/{resource}/{id}/timeline for entity-specific histories) and fetches a TimelineSpec from the server. Events are embedded in the spec in display order — sort them on the server before building.

Basic setup (JS)

typescript
import { TimelineView } from '@retrofit-ui/builder-zod';

// URL prefix below is arbitrary — pick anything and match `apiBase` to it.
app.get('/ops/deployments/timeline', async (_req, res) => {
  const events = await db.query(
    `SELECT title, description, created_at AS timestamp, status AS variant
     FROM deploy_events ORDER BY created_at DESC`,
  );

  res.json(
    TimelineView.events(events).title('Deployment History').build(),
  );
});

TimelineView.events(...) is the entry point — pass an array of event objects and chain .title() if you want a heading above the list.

Event fields

FieldTypeRequiredDescription
titlestringShort label shown in bold
timestampstringISO 8601 datetime; rendered as relative time ("2 hours ago")
descriptionstringLonger text shown below the title
variant'success' | 'warning' | 'danger' | 'neutral' | 'primary'Changes the timeline dot colour
iconstringShoelace icon name shown next to the title

Variants

The variant field colours the timeline dot for at-a-glance status scanning:

Variants
  • primary — default blue dot
  • success — green dot
  • warning — amber dot
  • danger — red dot
  • neutral — grey dot
Spec
typescript
TimelineView.events([
  { title: 'Deploy succeeded', timestamp: '2026-06-27T10:00:00Z', variant: 'success' },
  { title: 'Tests ran with warnings', timestamp: '2026-06-27T09:45:00Z', variant: 'warning' },
  { title: 'Build failed', timestamp: '2026-06-27T09:30:00Z', variant: 'danger' },
]).build();

Icons

Pass any Shoelace icon name as icon to render it inline next to the title:

typescript
TimelineView.events([
  { title: 'PR merged', timestamp: '...', icon: 'git-merge', variant: 'success' },
  { title: 'Review requested', timestamp: '...', icon: 'person-check' },
  { title: 'Comment added', timestamp: '...', icon: 'chat-left' },
]).build();

Entity timeline vs. resource timeline

The route the SPA uses to fetch depends on whether you include an entity ID:

URL hashServer endpointUse for
#/{resource}/timelineGET /api/ui/{resource}/timelineGlobal activity log for a resource
#/{resource}/{id}/timelineGET /api/ui/{resource}/{id}/timelineHistory of a single record

Link from a table's row actions to the entity timeline:

typescript
TableView.schema(OrderSchema)
  .rowAction({ label: 'History', routePattern: '/{id}/timeline' })
  .list({ method: 'GET', url: '/orders' })
  .build();

Back button

The SPA renders a "← Back" button automatically. It navigates to #/{resource}/{id} for entity timelines, or #/{resource} for resource timelines.