Timeline View
The timeline view renders a vertical event log — useful for audit trails, activity feeds, deployment histories, or any ordered sequence of events.
- 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
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)
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
| Field | Type | Required | Description |
|---|---|---|---|
title | string | ✓ | Short label shown in bold |
timestamp | string | ✓ | ISO 8601 datetime; rendered as relative time ("2 hours ago") |
description | string | — | Longer text shown below the title |
variant | 'success' | 'warning' | 'danger' | 'neutral' | 'primary' | — | Changes the timeline dot colour |
icon | string | — | Shoelace icon name shown next to the title |
Variants
The variant field colours the timeline dot for at-a-glance status scanning:
- primary — default blue dot
- success — green dot
- warning — amber dot
- danger — red dot
- neutral — grey dot
Spec
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:
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 hash | Server endpoint | Use for |
|---|---|---|
#/{resource}/timeline | GET /api/ui/{resource}/timeline | Global activity log for a resource |
#/{resource}/{id}/timeline | GET /api/ui/{resource}/{id}/timeline | History of a single record |
Link from a table's row actions to the entity timeline:
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.