/** * Team workload dashboard — fetches and renders team metrics. */ const container = document.querySelector('.app-details-container[data-team-workload-url]'); if (container) { const dataUrl = container.dataset.teamWorkloadUrl; const labelNotAssigned = container.dataset.labelNotAssigned || '—'; const elLoading = document.getElementById('team-loading'); const elError = document.getElementById('team-error'); const elEmpty = document.getElementById('team-empty'); const elContent = document.getElementById('team-content'); const elBody = document.getElementById('team-table-body'); const elRefresh = container.querySelector('button[name="team-refresh"]'); const periodButtons = container.querySelectorAll('.helpdesk-team-period-button'); let currentPeriod = 90; function showState(state) { if (elLoading) elLoading.hidden = state !== 'loading'; if (elError) elError.hidden = state !== 'error'; if (elEmpty) elEmpty.hidden = state !== 'empty'; if (elContent) elContent.hidden = state !== 'success'; if (elLoading) elLoading.setAttribute('aria-busy', state === 'loading' ? 'true' : 'false'); } function setText(id, value) { const el = document.getElementById(id); if (el) el.textContent = value; } function renderKpis(kpis) { setText('team-kpi-open', kpis.open_tickets ?? 0); setText('team-kpi-unassigned', kpis.unassigned ?? 0); setText('team-kpi-avg-age', kpis.avg_age_hours ?? 0); setText('team-kpi-resolved', kpis.resolved_in_period ?? 0); } function createCell(text) { const td = document.createElement('td'); td.textContent = text; return td; } function renderTable(members) { if (!elBody) return; elBody.replaceChildren(); for (const m of members) { const tr = document.createElement('tr'); const isUnassigned = m.support_user === ''; const name = isUnassigned ? labelNotAssigned : m.display_name; const nameCell = document.createElement('td'); nameCell.textContent = name; tr.appendChild(nameCell); tr.appendChild(createCell(String(m.open_tickets))); tr.appendChild(createCell(String(m.critical_tickets))); tr.appendChild(createCell(String(m.avg_age_hours))); tr.appendChild(createCell(String(m.resolved_in_period))); if (isUnassigned) { tr.classList.add('helpdesk-team-row-unassigned'); } elBody.appendChild(tr); } } async function fetchData(refresh = false) { showState('loading'); const params = new URLSearchParams({ periodDays: String(currentPeriod) }); if (refresh) params.set('refresh', '1'); try { const res = await fetch(dataUrl + '?' + params.toString(), { credentials: 'same-origin' }); const json = await res.json(); if (!json.ok) { showState('error'); return; } if (!json.members || json.members.length === 0) { showState('empty'); return; } renderKpis(json.kpis); renderTable(json.members); showState('success'); } catch { showState('error'); } } for (const button of periodButtons) { button.addEventListener('click', () => { const period = parseInt(button.dataset.period, 10); if (period === currentPeriod) return; currentPeriod = period; for (const b of periodButtons) { b.classList.toggle('active', b === button); b.setAttribute('aria-pressed', b === button ? 'true' : 'false'); } fetchData(); }); } if (elRefresh) { elRefresh.addEventListener('click', () => fetchData(true)); } fetchData(); }