diff --git a/VERSION b/VERSION index 9423d08..6c4bbe4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.8.20 +2.8.21 diff --git a/app/dashboard/backend/mission_router.py b/app/dashboard/backend/mission_router.py index 0c82376..950e4fb 100644 --- a/app/dashboard/backend/mission_router.py +++ b/app/dashboard/backend/mission_router.py @@ -732,7 +732,8 @@ async def mission_telefoni_ringing(event: MissionCallEvent, request: Request, to timestamp = event.timestamp or datetime.utcnow() context = MissionService.resolve_contact_context(event.caller_number) - queue_name = _display_destination(event) + queue_name = (event.queue_name or "Ukendt kø").strip() + recipient_name = _display_destination(event) execute_query( """ @@ -753,7 +754,13 @@ async def mission_telefoni_ringing(event: MissionCallEvent, request: Request, to answered_at = NULL, started_at = LEAST(mission_call_state.started_at, EXCLUDED.started_at), updated_at = NOW(), - last_payload = EXCLUDED.last_payload + last_payload = jsonb_set( + EXCLUDED.last_payload, + '{ringing_phones}', + COALESCE(mission_call_state.last_payload->'ringing_phones', '[]'::jsonb) + || COALESCE(EXCLUDED.last_payload->'ringing_phones', '[]'::jsonb), + true + ) """, ( event.call_id, @@ -763,7 +770,7 @@ async def mission_telefoni_ringing(event: MissionCallEvent, request: Request, to context.get("company_name"), context.get("customer_tag"), timestamp, - json.dumps(event.model_dump(mode="json")), + json.dumps({**event.model_dump(mode="json"), "ringing_phones": [recipient_name]}), ), ) @@ -786,6 +793,7 @@ async def mission_telefoni_ringing(event: MissionCallEvent, request: Request, to "queue_name": queue_name, "caller_number": event.caller_number, "recipient_extension": event.recipient_extension, + "ringing_phones": [recipient_name], **context, "timestamp": timestamp, } diff --git a/app/dashboard/backend/mission_service.py b/app/dashboard/backend/mission_service.py index be41817..248ecb2 100644 --- a/app/dashboard/backend/mission_service.py +++ b/app/dashboard/backend/mission_service.py @@ -26,12 +26,10 @@ class MissionService: @staticmethod def get_ring_timeout_seconds() -> int: - raw = MissionService.get_setting_value("mission_call_ring_timeout_seconds", "180") or "180" - try: - value = int(raw) - except (TypeError, ValueError): - value = 180 - return max(30, min(value, 3600)) + # A Yealink "Incoming call" event has no matching event when the + # caller abandons the call. Keep it briefly, then remove it from the + # live boards so stale ringing phones cannot remain visible. + return 30 @staticmethod def expire_stale_ringing_calls() -> None: @@ -216,7 +214,8 @@ class MissionService: MissionService.expire_stale_ringing_calls() rows = execute_query( """ - SELECT call_id, queue_name, caller_number, contact_name, company_name, customer_tag, state, started_at, answered_at, ended_at, updated_at + SELECT call_id, queue_name, caller_number, contact_name, company_name, customer_tag, state, started_at, answered_at, ended_at, updated_at, + COALESCE(last_payload->'ringing_phones', jsonb_build_array(queue_name)) AS ringing_phones FROM mission_call_state WHERE state = 'ringing' ORDER BY started_at DESC diff --git a/app/dashboard/frontend/mission_control_v2.html b/app/dashboard/frontend/mission_control_v2.html index e44e88e..cc87049 100644 --- a/app/dashboard/frontend/mission_control_v2.html +++ b/app/dashboard/frontend/mission_control_v2.html @@ -2956,8 +2956,10 @@ } const call = state.activeCalls[0]; + const phones = [...new Set((Array.isArray(call.ringing_phones) ? call.ringing_phones : [call.queue_name]).filter(Boolean))]; title.textContent = `${call.queue_name || 'Ukendt kø'} - ${call.caller_number || 'Ukendt nummer'}`; const parts = []; + if (phones.length) parts.push(`Ringer hos: ${phones.join(' · ')}`); if (call.contact_name) parts.push(call.contact_name); if (call.company_name) parts.push(call.company_name); parts.push(`Start: ${formatDate(call.started_at)}`); @@ -2973,16 +2975,20 @@ return; } - list.innerHTML = state.activeCalls.map((call) => ` + list.innerHTML = state.activeCalls.map((call) => { + const phones = [...new Set((Array.isArray(call.ringing_phones) ? call.ringing_phones : [call.queue_name]).filter(Boolean))]; + return `