+
+
+
+ <%-- replacement for Page type admin --%>
+
+
+
+
+
+
+
+
+
-
-
-
- ${chartButtonCode}
- ${weightButtonCode}
-
-
-
-
-
- ${padlockCode}
-
-
+
+
-
-
-
- ${padlockCode}
-
+
+ ${chartButtonCode}
+ ${weightButtonCode}
+
+
+
+
+
+ ${padlockCode}
+
-
-
-
-
-
-
+
Index: lams_gradebook/web/includes/jsp/jqGridIncludes.jsp
===================================================================
diff -u -re2956cb8a072cc5ac9ceabaa9dac30c5750bf10b -r2e6fc7e8ac72d08478858a62c4f84b9818c8c633
--- lams_gradebook/web/includes/jsp/jqGridIncludes.jsp (.../jqGridIncludes.jsp) (revision e2956cb8a072cc5ac9ceabaa9dac30c5750bf10b)
+++ lams_gradebook/web/includes/jsp/jqGridIncludes.jsp (.../jqGridIncludes.jsp) (revision 2e6fc7e8ac72d08478858a62c4f84b9818c8c633)
@@ -7,9 +7,12 @@
--%>
-
-
-
+
+
+
+
+
+
Index: lams_monitoring/web/css/_monitorLesson_base.scss
===================================================================
diff -u -r510cf291f6867875d52184469518fd30b806ee1a -r2e6fc7e8ac72d08478858a62c4f84b9818c8c633
--- lams_monitoring/web/css/_monitorLesson_base.scss (.../_monitorLesson_base.scss) (revision 510cf291f6867875d52184469518fd30b806ee1a)
+++ lams_monitoring/web/css/_monitorLesson_base.scss (.../_monitorLesson_base.scss) (revision 2e6fc7e8ac72d08478858a62c4f84b9818c8c633)
@@ -32,7 +32,7 @@
box-shadow: none;
}
-#content .panel-monitor-page, #content .panel-monitor-body {
+#content .card-monitor-page, #content .card-monitor-body {
margin-bottom: 0;
padding-bottom: 0;
}
@@ -45,6 +45,9 @@
font-size: 16px;
margin-left: 10px;
}
+.modal-header {
+ border: none !important;
+}
.ui-front {
z-index: 1100;
@@ -134,6 +137,40 @@
bottom: 0px;
}
+.dialogContainer{
+ pointer-events: none;
+ position: absolute;
+ width: calc(100% + 5px);
+ height: calc(100vh + 5px);
+ top: 0;
+ left: 0;
+ -webkit-transform-origin: 0 0;
+ transform-origin: 0 0;
+}
+
+#tabLearnersTable {
+ display: inline-table;
+}
+
+.progressBarCell {
+ padding: 15px 0;
+}
+
+.btn-group-xs > .btn {
+ padding: .25rem .4rem;
+ font-size: .875rem;
+ line-height: .5;
+ border-radius: .2rem;
+}
+
+#changeState {
+ min-height: 40px;
+}
+
+.card div div.col-4 {
+ opacity: .3;
+}
+
/********** LESSON TAB STYLES **********/
div#tabLesson {
/* height: 540px;*/
@@ -189,7 +226,7 @@
margin-bottom: 5px;
}
-#lessonStateLabel, #lessonScheduler input {
+#lessonScheduler input {
font-size:13px; // Larger than buttons but smaller than the date text next to it.
}
@@ -434,12 +471,124 @@
border-top: none;
}
-/********** RENAME LESSON FEATURE **********/
+/********** SVG zoom **********/
-/* when item is editable - show pencil icon on hover */
-#lesson-name-strong:hover +span+ i { /* when link is hovered select i */
- visibility: visible;
+button#zoomOut, button#zoomIn {
+ opacity: 0.7;
}
-#lesson-name-strong +span+ i { /* in all other case hide it */
- visibility: hidden;
+
+/********** Monitor sidebar **********/
+
+$monitor-sidebar-width: 450px !default;
+$sidebar-transition-time: 0.3s !default;
+$sidebar-shadow-designated: -1px 0 8px rgba(0, 0, 0, 0.2);
+
+.monitor-sidebar {
+ width: $monitor-sidebar-width;
+ position: fixed;
+ right: -$monitor-sidebar-width;
+ top: 90px;
+ z-index: 100;
+ transition: right $sidebar-transition-time ease-in-out;
+
+ &.monitor-sidebar-opened {
+ right: 0;
+ }
+
+ dt {
+ font-size: 1.3rem;
+ font-weight: 500;
+ padding: 0;
+ margin: 1.75rem 0;
+ color: #48465b;
+ margin: 1.5rem 0px 1rem;
+ }
+
+ .monitor-sidebar-toggler {
+ width: 55px;
+ margin-left: -55px;
+ cursor: pointer;
+
+ i:first-of-type {
+ margin-left: .25rem;
+ }
+ }
+
+ .monitor-sidebar-spinner {
+ z-index: 200;
+ border-radius: 50% 0 0 50%;
+ padding: .8rem .5rem .8rem 1rem;
+ font-size: 1.75rem;
+ line-height: initial;
+ box-shadow: -1px 0 8px rgba(0,0,0,0.2);
+ opacity: 0.8;
+ }
+
+ .monitor-sidebar-content {
+ box-shadow: $sidebar-shadow-designated;
+ border-radius: 0;
+ position: relative;
+ margin-bottom: 40px;
+ padding: 20px 20px;
+ background: #fff;
+ border-radius: .25rem;
+ box-shadow: 4px 4px 30px 0px rgba(75,102,171,0.2);
+ }
+
+ .monitor-sidebar-content>header {
+ margin: -20px -20px;
+ padding: 20px 20px;
+}
+
+}
+
+/********** Place Custom Checkbox Icon to right of label Bootstrap 4 **********/
+div.custom-control-right {
+ padding-right: 24px;
+ padding-left: 0;
+ margin-left: 0;
+ margin-right: 0;
+ display: grid;
+ padding-right: 40px;
+}
+div.custom-control-right .custom-control-label::after{
+ right: -1.5rem;
+ left: auto;
+}
+div.custom-control-right .custom-control-label::before {
+ right: -2.35rem;
+ left: auto;
+}
+
+/********** OPEN ACTIVITY MONITOR MODAL TRANSITION **********/
+/*
+.modal.fade .modal-dialog {
+ -webkit-transform: scale(0.1);
+ -moz-transform: scale(0.1);
+ -ms-transform: scale(0.1);
+ transform: scale(0.1);
+ opacity: 0;
+ -webkit-transition: all 0.7s;
+ -moz-transition: all 0.7s;
+ transition: all 0.7s;
+}
+
+.modal.fade.show .modal-dialog {
+ -webkit-transform: scale(1);
+ -moz-transform: scale(1);
+ -ms-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+}
+*/
+
+/* The cover (expanding background) for activity monitor page */
+.activity-monitor-cover {
+ position: fixed;
+ background: #EB5160;
+ z-index: 100;
+ transform-origin: 50% 50%;
+}
+.activity-monitor-cover {
+ transition: transform 800ms ease-in-out;
}
\ No newline at end of file
Index: lams_monitoring/web/includes/javascript/monitorLesson.js
===================================================================
diff -u -ra65568cc36db07abf19550359c0db03a9561c964 -r2e6fc7e8ac72d08478858a62c4f84b9818c8c633
--- lams_monitoring/web/includes/javascript/monitorLesson.js (.../monitorLesson.js) (revision a65568cc36db07abf19550359c0db03a9561c964)
+++ lams_monitoring/web/includes/javascript/monitorLesson.js (.../monitorLesson.js) (revision 2e6fc7e8ac72d08478858a62c4f84b9818c8c633)
@@ -43,9 +43,43 @@
* Sets up lesson tab.
*/
function initLessonTab(){
+
+ $('.monitor-sidebar-toggler').click(() => {
+ $('.monitor-sidebar').toggleClass('monitor-sidebar-opened');
+ });
+
+ //set lesson name
+ $(".modal-title", window.parent.document).html($("#lesson-name"));
+ //turn to inline mode for x-editable.js
+ $.fn.editable.defaults.mode = 'inline';
+ //enable renaming of lesson title
+ $('#lesson-name-strong', window.parent.document).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 presence availability. buttons may be temporarily disable by the tour.
$('#presenceButton').click(function(){
- var checked = $(this).toggleClass('btn-success').hasClass('btn-success');
+ var checked = $(this).toggleClass('btn-secondary btn-light').hasClass('btn-secondary');
var data = {
'presenceAvailable' : checked,
'lessonID' : lessonId
@@ -63,7 +97,7 @@
$('#imButton').prop('disabled', false);
alert(LABELS.LESSON_PRESENCE_ENABLE_ALERT);
} else {
- $('#imButton').removeClass('btn-success').hide();
+ $('#imButton').removeClass('btn-secondary').hide();
alert(LABELS.LESSON_PRESENCE_DISABLE_ALERT);
}
}
@@ -72,7 +106,7 @@
// sets instant messaging availability
$('#imButton').click(function(){
- var checked = $(this).toggleClass('btn-success').hasClass('btn-success');
+ var checked = $(this).toggleClass('btn-secondary btn-light').hasClass('btn-secondary');
var data = {
'presenceImAvailable' : checked,
'lessonID' : lessonId
@@ -97,33 +131,6 @@
});
$('#openImButton').click(openChatWindow);
-
- //turn to inline mode for x-editable.js
- $.fn.editable.defaults.mode = 'inline';
- //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({
@@ -203,7 +210,7 @@
// sets gradebook on complete functionality
$('#gradebookOnCompleteButton').click(function(){
- var checked = $(this).toggleClass('btn-success').hasClass('btn-success');
+ var checked = $(this).is(':checked');
var data = {
'gradebookOnComplete' : checked,
'lessonID' : lessonId
@@ -386,7 +393,7 @@
break;
case 3:
label = LABELS.LESSON_STATE_STARTED;
- labelColour = 'success';
+ labelColour = 'light';
break;
case 4:
label = LABELS.LESSON_STATE_SUSPENDED;
@@ -405,7 +412,7 @@
labelColour = 'danger';
break;
}
- $('#lessonStateLabel').attr('class', 'label label-' + labelColour).html(label + ' ');
+ $('#lessonStateLabel').attr('class', 'badge badge-' + labelColour).html(label + ' ');
// update available options in change state dropdown menu
var selectField = $('#lessonStateField');
@@ -603,7 +610,7 @@
function updatePresenceAvailableCount(){
- var checked = $('#presenceButton').hasClass('btn-success'),
+ var checked = $('#presenceButton').hasClass('btn-secondary'),
counter = $('#presenceCounter');
if (checked) {
$.ajax({
@@ -1182,10 +1189,91 @@
if (activity.url) {
var activityGroup = $('g[id="' + activity.id + '"]');
activityGroup.css('cursor', 'pointer');
- dblTap(activityGroup, function(){
- // double click on activity shape to open Monitoring for this activity
- openPopUp(LAMS_URL + activity.url, "MonitorActivity", popupHeight, popupWidth, true, true);
+
+ // double click on activity shape to open Monitoring for this activity
+ dblTap(activityGroup, function(event){
+
+ //source from https://gist.github.com/CodeMyUI/60e668178a95a53cfb34eb9f4958f804
+ var cover = document.getElementById('activity-monitor-cover'),
+ windowWidth = window.innerWidth,
+ windowHeight = window.innerHeight;
+
+ // get the position of the clicked card
+ var cardPosition = event.currentTarget.getBoundingClientRect();
+ // get the style of the clicked card
+ var cardColor = event.currentTarget.firstChild.getAttribute("fill");
+
+ //setCoverPosition
+ // style the cover so it is in exactly the same position as the card
+ cover.style.left = cardPosition.left + 'px';
+ cover.style.top = cardPosition.top + 'px';
+ cover.style.width = cardPosition.width + 'px';
+ cover.style.height = cardPosition.height + 'px';
+
+ //setCoverColor
+ // style the cover to be the same color as the card
+ cover.style.backgroundColor = cardColor;
+
+ //scaleCoverToFillWindow
+ // calculate the scale and position for the card to fill the page,
+ var scaleX = windowWidth / cardPosition.width;
+ var scaleY = windowHeight / cardPosition.height;
+ var offsetX = (windowWidth / 2 - cardPosition.width / 2 - cardPosition.left) / scaleX;
+ var offsetY = (windowHeight / 2 - cardPosition.height / 2 - cardPosition.top) / scaleY;
+ // set the transform on the cover - it will animate because of the transition set on it in the CSS
+ cover.style.transform = 'scaleX('+scaleX+') scaleY('+scaleY+') translate3d('+(offsetX)+'px, '+(offsetY)+'px, 0px)';
+
+ setTimeout(function() {
+ $('#activity-monitor-dialog')
+ .on('show.bs.modal', function(event){
+ var url = LAMS_URL + activity.url;
+ // load contents after opening the dialog
+ $('iframe', this).attr({'src' : url, 'id' : 'activityMonitorModal'});
+
+ //$('#activity-monitor-cover').html();
+ })
+ .on('hide.bs.modal', function(event){
+ $('iframe', this).attr('src', null);
+ //setCoverPosition
+ // style the cover so it is in exactly the same position as the card
+ cover.style.left = cardPosition.left + 'px';
+ cover.style.top = cardPosition.top + 'px';
+ cover.style.width = cardPosition.width + 'px';
+ cover.style.height = cardPosition.height + 'px';
+
+ //scaleCoverToFillWindow
+ // calculate the scale and position for the card to fill the page,
+ var scaleX = windowWidth / cardPosition.width;
+ var scaleY = windowHeight / cardPosition.height;
+ var offsetX = (windowWidth / 2 - cardPosition.width / 2 - cardPosition.left) / scaleX;
+ var offsetY = (windowHeight / 2 - cardPosition.height / 2 - cardPosition.top) / scaleY;
+ // set the transform on the cover - it will animate because of the transition set on it in the CSS
+ cover.style.transform = 'scaleX('+scaleX+') scaleY('+scaleY+') translate3d('+(offsetX)+'px, '+(offsetY)+'px, 0px)';
+
+ // animate scale back to the card size and position
+ cover.style.transform = 'scaleX('+1+') scaleY('+1+') translate3d('+(0)+'px, '+(0)+'px, 0px)';
+ setTimeout(function() {
+ // style the cover to 0x0 so it is hidden
+ cover.style.width = '0px';
+ cover.style.height = '0px';
+ }, 801);
+ })
+ .modal();
+ }, 800);
+
+
});
+
+ //init onHover popover showing information about activity
+ activityGroup.popover({
+ trigger: 'hover',
+ content: "Number of learners: " + activity.learnerCount,
+ container: '#sequenceCanvas',
+ title: activity.title ? activity.title : "Activity",
+ delay: {
+ show: "500"
+ },
+ });
}
});
initializePortraitPopover(LAMS_URL, 'large', 'top');
@@ -1205,21 +1293,21 @@
if ( liveEditEnabled ) {
if ( lockedForEdit ) {
if ( userId == lockedForEditUserId ) {
- $("#liveEditButton").removeClass('btn-default');
+ $("#liveEditButton").removeClass('btn-light');
$("#liveEditButton").addClass('btn-primary');
$("#liveEditButton").show();
$("#liveEditWarning").hide();
$("#liveEditWarning").text("");
} else {
$("#liveEditButton").removeClass('btn-primary');
- $("#liveEditButton").addClass('btn-default');
+ $("#liveEditButton").addClass('btn-light');
$("#liveEditButton").hide();
$("#liveEditWarning").text(LABELS.LIVE_EDIT_WARNING.replace("%0",lockedForEditUsername));
$("#liveEditWarning").show();
}
} else {
$("#liveEditButton").removeClass('btn-primary');
- $("#liveEditButton").addClass('btn-default');
+ $("#liveEditButton").addClass('btn-light');
$("#liveEditButton").show();
$("#liveEditWarning").hide();
$("#liveEditWarning").text("");
@@ -1243,8 +1331,39 @@
},
success : function(response) {
originalSequenceCanvas = response;
- sequenceCanvas = $('#sequenceCanvas').removeAttr('style')
- .html(originalSequenceCanvas);
+ sequenceCanvas = $('#sequenceCanvas').removeAttr('style').html(originalSequenceCanvas);
+
+ const svg = d3.select('#sequenceCanvas');
+ //g = d3.create("g");//svg.append('g');
+ //g.append(() => svg.node()) ;
+ //d3.select('#sequenceCanvas').append(g);
+ //svg.append('g');
+ //d3.create("svg")
+ //.attr("viewBox", [0, 0, width, height])
+ //.on("click", reset);
+ const zoom = d3.zoom().scaleExtent([1, 3]).on("zoom", function () {
+ svg.selectAll("g,image[id$='attention'],image[id$='learnerGroup'],image.ui-draggable.ui-draggable-handle,text[id$='learnerGroupText']").attr("transform", d3.event.transform);
+ });
+
+ svg.call(zoom);
+ //disable double click zoom
+ //TODO check as it seamingly can cause problems with touch devices https://stackoverflow.com/questions/29128426/d3-behavior-zoom-disable-double-tap
+ svg.on("dblclick.zoom", null);
+
+ function reset() {
+ svg.transition().duration(750).call(
+ zoom.transform,
+ d3.zoomIdentity,
+ d3.zoomTransform(svg.node()).invert([width / 2, height / 2])
+ );
+ }
+
+ $("#zoomIn").on("click", function() {
+ zoom.scaleBy(svg.transition().duration(750), 2);
+ });
+ $("#zoomOut").on("click", function() {
+ svg.transition().call(zoom.scaleBy, 0.5);
+ });
},
error : function(error) {
exit = true;
@@ -1597,7 +1716,7 @@
$('*[id^="act' + activity.id + 'attention"]', sequenceCanvas).click(function(event){
event.stopPropagation();
// switch to first tab where attention prompts are listed
- doSelectTab(1);
+ //doSelectTab(1);
});
}
}
@@ -1949,7 +2068,7 @@
*/
function resizeSequenceCanvas(width, height){
// can the calculation it be done nicer?
- var canvasHeight = height - $('.navbar').height() - $('#sequenceTopButtonsContainer').height()
+ var canvasHeight = height - $('#sequenceTopButtonsContainer').height()
- Math.min(20, $('#completedLearnersContainer').height()),
canvasWidth = width,
svg = $('svg', sequenceCanvas),
@@ -1958,9 +2077,9 @@
canvasPaddingLeft = Math.max(0, canvasWidth/2 - svg.attr('width')/2 - 40);
sequenceCanvas.css({
- 'padding-top' : canvasPaddingTop + 'px',
+ //'padding-top' : canvasPaddingTop + 'px',
'padding-left' : canvasPaddingLeft + 'px',
- 'height' : canvasHeight - 70 + 'px'
+ //'height' : canvasHeight - 70 + 'px'
});
}
@@ -2097,9 +2216,9 @@
';11;';
learnerProgressCellsTemplate +=
- ' '
+ ' '
+ LABELS.EMAIL_BUTTON
- + ' ';
+ + '';
}
// remove existing progress bars
@@ -2220,9 +2339,12 @@
*/
function updateGradebookTab() {
$("#gradebookLoading").show();
- $("#gradebookDiv").load(LAMS_URL + 'gradebook/gradebookMonitoring.do?isInTabs=true&lessonID=' + lessonId, function() {
- $("#gradebookLoading").hide();
- });
+ $("#gradebookDiv").load(
+ LAMS_URL + 'gradebook/gradebookMonitoring.do?isInTabs=true&lessonID=' + lessonId,
+ function() {
+ $("#gradebookLoading").hide();
+ }
+ );
}
//********** COMMON FUNCTIONS **********
@@ -2231,6 +2353,7 @@
* Updates all changeable elements of monitoring screen.
*/
function refreshMonitor(tabName, isAuto){
+ if (isAuto) return;
if (autoRefreshIntervalObject && !isAuto) {
clearInterval(autoRefreshIntervalObject);
autoRefreshIntervalObject = null;
Index: lams_monitoring/web/monitor.jsp
===================================================================
diff -u -rdbcb0f360525c386a55e74c6c876f031edb923f9 -r2e6fc7e8ac72d08478858a62c4f84b9818c8c633
--- lams_monitoring/web/monitor.jsp (.../monitor.jsp) (revision dbcb0f360525c386a55e74c6c876f031edb923f9)
+++ lams_monitoring/web/monitor.jsp (.../monitor.jsp) (revision 2e6fc7e8ac72d08478858a62c4f84b9818c8c633)
@@ -212,6 +212,7 @@
+
@@ -222,7 +223,7 @@
$(document).bind("mobileinit", function(){
$.mobile.loadingMessage = false;
$.mobile.ignoreContentEnabled = true;
- $('body').attr('data-enhance', 'false');
+ $('body').attr('data-enhance', 'false');
});
$(document).ready(function(){
@@ -231,6 +232,7 @@
initLearnersTab();
initGradebookTab();
refreshMonitor();
+
$('#description').readmore({
speed: 500,
@@ -240,42 +242,18 @@
// remove "loading..." screen
$('#loadingOverlay').remove();
- });
-
- function doSelectTab(tabId) {
- if ( tourInProgress ) {
- alert(LABELS.TOUR_DISABLED_ELEMENT);
- return;
- }
- actualDoSelectTab(tabId);
- }
- function actualDoSelectTab(tabId) {
- selectTab(tabId);
+ //show info dialog
var sequenceInfoDialog = $('#sequenceInfoDialog');
- if ( tabId == '2' ) {
- if (sequenceTabShowInfo) {
- sequenceInfoDialog.modal("show");
- sequenceTabShowInfo = false; // only show it once
- }
-
- } else {
- sequenceInfoDialog.modal("hide");
+ if (sequenceTabShowInfo) {
+ sequenceInfoDialog.modal("show");
+ sequenceTabShowInfo = false; // only show it once
}
-
- if ( tabId == '4' ) {
- updateGradebookTab();
- }
- }
- function switchToTblMonitor() {
- $("#content").load(
- LAMS_URL + 'monitoring/tblmonitor/start.do',
- {
- lessonID: ${lesson.lessonID}
- }
- );
- }
+ $('#gradebook-collapse').on('show.bs.collapse', function () {
+ updateGradebookTab();
+ })
+ });
<%@ include file="monitorTour.jsp" %>
@@ -288,240 +266,78 @@
-
-
-
- "
- onclick="javascript:switchToTblMonitor();" id="tbl-monitor-control">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-


