Index: lams_admin/src/java/org/lamsfoundation/lams/admin/service/ImportService.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_admin/src/java/org/lamsfoundation/lams/admin/service/ImportService.java (.../ImportService.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_admin/src/java/org/lamsfoundation/lams/admin/service/ImportService.java (.../ImportService.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -707,7 +707,7 @@ String timeZoneColumn = parseStringCell(row.getCell(ImportService.TIME_ZONE)); user.setTimeZone( - TimeZoneUtil.isTimezoneValid(timeZoneColumn) ? timeZoneColumn : TimeZoneUtil.getServerTimezone()); + TimeZoneUtil.isTimeZoneValid(timeZoneColumn) ? timeZoneColumn : TimeZoneUtil.getServerTimeZone()); service.updatePassword(user, password); Index: lams_central/src/java/org/lamsfoundation/lams/web/ProfileController.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_central/src/java/org/lamsfoundation/lams/web/ProfileController.java (.../ProfileController.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_central/src/java/org/lamsfoundation/lams/web/ProfileController.java (.../ProfileController.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -34,6 +34,7 @@ import org.lamsfoundation.lams.policies.service.IPolicyService; import org.lamsfoundation.lams.themes.Theme; import org.lamsfoundation.lams.themes.service.IThemeService; +import org.lamsfoundation.lams.timezone.TimeZoneUtil; import org.lamsfoundation.lams.usermanagement.Organisation; import org.lamsfoundation.lams.usermanagement.OrganisationType; import org.lamsfoundation.lams.usermanagement.SupportedLocale; @@ -57,6 +58,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -255,7 +257,7 @@ } userForm.setUserTheme(userSelectedTheme); - request.setAttribute("timezones", TimeZone.getAvailableIDs()); + request.setAttribute("timezones", TimeZoneUtil.getTimeZones()); return "profile/editprofile"; } Index: lams_learning/web/grouping/choose.jsp =================================================================== diff -u -reae47fcf3922751f0b47340e524e28197830e239 -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_learning/web/grouping/choose.jsp (.../choose.jsp) (revision eae47fcf3922751f0b47340e524e28197830e239) +++ lams_learning/web/grouping/choose.jsp (.../choose.jsp) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -111,7 +111,7 @@
-    +  
Index: lams_learning/web/grouping/show.jsp =================================================================== diff -u -r21aea119939539ce08a947354f84cb7dc6980d38 -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_learning/web/grouping/show.jsp (.../show.jsp) (revision 21aea119939539ce08a947354f84cb7dc6980d38) +++ lams_learning/web/grouping/show.jsp (.../show.jsp) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -75,7 +75,7 @@
  -   +
@@ -103,4 +103,4 @@ - + \ No newline at end of file Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -358,10 +358,9 @@ @Override public Lesson initializeLesson(String lessonName, String lessonDescription, long learningDesignId, Integer organisationId, Integer userID, String customCSV, Boolean enableLessonIntro, - Boolean displayDesignImage, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, - Boolean liveEditEnabled, Boolean enableLessonNotifications, Boolean forceLearnerRestart, - Boolean allowLearnerRestart, Boolean gradebookOnComplete, Integer scheduledNumberDaysToLessonFinish, - Long precedingLessonId) { + Boolean displayDesignImage, Boolean liveEditEnabled, Boolean enableLessonNotifications, + Boolean forceLearnerRestart, Boolean allowLearnerRestart, Boolean gradebookOnComplete, + Integer scheduledNumberDaysToLessonFinish, Long precedingLessonId) { securityService.ensureGroupMonitor(organisationId, userID, "intializeLesson"); @@ -390,9 +389,8 @@ User user = userID != null ? (User) baseDAO.find(User.class, userID) : null; Lesson initializedLesson = initializeLesson(lessonName, lessonDescription, originalLearningDesign, user, runSeqFolder, LearningDesign.COPY_TYPE_LESSON, customCSV, enableLessonIntro, displayDesignImage, - learnerPresenceAvailable, learnerImAvailable, liveEditEnabled, enableLessonNotifications, - forceLearnerRestart, allowLearnerRestart, gradebookOnComplete, scheduledNumberDaysToLessonFinish, - precedingLesson); + liveEditEnabled, enableLessonNotifications, forceLearnerRestart, allowLearnerRestart, + gradebookOnComplete, scheduledNumberDaysToLessonFinish, precedingLesson); logLessonStateChange(LogEvent.TYPE_TEACHER_LESSON_CREATE, initializedLesson, userID, null, initializedLesson.getLessonStateId()); @@ -401,8 +399,7 @@ @Override public Lesson initializeLessonForPreview(String lessonName, String lessonDescription, long learningDesignId, - Integer userID, String customCSV, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, - Boolean liveEditEnabled) { + Integer userID, String customCSV, Boolean liveEditEnabled) { LearningDesign originalLearningDesign = learningDesignDAO.getLearningDesignById(new Long(learningDesignId)); if (originalLearningDesign == null) { throw new MonitoringServiceException( @@ -411,14 +408,13 @@ User user = userID != null ? (User) baseDAO.find(User.class, userID) : null; return initializeLesson(lessonName, lessonDescription, originalLearningDesign, user, null, - LearningDesign.COPY_TYPE_PREVIEW, customCSV, false, false, learnerPresenceAvailable, learnerImAvailable, - liveEditEnabled, true, false, false, false, null, null); + LearningDesign.COPY_TYPE_PREVIEW, customCSV, false, false, liveEditEnabled, true, false, false, false, + null, null); } @Override public Lesson initializeLessonWithoutLDcopy(String lessonName, String lessonDescription, long learningDesignID, - User user, String customCSV, Boolean enableLessonIntro, Boolean displayDesignImage, - Boolean learnerPresenceAvailable, Boolean learnerImAvailable, Boolean liveEditEnabled, + User user, String customCSV, Boolean enableLessonIntro, Boolean displayDesignImage, Boolean liveEditEnabled, Boolean enableLessonNotifications, Boolean forceLearnerRestart, Boolean allowLearnerRestart, Boolean gradebookOnComplete, Integer scheduledNumberDaysToLessonFinish, Lesson precedingLesson) { LearningDesign learningDesign = learningDesignDAO.getLearningDesignById(learningDesignID); @@ -427,9 +423,8 @@ "Learning design for id=" + learningDesignID + " is missing. Unable to initialize lesson."); } Lesson lesson = createNewLesson(lessonName, lessonDescription, user, learningDesign, enableLessonIntro, - displayDesignImage, learnerPresenceAvailable, learnerImAvailable, liveEditEnabled, - enableLessonNotifications, forceLearnerRestart, allowLearnerRestart, gradebookOnComplete, - scheduledNumberDaysToLessonFinish, precedingLesson); + displayDesignImage, liveEditEnabled, enableLessonNotifications, forceLearnerRestart, + allowLearnerRestart, gradebookOnComplete, scheduledNumberDaysToLessonFinish, precedingLesson); logLessonGeneralChange(LogEvent.TYPE_TEACHER_LESSON_CREATE, user != null ? user.getUserId() : null, lesson != null ? lesson.getLessonId() : null, MonitoringService.AUDIT_LESSON_CREATED_KEY, new Object[] { lessonName, learningDesign.getTitle(), learningDesign.getLearningDesignId() }); @@ -438,10 +433,9 @@ private Lesson initializeLesson(String lessonName, String lessonDescription, LearningDesign originalLearningDesign, User user, WorkspaceFolder workspaceFolder, int copyType, String customCSV, Boolean enableLessonIntro, - Boolean displayDesignImage, Boolean learnerPresenceAvailable, Boolean learnerImAvailable, - Boolean liveEditEnabled, Boolean enableLessonNotifications, Boolean forceLearnerRestart, - Boolean allowLearnerRestart, Boolean gradebookOnComplete, Integer scheduledNumberDaysToLessonFinish, - Lesson precedingLesson) { + Boolean displayDesignImage, Boolean liveEditEnabled, Boolean enableLessonNotifications, + Boolean forceLearnerRestart, Boolean allowLearnerRestart, Boolean gradebookOnComplete, + Integer scheduledNumberDaysToLessonFinish, Lesson precedingLesson) { // copy the current learning design LearningDesign copiedLearningDesign = authoringService.copyLearningDesign(originalLearningDesign, new Integer(copyType), user, workspaceFolder, true, null, customCSV); @@ -456,9 +450,8 @@ } Lesson lesson = createNewLesson(title, lessonDescription, user, copiedLearningDesign, enableLessonIntro, - displayDesignImage, learnerPresenceAvailable, learnerImAvailable, liveEditEnabled, - enableLessonNotifications, forceLearnerRestart, allowLearnerRestart, gradebookOnComplete, - scheduledNumberDaysToLessonFinish, precedingLesson); + displayDesignImage, liveEditEnabled, enableLessonNotifications, forceLearnerRestart, + allowLearnerRestart, gradebookOnComplete, scheduledNumberDaysToLessonFinish, precedingLesson); logLessonGeneralChange(LogEvent.TYPE_TEACHER_LESSON_CREATE, user != null ? user.getUserId() : null, lesson != null ? lesson.getLessonId() : null, MonitoringService.AUDIT_LESSON_CREATED_KEY, new Object[] { lessonName, copiedLearningDesign.getTitle(), @@ -1230,24 +1223,6 @@ } @Override - public Boolean togglePresenceAvailable(long lessonId, Integer userId, Boolean presenceAvailable) { - securityService.ensureLessonMonitor(lessonId, userId, "set presence available"); - Lesson requestedLesson = lessonDAO.getLesson(new Long(lessonId)); - requestedLesson.setLearnerPresenceAvailable(presenceAvailable != null ? presenceAvailable : Boolean.FALSE); - lessonDAO.updateLesson(requestedLesson); - return requestedLesson.getLearnerPresenceAvailable(); - } - - @Override - public Boolean togglePresenceImAvailable(long lessonId, Integer userId, Boolean presenceImAvailable) { - securityService.ensureLessonMonitor(lessonId, userId, "set presence instant messaging available"); - Lesson requestedLesson = lessonDAO.getLesson(new Long(lessonId)); - requestedLesson.setLearnerImAvailable(presenceImAvailable != null ? presenceImAvailable : Boolean.FALSE); - lessonDAO.updateLesson(requestedLesson); - return requestedLesson.getLearnerImAvailable(); - } - - @Override public Boolean toggleGradebookOnComplete(long lessonId, Integer userId, Boolean gradebookOnComplete) { securityService.ensureLessonMonitor(lessonId, userId, "set gradebook on complete"); Lesson requestedLesson = lessonDAO.getLesson(new Long(lessonId)); @@ -2137,13 +2112,12 @@ */ private Lesson createNewLesson(String lessonName, String lessonDescription, User user, LearningDesign copiedLearningDesign, Boolean enableLessonIntro, Boolean displayDesignImage, - Boolean learnerPresenceAvailable, Boolean learnerImAvailable, Boolean liveEditEnabled, - Boolean enableLessonNotifications, Boolean forceLearnerRestart, Boolean allowLearnerRestart, - Boolean gradebookOnComplete, Integer scheduledNumberDaysToLessonFinish, Lesson precedingLesson) { + Boolean liveEditEnabled, Boolean enableLessonNotifications, Boolean forceLearnerRestart, + Boolean allowLearnerRestart, Boolean gradebookOnComplete, Integer scheduledNumberDaysToLessonFinish, + Lesson precedingLesson) { Lesson newLesson = Lesson.createNewLessonWithoutClass(lessonName, lessonDescription, user, copiedLearningDesign, - enableLessonIntro, displayDesignImage, learnerPresenceAvailable, learnerImAvailable, liveEditEnabled, - enableLessonNotifications, forceLearnerRestart, allowLearnerRestart, gradebookOnComplete, - scheduledNumberDaysToLessonFinish); + enableLessonIntro, displayDesignImage, liveEditEnabled, enableLessonNotifications, forceLearnerRestart, + allowLearnerRestart, gradebookOnComplete, scheduledNumberDaysToLessonFinish); if (precedingLesson != null) { HashSet precedingLessons = new HashSet(); precedingLessons.add(precedingLesson); @@ -2852,7 +2826,6 @@ newLesson = this.initializeLesson(lesson.getLessonName(), lesson.getLessonDescription(), lesson.getLearningDesign().getLearningDesignId(), group.getOrganisationId(), creatorId, null, lesson.isEnableLessonIntro(), lesson.isDisplayDesignImage(), - lesson.getLearnerPresenceAvailable(), lesson.getLearnerImAvailable(), lesson.getLiveEditEnabled(), lesson.getEnableLessonNotifications(), lesson.getForceLearnerRestart(), lesson.getAllowLearnerRestart(), lesson.getGradebookOnComplete(), null, null); Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringController.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringController.java (.../MonitoringController.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringController.java (.../MonitoringController.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -249,8 +249,6 @@ long ldId = WebUtil.readLongParam(request, AttributeNames.PARAM_LEARNINGDESIGN_ID); Integer copyType = WebUtil.readIntParam(request, "copyType", true); String customCSV = request.getParameter("customCSV"); - Boolean learnerPresenceAvailable = WebUtil.readBooleanParam(request, "learnerPresenceAvailable", false); - Boolean learnerImAvailable = WebUtil.readBooleanParam(request, "learnerImAvailable", false); Boolean liveEditEnabled = WebUtil.readBooleanParam(request, "liveEditEnabled", false); Boolean forceRestart = WebUtil.readBooleanParam(request, "forceRestart", false); Boolean allowRestart = WebUtil.readBooleanParam(request, "allowRestart", false); @@ -259,12 +257,12 @@ Lesson newLesson = null; if ((copyType != null) && copyType.equals(LearningDesign.COPY_TYPE_PREVIEW)) { newLesson = monitoringService.initializeLessonForPreview(title, desc, ldId, getUserId(), customCSV, - learnerPresenceAvailable, learnerImAvailable, liveEditEnabled); + liveEditEnabled); } else { try { newLesson = monitoringService.initializeLesson(title, desc, ldId, organisationId, getUserId(), - customCSV, false, false, learnerPresenceAvailable, learnerImAvailable, liveEditEnabled, false, - forceRestart, allowRestart, gradebookOnComplete, null, null); + customCSV, false, false, liveEditEnabled, false, forceRestart, allowRestart, + gradebookOnComplete, null, null); } catch (SecurityException e) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "User is not a monitor in the organisation"); return null; @@ -366,8 +364,6 @@ boolean startMonitor = WebUtil.readBooleanParam(request, "startMonitor", false); boolean enableLiveEdit = WebUtil.readBooleanParam(request, "liveEditEnable", false); boolean notificationsEnable = WebUtil.readBooleanParam(request, "notificationsEnable", false); - boolean presenceEnable = WebUtil.readBooleanParam(request, "presenceEnable", false); - boolean imEnable = WebUtil.readBooleanParam(request, "imEnable", false); Integer splitNumberLessons = WebUtil.readIntParam(request, "splitNumberLessons", true); boolean schedulingEnable = WebUtil.readBooleanParam(request, "schedulingEnable", false); Long orgGroupingId = WebUtil.readLongParam(request, "orgGroupingId", true); @@ -445,7 +441,7 @@ Lesson lesson = null; try { lesson = monitoringService.initializeLesson(lessonInstanceName, introDescription, learningDesignID, - organisationId, userId, null, introEnable, introImage, presenceEnable, imEnable, + organisationId, userId, null, introEnable, introImage, enableLiveEdit, notificationsEnable, forceRestart, allowRestart, gradebookOnComplete, timeLimitIndividual, precedingLessonId); @@ -1613,50 +1609,8 @@ } /** - * Set whether or not the presence available button is available in learner. Expects parameters lessonID and - * presenceAvailable. - */ - @RequestMapping(path = "/presenceAvailable", method = RequestMethod.POST) - public String presenceAvailable(HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException { - Long lessonID = new Long(WebUtil.readLongParam(request, "lessonID")); - Integer userID = getUserId(); - Boolean presenceAvailable = WebUtil.readBooleanParam(request, "presenceAvailable", false); - - try { - monitoringService.togglePresenceAvailable(lessonID, userID, presenceAvailable); - - if (!presenceAvailable) { - monitoringService.togglePresenceImAvailable(lessonID, userID, false); - } - } catch (SecurityException e) { - response.sendError(HttpServletResponse.SC_FORBIDDEN, "User is not a monitor in the lesson"); - } - return null; - } - - /** - * Set whether or not the presence available button is available in learner. Expects parameters lessonID and - * presenceImAvailable. - */ - @RequestMapping(path = "/presenceImAvailable", method = RequestMethod.POST) - public String presenceImAvailable(HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException { - Long lessonID = new Long(WebUtil.readLongParam(request, "lessonID")); - Integer userID = getUserId(); - Boolean presenceImAvailable = WebUtil.readBooleanParam(request, "presenceImAvailable", false); - - try { - monitoringService.togglePresenceImAvailable(lessonID, userID, presenceImAvailable); - } catch (SecurityException e) { - response.sendError(HttpServletResponse.SC_FORBIDDEN, "User is not a monitor in the lesson"); - } - return null; - } - - /** * Set whether or not the activity scores / gradebook values are shown to the learner at the end of the lesson. - * Expects parameters lessonID and presenceAvailable. + * Expects parameters lessonID and gradebookOnComplete. */ @RequestMapping(path = "/gradebookOnComplete", method = RequestMethod.POST) public String gradebookOnComplete(HttpServletRequest request, HttpServletResponse response) throws IOException { Index: lams_monitoring/web/gate/gateStatus.jsp =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_monitoring/web/gate/gateStatus.jsp (.../gateStatus.jsp) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_monitoring/web/gate/gateStatus.jsp (.../gateStatus.jsp) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -34,6 +34,17 @@ + + + + +

+ " + value="" /> +

+
+
@@ -48,16 +59,4 @@
- - - - - - -

- " - value="" /> -

-
\ No newline at end of file Index: lams_monitoring/web/includes/javascript/monitorLesson.js =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_monitoring/web/includes/javascript/monitorLesson.js (.../monitorLesson.js) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_monitoring/web/includes/javascript/monitorLesson.js (.../monitorLesson.js) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -293,61 +293,6 @@ $('#forceBackwardsDialog').modal('hide'); }); - - $('#presenceButton').change(function(){ - var checked = $(this).prop('checked'), - 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) { - $('#imButtonWrapper').show(); - showToast(LABELS.LESSON_PRESENCE_ENABLE_ALERT); - } else { - $('#imButtonWrapper, #openImButton').hide(); - $('#imButton').prop('checked', false); - showToast(LABELS.LESSON_PRESENCE_DISABLE_ALERT); - } - } - }); - }); - - // sets instant messaging availability - $('#imButton').click(function(){ - var checked = $(this).prop('checked'), - 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); - showToast(LABELS.LESSON_IM_ENABLE_ALERT); - } else { - $('#openImButton').hide(); - showToast(LABELS.LESSON_IM_DISABLE_ALERT); - } - } - }); - }); - - $('#openImButton').click(openChatWindow); - //enable renaming of lesson title $('#lesson-name').editable({ type: 'text', @@ -465,6 +410,7 @@ }, success : function(response) { + // update lesson state label lessonStateId = +response.lessonStateID; var label = null, @@ -532,17 +478,19 @@ lessonFinishDateSpan = $('#lessonFinishDateSpan'), lessonStateChanger = $('#lessonStateChanger'), stateLabel = $('#lessonStateLabel'); + switch (lessonStateId) { - //created but not started lesson + // created but not started lesson case 1: scheduleControls.css('display','inline'); if ( response.finishDate ) { lessonFinishDateSpan.text(LABELS.LESSON_FINISH.replace("%0",response.finishDate)).css('display','inline'); $("#scheduleDisableLessonButton").html(LABELS.RESCHEDULE); $("#disableLessonButton").css('display', 'none'); + } else { + lessonFinishDateSpan.hide(); } startDateField.hide(); - lessonFinishDateSpan.hide(); lessonStateChanger.hide(); break; //scheduled lesson @@ -1032,7 +980,7 @@ cache : false, type : 'POST', success : function() { - loadTab(); + document.location.reload(); } }); } @@ -1051,16 +999,6 @@ return list; } - -function openChatWindow(){ - // variables are set in JSP page - window.open(LAMS_URL + 'learning/presenceChat.jsp?lessonID=' + lessonId - + '&presenceEnabledPatch=true&presenceImEnabled=true&presenceShown=true&createDateTime=' - + createDateTimeStr - ,'Chat' - ,'width=650,height=350,resizable=no,scrollbars=no,status=no,menubar=no,toolbar=no'); -} - function showEmailDialog(userId){ //check whether current window is a top level one (otherwise it's an iframe or popup) @@ -1089,28 +1027,6 @@ }, false, true); } -/* -function updatePresenceAvailableCount(){ - var checked = $('#presenceButton').prop('checked'); - counter = $('#presenceCounter'); - if (checked) { - $.ajax({ - dataType : 'text', - url : LAMS_URL + 'learning/learner/getPresenceChatActiveUserCount.do?', - cache : false, - data : { - 'lessonID' : lessonId - }, - success : function(result) { - counter.text(result).show(); - } - }); - } else { - counter.hide(); - } -} -*/ - function updateContributeActivities(contributeActivities) { let requiredTasksPanel = $('#required-tasks'), requiredTasksContent = $('#required-tasks-content', requiredTasksPanel); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -35,6 +35,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -154,6 +155,7 @@ implements IAssessmentService, ICommonAssessmentService, ToolContentManager, ToolSessionManager, ToolRestManager, IQbToolService { private static Logger log = Logger.getLogger(AssessmentServiceImpl.class.getName()); + private static Logger logAutosave = Logger.getLogger(AssessmentServiceImpl.class.getName() + "_autosave"); private AssessmentDAO assessmentDao; @@ -812,6 +814,11 @@ assessmentResultDao.update(result); + if (!isAutosave && assessment.getTimeLimitAdjustments().containsKey(userId.intValue())) { + // make time widget stop displaying individual extension for this user + FluxRegistry.emit(AssessmentConstants.TIME_LIMIT_PANEL_UPDATE_SINK_NAME, assessment.getContentId()); + } + // refresh non-leaders when leader changed his answers or submitted them if (assessment.isUseSelectLeaderToolOuput() && (!isAutosave || isAnswerModified)) { AssessmentSession session = getSessionBySessionId(result.getSessionId()); @@ -850,11 +857,41 @@ } } + StringBuilder autosaveLogBuilder = null; + if (StringUtils.isNotBlank(questionResult.getAnswer()) && "".equals(questionDto.getAnswer())) { + autosaveLogBuilder = new StringBuilder("For learner ").append(assessmentResult.getUser().getUid()) + .append(" \"").append(assessmentResult.getUser().getLoginName()).append("\" for question ") + .append(questionDto.getUid()).append(" for question result ").append(questionResult.getUid()) + .append(" answer was \"").append(questionResult.getAnswer()) + .append("\" and it is now blank, skipping save."); + log.warn(autosaveLogBuilder); + if (logAutosave.isTraceEnabled()) { + logAutosave.trace(autosaveLogBuilder); + } + questionResult.setAnswerModified(false); + return questionResult; + } + boolean isAnswerModified = !Objects.equals(questionResult.getAnswerBoolean(), questionDto.getAnswerBoolean()) || !Objects.equals( questionResult.getAnswerFloat(), questionDto.getAnswerFloat()) || !Objects.equals( questionResult.getAnswer(), questionDto.getAnswer()); + // this is for logging every autosave as requested by Imperial + // it produces a lot of logs, so it goes to a separate file + + if (logAutosave.isTraceEnabled()) { + autosaveLogBuilder = new StringBuilder("For learner ").append(assessmentResult.getUser().getUid()) + .append(" \"").append(assessmentResult.getUser().getLoginName()).append("\" for question ") + .append(questionDto.getUid()).append(" for question result ").append(questionResult.getUid()) + .append(" answer was \"").append(questionResult.getAnswer()).append("\" and it is now \"") + .append(questionDto.getAnswer()).append("\", answerBoolean was \"") + .append(questionResult.getAnswerBoolean()).append("\" and it is now \"") + .append(questionDto.getAnswerBoolean()).append("\", answerFloat was \"") + .append(questionResult.getAnswerFloat()).append("\" and it is now \"") + .append(questionDto.getAnswerFloat()).append("\""); + } + // store question answer values questionResult.setAnswerBoolean(questionDto.getAnswerBoolean()); questionResult.setAnswerFloat(questionDto.getAnswerFloat()); @@ -882,6 +919,12 @@ isAnswerModified |= !Objects.equals(optionAnswer.getAnswerBoolean(), optionDto.getAnswerBoolean()); } + if (logAutosave.isTraceEnabled()) { + autosaveLogBuilder.append(", for option ").append(optionDto.getUid()).append(" option result ") + .append(optionAnswer.getUid()).append(" was \"").append(optionAnswer.getAnswerBoolean()) + .append("\" and it is now \"").append(optionDto.getAnswerBoolean()).append("\""); + } + // store option answer values optionAnswer.setAnswerBoolean(optionDto.getAnswerBoolean()); if (questionDto.getType() == QbQuestion.TYPE_ORDERING) { @@ -893,15 +936,20 @@ } } + if (logAutosave.isTraceEnabled()) { + logAutosave.trace(autosaveLogBuilder); + } + // store confidence levels entered by the learner if (assessment.isEnableConfidenceLevels()) { isAnswerModified |= !Objects.equals(questionResult.getConfidenceLevel(), questionDto.getConfidenceLevel()); questionResult.setConfidenceLevel(questionDto.getConfidenceLevel()); } // store justification entered by the learner - if (assessment.isAllowAnswerJustification() || (questionDto.getType().equals(QbQuestion.TYPE_MARK_HEDGING) - && questionDto.isHedgingJustificationEnabled())) { + if (assessment.isAllowAnswerJustification() || (questionDto.getType(). + + equals(QbQuestion.TYPE_MARK_HEDGING) && questionDto.isHedgingJustificationEnabled())) { isAnswerModified |= !Objects.equals(questionResult.getJustification(), questionDto.getJustification()); questionResult.setJustification(questionDto.getJustification()); } @@ -1441,13 +1489,14 @@ if (!results.isEmpty()) { //prepare list of the questions to display, filtering out questions that aren't supposed to be answered - Set questions = new TreeSet<>(); + Set questions = null; //in case there is at least one random question - we need to show all questions in a drop down select if (assessment.hasRandomQuestion()) { - questions.addAll(assessment.getQuestions()); + questions = new TreeSet<>(assessment.getQuestions()); //otherwise show only questions from the question list } else { + questions = new LinkedHashSet<>(); for (QuestionReference reference : assessment.getQuestionReferences()) { questions.add(reference.getQuestion()); } @@ -3042,9 +3091,9 @@ } } - // ***************************************************************************** - // private methods - // ***************************************************************************** +// ***************************************************************************** +// private methods +// ***************************************************************************** private Assessment getDefaultAssessment() throws AssessmentApplicationException { Long defaultAssessmentId = getToolDefaultContentIdBySignature(AssessmentConstants.TOOL_SIGNATURE); @@ -3068,9 +3117,9 @@ return contentId; } - // ***************************************************************************** - // set methods for Spring Bean - // ***************************************************************************** +// ***************************************************************************** +// set methods for Spring Bean +// ***************************************************************************** public void setLogEventService(ILogEventService logEventService) { this.logEventService = logEventService; @@ -3116,9 +3165,9 @@ this.assessmentConfigDao = assessmentConfigDao; } - // ******************************************************************************* - // ToolContentManager, ToolSessionManager methods - // ******************************************************************************* +// ******************************************************************************* +// ToolContentManager, ToolSessionManager methods +// ******************************************************************************* @Override public void exportToolContent(Long toolContentId, String rootPath) throws DataMissingException, ToolException { @@ -3786,6 +3835,7 @@ assessment.setAllowQuestionFeedback( JsonUtil.optBoolean(toolContentJSON, "allowQuestionFeedback", Boolean.FALSE)); assessment.setAllowDiscloseAnswers(JsonUtil.optBoolean(toolContentJSON, "allowDiscloseAnswers", Boolean.FALSE)); + assessment.setAllowDiscloseAnswers(JsonUtil.optBoolean(toolContentJSON, "allowAnswerRating", Boolean.TRUE)); assessment.setAllowRightAnswersAfterQuestion( JsonUtil.optBoolean(toolContentJSON, "allowRightAnswersAfterQuestion", Boolean.FALSE)); assessment.setAllowWrongAnswersAfterQuestion( Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java (.../LearningController.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/LearningController.java (.../LearningController.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -74,6 +74,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -293,7 +294,7 @@ //user is allowed to answer questions if assessment activity doesn't have leaders or he is the leader boolean hasEditRight = - !assessment.isUseSelectLeaderToolOuput() || assessment.isUseSelectLeaderToolOuput() && isUserLeader; + (!assessment.isUseSelectLeaderToolOuput() || assessment.isUseSelectLeaderToolOuput() && isUserLeader) && !mode.isTeacher(); //showResults if user has finished the last result boolean showResults = (lastResult != null) && (lastResult.getFinishDate() != null); @@ -463,7 +464,7 @@ /** * Shows next page. It's available only to leaders as non-leaders see all questions on one page. */ - @RequestMapping("/nextPage") + @PostMapping("/nextPage") public String nextPage(HttpServletRequest request) throws ServletException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { return nextPage(request, false, -1); @@ -585,7 +586,7 @@ * @throws IllegalAccessException */ @SuppressWarnings("unchecked") - @RequestMapping("/submitAll") + @PostMapping("/submitAll") public String submitAll(HttpServletRequest request) throws ServletException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { SessionMap sessionMap = getSessionMap(request); @@ -688,7 +689,7 @@ /** * auto saves responses */ - @RequestMapping("/autoSaveAnswers") + @PostMapping("/autoSaveAnswers") @ResponseStatus(HttpStatus.OK) @ResponseBody public String autoSaveAnswers(HttpServletRequest request, HttpServletResponse response) Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java =================================================================== diff -u -r0b1d534ce1915b907afff0171909f90226b31921 -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 0b1d534ce1915b907afff0171909f90226b31921) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -357,7 +357,7 @@ String gradeString = request.getParameter(AssessmentConstants.PARAM_GRADE); if (StringUtils.isNotBlank(gradeString) && !gradeString.strip().equals("-")) { newGrade = Float.valueOf(gradeString); - responseText = teacher.getLastName() + " " + teacher.getFirstName(); + responseText = teacher.getFullName(); } } else if (column.equals(AssessmentConstants.PARAM_MARKER_COMMENT)) { markerComment = request.getParameter(AssessmentConstants.PARAM_MARKER_COMMENT); @@ -484,7 +484,7 @@ ArrayNode userData = JsonNodeFactory.instance.arrayNode(); userData.add(userDto.getUserId()); userData.add(userDto.getSessionId()); - String fullName = HtmlUtils.htmlEscape(userDto.getFirstName() + " " + userDto.getLastName()); + String fullName = HtmlUtils.htmlEscape(userDto.getFullName()); userData.add(fullName); userData.add(userDto.getGrade()); if (userDto.getPortraitId() != null) { @@ -594,7 +594,7 @@ for (AssessmentUserDTO userDto : userDtos) { Long questionResultUid = userDto.getQuestionResultUid(); - String fullName = HtmlUtils.htmlEscape(userDto.getFirstName() + " " + userDto.getLastName()); + String fullName = HtmlUtils.htmlEscape(userDto.getFullName()); ArrayNode userData = JsonNodeFactory.instance.arrayNode(); if (questionResultUid != null) { @@ -1005,7 +1005,7 @@ ObjectNode userJSON = JsonNodeFactory.instance.objectNode(); userJSON.put("value", "user-" + user.getUserId()); - String name = user.getFirstName() + " " + user.getLastName() + " (" + user.getLogin() + ")"; + String name = user.getFullName() + " (" + user.getLogin() + ")"; if (grouping != null) { Group group = grouping.getGroupBy(user); if (group != null && !group.isNull()) { @@ -1058,7 +1058,7 @@ userJSON.put("userId", user.getUserId()); userJSON.put("adjustment", timeLimitAdjustments.get(user.getUserId().intValue())); - String name = user.getFirstName() + " " + user.getLastName() + " (" + user.getLogin() + ")"; + String name = user.getFullName() + " (" + user.getLogin() + ")"; if (grouping != null) { Group group = grouping.getGroupBy(user); if (group != null && !group.isNull()) { Index: lams_tool_assessment/web/pages/learning/learning.jsp =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_assessment/web/pages/learning/learning.jsp (.../learning.jsp) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_assessment/web/pages/learning/learning.jsp (.../learning.jsp) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -112,34 +112,36 @@ }); } - initWebsocket('assessmentTimeLimit${sessionMap.assessment.contentId}', - ''.replace('http', 'ws') - + 'learningWebsocket?toolContentID=${sessionMap.assessment.contentId}', - function (e) { - // read JSON object - var input = JSON.parse(e.data); + + initWebsocket('assessmentTimeLimit${sessionMap.assessment.contentId}', + ''.replace('http', 'ws') + 'learningWebsocket?toolContentID=${sessionMap.assessment.contentId}', + function (e) { + // read JSON object + var input = JSON.parse(e.data); + + if (input.clearTimer == true) { + // teacher stopped the timer, destroy it + $('#countdown').countdown('destroy').remove(); + } else { + // teacher updated the timer + var secondsLeft = +input.secondsLeft, + counterInitialised = $('#countdown').length > 0; + + if (counterInitialised) { + // just set the new time + $('#countdown').countdown('option', 'until', secondsLeft + 'S'); + } else { + // initialise the timer + displayCountdown(secondsLeft); + } + } + + // reset ping timer + websocketPing('assessmentTimeLimit${sessionMap.assessment.contentId}', true); + } + ); + - if (input.clearTimer == true) { - // teacher stopped the timer, destroy it - $('#countdown').countdown('destroy').remove(); - } else { - // teacher updated the timer - var secondsLeft = +input.secondsLeft, - counterInitialised = $('#countdown').length > 0; - - if (counterInitialised) { - // just set the new time - $('#countdown').countdown('option', 'until', secondsLeft + 'S'); - } else { - // initialise the timer - displayCountdown(secondsLeft); - } - } - - // reset ping timer - websocketPing('assessmentTimeLimit${sessionMap.assessment.contentId}', true); - }); - //autocomplete for VSA $('.ui-autocomplete-input').each(function(){ $(this).autocomplete({ @@ -207,7 +209,6 @@ left: '', right: '0%', opacity: '.8', - width: '230px', cursor: 'default', border: 'none' } @@ -232,11 +233,11 @@ var hours = $("#countdown").countdown('getTimes')[4]; var minutes = $("#countdown").countdown('getTimes')[5]; if (screenCountdown.data("hours") != hours || screenCountdown.data("minutes") != minutes) { - var timeLeftText = " "; + var timeLeftText = " "; if (hours > 0) { - timeLeftText += hours + " "; + timeLeftText += hours + " "; } - timeLeftText += minutes + " "; + timeLeftText += minutes + " "; screenCountdown.html(timeLeftText); screenCountdown.data("hours", hours); @@ -269,13 +270,14 @@ //autosave feature - var autosaveInterval = ${isLeadershipEnabled and isUserLeader ? 10000 : 30000}; // 30 or 10 seconds interval + var autosaveInterval = ${isLeadershipEnabled and isUserLeader ? 10000 : 30000}, // 30 or 10 seconds interval + autosaveWindowId = new Date().getTime(); // all we need for this ID is to be unique function learnerAutosave(isCommand){ // isCommand means that the autosave was triggered by force complete or another command websocket message // in this case do not check multiple tabs open, just autosave if (!isCommand) { - let shouldAutosave = preventLearnerAutosaveFromMultipleTabs(autosaveInterval); + let shouldAutosave = preventLearnerAutosaveFromMultipleTabs(autosaveWindowId, autosaveInterval); if (!shouldAutosave) { return; } @@ -349,9 +351,9 @@ // validate only if time limit is not expired // otherwise confirm with learner that he wants to submit if (!isTimelimitExpired && (!validateAnswers() - || (!isResubmitAllowed && - !confirm("")))) { - return; + || (!isResubmitAllowed && + !confirm("")))) { + return; } disableButtons(); @@ -616,10 +618,13 @@ -
- -
+ +
+ +
+
+ <%@ include file="parts/paging.jsp"%>
Index: lams_tool_assessment/web/pages/learning/parts/allquestions.jsp =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_assessment/web/pages/learning/parts/allquestions.jsp (.../allquestions.jsp) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_assessment/web/pages/learning/parts/allquestions.jsp (.../allquestions.jsp) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -1,155 +1,156 @@ <%@ include file="/common/taglibs.jsp"%> - <%-- Prepare same content for each question Etherpad. Each group participant's first and last name --%> - - + <%-- Prepare same content for each question Etherpad. Each group participant's first and last name --%> + + :
-
-
-
-
+
+
+
+
- - - - -
-
-
+ + + + +
+
+
- ${questionIndex + sessionMap.questionNumberingOffset}. - - + ${questionIndex + sessionMap.questionNumberingOffset}. + + - ${question.title} - + ${question.title} + - + - - + + - - - - + + + + " - alt=""> + title="" + alt=""> - -
-
- -
-
- ${question.question} -
- - - - - <%@ include file="multiplechoice.jsp"%> - - - - <%@ include file="matchingpairs.jsp"%> - - - - <%@ include file="vsa.jsp"%> - - - - <%@ include file="numerical.jsp"%> - - - - <%@ include file="truefalse.jsp"%> - - - - <%@ include file="essay.jsp"%> - - - - <%@ include file="ordering.jsp"%> - - - - - - <%@ include file="../results/markhedging.jsp"%> - - -
- <%@ include file="markhedging.jsp"%> -
-
-
-
-
- - - <%@ include file="confidencelevel.jsp"%> - - - <%--Display jsutification for each question --%> - +
+ ${question.question} +
+
+ + + + + <%@ include file="multiplechoice.jsp"%> + + + + <%@ include file="matchingpairs.jsp"%> + + + + <%@ include file="vsa.jsp"%> + + + + <%@ include file="numerical.jsp"%> + + + + <%@ include file="truefalse.jsp"%> + + + + <%@ include file="essay.jsp"%> + + + + <%@ include file="ordering.jsp"%> + + + + + + <%@ include file="../results/markhedging.jsp"%> + + +
+ <%@ include file="markhedging.jsp"%> +
+
+
+
+
+ + + <%@ include file="confidencelevel.jsp"%> + + + <%--Display jsutification for each question --%> + -
- + + -
- -
-
-
-
-
- - <%--Display Etherpad for each question --%> - -
-
+
+
+
+ + <%--Display Etherpad for each question --%> + +
+ - -
-
- ${questionEtherpadContent} -
-
-
-
- + + + +
+
+ ${questionEtherpadContent} +
+
+
+ +
\ No newline at end of file Index: lams_tool_assessment/web/pages/learning/results.jsp =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_assessment/web/pages/learning/results.jsp (.../results.jsp) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_assessment/web/pages/learning/results.jsp (.../results.jsp) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -18,7 +18,7 @@ - + - - - - - - - - - - <%-- codeStyles is a set, so each code style will be listed only once --%> - - - - - - - - - - - - - - - - - - + + + + + + -
-
-
- -
-
- -
- - - - - - + - -
- - + + + + + + + + + + + <%-- codeStyles is a set, so each code style will be listed only once --%> + + + + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+ + + + + + - - - - - - - - - - - - - - - - -
+ + -
- - - ${userSummary.numberOfAttempts} -
- - - - -
- - -
${userSummary.lastAttemptGrade}
-
- - -
-
-
-
- - - - - - - - - -
- - - -
- - - -
-
-
- +
-
-
- - <%--Display Etherpad for each question --%> - -
- - -
-
- -
-
-
-
- + + + + + + ${userSummary.numberOfAttempts} + + - - - + + + + + + + + + -
- - - - + + + + + +
${userSummary.lastAttemptGrade}
+ + + - - + +
+
+
+
+ + + + + + + + + +
+ + + +
+ + + +
+
+
+ + + +
+
+
+ + <%--Display Etherpad for each question --%> + +
+ + +
+
+ +
+
+
+
+
+ + + + + + + + + + + + + \ No newline at end of file Index: lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/service/DokumaranService.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/service/DokumaranService.java (.../DokumaranService.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/service/DokumaranService.java (.../DokumaranService.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -438,15 +438,11 @@ user.setSessionFinished(true); dokumaranUserDao.saveObject(user); - // DokumaranSession session = dokumaranSessionDao.getSessionBySessionId(toolSessionId); - // session.setStatus(DokumaranConstants.COMPLETED); - // dokumaranSessionDao.saveObject(session); + DokumaranSession session = dokumaranSessionDao.getSessionBySessionId(toolSessionId); //finish Etherpad session. Encapsulate it in try-catch block as we don't want it to affect regular LAMS workflow. try { EPLiteClient client = etherpadService.getClient(); - - DokumaranSession session = dokumaranSessionDao.getSessionBySessionId(toolSessionId); String groupId = session.getEtherpadGroupId(); String userName = user.getFullName(); @@ -467,6 +463,11 @@ log.debug(e1.getMessage()); } + Dokumaran dokumaran = session.getDokumaran(); + if (dokumaran.getTimeLimitAdjustments().containsKey(userId.intValue())) { + FluxRegistry.emit(DokumaranConstants.TIME_LIMIT_PANEL_UPDATE_SINK_NAME, dokumaran.getContentId()); + } + String nextUrl = null; try { nextUrl = this.leaveToolSession(toolSessionId, userId); Index: lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/web/controller/MonitoringController.java =================================================================== diff -u -r3340a9fb8b4f086b2aa82aa121a2c597d863e8b9 -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 3340a9fb8b4f086b2aa82aa121a2c597d863e8b9) +++ lams_tool_doku/src/java/org/lamsfoundation/lams/tool/dokumaran/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -495,6 +495,10 @@ } userJSON.put("name", name); + DokumaranUser dokumaranUser = dokumaranService.getLearnerByIDAndContent(user.getUserId().longValue(), + toolContentId); + userJSON.put("finished", dokumaranUser != null && dokumaranUser.isSessionFinished()); + responseJSON.add(userJSON); } return responseJSON.toString(); Index: lams_tool_doku/web/pages/learning/learning.jsp =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_doku/web/pages/learning/learning.jsp (.../learning.jsp) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_doku/web/pages/learning/learning.jsp (.../learning.jsp) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -68,41 +68,43 @@
}); - let timeLimitExceeded = ${timeLimitExceeded}; - initWebsocket('dokuTimeLimit${sessionMap.toolContentID}', - ''.replace('http', 'ws') - + 'learningWebsocket?toolContentID=${sessionMap.toolContentID}', - function (e) { - // create JSON object - var input = JSON.parse(e.data); + + let timeLimitExceeded = ${timeLimitExceeded}; + initWebsocket('dokuTimeLimit${sessionMap.toolContentID}', + ''.replace('http', 'ws') + 'learningWebsocket?toolContentID=${sessionMap.toolContentID}', + function (e) { + // create JSON object + var input = JSON.parse(e.data); + + if (input.clearTimer == true) { + // teacher stopped the timer, destroy it + $('#countdown').countdown('destroy').remove(); + } else if (typeof input.secondsLeft != 'undefined'){ + // teacher updated the timer + var secondsLeft = +input.secondsLeft, + counterInitialised = $('#countdown').length > 0; + + if (counterInitialised) { + // just set the new time + $('#countdown').countdown('option', 'until', secondsLeft + 'S'); + } else if (timeLimitExceeded){ + if (secondsLeft > 0) { + // teacher gave extra time, reload to writable Etherpad + location.reload(); + return; + } + } else { + // initialise the timer + displayCountdown(secondsLeft); + } + } + + // reset ping timer + websocketPing('dokuTimeLimit${sessionMap.toolContentID}', true); + } + ); + - if (input.clearTimer == true) { - // teacher stopped the timer, destroy it - $('#countdown').countdown('destroy').remove(); - } else if (typeof input.secondsLeft != 'undefined'){ - // teacher updated the timer - var secondsLeft = +input.secondsLeft, - counterInitialised = $('#countdown').length > 0; - - if (counterInitialised) { - // just set the new time - $('#countdown').countdown('option', 'until', secondsLeft + 'S'); - } else if (timeLimitExceeded){ - if (secondsLeft > 0) { - // teacher gave extra time, reload to writable Etherpad - location.reload(); - return; - } - } else { - // initialise the timer - displayCountdown(secondsLeft); - } - } - - // reset ping timer - websocketPing('dokuTimeLimit${sessionMap.toolContentID}', true); - }); - $('[data-bs-toggle="tooltip"]').each((i, el) => { new bootstrap.Tooltip($(el)) }); Index: lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/dto/MessageDTO.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/dto/MessageDTO.java (.../MessageDTO.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/dto/MessageDTO.java (.../MessageDTO.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -21,12 +21,15 @@ * **************************************************************** */ + + package org.lamsfoundation.lams.tool.forum.dto; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.lamsfoundation.lams.rating.dto.ItemRatingDTO; import org.lamsfoundation.lams.tool.forum.model.ForumReport; import org.lamsfoundation.lams.tool.forum.model.Message; @@ -43,9 +46,8 @@ private String comment; private boolean released; - //rating fields - private String averageRating; - private String numberOfVotes; + //rating field used by lams:Rating tag + private ItemRatingDTO itemRatingDto; // number of posts the learner has made in this topic. // used when this message is a root topic. @@ -198,22 +200,6 @@ this.released = isReleased; } - public String getAverageRating() { - return averageRating; - } - - public void setAverageRating(String averageRating) { - this.averageRating = averageRating; - } - - public String getNumberOfVotes() { - return numberOfVotes; - } - - public void setNumberOfVotes(String numberOfVotes) { - this.numberOfVotes = numberOfVotes; - } - public int getNumOfPosts() { return numOfPosts; } @@ -237,4 +223,12 @@ public void setAuthorUserId(Long authorUserId) { this.authorUserId = authorUserId; } + + public ItemRatingDTO getItemRatingDto() { + return itemRatingDto; + } + + public void setItemRatingDto(ItemRatingDTO itemRatingDto) { + this.itemRatingDto = itemRatingDto; + } } \ No newline at end of file Index: lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/service/ForumService.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/service/ForumService.java (.../ForumService.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/service/ForumService.java (.../ForumService.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -41,7 +41,11 @@ import org.lamsfoundation.lams.lesson.service.ILessonService; import org.lamsfoundation.lams.logevent.LogEvent; import org.lamsfoundation.lams.logevent.service.ILogEventService; +import org.lamsfoundation.lams.rating.dto.ItemRatingCriteriaDTO; +import org.lamsfoundation.lams.rating.dto.ItemRatingDTO; +import org.lamsfoundation.lams.rating.model.Rating; import org.lamsfoundation.lams.rating.model.RatingCriteria; +import org.lamsfoundation.lams.rating.model.ToolActivityRatingCriteria; import org.lamsfoundation.lams.rest.RestTags; import org.lamsfoundation.lams.rest.ToolRestManager; import org.lamsfoundation.lams.tool.ToolCompletionStatus; @@ -95,6 +99,7 @@ import java.util.Date; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -723,15 +728,32 @@ for (Attachment attachment : message.getAttachments()) { attachment.setFileDisplayUuid(forumToolContentHandler.getFileUuid(attachment.getFileUuid())); } - MessageDTO dto = MessageDTO.getMessageDTO(message); - dto.setLevel(msgSeq.getMessageLevel()); + MessageDTO msgDTO = MessageDTO.getMessageDTO(message); + msgDTO.setLevel(msgSeq.getMessageLevel()); + //set averageRating if (message.getForum().isAllowRateMessages()) { + ItemRatingDTO itemRatingDTO = new ItemRatingDTO(); + msgDTO.setItemRatingDto(itemRatingDTO); + + Long itemId = message.getUid(); + itemRatingDTO.setItemId(itemId); + + List criteriaDtos = new LinkedList<>(); + itemRatingDTO.setCriteriaDtos(criteriaDtos); + + RatingCriteria criteria = new ToolActivityRatingCriteria(); + ItemRatingCriteriaDTO criteriaDto = new ItemRatingCriteriaDTO(); + criteriaDto.setRatingCriteria(criteria); + criteriaDto.setUserRating("0"); + AverageRatingDTO averageRating = getAverageRatingDTOByMessage(message.getUid()); - dto.setAverageRating(averageRating.getRating()); - dto.setNumberOfVotes(averageRating.getNumberOfVotes()); + criteriaDto.setAverageRating(averageRating.getRating()); + criteriaDto.setNumberOfVotes(averageRating.getNumberOfVotes()); + + criteriaDtos.add(criteriaDto); } - return dto; + return msgDTO; } /** Index: lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/web/controller/MonitoringController.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/web/controller/MonitoringController.java (.../MonitoringController.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -285,7 +285,7 @@ responseRow.put("numberOfPosts", numberOfPosts); if (userData.length > 1 && userData[1] != null) { - responseRow.put(ForumConstants.ATTR_PORTRAIT_ID, (String) userData[2]); + responseRow.put(ForumConstants.ATTR_PORTRAIT_ID, (String) userData[1]); } rows.add(responseRow); Index: lams_tool_images/src/java/org/lamsfoundation/lams/tool/imageGallery/service/ImageGalleryServiceImpl.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_images/src/java/org/lamsfoundation/lams/tool/imageGallery/service/ImageGalleryServiceImpl.java (.../ImageGalleryServiceImpl.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_images/src/java/org/lamsfoundation/lams/tool/imageGallery/service/ImageGalleryServiceImpl.java (.../ImageGalleryServiceImpl.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -23,6 +23,26 @@ package org.lamsfoundation.lams.tool.imageGallery.service; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeSet; + +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletRequest; + import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.lamsfoundation.lams.confidencelevel.ConfidenceLevelDTO; @@ -73,27 +93,6 @@ import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.imgscalr.ResizePictureUtil; -import javax.imageio.ImageIO; -import javax.servlet.http.HttpServletRequest; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeSet; - /** * @author Andrey Balan */ @@ -521,9 +520,8 @@ if (mediumIS == null) { throw new UploadImageGalleryFileException("Impossible to resize image"); } - String mediumFileName = - ImageGalleryServiceImpl.MEDIUM_FILENAME_PREFIX + fileName.substring(0, fileName.indexOf('.')) - + ".jpg"; + String mediumFileName = ImageGalleryServiceImpl.MEDIUM_FILENAME_PREFIX + + fileName.substring(0, fileName.indexOf('.')) + ".jpg"; NodeKey mediumNodeKey = imageGalleryToolContentHandler.uploadFile(mediumIS, mediumFileName, "image/jpeg"); image.setMediumFileUuid(mediumNodeKey.getNodeId()); image.setMediumFileDisplayUuid(mediumNodeKey.getUuid()); @@ -537,9 +535,8 @@ // prepare thumbnail image InputStream originalIS2 = imageGalleryToolContentHandler.getFileInputStream(nodeKey.getNodeId()); InputStream thumbnailIS = ResizePictureUtil.resize(originalIS2, thumbnailImageDimensions); - String thumbnailFileName = - ImageGalleryServiceImpl.THUMBNAIL_FILENAME_PREFIX + fileName.substring(0, fileName.indexOf('.')) - + ".jpg"; + String thumbnailFileName = ImageGalleryServiceImpl.THUMBNAIL_FILENAME_PREFIX + + fileName.substring(0, fileName.indexOf('.')) + ".jpg"; NodeKey thumbnailNodeKey = imageGalleryToolContentHandler.uploadFile(thumbnailIS, thumbnailFileName, "image/jpeg"); image.setThumbnailFileUuid(thumbnailNodeKey.getNodeId()); @@ -873,8 +870,8 @@ public void removeToolContent(Long toolContentId) throws ToolException { ImageGallery imageGallery = imageGalleryDao.getByContentId(toolContentId); if (imageGallery == null) { - ImageGalleryServiceImpl.log.warn( - "Can not remove the tool content as it does not exist, ID: " + toolContentId); + ImageGalleryServiceImpl.log + .warn("Can not remove the tool content as it does not exist, ID: " + toolContentId); return; } @@ -896,8 +893,8 @@ } ImageGallery gallery = imageGalleryDao.getByContentId(toolContentId); if (gallery == null) { - ImageGalleryServiceImpl.log.warn( - "Did not find activity with toolContentId: " + toolContentId + " to remove learner content"); + ImageGalleryServiceImpl.log + .warn("Did not find activity with toolContentId: " + toolContentId + " to remove learner content"); return; } @@ -971,12 +968,10 @@ session.setStatus(ImageGalleryConstants.COMPLETED); imageGallerySessionDao.saveObject(session); } else { - ImageGalleryServiceImpl.log.error( - "Fail to leave tool Session.Could not find shared imageGallery " + "session by given session id: " - + toolSessionId); - throw new DataMissingException( - "Fail to leave tool Session." + "Could not find shared imageGallery session by given session id: " - + toolSessionId); + ImageGalleryServiceImpl.log.error("Fail to leave tool Session.Could not find shared imageGallery " + + "session by given session id: " + toolSessionId); + throw new DataMissingException("Fail to leave tool Session." + + "Could not find shared imageGallery session by given session id: " + toolSessionId); } return toolService.completeToolSession(toolSessionId, learnerId); } Index: lams_tool_images/web/pages/learning/learning.jsp =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_images/web/pages/learning/learning.jsp (.../learning.jsp) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_images/web/pages/learning/learning.jsp (.../learning.jsp) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -31,7 +31,7 @@ - + @@ -46,9 +46,7 @@ - <%@ include file="/common/uppylang.jsp"%> - @@ -58,7 +56,7 @@ $(document).ready(function(){ $('.fotorama') - .on('fotorama:show ', + .on('fotorama:show ', function (e, fotorama, extra) { loadImageData(fotorama.activeFrame.id); } @@ -67,38 +65,37 @@ //TODO history : true, width: ${mediumImageDimensions + 60}, height: Math.round(${mediumImageDimensions + 60}*9/16), - maxwidth: '100%', - //ratio: 16/9, - allowfullscreen: true, - keyboard: true, - nav: 'thumbs', - fit: 'scaledown', - //thumbfit: 'contain', - loop: true, - thumbwidth: 80,//${thumbnailImageDimensions}, - thumbheight: 80,//${thumbnailImageDimensions}, - data: [ - - { - img: "download/?uuid=${image.mediumFileDisplayUuid}&preferDownload=false", - full: "download/?uuid=${image.originalFileDisplayUuid}&preferDownload=false", - id: '${image.uid}', // Custom anchor is used with the hash:true option. - caption:'
${image.titleEscaped}
' + - '
${image.descriptionEscaped}
' - - - ${fn:replace(portrait, "'", "\\'")} <%-- escape the url --%> + maxwidth: '100%', + //ratio: 16/9, + allowfullscreen: true, + keyboard: true, + nav: 'thumbs', + fit: 'scaledown', + //thumbfit: 'contain', + loop: true, + thumbwidth: 80,//${thumbnailImageDimensions}, + thumbheight: 80,//${thumbnailImageDimensions}, + data: [ + + { + img: "download/?uuid=${image.mediumFileDisplayUuid}&preferDownload=false", + full: "download/?uuid=${image.originalFileDisplayUuid}&preferDownload=false", + id: '${image.uid}', // Custom anchor is used with the hash:true option. + caption:'
${image.titleEscaped}
' + + '
${image.descriptionEscaped}
' + + + ${fn:replace(portrait, "'", "\\'")} <%-- escape the url --%> + '
${portrait}
' -
- //html: $('selector'), // ...or '
123
'. Custom HTML inside the frame. - //fit: 'cover' // Override the global fit option. - //any: 'Any data relative to the frame you want to store' - }, -
- ] - } - ); - +
+ //html: $('selector'), // ...or '
123
'. Custom HTML inside the frame. + //fit: 'cover' // Override the global fit option. + //any: 'Any data relative to the frame you want to store' + }, +
+ ] + } + ); }); function checkNew(){ @@ -131,7 +128,7 @@
<%--Advanced settings and notices-----------------------------------%> - + @@ -177,9 +174,11 @@ -
- -
+ +
+ +
+
<%--Main image---------------------------------------------------%>
@@ -195,7 +194,7 @@
- +
Index: lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceServiceImpl.java =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceServiceImpl.java (.../ResourceServiceImpl.java) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_larsrc/src/java/org/lamsfoundation/lams/tool/rsrc/service/ResourceServiceImpl.java (.../ResourceServiceImpl.java) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -1170,31 +1170,33 @@ // **************************** Handle topic ********************* ArrayNode resources = JsonUtil.optArray(toolContentJSON, "resources"); Set itemList = new LinkedHashSet<>(); - for (JsonNode itemData : resources) { - ResourceItem item = new ResourceItem(); - item.setTitle(JsonUtil.optString(itemData, "title")); - item.setType(JsonUtil.optInt(itemData, "type").shortValue()); - item.setCreateBy(resourceUser); - item.setCreateDate(updateDate); - item.setComplete(false); - item.setCreateByAuthor(true); - item.setHide(false); - item.setOrderId(JsonUtil.optInt(itemData, RestTags.DISPLAY_ORDER)); + if (resources != null) { + for (JsonNode itemData : resources) { + ResourceItem item = new ResourceItem(); + item.setTitle(JsonUtil.optString(itemData, "title")); + item.setType(JsonUtil.optInt(itemData, "type").shortValue()); + item.setCreateBy(resourceUser); + item.setCreateDate(updateDate); + item.setComplete(false); + item.setCreateByAuthor(true); + item.setHide(false); + item.setOrderId(JsonUtil.optInt(itemData, RestTags.DISPLAY_ORDER)); - item.setInstructions(JsonUtil.optString(itemData, "instructions")); - item.setFileName(JsonUtil.optString(itemData, "name")); - item.setFileType(JsonUtil.optString(itemData, "fileType")); - item.setFileUuid(JsonUtil.optLong(itemData, "crUuid")); - item.setFileVersionId(JsonUtil.optLong(itemData, "crVersionId")); - item.setUrl(JsonUtil.optString(itemData, "url")); + item.setInstructions(JsonUtil.optString(itemData, "instructions")); + item.setFileName(JsonUtil.optString(itemData, "name")); + item.setFileType(JsonUtil.optString(itemData, "fileType")); + item.setFileUuid(JsonUtil.optLong(itemData, "crUuid")); + item.setFileVersionId(JsonUtil.optLong(itemData, "crVersionId")); + item.setUrl(JsonUtil.optString(itemData, "url")); - // TODO files - need to save it somehow, validate the file size, etc. Needed for websites, files & LO - if ((item.getFileName() != null) || (item.getFileUuid() != null)) { - throw new IOException( - "Only URLS supported via REST interface currently - files and learning objects are not supported."); - } + // TODO files - need to save it somehow, validate the file size, etc. Needed for websites, files & LO + if ((item.getFileName() != null) || (item.getFileUuid() != null)) { + throw new IOException( + "Only URLS supported via REST interface currently - files and learning objects are not supported."); + } - itemList.add(item); + itemList.add(item); + } } resource.setResourceItems(itemList); Index: lams_tool_larsrc/web/pages/learning/learning.jsp =================================================================== diff -u -rd0f4c3bdd871e236755472c8443c337b2b96e48c -r330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82 --- lams_tool_larsrc/web/pages/learning/learning.jsp (.../learning.jsp) (revision d0f4c3bdd871e236755472c8443c337b2b96e48c) +++ lams_tool_larsrc/web/pages/learning/learning.jsp (.../learning.jsp) (revision 330b0d5f8fa4a8deb6d7454f92bdbd289e89cb82) @@ -16,8 +16,7 @@ <%-- If you change this file, remember to update the copy made for CNG-36 --%> - - +