// Page script for jobDetail.html. Shared bootstrapping lives in js/app.js; // this file just fetches the requested job and renders the detail view. var urlParams = new URLSearchParams(window.location.search); var jobId = urlParams.get('jobId'); CollabCentral.init(function (ctx) { loadJobDetail(ctx.appName); }); function loadJobDetail(appName) { if (!jobId) { document.getElementById('notFoundPanel').classList.remove('hidden'); return; } fetch('/CollabCentral/' + appName + '/jobs/detail/' + encodeURIComponent(jobId)) .then(function (res) { if (res.status === 404) { document.getElementById('notFoundPanel').classList.remove('hidden'); return null; } if (!res.ok) throw new Error('HTTP ' + res.status); return res.json(); }) .then(function (job) { if (!job) return; renderJob(job); document.getElementById('detailPanel').classList.remove('hidden'); }) .catch(function (err) { console.error('Failed to load job detail:', err); document.getElementById('notFoundPanel').classList.remove('hidden'); }); } function renderJob(job) { document.getElementById('jobTitle').textContent = 'Job #' + (job.jobId || '?'); var subtitle = 'Sent by ' + (job.senderDisplayName || 'unknown'); if (job.startTime) subtitle += ' ยท started ' + CollabCentral.formatDate(job.startTime); document.getElementById('subtitle').textContent = subtitle; var stats = job.stats || {}; var rows = [ ['Job ID', job.jobId], ['Submitted by', job.senderDisplayName], ['Scheduled for', job.scheduledFor ? CollabCentral.formatDate(job.scheduledFor) : 'Sent immediately'], ['Started', CollabCentral.formatDate(job.startTime)], ['Completed', job.endTime ? CollabCentral.formatDate(job.endTime) : 'In progress'], ['Total duration', stats.totalTime], ['Webex time', stats.webexTime], ['Average per message', stats.averageTime], ['Recipients', (job.memberList || []).length], ['Delivered', formatSuccess(stats)], ]; var dl = document.getElementById('summaryGrid'); dl.innerHTML = ''; for (var i = 0; i < rows.length; i++) { var key = rows[i][0], val = rows[i][1]; if (val === undefined || val === null || val === '') continue; var dt = document.createElement('dt'); dt.textContent = key; var dd = document.createElement('dd'); dd.textContent = val; dl.appendChild(dt); dl.appendChild(dd); } // Message preview: prefer HTML, fall back to markdown/text. var preview = document.getElementById('messagePreview'); var msg = (job.message && job.message.english) || job.message || {}; if (msg.html) { preview.innerHTML = msg.html; } else if (msg.markdown) { preview.textContent = msg.markdown; } else if (msg.text) { preview.textContent = msg.text; } else if (typeof msg.raw === 'string') { preview.textContent = msg.raw; } else { preview.innerHTML = 'No message content available.'; } var members = job.memberList || []; document.getElementById('recipientCount').textContent = members.length; $('#recipients').dataTable({ data: members.map(formatRecipientRow), columns: [ { data: 'displayName' }, { data: 'email' }, { data: 'status' }, { data: 'time' }, { data: 'error' }, ], pageLength: 50, lengthMenu: [25, 50, 100, 250], order: [[2, 'asc']], searching: true, info: true, paging: true, }); } function formatRecipientRow(m) { var result = m.results || null; var status; var email = 'โ€”'; var err = ''; if (!result) { status = 'Pending'; } else if (result.id && !result.message && !result.errors) { status = 'Delivered'; email = result.toPersonEmail || email; } else { status = 'Failed'; email = result.toPersonEmail || email; if (result.message) err = result.message; else if (result.errors && result.errors.length) { err = result.errors.map(function (e) { return e.description || e.code || JSON.stringify(e); }).join('; '); } } return { displayName: m.displayName || 'โ€”', email: email, status: status, time: m.msgTime ? (m.msgTime / 1000).toFixed(2) + ' s' : 'โ€”', error: err, }; } function formatSuccess(stats) { if (!stats || stats.succeededMsgs === undefined) return null; var pct = (typeof stats.succeededMsgPct === 'number') ? stats.succeededMsgPct.toFixed(1) : stats.succeededMsgPct; return stats.succeededMsgs + ' / ' + stats.totalMsgs + ' (' + pct + '%)'; }