/* globals _, Logger, Slick, tinyMCE, InstructorDashboard, PendingInstructorTasks, createTaskListTable */ (function() { 'use strict'; var IntervalManager, KeywordValidator, createEmailContentTable, createEmailMessageViews, findAndAssert, pWrapper, plantInterval, plantTimeout, sentToFormatter, setupCopyEmailButton, subjectFormatter, unknownIfNullFormatter, unknownP, anyOf = [].indexOf || function(item) { var i, l; for (i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) { return i; } } return -1; }; plantTimeout = function(ms, cb) { return setTimeout(cb, ms); }; plantInterval = function(ms, cb) { return setInterval(cb, ms); }; findAndAssert = function($root, selector) { var item, msg; item = $root.find(selector); if (item.length !== 1) { msg = 'Failed Element Selection'; throw msg; } else { return item; } }; this.statusAjaxError = function(handler) { return function(jqXHR, textStatus, errorThrown) { // eslint-disable-line no-unused-vars return handler.apply(this, arguments); }; }; this.createTaskListTable = function($tableTasks, tasksData) { var $tablePlaceholder, columns, options, tableData; $tableTasks.empty(); options = { enableCellNavigation: true, enableColumnReorder: false, autoHeight: true, rowHeight: 100, forceFitColumns: true }; columns = [ { id: 'task_type', field: 'task_type', /* Translators: a "Task" is a background process such as grading students or sending email */ name: gettext('Task Type'), minWidth: 102 }, { id: 'task_input', field: 'task_input', /* Translators: a "Task" is a background process such as grading students or sending email */ name: gettext('Task inputs'), minWidth: 150 }, { id: 'task_id', field: 'task_id', /* Translators: a "Task" is a background process such as grading students or sending email */ name: gettext('Task ID'), minWidth: 150 }, { id: 'requester', field: 'requester', /* Translators: a "Requester" is a username that requested a task such as sending email */ name: gettext('Requester'), minWidth: 80 }, { id: 'created', field: 'created', /* Translators: A timestamp of when a task (eg, sending email) was submitted appears after this */ name: gettext('Submitted'), minWidth: 120 }, { id: 'duration_sec', field: 'duration_sec', /* Translators: The length of a task (eg, sending email) in seconds appears this */ name: gettext('Duration (sec)'), minWidth: 80 }, { id: 'task_state', field: 'task_state', /* Translators: The state (eg, "In progress") of a task (eg, sending email) appears after this. */ name: gettext('State'), minWidth: 80 }, { id: 'status', field: 'status', /* Translators: a "Task" is a background process such as grading students or sending email */ name: gettext('Task Status'), minWidth: 80 }, { id: 'task_message', field: 'task_message', /* Translators: a "Task" is a background process such as grading students or sending email */ name: gettext('Task Progress'), minWidth: 120 } ]; tableData = tasksData; $tablePlaceholder = $('
', { class: 'slickgrid' }); $tableTasks.append($tablePlaceholder); return new Slick.Grid($tablePlaceholder, tableData, columns, options); }; subjectFormatter = function(row, cell, value) { var subjectText; if (value === null) { return gettext('An error occurred retrieving your email. Please try again later, and contact technical support if the problem persists.'); // eslint-disable-line max-len } subjectText = $('').text(value.subject).html(); return edx.HtmlUtils.joinHtml(edx.HtmlUtils.HTML( '

'), subjectText, edx.HtmlUtils.HTML('

') ); }; pWrapper = function(value) { return edx.HtmlUtils.joinHtml(edx.HtmlUtils.HTML('

'), value, edx.HtmlUtils.HTML('

')); }; unknownP = function() { return pWrapper(gettext('Unknown')); }; sentToFormatter = function(row, cell, value) { if (value === null) { return unknownP(); } else { return pWrapper(value.join(', ')); } }; unknownIfNullFormatter = function(row, cell, value) { if (value === null) { return unknownP(); } else { return pWrapper(value); } }; createEmailContentTable = function($tableEmails, $tableEmailsInner, emailData) { var $tablePlaceholder, columns, options, tableData; $tableEmailsInner.empty(); $tableEmails.show(); options = { enableCellNavigation: true, enableColumnReorder: false, autoHeight: true, rowHeight: 50, forceFitColumns: true }; columns = [ { id: 'email', field: 'email', name: gettext('Subject'), minWidth: 80, cssClass: 'email-content-cell', formatter: subjectFormatter }, { id: 'requester', field: 'requester', name: gettext('Sent By'), minWidth: 80, maxWidth: 100, cssClass: 'email-content-cell', formatter: unknownIfNullFormatter }, { id: 'sent_to', field: 'sent_to', name: gettext('Sent To'), minWidth: 80, maxWidth: 100, cssClass: 'email-content-cell', formatter: sentToFormatter }, { id: 'created', field: 'created', name: gettext('Time Sent'), minWidth: 80, cssClass: 'email-content-cell', formatter: unknownIfNullFormatter }, { id: 'number_sent', field: 'number_sent', name: gettext('Number Sent'), minwidth: 100, maxWidth: 150, cssClass: 'email-content-cell', formatter: unknownIfNullFormatter } ]; tableData = emailData; $tablePlaceholder = $('
', { class: 'slickgrid' }); $tableEmailsInner.append($tablePlaceholder); Slick.Grid($tablePlaceholder, tableData, columns, options); return $tableEmails.append($('
')); }; createEmailMessageViews = function($messagesWrapper, emails) { var $closeButton, $created, $emailContent, $emailContentHeader, $emailHeader, $emailWrapper, $message, $messageContent, $requester, $sentTo, $subject, emailId, emailInfo, interpolateHeader, i, len; $messagesWrapper.empty(); for (i = 0, len = emails.length; i < len; i++) { emailInfo = emails[i]; if (!emailInfo.email) { return; } emailId = emailInfo.email.id; $messageContent = $('
', { 'aria-hidden': 'true', class: 'modal email-modal', id: 'email_message_' + emailId }); $emailWrapper = $('
', { class: 'inner-wrapper email-content-wrapper' }); $emailHeader = $('
', { class: 'email-content-header' }); $emailHeader.append($('', { type: 'button', name: 'copy-email-body-text', value: gettext('Copy Email To Editor'), id: 'copy_email_' + emailId })); $closeButton = $('', { href: '#', class: 'close-modal' }); $closeButton.append($('', { class: 'icon fa fa-times' })); $emailHeader.append($closeButton); interpolateHeader = function(title, value) { return edx.HtmlUtils.setHtml($('

', { class: 'message-bold' }), edx.HtmlUtils.joinHtml(edx.HtmlUtils.HTML(''), title, edx.HtmlUtils.HTML(''), value)); }; $subject = interpolateHeader(gettext('Subject:'), emailInfo.email.subject); $requester = interpolateHeader(gettext('Sent By:'), emailInfo.requester); $created = interpolateHeader(gettext('Time Sent:'), emailInfo.created); $sentTo = interpolateHeader(gettext('Sent To:'), emailInfo.sent_to.join(', ')); $emailHeader.append($subject); $emailHeader.append($requester); $emailHeader.append($created); $emailHeader.append($sentTo); $emailWrapper.append($emailHeader); $emailWrapper.append($('
')); $emailContent = $('
', { class: 'email-content-message' }); $emailContentHeader = edx.HtmlUtils.setHtml($('

', { class: 'message-bold' }), edx.HtmlUtils.joinHtml(edx.HtmlUtils.HTML(''), gettext('Message:'), edx.HtmlUtils.HTML(''))); $emailContent.append($emailContentHeader); $message = edx.HtmlUtils.setHtml($('
'), edx.HtmlUtils.HTML(emailInfo.email.html_message)); $emailContent.append($message); $emailWrapper.append($emailContent); $messageContent.append($emailWrapper); $messagesWrapper.append($messageContent); $('#email_message_' + emailInfo.email.id + '_trig').leanModal({ closeButton: '.close-modal', copyEmailButton: '#copy_email_' + emailId }); setupCopyEmailButton(emailId, emailInfo.email.html_message, emailInfo.email.subject); } }; setupCopyEmailButton = function(emailId, htmlMessage, subject) { return $('#copy_email_' + emailId).click(function() { var editor; editor = tinyMCE.get('mce_0'); editor.setContent(htmlMessage); return $('#id_subject').val(subject); }); }; IntervalManager = (function() { function intervalManager(ms, fn) { this.ms = ms; this.fn = fn; this.intervalID = null; this.failedTries = 0; } intervalManager.prototype.start = function() { this.fn(); if (this.intervalID === null) { this.intervalID = setInterval(this.fn, this.ms); return this.intervalID; } return this.intervalID; }; intervalManager.prototype.stop = function() { clearInterval(this.intervalID); this.intervalID = null; return this.intervalID; }; intervalManager.prototype.failed_retry_threshold = 5; intervalManager.prototype.backOff = function() { this.failedTries++; if (this.failedTries >= this.failed_retry_threshold) { this.stop(); } }; return intervalManager; }()); this.PendingInstructorTasks = (function() { function PendingInstructorTasks($section) { var TASK_LIST_POLL_INTERVAL, ths = this; this.$section = $section; this.reload_running_tasks_list = function() { return PendingInstructorTasks.prototype.reload_running_tasks_list.apply( ths, arguments ); }; this.$running_tasks_section = findAndAssert(this.$section, '.running-tasks-section'); this.$table_running_tasks = findAndAssert(this.$section, '.running-tasks-table'); this.$no_tasks_message = findAndAssert(this.$section, '.no-pending-tasks-message'); if (this.$table_running_tasks.length) { TASK_LIST_POLL_INTERVAL = 20000; this.reload_running_tasks_list(); this.task_poller = new IntervalManager(TASK_LIST_POLL_INTERVAL, function() { return ths.reload_running_tasks_list(); }); } } PendingInstructorTasks.prototype.reload_running_tasks_list = function() { var listEndpoint, ths = this; listEndpoint = this.$table_running_tasks.data('endpoint'); return $.ajax({ type: 'POST', dataType: 'json', url: listEndpoint, success: function(data) { if (data.tasks.length) { createTaskListTable(ths.$table_running_tasks, data.tasks); ths.$no_tasks_message.hide(); return ths.$running_tasks_section.show(); } else { ths.$running_tasks_section.hide(); ths.$no_tasks_message.empty(); ths.$no_tasks_message.append($('

').text(gettext('No tasks currently running.'))); return ths.$no_tasks_message.show(); } }, error: function() { ths.task_poller.backOff(); } }); }; return PendingInstructorTasks; }()); KeywordValidator = (function() { function keywordValidator() {} keywordValidator.keyword_regex = /%%+[^%]+%%/g; keywordValidator.keywords = [ '%%USER_ID%%', '%%USER_FULLNAME%%', '%%COURSE_DISPLAY_NAME%%', '%%COURSE_END_DATE%%' ]; keywordValidator.validate_string = function(string) { var foundKeyword, foundKeywords, invalidKeywords, isValid, keywords, regexMatch, validation, i, len; regexMatch = string.match(KeywordValidator.keyword_regex); foundKeywords = regexMatch === null ? [] : regexMatch; invalidKeywords = []; isValid = true; keywords = KeywordValidator.keywords; validation = function(foundkeyword) { if (anyOf.call(keywords, foundkeyword) < 0) { return invalidKeywords.push(foundkeyword); } else { return invalidKeywords; } }; for (i = 0, len = foundKeywords.length; i < len; i++) { foundKeyword = foundKeywords[i]; validation(foundKeyword); } if (invalidKeywords.length !== 0) { isValid = false; } return { isValid: isValid, invalidKeywords: invalidKeywords }; }; return keywordValidator; }).call(this); this.ReportDownloads = (function() { /* Report Downloads -- links expire quickly, so we refresh every 5 mins */ function ReportDownloads($section) { var POLL_INTERVAL, reportdownloads = this; this.$section = $section; this.$report_downloads_table = this.$section.find('.report-downloads-table'); POLL_INTERVAL = 20000; this.downloads_poller = new InstructorDashboard.util.IntervalManager(POLL_INTERVAL, function() { return reportdownloads.reload_report_downloads(); }); } ReportDownloads.prototype.reload_report_downloads = function() { var endpoint, ths = this; endpoint = this.$report_downloads_table.data('endpoint'); return $.ajax({ type: 'POST', dataType: 'json', url: endpoint, success: function(data) { if (data.downloads.length) { return ths.create_report_downloads_table(data.downloads); } else { return false; } }, error: function() { ths.downloads_poller.backOff(); } }); }; ReportDownloads.prototype.create_report_downloads_table = function(reportDownloadsData) { var $tablePlaceholder, columns, grid, options; this.$report_downloads_table.empty(); options = { enableCellNavigation: true, enableColumnReorder: false, rowHeight: 30, forceFitColumns: true }; columns = [ { id: 'link', field: 'link', name: gettext('File Name'), toolTip: gettext('Links are generated on demand and expire within 5 minutes due to the sensitive nature of student information.'), // eslint-disable-line max-len sortable: false, minWidth: 150, cssClass: 'file-download-link', formatter: function(row, cell, value, columnDef, dataContext) { return edx.HtmlUtils.joinHtml(edx.HtmlUtils.HTML( ''), dataContext.name, edx.HtmlUtils.HTML('')); } } ]; $tablePlaceholder = $('

', { class: 'slickgrid' }); this.$report_downloads_table.append($tablePlaceholder); grid = new Slick.Grid($tablePlaceholder, reportDownloadsData, columns, options); grid.onClick.subscribe(function(event) { var reportUrl; reportUrl = event.target.href; if (reportUrl) { return Logger.log('edx.instructor.report.downloaded', { report_url: reportUrl }); } return Logger.log('edx.instructor.report.downloaded', { report_url: reportUrl }); }); return grid.autosizeColumns(); }; return ReportDownloads; }()); if (typeof _ !== 'undefined' && _ !== null) { _.defaults(window, { InstructorDashboard: {} }); window.InstructorDashboard.util = { plantTimeout: plantTimeout, plantInterval: plantInterval, statusAjaxError: this.statusAjaxError, IntervalManager: IntervalManager, createTaskListTable: createTaskListTable, createEmailContentTable: createEmailContentTable, createEmailMessageViews: createEmailMessageViews, PendingInstructorTasks: PendingInstructorTasks, KeywordValidator: KeywordValidator, ReportDownloads: this.ReportDownloads }; } }).call(this);