// 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 + '%)';
}