/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

SurfaceComponent / FileBehavior
Tableui/DataTableColumns built by buildColumns(tz)
Date rangeui/DateRangeFilterDrives date_from / date_to; defaults to Today
Searchui/TextInputDebounced 250ms smart search
Bot filterui/SelectGET /api/v1/bots; disabled when a campaign is selected
Campaign filterui/SelectGET /api/v1/campaigns; selecting one clears the bot filter
Status filterui/SelectStatus allow-list
Min durationui/TextInput (number)Sets min_duration
PaginationPage buttons50 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 rows
  • GET /api/v1/calls/count?<params without limit/skip> for the total
Paging is server-driven (limit=50, skip=page*50); total powers the “showing X–Y of N” subtitle and the prev/next controls. The debounced search term is classified before being sent:
PatternParam
24-char hex (Mongo ObjectId)campaign_id
36-char UUID, or campaign- prefixsession_id
Anything elsephone
This lets one box accept a phone number, a session ID, or a campaign ID without a mode switch.

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 through statusVariant: 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:
CodeLabel
408No answer (rang out)
480 / 600Phone unreachable
486Line busy
487Call cancelled
603Call declined
404Invalid number
403Trunk auth failed
488Codec mismatch
503Carrier 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 from GET /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.

Call Detail

Transcript, recording, latency, and cache sections.

Design System

DataTable and DateRangeFilter internals.