Index: lams_monitoring/web/includes/javascript/monitorLesson.js =================================================================== diff -u -r4436ad48ebfcbce1f25ad39db54f55c32873afc1 -r10e621722cb5d82f5eda3241c614ee152e78d9ba --- lams_monitoring/web/includes/javascript/monitorLesson.js (.../monitorLesson.js) (revision 4436ad48ebfcbce1f25ad39db54f55c32873afc1) +++ lams_monitoring/web/includes/javascript/monitorLesson.js (.../monitorLesson.js) (revision 10e621722cb5d82f5eda3241c614ee152e78d9ba) @@ -1,20 +1,30 @@ -// ********** GLOBAL VARIABLES ********** +// ********** GLOBAL VARIABLES ********** // copy of lesson SVG so it does no need to be fetched every time var originalSequenceCanvas = null, // DIV container for lesson SVG // it gets accessed so many times it's worth to cache it here - sequenceCanvas = null, + sequenceCanvas = $('#sequenceCanvas'), // switch between SVG original size and fit-to-sreen (enlarge/shrink) learningDesignSvgFitScreen = false, // info box show timeout sequenceInfoTimeout = 8000, // which learner was selected in the search box sequenceSearchedLearner = null, +// container for learners' progress bars metadata + bars = null, +// placeholder for single learner's progress bar and title + learnerProgressCellsTemplate = null, // for synchronisation purposes + learnersRefreshInProgress = false, sequenceRefreshInProgress = false, +// total number of learners with ongoing progress + learnerPossibleNumber = 0, +// page in Learners tab + learnerProgressCurrentPageNumber = 1, + //auto refresh all tabs every 30 seconds - autoRefreshInterval = 99990 * 1000, + autoRefreshInterval = 30 * 1000, autoRefreshIntervalObject = null, // when user is doing something, do not auto refresh autoRefreshBlocked = false, @@ -28,110 +38,50 @@ popupHeight = 720, gateOpenIconPath = 'images/svg/gateOpen.svg', - gateOpenIconData = null, - - fileDownloadCheckTimer; + gateOpenIconData = null; -$(document).ready(function(){ - initCommonElements(); - initSequenceTab(); - initGradebookTab(); - loadTab('sequence'); -}); -function loadTab(tabName, button) { - $('.navigate-btn, .lesson-properties').removeClass('active'); - $('.component-sidebar').removeClass('expanded'); - if (button) { - $(button).addClass('active'); - } - - let tabContent = $('.monitoring-page-content .tab-content'); - - if (tabName == 'sequence') { - tabContent.load(LAMS_URL + 'monitoring/monitoring/displaySequenceTab.do', function(){ - refreshMonitor('sequence'); - canvasFitScreen(learningDesignSvgFitScreen, true); - }); - } else if (tabName == 'learners') { - tabContent.load(LAMS_URL + 'monitoring/monitoring/displayLearnersTab.do', function(){ - refreshMonitor('learners'); - }); - } else if (tabName == 'gradebook') { - tabContent.load(LAMS_URL + 'monitoring/monitoring/displayGradebookTab.do', function(){ - refreshMonitor('gradebook'); - }); - } -} -function initCommonElements(){ - /* - $('.hamburger').click(function(){ - $(this).toggleClass('active'); - $('.component-sidebar, .monitoring-page-content').toggleClass('active'); - }); - */ - - $('#edit-lesson-btn').click(function(){ - $('.lesson-properties').toggleClass('active'); - $('.component-sidebar').toggleClass('expanded'); - }); - $('#load-sequence-tab-btn').click(function(){ - loadTab('sequence', this); - }); - - $('#load-learners-tab-btn').click(function(){ - loadTab('learners', this); - }); - - $('#load-gradebook-tab-btn').click(function(){ - loadTab('gradebook', this); - }); - - - initLessonTab(); -} - //********** LESSON TAB FUNCTIONS ********** /** * Sets up lesson tab. */ function initLessonTab(){ // sets presence availability. buttons may be temporarily disable by the tour. - $('#presenceButton').change(function(){ - var checked = $(this).prop('checked'), - data = { - 'presenceAvailable' : checked, - 'lessonID' : lessonId - }; + $('#presenceButton').click(function(){ + var checked = $(this).toggleClass('btn-success').hasClass('btn-success'); + var data = { + 'presenceAvailable' : checked, + 'lessonID' : lessonId + }; data[csrfTokenName] = csrfTokenValue; $.ajax({ url : LAMS_URL + 'monitoring/monitoring/presenceAvailable.do', type : 'POST', cache : false, data : data, success : function() { - // updatePresenceAvailableCount(); + updatePresenceAvailableCount(); if (checked) { - $('#imButtonWrapper').show(); - showToast(LABELS.LESSON_PRESENCE_ENABLE_ALERT); + $('#imButton').show(); + $('#imButton').prop('disabled', false); + alert(LABELS.LESSON_PRESENCE_ENABLE_ALERT); } else { - $('#imButtonWrapper, #openImButton').hide(); - $('#imButton').prop('checked', false); - showToast(LABELS.LESSON_PRESENCE_DISABLE_ALERT); + $('#imButton').removeClass('btn-success').hide(); + alert(LABELS.LESSON_PRESENCE_DISABLE_ALERT); } } }); }); // sets instant messaging availability $('#imButton').click(function(){ - var checked = $(this).prop('checked'), - data = { - 'presenceImAvailable' : checked, - 'lessonID' : lessonId - }; + var checked = $(this).toggleClass('btn-success').hasClass('btn-success'); + var data = { + 'presenceImAvailable' : checked, + 'lessonID' : lessonId + }; data[csrfTokenName] = csrfTokenValue; $.ajax({ url : LAMS_URL + 'monitoring/monitoring/presenceImAvailable.do', @@ -142,24 +92,23 @@ if (checked) { $('#openImButton').show(); $('#openImButton').prop('disabled', false); - showToast(LABELS.LESSON_IM_ENABLE_ALERT); + alert(LABELS.LESSON_IM_ENABLE_ALERT); } else { $('#openImButton').hide(); - showToast(LABELS.LESSON_IM_DISABLE_ALERT); + alert(LABELS.LESSON_IM_DISABLE_ALERT); } } }); }); $('#openImButton').click(openChatWindow); - //turn to inline mode for x-editable.js $.fn.editable.defaults.mode = 'inline'; // do not cancel on clicking outside of box $.fn.editable.defaults.onblur = 'ignore'; //enable renaming of lesson title - $('#lesson-name').editable({ + $('#lesson-name-strong').editable({ type: 'text', pk: lessonId, url: LAMS_URL + 'monitoring/monitoring/renameLesson.do?' + $("#csrf-form", window.parent.document).serialize(), @@ -207,7 +156,7 @@ } }, false); - $('.modal-body', classDialog).empty().append($('#classDialogContents').show()).closest('.modal-dialog').addClass('modal-lg'); + $('.modal-body', classDialog).empty().append($('#classDialogContents').show()); // search for users in the organisation with the term the Monitor entered $('.dialogSearchPhrase', classDialog).autocomplete({ @@ -247,7 +196,7 @@ 'height' : 500, 'width' : 510, 'title' : LABELS.PROGRESS_EMAIL_TITLE, - 'resizable' : false, + 'resizable' : true, 'open' : function(){ autoRefreshBlocked = true; }, @@ -260,9 +209,9 @@ $("#emaildatePicker").datetimepicker(); // sets gradebook on complete functionality - $('#gradebookOnCompleteButton').change(function(){ - var checked = $(this).prop('checked'), - data = { + $('#gradebookOnCompleteButton').click(function(){ + var checked = $(this).toggleClass('btn-success').hasClass('btn-success'); + var data = { 'gradebookOnComplete' : checked, 'lessonID' : lessonId }; @@ -274,9 +223,9 @@ data : data, success : function() { if (checked) { - showToast(LABELS.LESSON_ACTIVITY_SCORES_ENABLE_ALERT); + alert(LABELS.LESSON_ACTIVITY_SCORES_ENABLE_ALERT); } else { - showToast(LABELS.LESSON_ACTIVITY_SCORES_DISABLE_ALERT); + alert(LABELS.LESSON_ACTIVITY_SCORES_DISABLE_ALERT); } } }); @@ -313,7 +262,7 @@ $('#lessonStartApply').hide(); $('#lessonStateApply').hide(); $("#scheduleDisableLessonButton").html(LABELS.SCHEDULE); - $("#scheduleDisableLessonButton").css('display', 'block'); // must be inline or it will be wrong size + $("#scheduleDisableLessonButton").css('display', 'inline'); // must be inline or it will be wrong size $("#disableLessonButton").show(); $('#lessonDisableApply').show(); break; @@ -463,7 +412,7 @@ labelColour = 'danger'; break; } - $('#lessonStateLabel').attr('class', 'badge bg-' + labelColour).html(label + ' '); + $('#lessonStateLabel').attr('class', 'label label-' + labelColour).html(label + ' '); // update available options in change state dropdown menu var selectField = $('#lessonStateField'); @@ -549,136 +498,11 @@ } }); - /* - drawChart('pie', 'chartDiv', - LAMS_URL + 'monitoring/monitoring/getLessonChartData.do?lessonID=' + lessonId, - true); - - updatePresenceAvailableCount(); - */ -} - -function drawLessonCompletionChart(){ - d3.json(LAMS_URL + 'monitoring/monitoring/getLessonChartData.do?lessonID=' + lessonId, - function(error, response){ - if (error) { - // forward error to browser - throw error; - } - - if (!response || $.isEmptyObject(response)) { - // if there is no data to display - return; - } - - let chartDiv = $('#completion-chart'), - lessonCompletionChart = chartDiv.data('chart'), - percent = [], - labels = [], - raw = []; - - $(response.data).each(function(){ - labels.push(this.name); - percent.push(this.value); - raw.push(this.raw); - }); - - if (lessonCompletionChart != null) { - // chart already exists, just update data - lessonCompletionChart.data.datasets[0].data = percent; - lessonCompletionChart.lessonCompletionChartRawData = raw; - lessonCompletionChart.update(); - return; - } + drawChart('pie', 'chartDiv', + LAMS_URL + 'monitoring/monitoring/getLessonChartData.do?lessonID=' + lessonId, + true); - let ctx = chartDiv[0].getContext('2d'); - lessonCompletionChart = new Chart(ctx, { - type : 'doughnut', - borderWidth : 0, - data : { - elements : { - arc : { - borderWidth : 0, - fontSize : 0, - } - }, - datasets : [ { - data : percent, - backgroundColor : [ 'rgba(255, 195, 55, 1)', - 'rgba(253, 60, 165, 1)', - 'rgba(5, 204, 214, 1)' - ], - borderWidth : 0 - } ], - labels : labels - }, - options : { - tooltips : { - enabled : true, - callbacks: { - label : function(tooltipItem, data) { - let index = tooltipItem.index, - - rawData = this._chart.lessonCompletionChartRawData, - percent = data.datasets[0].data, - - label = labels[index], - value = percent[index], - rawValue = rawData[index]; - - return label + ": " + rawValue + " (" + value + "%)"; - } - } - }, - legend : { - position: 'bottom', - align: 'start', - labels : { - generateLabels : function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - let meta = chart.getDatasetMeta(0), - style = meta.controller.getStyle(i), - value = data.datasets[0].data[i], - rawData = chart.lessonCompletionChartRawData || raw, - rawValue = rawData[i]; - - return { - text: label + ": " + rawValue + " (" + value + "%)", - fillStyle: style.backgroundColor, - strokeStyle: style.borderColor, - lineWidth: style.borderWidth, - hidden: isNaN(value) || meta.data[i].hidden, - - // Extra data used for toggling the - // correct item - index: i - }; - }); - } - return []; - } - } - }, - animation : { - animateScale : true, - animateRotate : true, - duration : 1000 - } - }, - plugins: [{ - beforeInit: function(chart) { - chart.legend.afterFit = function() { - this.height = this.height + 250; - }; - } - }] - }); - - lessonCompletionChart.lessonCompletionChartRawData = raw; - chartDiv.data('chart', lessonCompletionChart); - }); + updatePresenceAvailableCount(); } function checkScheduleDate(startDateString, endDateString) { @@ -784,9 +608,9 @@ }, false, true); } -/* + function updatePresenceAvailableCount(){ - var checked = $('#presenceButton').prop('checked'); + var checked = $('#presenceButton').hasClass('btn-success'), counter = $('#presenceCounter'); if (checked) { $.ajax({ @@ -804,20 +628,12 @@ counter.hide(); } } -*/ function updateContributeActivities(contributeActivities) { - let requiredTasksPanel = $('#required-tasks'), - requiredTasksContent = $('#required-tasks-content', requiredTasksPanel); - - if (!contributeActivities || contributeActivities.length === 0) { - requiredTasksPanel.remove(); - return; - } + $('.contributeRow').remove(); + var header = $('#contributeHeader'), + row = header; - $('.contribute-row', requiredTasksContent).remove(); - - /* // special case - add a Live Edit option. This does not directly map to an activity if ( lockedForEdit && lockedForEditUserId == userId) { // show Live Edit task only if currently editing myself, not if someone else is editing. @@ -830,63 +646,62 @@ cell = $('
').addClass('contributeEntryCell').html(entryContent); row = row.append(cell); } - */ - if (contributeActivities) { $.each(contributeActivities, function(){ - let contributeActivity = this; + var contributeId = 'contribute' + this.activityID, + contributeActivity = this, + cell = $('
').addClass('contributeActivityCell').text(this.title).attr('id', contributeId); + row = $('
').addClass('contributeRow').insertAfter(row).append(cell); - let row = $('
').addClass('row contribute-row' + (contributeActivity.title ? ' ml-1' : '')) - .appendTo(requiredTasksContent); - $.each(this.contributeEntries, function(){ - var entryContent = '
' + (contributeActivity.title ? '' + contributeActivity.title + '
(' : ''); + var entryContent = ''; switch (this.contributionType) { - case 3 : entryContent += LABELS.CONTRIBUTE_GATE; break; - case 6 : entryContent += LABELS.CONTRIBUTE_GROUPING; break; - case 7 : entryContent += LABELS.CONTRIBUTE_TOOL; break; - case 9 : entryContent += LABELS.CONTRIBUTE_BRANCHING; break; - case 11 : entryContent += LABELS.CONTRIBUTE_CONTENT_EDITED; break; - case 12 : entryContent += LABELS.CONTRIBUTE_GATE_PASSWORD; break; + case 3 : entryContent = LABELS.CONTRIBUTE_GATE; break; + case 6 : entryContent = LABELS.CONTRIBUTE_GROUPING; break; + case 7 : entryContent = LABELS.CONTRIBUTE_TOOL; break; + case 9 : entryContent = LABELS.CONTRIBUTE_BRANCHING; break; + case 11 : entryContent = LABELS.CONTRIBUTE_CONTENT_EDITED; break; + case 12 : entryContent = LABELS.CONTRIBUTE_GATE_PASSWORD; break; } - if (contributeActivity.title) { - entryContent += ')'; - } - entryContent += '
'; switch (this.contributionType) { case 3 : case 12 : if (this.isComplete) { - entryContent += '
'; } else { - entryContent += '
'; - + + LABELS.CONTRIBUTE_OPEN_GATE_BUTTON + '
'; } break; - default : entryContent += ''; + + '">' + LABELS.CONTRIBUTE_BUTTON + ''; } - row.html(entryContent + "
"); + cell = $('
').addClass('contributeEntryCell').html(entryContent); + row = row.append(cell); }); }); - - requiredTasksPanel.show(); + } + + if ($('.contributeRow').length == 0) { + $('#requiredTasks').hide(); } else { - requiredTasksPanel.hide(); + $('#requiredTasks').show(); } } @@ -974,16 +789,13 @@ return; // does not exist so add to list - var checkboxId = 'email-progress-date-' + dateObj.id, - checkbox = $('').attr({ - 'type' : 'checkbox', - 'id' : checkboxId - }).addClass('form-check-input me-1') - .change(function(){ - editEmailProgressDate($(this)); - }), + var checkbox = $('').attr({ + 'type' : 'checkbox' + }).change(function(){ + editEmailProgressDate($(this)); + }), - dateString = $('