mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-05-18 20:08:19 +00:00
feat: SSE-driven worklist + agent call history split + remove SOURCE column
Worklist:
- SSE stream replaces 30s poll — EventSource on /api/supervisor/worklist/stream
triggers immediate fetchWorklist() on missed-call events
- Toast notification: 'Missed Call — {name} — needs callback'
- No polling fallback — SSE is the source of truth
Call History split by role:
- Agent: 'My Call History' — own calls only (matched by agent relation
or chain-parsed agentName), missed calls excluded (they belong on
the Call Desk queue), no Agent/Recording/SLA columns, phone clickable
via PhoneActionCell instead of separate Call button
- Supervisor: 'Call History' — all calls, Agent + Recording columns visible
Worklist panel:
- SOURCE/BRANCH column removed from display (data stays on row)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -178,34 +178,9 @@ const formatTimeAgo = (dateStr: string): string => {
|
||||
const formatDisposition = (disposition: string): string =>
|
||||
disposition.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
|
||||
|
||||
const formatSource = (source: string): string => {
|
||||
const map: Record<string, string> = {
|
||||
FACEBOOK_AD: 'Facebook',
|
||||
GOOGLE_AD: 'Google',
|
||||
WALK_IN: 'Walk-in',
|
||||
REFERRAL: 'Referral',
|
||||
WEBSITE: 'Website',
|
||||
PHONE_INQUIRY: 'Phone',
|
||||
PHONE: 'Phone',
|
||||
OTHER: 'Other',
|
||||
};
|
||||
return map[source] ?? source.replace(/_/g, ' ');
|
||||
};
|
||||
|
||||
// Resolve a DID (e.g. "918041763265") to a friendly branch/campaign name.
|
||||
// The DID is the phone number the caller dialed — it identifies which
|
||||
// hospital branch or campaign the call came through. Falls back to the
|
||||
// last 10 digits if no mapping is found.
|
||||
const formatDid = (did: string): string => {
|
||||
if (!did) return '—';
|
||||
// Known DIDs — loaded from the sidecar theme tokens at boot (via
|
||||
// the ThemeTokenProvider). For now, hardcode nothing — strip country
|
||||
// code and show the DID as a short number so it's at least readable.
|
||||
const digits = did.replace(/\D/g, '');
|
||||
// Strip leading 91 (India) for display
|
||||
const short = digits.length > 10 && digits.startsWith('91') ? digits.slice(2) : digits;
|
||||
return short;
|
||||
};
|
||||
// formatSource + formatDid kept for reference but no longer rendered
|
||||
// in the table — SOURCE/BRANCH column removed from display per user
|
||||
// request. Data stays on the row for future use.
|
||||
|
||||
const IconInbound = faIcon(faPhoneArrowDown);
|
||||
const IconOutbound = faIcon(faPhoneArrowUp);
|
||||
@@ -239,7 +214,7 @@ const buildRows = (missedCalls: MissedCall[], followUps: WorklistFollowUp[], lea
|
||||
// Branch column: prefer the campaign name (e.g. "Cervical Cancer
|
||||
// Screening Drive") over the raw DID. Falls back to formatted DID
|
||||
// for organic calls with no campaign.
|
||||
source: call.campaign?.campaignName ?? (call.callSourceNumber ? formatDid(call.callSourceNumber) : null),
|
||||
source: call.campaign?.campaignName ?? call.callSourceNumber ?? null,
|
||||
lastDisposition: call.disposition ?? null,
|
||||
missedCallId: call.id,
|
||||
});
|
||||
@@ -497,7 +472,6 @@ export const WorklistPanel = ({ missedCalls, followUps, leads, loading, onSelect
|
||||
<Table.Head id="priority" label="SCORE" className="w-20" isRowHeader allowsSorting />
|
||||
<Table.Head id="name" label="PATIENT" allowsSorting />
|
||||
<Table.Head label="PHONE" />
|
||||
<Table.Head label={tab === 'missed' ? 'BRANCH' : 'SOURCE'} className="w-28" />
|
||||
<Table.Head id="sla" label="SLA" className="w-24" allowsSorting />
|
||||
</Table.Header>
|
||||
<Table.Body items={pagedRows}>
|
||||
@@ -578,15 +552,6 @@ export const WorklistPanel = ({ missedCalls, followUps, leads, loading, onSelect
|
||||
<span className="text-xs text-quaternary italic">No phone</span>
|
||||
)}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{row.source ? (
|
||||
<span className="text-xs text-tertiary truncate block max-w-[100px]">
|
||||
{formatSource(row.source)}
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-xs text-quaternary">—</span>
|
||||
)}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Badge size="sm" color={sla.color} type="pill-color">
|
||||
{sla.label}
|
||||
|
||||
Reference in New Issue
Block a user