// Page script for monitorJobs.html. Shared bootstrapping lives in js/app.js; // this file just wires the three DataTables (running, scheduled, completed) // once the user is confirmed authorized. CollabCentral.init(function (ctx) { document.getElementById('jobsPanel').classList.remove('hidden'); initJobTables(ctx.appName); }); function jobDetailLink(appName, jobId, label) { if (jobId === undefined || jobId === null) return CollabCentral.escapeHtml(label); return '' + CollabCentral.escapeHtml(label) + ''; } function renderDate(val) { return val ? CollabCentral.escapeHtml(CollabCentral.formatDate(val)) : ''; } function renderSuccessRate(pct) { if (pct === undefined || pct === null || pct === '') return ''; var n = typeof pct === 'number' ? pct : parseFloat(pct); if (isNaN(n)) return CollabCentral.escapeHtml(pct); return n.toFixed(1) + '%'; } function renderDelivered(row) { var s = row.stats || {}; if (s.succeededMsgs === undefined || s.totalMsgs === undefined) return ''; return s.succeededMsgs + ' / ' + s.totalMsgs; } function initJobTables(appName) { $('#runningJobs').dataTable({ ajax: { url: '/CollabCentral/' + appName + '/jobs/list/running', dataSrc: '', }, columns: [ { data: 'senderDisplayName' }, { data: 'appName' }, { data: 'startTime', render: function (v) { return renderDate(v); } }, { data: 'totalRecipients' }, { data: 'completedRecipients', render: function (val, type, row) { if (type !== 'display' || row.jobId === undefined || row.jobId === null) return val; var text = (val === undefined || val === null) ? 'view' : val + ' · view'; return jobDetailLink(appName, row.jobId, text); }, }, ], searching: false, info: false, ordering: false, paging: false, language: { emptyTable: 'No running jobs.' }, }); $('#scheduledJobs').dataTable({ ajax: { url: '/CollabCentral/' + appName + '/jobs/list/scheduled', dataSrc: '', }, columns: [ { data: 'senderDisplayName' }, { data: 'appName' }, { data: 'message', render: function (val, type, row) { if (type !== 'display') return ''; // Message is stored per-language; prefer english.html or english.markdown. var m = (val && (val.english || val)) || {}; var html = m.html || m.markdown || m.text || ''; // Truncate to keep the row compact var text = html.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim(); if (text.length > 120) text = text.slice(0, 117) + '…'; return CollabCentral.escapeHtml(text); }, }, { data: 'totalRecipients' }, { data: 'scheduledFor', render: function (v) { return renderDate(v); } }, ], searching: false, info: false, ordering: false, paging: false, language: { emptyTable: 'No scheduled jobs.' }, }); $('#completedJobs').dataTable({ ajax: { url: '/CollabCentral/' + appName + '/jobs/list/completed', dataSrc: '', }, columns: [ { data: 'jobId', render: function (jobId, type) { if (type !== 'display') return jobId; return jobDetailLink(appName, jobId, '#' + jobId); }, }, { data: 'senderDisplayName' }, { data: 'appName' }, { data: 'startTime', render: function (v) { return renderDate(v); } }, { data: 'endTime', render: function (v) { return renderDate(v); } }, { data: 'stats.totalTime' }, { data: null, render: function (row, type) { if (type !== 'display') return ''; return renderDelivered(row); }, }, { data: 'stats.succeededMsgPct', render: function (v) { return renderSuccessRate(v); } }, ], order: [[3, 'desc']], pageLength: 25, lengthMenu: [10, 25, 50, 100], searching: true, info: true, paging: true, language: { emptyTable: 'No completed jobs in the last 30 days.' }, }); }