From b1a4342a9aaf98d1d1bda6c58c0c05e52b024371 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 4 May 2026 22:46:31 +0200 Subject: [PATCH] hotfix: server-render initial telephony calls --- RELEASE_NOTES_v2.2.85.md | 15 ++++++++ VERSION | 2 +- app/modules/telefoni/frontend/views.py | 42 ++++++++++++++++++++- app/modules/telefoni/templates/log.html | 50 ++++++++++++++++++++++++- 4 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 RELEASE_NOTES_v2.2.85.md diff --git a/RELEASE_NOTES_v2.2.85.md b/RELEASE_NOTES_v2.2.85.md new file mode 100644 index 0000000..add0521 --- /dev/null +++ b/RELEASE_NOTES_v2.2.85.md @@ -0,0 +1,15 @@ +# Release Notes v2.2.85 + +Dato: 2026-05-04 + +## Hotfix + +- Telefoni-siden (`/telefoni`) rendrer nu seneste opkald server-side ved page load (SSR fallback). +- Dette sikrer, at brugeren ser opkald med det samme, selv hvis browserens JS/rendering/filter-state fejler eller er cachet. +- Klient-side `loadCalls()` koerer stadig bagefter og opdaterer tabellen som foer. + +## Berorte filer + +- `app/modules/telefoni/frontend/views.py` +- `app/modules/telefoni/templates/log.html` +- `VERSION` diff --git a/VERSION b/VERSION index 9214f6a..5bca469 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.84 +2.2.85 diff --git a/app/modules/telefoni/frontend/views.py b/app/modules/telefoni/frontend/views.py index 04fa62d..68b6048 100644 --- a/app/modules/telefoni/frontend/views.py +++ b/app/modules/telefoni/frontend/views.py @@ -3,6 +3,7 @@ import logging from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates +from app.core.database import execute_query logger = logging.getLogger(__name__) router = APIRouter() @@ -11,4 +12,43 @@ templates = Jinja2Templates(directory="app") @router.get("/telefoni", response_class=HTMLResponse) async def telefoni_log_page(request: Request): - return templates.TemplateResponse("modules/telefoni/templates/log.html", {"request": request}) + initial_calls = [] + try: + initial_calls = execute_query( + """ + SELECT + t.id, + t.direction, + COALESCE( + NULLIF(TRIM(t.ekstern_nummer), ''), + NULLIF(TRIM(t.raw_payload->>'caller'), ''), + NULLIF(TRIM(t.raw_payload->>'callee'), '') + ) AS display_number, + t.started_at, + t.duration_sec, + t.ended_at, + u.full_name, + u.username, + t.kontakt_id, + CONCAT(COALESCE(c.first_name, ''), ' ', COALESCE(c.last_name, '')) AS contact_name, + t.sag_id, + s.titel AS sag_titel + FROM telefoni_opkald t + LEFT JOIN users u ON u.user_id = t.bruger_id + LEFT JOIN contacts c ON c.id = t.kontakt_id + LEFT JOIN sag_sager s ON s.id = t.sag_id + ORDER BY t.started_at DESC + LIMIT 50 + """, + (), + ) or [] + except Exception as e: + logger.warning("⚠️ Could not load initial telefoni calls for SSR fallback: %s", e) + + return templates.TemplateResponse( + "modules/telefoni/templates/log.html", + { + "request": request, + "initial_calls": initial_calls, + }, + ) diff --git a/app/modules/telefoni/templates/log.html b/app/modules/telefoni/templates/log.html index 7e077a2..de3dbb1 100644 --- a/app/modules/telefoni/templates/log.html +++ b/app/modules/telefoni/templates/log.html @@ -59,7 +59,41 @@ - Indlæser... + {% if initial_calls and initial_calls|length > 0 %} + {% for r in initial_calls %} + + {{ r.started_at or '-' }} + {{ r.full_name or r.username or '-' }} + {{ 'Udgående' if r.direction == 'outbound' else 'Indgående' }} + {{ r.display_number or '-' }} + + {% if r.kontakt_id %} + {{ r.contact_name or ('Kontakt #' ~ r.kontakt_id) }} + {% else %} + - + {% endif %} + + + {% if r.sag_id %} + {{ r.sag_titel or ('Sag #' ~ r.sag_id) }} + {% else %} + - + {% endif %} + + + {% if r.duration_sec is not none %} + {{ r.duration_sec }}s + {% elif r.ended_at %} + - + {% else %} + I gang + {% endif %} + + + {% endfor %} + {% else %} + Indlæser... + {% endif %} @@ -178,6 +212,7 @@ function escapeHtml(str) { } let telefoniCurrentUserId = null; +let telefoniAutoResetTried = false; const telefoniCallMap = new Map(); const linkSagState = { callId: null, @@ -846,10 +881,22 @@ async function loadCalls() { telefoniCallMap.clear(); (rows || []).forEach(r => telefoniCallMap.set(Number(r.id), r)); if (!rows || rows.length === 0) { + const hadFilters = Boolean(userId || from || to || withoutCase); + if (hadFilters && !telefoniAutoResetTried) { + telefoniAutoResetTried = true; + document.getElementById('filterUser').value = ''; + document.getElementById('filterFrom').value = ''; + document.getElementById('filterTo').value = ''; + document.getElementById('filterWithoutCase').checked = false; + await loadCalls(); + return; + } tbody.innerHTML = 'Ingen opkald fundet'; return; } + telefoniAutoResetTried = false; + tbody.innerHTML = rows.map(r => { const started = r.started_at ? new Date(r.started_at) : null; const dateTxt = started ? started.toLocaleString('da-DK') : '-'; @@ -974,6 +1021,7 @@ document.addEventListener('DOMContentLoaded', async () => { if (fromFilter) fromFilter.value = ''; if (toFilter) toFilter.value = ''; if (withoutCaseFilter) withoutCaseFilter.checked = false; + telefoniAutoResetTried = false; await loadUsers(); document.getElementById('btnRefresh').addEventListener('click', loadCalls);