import { apiGet, isAuthRedirectError } from '../api.js'; import { guard } from '../core/auth-guard.js'; import { ticketStatusLabel, ticketPriorityLabel, eventTypeLabel, eventTypeBadgeClass, statusBadgeClass, priorityBadgeClass, } from '../core/constants.js'; import { esc, formatDateTime, extrasName } from '../core/utils.js'; import { bindAttachmentPreview } from '../core/attachment-preview.js'; import { eventInhaltHtml, sortEventsChronologicalWithAttachmentsLast, } from '../core/ticket-events.js'; const loadingEl = document.getElementById('page-loading'); const mainEl = document.getElementById('page-main'); const errEl = document.getElementById('page-error'); const listEl = document.getElementById('home-ticket-list'); const emptyEl = document.getElementById('home-empty'); const tpl = document.getElementById('tpl-home-ticket'); function showError(msg) { loadingEl.hidden = true; mainEl.hidden = true; errEl.hidden = false; errEl.textContent = msg; } function renderEventBoxes(events) { const evChrono = sortEventsChronologicalWithAttachmentsLast(events); if (evChrono.length === 0) { return '

Noch keine Ereignisse in der Historie.

'; } return evChrono .map( (ev) => `
${esc(eventTypeLabel[ev.type] || ev.type)}
${eventInhaltHtml(ev)}
`, ) .join(''); } function fillTicketCard(node, t, events) { const id = t.id; const detailId = `home-ticket-detail-${id}`; node.dataset.ticketId = id; const btn = node.querySelector('.home-ticket-collapse-btn'); const panel = node.querySelector('.home-ticket-collapsible'); panel.id = detailId; btn.setAttribute('aria-controls', detailId); const mn = t.machine ? extrasName(t.machine) : ''; const machineLabel = t.machine ? `${esc(t.machine.seriennummer)}${mn ? ` · ${esc(mn)}` : ''}` : ''; const standort = t.machine ? esc(t.machine.standort) : '—'; const headEl = node.querySelector('.home-ticket-head'); headEl.classList.toggle('home-ticket-head-overdue', Boolean(t.isOverdue)); const titleA = node.querySelector('.js-ticket-link'); titleA.href = `/ticket.html?id=${encodeURIComponent(id)}`; titleA.textContent = t.title; const st = node.querySelector('.js-status'); st.textContent = ticketStatusLabel[t.status]; st.className = `badge js-status ${statusBadgeClass[t.status] || ''}`; const pr = node.querySelector('.js-priority'); pr.textContent = ticketPriorityLabel[t.priority]; pr.className = `badge js-priority ${priorityBadgeClass[t.priority] || ''}`; const metaM = node.querySelector('.js-meta-machine'); metaM.innerHTML = t.machine ? `Maschine: ${machineLabel}` : 'Keine Maschine'; node.querySelector('.js-meta-standort').textContent = standort; node.querySelector('.js-meta-created').textContent = formatDateTime(t.createdAt); node.querySelector('.js-meta-updated').textContent = formatDateTime(t.updatedAt); const openA = node.querySelector('.js-ticket-open'); openA.href = `/ticket.html?id=${encodeURIComponent(id)}`; node.querySelector('.js-desc').textContent = t.description; const mBlock = node.querySelector('.js-machine-block'); if (t.machine) { const m = t.machine; mBlock.innerHTML = `

Maschine: ${esc(m.seriennummer)}${mn ? ` · ${esc(mn)}` : ''}  ·  Typ: ${esc(m.typ)}

`; } else { mBlock.innerHTML = ''; } node.querySelector('.js-events').innerHTML = renderEventBoxes(events); const chev = btn.querySelector('.home-ticket-chevron'); btn.onclick = () => { const willShow = panel.hidden; panel.hidden = !willShow; btn.setAttribute('aria-expanded', String(willShow)); chev.textContent = willShow ? '▲' : '▼'; }; } async function run() { const tickets = await apiGet('/tickets?open=1'); const eventsLists = tickets.length === 0 ? [] : await Promise.all(tickets.map((t) => apiGet(`/tickets/${t.id}/events`))); const openCount = tickets.filter((t) => t.status === 'OPEN').length; const waitingCount = tickets.filter((t) => t.status === 'WAITING').length; document.getElementById('kpi-open').textContent = `${openCount} Offen`; document.getElementById('kpi-waiting').textContent = `${waitingCount} Wartend`; document.getElementById('kpi-total').textContent = `gesamt: ${tickets.length}`; listEl.innerHTML = ''; if (tickets.length === 0) { emptyEl.hidden = false; } else { emptyEl.hidden = true; tickets.forEach((t, i) => { const frag = tpl.content.cloneNode(true); const article = frag.querySelector('.home-ticket-card'); fillTicketCard(article, t, eventsLists[i] || []); listEl.appendChild(article); }); } } async function init() { const st = await guard({ activeNav: 'start' }); if (!st) return; loadingEl.hidden = true; mainEl.hidden = false; bindAttachmentPreview(document.body); try { await run(); } catch (e) { if (isAuthRedirectError(e)) return; showError(e.message || 'Fehler'); } } init();