/dashboard/calls is src/pages/CallList.tsx. It renders server-paginated calls in a DataTable, filtered by date range, bot, campaign, status, search, and minimum duration.
Surfaces
| Surface | Component / File | Behavior |
|---|---|---|
| Table | ui/DataTable | Columns built by buildColumns(tz) |
| Date range | ui/DateRangeFilter | Drives date_from / date_to; defaults to Today |
| Search | ui/TextInput | Debounced 250ms smart search |
| Bot filter | ui/Select | GET /api/v1/bots; disabled when a campaign is selected |
| Campaign filter | ui/Select | GET /api/v1/campaigns; selecting one clears the bot filter |
| Status filter | ui/Select | Status allow-list |
| Min duration | ui/TextInput (number) | Sets min_duration |
| Pagination | Page buttons | 50 rows per server page |
Data Fetch
fetchCalls only runs once a dateRange exists. It builds query params and fires two requests in parallel:
GET /api/v1/calls?<params>for the page rowsGET /api/v1/calls/count?<params without limit/skip>for the total
limit=50, skip=page*50); total powers the “showing X–Y of N” subtitle and the prev/next controls.
Smart Search
The debounced search term is classified before being sent:| Pattern | Param |
|---|---|
| 24-char hex (Mongo ObjectId) | campaign_id |
36-char UUID, or campaign- prefix | session_id |
| Anything else | phone |
Columns
buildColumns(tz) produces: Caller ID, Type (Campaign/Agent/Bot badge), Campaign (name + short id), Carrier / DID, Bot (name + short id), Duration (sortable), Ended by, Status, and Date/Time (sortable, rendered in the display timezone). Duration and Date/Time are the only client-sortable columns.
Status & SIP Mapping
Status badges map throughstatusVariant: completed → success, active/ringing/attaching/in_progress → primary, failed/exhausted/abandoned → danger, others neutral.
The “Ended by” column shows disconnected_by plus a human-friendly SIP status via friendlySipStatus, which maps raw codes to labels:
| Code | Label |
|---|---|
| 408 | No answer (rang out) |
| 480 / 600 | Phone unreachable |
| 486 | Line busy |
| 487 | Call cancelled |
| 603 | Call declined |
| 404 | Invalid number |
| 403 | Trunk auth failed |
| 488 | Codec mismatch |
| 503 | Carrier unavailable |
Row Navigation
Clicking a row navigates to/dashboard/calls/:session_id when a session ID exists; otherwise, for campaign rows without a session, to /dashboard/campaigns/:campaign_id.
Export
There is no bulk export on the list. Per-call raw JSON export lives on the call detail page (admin-only), which downloads fromGET /api/v1/calls/:id/export.json.
CXB Variant
src/pages/CallListCXB.tsx is an alternate, simplified call list (CX Bridge style): infinite scroll instead of numbered pages, a fixed status filter set (all/completed/failed/voicemail), and CSS-class status badges rather than the shared Badge. It paginates GET /api/v1/calls with limit=30 and page.
The active
/dashboard/calls route in src/App.tsx renders CallList, not CallListCXB. The CXB variant (like OverviewCXB) is a brand-specific alternate page kept in the codebase and is not wired into the default route tree.Related Docs
Call Detail
Transcript, recording, latency, and cache sections.
Design System
DataTable and DateRangeFilter internals.