Index: lams_central/web/css/components.css =================================================================== diff -u -r84204c571e0ab10c9006730dc413cebec8a66167 -rab9c4c312eb687a2b58efc563dc1b824087548e3 --- lams_central/web/css/components.css (.../components.css) (revision 84204c571e0ab10c9006730dc413cebec8a66167) +++ lams_central/web/css/components.css (.../components.css) (revision ab9c4c312eb687a2b58efc563dc1b824087548e3) @@ -273,10 +273,11 @@ align-items: flex-start; flex-direction: column; transition: all .3s ease; + transform: translateX(-7rem); } .component-sidebar.active { - transform: translateX(-7rem); + transform: translateX(0); } .component-sidebar .component-menu-btn a { Index: lams_monitoring/web/css/components-monitoring-responsive.css =================================================================== diff -u -r989f22a0c998fff45aabca43d753612f0d8e4358 -rab9c4c312eb687a2b58efc563dc1b824087548e3 --- lams_monitoring/web/css/components-monitoring-responsive.css (.../components-monitoring-responsive.css) (revision 989f22a0c998fff45aabca43d753612f0d8e4358) +++ lams_monitoring/web/css/components-monitoring-responsive.css (.../components-monitoring-responsive.css) (revision ab9c4c312eb687a2b58efc563dc1b824087548e3) @@ -3,7 +3,7 @@ } .hidden-xs { - display: block !important; + display: initial !important; } @media ( max-width : 1200px) { Index: lams_monitoring/web/css/components-monitoring.css =================================================================== diff -u -r84204c571e0ab10c9006730dc413cebec8a66167 -rab9c4c312eb687a2b58efc563dc1b824087548e3 --- lams_monitoring/web/css/components-monitoring.css (.../components-monitoring.css) (revision 84204c571e0ab10c9006730dc413cebec8a66167) +++ lams_monitoring/web/css/components-monitoring.css (.../components-monitoring.css) (revision ab9c4c312eb687a2b58efc563dc1b824087548e3) @@ -38,19 +38,69 @@ .monitoring-page-content { min-height: 100%; - padding: 2rem 4.8rem 2rem 11.8rem; + padding: 2rem 4.8rem 2rem 4.8rem; transition: all .3s ease; + vertical-align: top; + text-align: center; } .monitoring-page-content.active { - padding-left: 4.8rem; + padding-left: 11.8rem; } -.monitoring-page-content { - vertical-align: top; - text-align: center; +.component-sidebar { + align-items: center; } +.component-sidebar .lams-logo { + width: 3.6rem; +} + +.component-sidebar.active.expanded { + width: 30rem; +} + +.component-sidebar.active.expanded ~ .monitoring-page-content.active { + padding-left: 30.8rem; +} + +.component-sidebar .component-menu { + width: 100%; + display: flex; + justify-content: flex-start; +} + +.component-sidebar .component-menu-btn { + width: 3.6rem; + height: 100%; +} + +.component-sidebar #edit-lesson-btn { + margin-bottom: 1.5rem; +} + +.component-sidebar .lesson-properties { + width: 0; + height: 100%; + padding-left: 2rem; + overflow: hidden; + text-align: left; + transition: all .3s ease; +} + +.component-sidebar .lesson-properties.active { + width: 100%; +} + +.component-sidebar .lesson-properties #gradebookOnCompleteButton { + margin-top: 1rem; +} + +.component-sidebar .lesson-properties .btn { + display: block; + margin-top: .5rem; +} + .monitoring-page-content .monitoring-layout-element { display: inline-block; max-width: 80%; Index: lams_monitoring/web/includes/javascript/monitorLesson5.js =================================================================== diff -u -r84204c571e0ab10c9006730dc413cebec8a66167 -rab9c4c312eb687a2b58efc563dc1b824087548e3 --- lams_monitoring/web/includes/javascript/monitorLesson5.js (.../monitorLesson5.js) (revision 84204c571e0ab10c9006730dc413cebec8a66167) +++ lams_monitoring/web/includes/javascript/monitorLesson5.js (.../monitorLesson5.js) (revision ab9c4c312eb687a2b58efc563dc1b824087548e3) @@ -1,18 +1,19 @@ // ********** GLOBAL VARIABLES ********** // copy of lesson SVG so it does no need to be fetched every time -let originalSequenceCanvas = null, - // DIV container for lesson SVG - // it gets accessed so many times it's worth to cache it here +var originalSequenceCanvas = null, +// DIV container for lesson SVG +// it gets accessed so many times it's worth to cache it here sequenceCanvas = $('#sequenceCanvas'), - // switch between SVG original size and fit-to-sreen (enlarge/shrink) +// 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 +// which learner was selected in the search box sequenceSearchedLearner = null, - // for synchronisation purposes +// for synchronisation purposes sequenceRefreshInProgress = false, - //auto refresh all tabs every 30 seconds + +//auto refresh all tabs every 30 seconds autoRefreshInterval = 30 * 1000, autoRefreshIntervalObject = null, // when user is doing something, do not auto refresh @@ -25,26 +26,336 @@ // popup window size popupWidth = 1280, popupHeight = 720, - + gateOpenIconPath = 'images/svg/gateOpen.svg', gateOpenIconData = null; -function refreshMonitor(tabName, isAuto){ - if (autoRefreshIntervalObject && !isAuto) { - clearInterval(autoRefreshIntervalObject); - autoRefreshIntervalObject = null; + + +//********** LESSON TAB FUNCTIONS ********** + +/** + * Sets up lesson tab. + */ +function initLessonTab(){ + // sets presence availability. buttons may be temporarily disable by the tour. + $('#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(); + if (checked) { + $('#imButton').show(); + $('#imButton').prop('disabled', false); + alert(LABELS.LESSON_PRESENCE_ENABLE_ALERT); + } else { + $('#imButton').removeClass('btn-success').hide(); + alert(LABELS.LESSON_PRESENCE_DISABLE_ALERT); + } + } + }); + }); + + // sets instant messaging availability + $('#imButton').click(function(){ + 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', + type : 'POST', + cache : false, + data : data, + success : function() { + if (checked) { + $('#openImButton').show(); + $('#openImButton').prop('disabled', false); + alert(LABELS.LESSON_IM_ENABLE_ALERT); + } else { + $('#openImButton').hide(); + 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-strong').editable({ + type: 'text', + pk: lessonId, + url: LAMS_URL + 'monitoring/monitoring/renameLesson.do?' + $("#csrf-form", window.parent.document).serialize(), + validate: function(value) { + //close editing area on validation failure + if (!value.trim()) { + $('.editable-open').editableContainer('hide', 'cancel'); + return 'Can not be empty!'; + } + }, + //assume server response: 200 Ok {status: 'error', msg: 'field cannot be empty!'} + success: function(response, newValue) { + if(response.status == 'error') { + return response.msg; //msg will be shown in editable form + } + } + //hide and show pencil on showing and hiding editing widget + }).on('shown', function(e, editable) { + $(this).nextAll('i.fa-pencil').hide(); + }).on('hidden', function(e, reason) { + $(this).nextAll('i.fa-pencil').show(); + }); + */ + // sets up calendar for schedule date choice + $('#scheduleDatetimeField').datetimepicker({ + 'minDate' : 0 + }); + // sets up calendar for schedule date choice + $('#disableDatetimeField').datetimepicker({ + 'minDate' : 0 + }); + + // sets up dialog for editing class + var classDialog = showDialog('classDialog',{ + 'autoOpen' : false, + 'width' : 950, + 'title' : LABELS.LESSON_EDIT_CLASS, + 'resizable' : true, + 'open' : function(){ + autoRefreshBlocked = true; + }, + 'close' : function(){ + autoRefreshBlocked = false; + refreshMonitor(); + } + }, false); + + $('.modal-body', classDialog).empty().append($('#classDialogContents').show()); + + // search for users in the organisation with the term the Monitor entered + $('.dialogSearchPhrase', classDialog).autocomplete({ + 'source' : LAMS_URL + "monitoring/monitoring/autocomplete.do?scope=organisation&lessonID=" + lessonId, + 'delay' : 700, + 'select' : function(event, ui){ + var phraseField = $(this), + dialog = $('#classDialog'); + // learner's ID in ui.item.value is not used here + phraseField.val(ui.item.label); + // show the "clear search phrase" button + $('.dialogSearchPhraseClear', dialog).css('visibility', 'visible'); + // reset to page 1 + dialog.data('LearnerAjaxProperties').data.pageNumber = 1; + showClassDialog('Learner'); + return false; + } + }) + // run the real search when the Monitor presses Enter + .keypress(function(e){ + if (e.which == 13) { + var phraseField = $(this), + dialog = $('#classDialog'); + + phraseField.autocomplete("close"); + if (phraseField.val()) { + $('.dialogSearchPhraseClear', dialog).css('visibility', 'visible'); + } + // reset to page 1 + dialog.data('LearnerAjaxProperties').pageNumber = 1; + showClassDialog('Learner'); + } + }); + + var emailProgressDialog = showDialog('emailProgressDialog',{ + 'autoOpen' : false, + 'height' : 500, + 'width' : 510, + 'title' : LABELS.PROGRESS_EMAIL_TITLE, + 'resizable' : true, + 'open' : function(){ + autoRefreshBlocked = true; + }, + 'close' : function(){ + autoRefreshBlocked = false; + } + }, false); + $('.modal-body', emailProgressDialog).empty().append($('#emailProgressDialogContents').show()); + //initialize datetimepicker + $("#emaildatePicker").datetimepicker(); + + // sets gradebook on complete functionality + $('#gradebookOnCompleteButton').click(function(){ + var checked = $(this).toggleClass('btn-success').hasClass('btn-success'); + var data = { + 'gradebookOnComplete' : checked, + 'lessonID' : lessonId + }; + data[csrfTokenName] = csrfTokenValue; + $.ajax({ + url : LAMS_URL + 'monitoring/monitoring/gradebookOnComplete.do', + type : 'POST', + cache : false, + data : data, + success : function() { + if (checked) { + alert(LABELS.LESSON_ACTIVITY_SCORES_ENABLE_ALERT); + } else { + alert(LABELS.LESSON_ACTIVITY_SCORES_DISABLE_ALERT); + } + } + }); + }); + + +} + +/** + * Shows all learners in the lesson class. + */ +function showLessonLearnersDialog() { + var ajaxProperties = { + url : LAMS_URL + 'monitoring/monitoring/getLessonLearners.do', + data : { + 'lessonID' : lessonId + } + }; + + showLearnerGroupDialog(ajaxProperties, LABELS.LESSON_GROUP_DIALOG_CLASS, true, false, false, true); +} + +/** + * Lesson state field changed but the apply button not yet pressed + */ +function lessonStateFieldChanged() { + + //state chosen in the dropdown menu + var state = +$('#lessonStateField').val(); + switch (state) { + //'disable' is chosen + case 4: + $('#lessonScheduler').show(); + $('#lessonStartApply').hide(); + $('#lessonStateApply').hide(); + $("#scheduleDisableLessonButton").html(LABELS.SCHEDULE); + $("#scheduleDisableLessonButton").css('display', 'inline'); // must be inline or it will be wrong size + $("#disableLessonButton").show(); + $('#lessonDisableApply').show(); + break; + default: + $('#lessonDisableApply').hide(); + $('#lessonStateApply').show(); + break; } +} - if (!autoRefreshIntervalObject) { - autoRefreshIntervalObject = setInterval(function(){ - // refreshMonitor(null, true); - }, autoRefreshInterval); +/** + * Apply the lesson state change and update widgets. + */ +function changeLessonState(){ + var method = null; + + //state chosen in the dropdown menu + var state = +$('#lessonStateField').val(); + switch (state) { + + //'activate' is chosen + case 3: + switch (lessonStateId) { + case 4: //SUSPENDED + method = "unsuspendLesson"; + break; + case 6: //ARCHIVED + method = "unarchiveLesson"; + break; + } + break; + + + //'disable' is handled by scheduleDisableLesson, disableLesson + // case 4: + + //'archive' is chosen + case 6: + method = "archiveLesson"; + break; + + //'remove' is chosen + case 7: + if (confirm(LABELS.LESSON_REMOVE_ALERT)){ + if (confirm(LABELS.LESSON_REMOVE_DOUBLECHECK_ALERT)) { + method = "removeLesson"; + } + } + break; } - updateLessonTab(); - updateSequenceTab(); + if (method) { + applyStateChange(state, method) + } } +function scheduleDisableLesson() { + var date = $('#disableDatetimeField').val(); + if (date) { + if ( checkScheduleDate(lessonStartDate, date) ) { + applyStateChange(4, "suspendLesson", date); + } else { + alert(LABELS.LESSON_ERROR_START_END_DATE); + } + } else { + alert(LABELS.LESSON_ERROR_SCHEDULE_DATE); + } +} + +function disableLesson() { + applyStateChange(4, "suspendLesson"); +} + +function applyStateChange(state, method, newLessonEndDate) { + var params = { + 'lessonID' : lessonId + }; + params[csrfTokenName] = csrfTokenValue; + + if (newLessonEndDate) { + params.lessonEndDate = newLessonEndDate; + } + + $.ajax({ + url : LAMS_URL + 'monitoring/monitoring/' + method + ".do", + data: params, + type: "POST", + cache : false, + success: function() { + if (state == 7) { + // user chose to finish the lesson, close monitoring and refresh the lesson list + closeMonitorLessonDialog(true); + } else { + refreshMonitor('lesson'); + } + if ( state == 4 ) { + lessonEndDate = newLessonEndDate; + } + } + }); +} + /** * Updates widgets in lesson tab according to response sent to refreshMonitor() */ @@ -58,17 +369,258 @@ }, success : function(response) { + // update lesson state label + lessonStateId = +response.lessonStateID; + var label = null, + labelColour = 'warning'; + switch (lessonStateId) { + case 1: + label = LABELS.LESSON_STATE_CREATED; + labelColour = 'warning'; + break; + case 2: + label = LABELS.LESSON_STATE_SCHEDULED; + labelColour = 'warning'; + break; + case 3: + label = LABELS.LESSON_STATE_STARTED; + labelColour = 'success'; + break; + case 4: + label = LABELS.LESSON_STATE_SUSPENDED; + labelColour = 'danger'; + break; + case 5: + label = LABELS.LESSON_STATE_FINISHED; + labelColour = 'danger'; + break; + case 6: + label = LABELS.LESSON_STATE_ARCHIVED; + labelColour = 'danger'; + break; + case 7: + label = LABELS.LESSON_STATE_REMOVED; + labelColour = 'danger'; + break; + } + $('#lessonStateLabel').attr('class', 'label label-' + labelColour).html(label + ' '); + + // update available options in change state dropdown menu + var selectField = $('#lessonStateField'); + // remove all except "Select status" option + selectField.children('option:not([value="-1"])').remove(); + switch (lessonStateId) { + case 3: + if ( ! ( lessonEndDate && lessonEndDate > "") ) { + $('