hotfix: server-render initial telephony calls

This commit is contained in:
Christian 2026-05-04 22:46:31 +02:00
parent 93da2866dc
commit b1a4342a9a
4 changed files with 106 additions and 3 deletions

15
RELEASE_NOTES_v2.2.85.md Normal file
View File

@ -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`

View File

@ -1 +1 @@
2.2.84
2.2.85

View File

@ -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,
},
)

View File

@ -59,7 +59,41 @@
</tr>
</thead>
<tbody id="telefoniRows">
<tr><td colspan="7" class="text-muted small">Indlæser...</td></tr>
{% if initial_calls and initial_calls|length > 0 %}
{% for r in initial_calls %}
<tr>
<td>{{ r.started_at or '-' }}</td>
<td>{{ r.full_name or r.username or '-' }}</td>
<td>{{ 'Udgående' if r.direction == 'outbound' else 'Indgående' }}</td>
<td>{{ r.display_number or '-' }}</td>
<td>
{% if r.kontakt_id %}
<a href="/contacts/{{ r.kontakt_id }}">{{ r.contact_name or ('Kontakt #' ~ r.kontakt_id) }}</a>
{% else %}
-
{% endif %}
</td>
<td>
{% if r.sag_id %}
<a href="/sag/{{ r.sag_id }}/v3">{{ r.sag_titel or ('Sag #' ~ r.sag_id) }}</a>
{% else %}
-
{% endif %}
</td>
<td class="text-end">
{% if r.duration_sec is not none %}
{{ r.duration_sec }}s
{% elif r.ended_at %}
-
{% else %}
I gang
{% endif %}
</td>
</tr>
{% endfor %}
{% else %}
<tr><td colspan="7" class="text-muted small">Indlæser...</td></tr>
{% endif %}
</tbody>
</table>
</div>
@ -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 = '<tr><td colspan="7" class="text-muted small">Ingen opkald fundet</td></tr>';
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);