Timeline Component
Overview
The Timeline component renders a vertical or horizontal timeline visualization of events. It supports two modes:
- Normal mode — displays events within a date range with navigation controls (prev/next period, day/week/month/year views)
- Tracking mode — displays shipment/order tracking progress as milestones (completed, pending, and extra events) without date-range navigation
Both modes are driven by YAML configuration with GraphQL event sources and template-based mapping.
Component Registration
Registered as timeline in src/modules/common/components/layout/component-render.tsx.
Modes
Normal Mode (default)
Displays events in a date-range window. Navigation controls allow switching between day/week/month/year views and navigating forward/backward. Events are sorted chronologically.
Supports both horizontal and vertical orientations.
Tracking Mode (mode: tracking)
Displays a vertical timeline showing order/shipment tracking progress. Milestones are matched against real events from a GraphQL query. No date-range navigation is shown.
Each milestone can be in one of three states:
| State | Visual | Description |
|---|---|---|
| Completed | Green filled dot | Event exists matching the milestone key |
| Pending | Blue outlined dot | No matching event found |
| Extra | Green filled dot at 60% opacity | Event exists but doesn't match any milestone (extraEvents: show only) |
Data Flow
- Query returns tracking events for an order or commodity
- Mapping normalizes events and produces a
keyfor matching (e.g.,key: '{{ item.eventDefinition.eventName }}') - Milestones are matched by
keyagainst mapped events - The component does not filter mapped events by
includeInTrackingorisInactive; apply those filters in the query or mapping source when needed - If multiple events match one milestone key, the latest by date is used
- Completed milestones + extras are sorted chronologically; pending milestones are appended at the end in YAML order
Description Priority
| State | Title | Description |
|---|---|---|
| Completed | Event title → milestone label | Event description → milestone description |
| Pending | Milestone label | Milestone description |
| Extra | Event title | Event description |
YAML Configuration
Basic Normal Mode
- component: timeline
name: orderTimeline
props:
orientation: vertical
startDate: '{{ variables.startDate }}'
endDate: '{{ variables.endDate }}'
view: week
options:
height: 400
showTodayMarker: true
enableZoom: true
enableNavigation: true
showTwoColumns: true
alternateSides: false
dateFormat: 'MMM DD'
timeFormat: 'h:mm A'
eventSources:
- query:
command: >
query($organizationId: Int!, $startDate: String!, $endDate: String!) {
events(organizationId: $organizationId, startDate: $startDate, endDate: $endDate) {
items { id title description eventDate }
}
}
variables:
organizationId: '{{ number organizationId }}'
startDate: '{{ startDate }}'
endDate: '{{ endDate }}'
path: data.events.items
mapping:
date: '{{ item.eventDate }}'
title: '{{ item.title }}'
description: '{{ item.description }}'
Tracking Mode
- component: timeline
name: orderTracking
props:
mode: tracking
orientation: vertical
options:
showTwoColumns: true
alternateSides: false
extraEvents: hide
eventSources:
- query:
command: >
query($organizationId: Int!, $orderId: Int!) {
order(organizationId: $organizationId, orderId: $orderId) {
orderId
trackingEvents {
trackingEventId
eventDate
description
location
includeInTracking
isInactive
eventDefinition { eventName }
}
}
}
variables:
organizationId: '{{ number organizationId }}'
orderId: '{{ number orderId }}'
path: order.trackingEvents
mapping:
key: '{{ item.eventDefinition.eventName }}'
id: '{{ item.trackingEventId }}'
date: '{{ item.eventDate }}'
title: '{{ item.eventDefinition.eventName }}'
description: '{{ item.description }}'
milestones:
- key: 'Shipment Created'
label: { en-US: 'Shipment Created' }
description: 'Order registered in the system'
- key: 'In Transit'
label: { en-US: 'In Transit' }
description: 'Package is on its way'
icon: truck
- key: 'Delivered'
label: { en-US: 'Delivered' }
description: 'Final delivery completed'
icon: check-circle
Props Reference
Top-Level Props
| Prop | Type | Default | Description |
|---|---|---|---|
mode | 'normal' | 'tracking' | 'normal' | Timeline mode |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Layout direction. Tracking mode always uses vertical |
startDate | string | Start of current week | Start date for normal mode (template expression) |
endDate | string | End of current week | End date for normal mode (template expression) |
view | 'day' | 'week' | 'month' | 'year' | 'week' | Initial view period for normal mode |
options | object | See below | Display options |
eventSources | array | [] | Event data sources |
eventTemplate | object | — | Custom event rendering template (normal mode only) |
activeTemplate | object | — | Mobile-only renderer for an event whose mapped status is active |
milestones | array | [] | Milestone definitions (tracking mode only) |
Options
| Option | Type | Default | Description |
|---|---|---|---|
height | string | number | 400 (horizontal) / 'auto' (vertical) | Container height |
showTodayMarker | boolean | true | Show a marker for today's date |
enableZoom | boolean | true | Show day/week/month/year view switcher |
enableNavigation | boolean | true | Show prev/next/today navigation |
alternateSides | boolean | true | Alternate events left/right in vertical mode |
showTwoColumns | boolean | true | Show date on opposite side in vertical mode |
dateFormat | string | 'MMM DD' | Moment.js date format |
timeFormat | string | 'h:mm A' | Moment.js time format |
extraEvents | 'show' | 'hide' | 'hide' | Whether to show events that don't match any milestone (tracking mode only) |
Event Source
| Prop | Type | Required | Description |
|---|---|---|---|
query.command | string | Yes | GraphQL query string |
query.variables | object | No | Query variables (template expressions supported) |
query.path | string | No | Dot-path to extract data from query result |
query.mapping | object | No | Template-based field mapping for each event |
events | any | No | Static events (fallback or primary source) |
backgroundColor | string | No | Default background color for events from this source |
textColor | string | No | Default text color |
borderColor | string | No | Default border color (renders outlined dot) |
Milestones (Tracking Mode Only)
| Prop | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Match key — compared against the mapped event key field |
label | object | No | Localized display label (e.g., { en-US: 'Shipped' }). Falls back to key |
description | string | No | Description shown for pending milestones, or as fallback for completed |
icon | string | No | Icon rendered inside the dot (FontAwesome icon name, e.g., truck, check-circle, plane) |
Icons
Milestone icons use the existing Icon component which supports:
- FontAwesome (default) — free solid, regular, and brand icons. Use the icon name directly (e.g.,
truck,box-open,plane,passport,check-circle) - Tabler icons — prefix with
tabler-(e.g.,tabler-truck) - Full icon reference: fontawesome.com/icons
Icons render inside the timeline dot at reduced size. If no icon is specified, the dot shows the default filled or outlined circle.
Mobile behavior
The native renderer supports normal and tracking modes, static or GraphQL-backed event sources, date navigation, day/week/month/year switching, horizontal scrolling, and event actions. events.onEventClick runs with the selected event available as event. Query failures show an inline error with a retry action; static events act as the fallback when a source query fails.
Normal mode can use eventTemplate. Mobile also supports activeTemplate, selected when an event maps status: active; the template receives the event as item. Tracking mode uses its built-in milestone presentation and ignores per-event templates. On mobile, alternateSides and showTodayMarker are accepted for contract compatibility but are not visually implemented. Horizontal mode uses cards in a scrolling row rather than the web timeline's pixel-based time axis.
Files
| File | Description |
|---|---|
src/modules/common/components/layout/components/timeline-component.tsx | Component implementation |
src/modules/common/components/layout/components/icon-component.tsx | Icon resolution (FontAwesome, Tabler) |
src/modules/common/components/layout/component-render.tsx | Component registration |
Related Documentation
- Slot Component — Component extensions using slots