Index: lams_monitoring/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r0083f3733489a25a89db5cfa6810303c015acd8f -r99df1f178e0956c7f6691ee7c0eda8459ce1b2a2 --- lams_monitoring/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 0083f3733489a25a89db5cfa6810303c015acd8f) +++ lams_monitoring/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 99df1f178e0956c7f6691ee7c0eda8459ce1b2a2) @@ -540,4 +540,7 @@ label.monitoring.search.learners = Search learners button.copy.lesson.url.tooltip = Copy lesson link to clipboard learner.completed.activity.count = Completed activities -learner.completed.lesson = Lesson finished \ No newline at end of file +learner.completed.lesson = Lesson finished +label.monitoring.learning.design.path = Path to learning design +label.monitoring.learning.design.path.courses = Courses +label.monitoring.learning.design.path.run.sequences = Run sequences \ No newline at end of file Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringController.java =================================================================== diff -u -re7b29886c3fc2a5edef72022a8df8b1833ac6b47 -r99df1f178e0956c7f6691ee7c0eda8459ce1b2a2 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringController.java (.../MonitoringController.java) (revision e7b29886c3fc2a5edef72022a8df8b1833ac6b47) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringController.java (.../MonitoringController.java) (revision 99df1f178e0956c7f6691ee7c0eda8459ce1b2a2) @@ -23,32 +23,10 @@ package org.lamsfoundation.lams.monitoring.web; -import java.io.IOException; -import java.io.PrintWriter; -import java.security.InvalidParameterException; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeSet; -import java.util.Vector; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.lamsfoundation.lams.authoring.IAuthoringService; @@ -79,34 +57,34 @@ import org.lamsfoundation.lams.usermanagement.Organisation; import org.lamsfoundation.lams.usermanagement.Role; import org.lamsfoundation.lams.usermanagement.User; +import org.lamsfoundation.lams.usermanagement.WorkspaceFolder; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.usermanagement.exception.UserException; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; -import org.lamsfoundation.lams.util.CommonConstants; -import org.lamsfoundation.lams.util.DateUtil; -import org.lamsfoundation.lams.util.JsonUtil; -import org.lamsfoundation.lams.util.MessageService; -import org.lamsfoundation.lams.util.ValidationUtil; -import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.util.*; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.*; import org.springframework.web.util.HtmlUtils; - -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.JsonNodeFactory; -import com.fasterxml.jackson.databind.node.ObjectNode; - import reactor.core.publisher.Flux; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.io.PrintWriter; +import java.security.InvalidParameterException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.Map.Entry; + /** * The action servlet that provide all the monitoring functionalities. It interact with the teacher via JSP monitoring * interface. @@ -369,7 +347,8 @@ boolean allowRestart = WebUtil.readBooleanParam(request, "allowRestart", false); boolean precedingLessonEnable = WebUtil.readBooleanParam(request, "precedingLessonEnable", false); - Long precedingLessonId = precedingLessonEnable ? WebUtil.readLongParam(request, "precedingLessonId", true) + Long precedingLessonId = precedingLessonEnable + ? WebUtil.readLongParam(request, "precedingLessonId", true) : null; boolean timeLimitEnable = WebUtil.readBooleanParam(request, "timeLimitEnable", false); Integer timeLimitDays = WebUtil.readIntParam(request, "timeLimitDays", true); @@ -397,10 +376,10 @@ String staffGroupName = organisation.getName() + " staff"; // either all users participate in a lesson, or we split them among instances - List lessonInstanceLearners = splitNumberLessons == null ? learners - : new ArrayList<>((learners.size() / splitNumberLessons) + 1); - for (int lessonIndex = 1; lessonIndex <= (splitNumberLessons == null ? 1 - : splitNumberLessons); lessonIndex++) { + List lessonInstanceLearners = + splitNumberLessons == null ? learners : new ArrayList<>((learners.size() / splitNumberLessons) + 1); + for (int lessonIndex = 1; + lessonIndex <= (splitNumberLessons == null ? 1 : splitNumberLessons); lessonIndex++) { String lessonInstanceName = lessonName; String learnerGroupInstanceName = learnerGroupName; String staffGroupInstanceName = staffGroupName; @@ -411,16 +390,16 @@ learnerGroupInstanceName += " " + lessonIndex; staffGroupInstanceName += " " + lessonIndex; lessonInstanceLearners.clear(); - for (int learnerIndex = lessonIndex - 1; learnerIndex < learners - .size(); learnerIndex += splitNumberLessons) { + for (int learnerIndex = lessonIndex - 1; + learnerIndex < learners.size(); learnerIndex += splitNumberLessons) { lessonInstanceLearners.add(learners.get(learnerIndex)); } } if (log.isDebugEnabled()) { - log.debug("Creating lesson " - + (splitNumberLessons == null ? "" : "(" + lessonIndex + "/" + splitNumberLessons + ") ") - + "\"" + lessonInstanceName + "\""); + log.debug("Creating lesson " + (splitNumberLessons == null + ? "" + : "(" + lessonIndex + "/" + splitNumberLessons + ") ") + "\"" + lessonInstanceName + "\""); } Lesson lesson = null; @@ -493,8 +472,8 @@ return; } Lesson lesson = lessonService.getLesson(lessonId); - Vector learners = userManagementService - .getUsersFromOrganisationByRole(lesson.getOrganisation().getOrganisationId(), Role.LEARNER, true); + Vector learners = userManagementService.getUsersFromOrganisationByRole( + lesson.getOrganisation().getOrganisationId(), Role.LEARNER, true); lessonService.addLearners(lesson, learners); } @@ -773,7 +752,8 @@ orderAscending); // if the result is less then page size, then no need for full check of user count - Integer userCount = users.size() < MonitoringController.USER_PAGE_SIZE ? users.size() + Integer userCount = users.size() < MonitoringController.USER_PAGE_SIZE + ? users.size() : userManagementService.getCountRoleForOrg(lesson.getOrganisation().getOrganisationId(), isMonitor ? Role.ROLE_MONITOR : Role.ROLE_LEARNER, searchPhrase); @@ -890,8 +870,9 @@ log.info((add ? "Added a " : "Removed a ") + role + " with ID " + userId + (add ? " to" : " from") + " lesson " + lessonId); } else { - log.warn("Failed when trying to " + (add ? "add a " : "remove a ") + role + " with ID " + userId - + (add ? " to" : " from") + " lesson " + lessonId); + log.warn("Failed when trying to " + (add ? "add a " : "remove a ") + role + " with ID " + userId + (add + ? " to" + : " from") + " lesson " + lessonId); } } @@ -929,8 +910,8 @@ String languageOutput = ""; for (int i = 0; i < languageCollection.size(); i++) { - languageOutput += "" - + messageService.getMessage(languageCollection.get(i)) + ""; + languageOutput += "" + messageService.getMessage( + languageCollection.get(i)) + ""; } languageOutput += ""; @@ -1018,15 +999,16 @@ Organisation organisation = (Organisation) userManagementService.findById(Organisation.class, lessonDTO.getOrganisationID()); request.setAttribute("notificationsAvailable", organisation.getEnableCourseNotifications()); - boolean enableLiveEdit = organisation.getEnableLiveEdit() - && userManagementService.isUserInRole(user.getUserID(), organisation.getOrganisationId(), Role.AUTHOR); + boolean enableLiveEdit = + organisation.getEnableLiveEdit() && userManagementService.isUserInRole(user.getUserID(), + organisation.getOrganisationId(), Role.AUTHOR); request.setAttribute("enableLiveEdit", enableLiveEdit); request.setAttribute("lesson", lessonDTO); boolean isTBLSequence = learningDesignService.isTBLSequence(lessonDTO.getLearningDesignID()); request.setAttribute("isTBLSequence", isTBLSequence); if (isTBLSequence) { - Map activityTypesMeta = learningDesignService - .getAvailableTBLActivityTypes(lessonDTO.getLearningDesignID()); + Map activityTypesMeta = learningDesignService.getAvailableTBLActivityTypes( + lessonDTO.getLearningDesignID()); for (Entry entry : activityTypesMeta.entrySet()) { request.setAttribute(entry.getKey(), entry.getValue()); } @@ -1040,6 +1022,24 @@ request.setAttribute("burningQuestionsEnabled", burningQuestionsEnabled); } + // build path to learning design in authoring + // it gets displayed in Edit tab at the bottom + LearningDesign learningDesign = learningDesignService.getLearningDesign(lessonDTO.getLearningDesignID()); + StringBuilder ldPathBuilder = new StringBuilder("/").append(learningDesign.getTitle()); + WorkspaceFolder workspaceFolder = learningDesign.getWorkspaceFolder(); + while (workspaceFolder != null) { + if (workspaceFolder.getParentWorkspaceFolder() == null) { + ldPathBuilder.insert(0, messageService.getMessage("label.monitoring.learning.design.path.courses")); + } else if (workspaceFolder.getWorkspaceFolderType().equals(WorkspaceFolder.RUN_SEQUENCES)) { + ldPathBuilder.insert(0, + "/" + messageService.getMessage("label.monitoring.learning.design.path.run.sequences")); + } else { + ldPathBuilder.insert(0, "/" + workspaceFolder.getName()); + } + workspaceFolder = workspaceFolder.getParentWorkspaceFolder(); + } + request.setAttribute("ldPath", ldPathBuilder.toString()); + return "monitor"; } @@ -1137,8 +1137,8 @@ responseJSON.put("lessonName", HtmlUtils.htmlEscape(lesson.getLessonName())); responseJSON.put("lessonInstructions", learningDesign.getDescription()); - Date startOrScheduleDate = lesson.getStartDateTime() == null ? lesson.getScheduleStartDate() - : lesson.getStartDateTime(); + Date startOrScheduleDate = + lesson.getStartDateTime() == null ? lesson.getScheduleStartDate() : lesson.getStartDateTime(); Date finishDate = lesson.getScheduleEndDate(); DateFormat indfm = null; @@ -1246,15 +1246,15 @@ // find leaders from Leader Selection Tool if (activity.isToolActivity()) { ToolActivity toolActivity = (ToolActivity) activity; - if (ILamsToolService.LEADER_SELECTION_TOOL_SIGNATURE - .equals(toolActivity.getTool().getToolSignature())) { + if (ILamsToolService.LEADER_SELECTION_TOOL_SIGNATURE.equals( + toolActivity.getTool().getToolSignature())) { leaders.addAll(lamsToolService.getLeaderUserId(activity.getActivityId())); } } } - Map learnerCounts = monitoringService - .getCountLearnersCurrentActivities(activityIds.toArray(new Long[activityIds.size()])); + Map learnerCounts = monitoringService.getCountLearnersCurrentActivities( + activityIds.toArray(new Long[activityIds.size()])); ArrayNode activitiesJSON = JsonNodeFactory.instance.arrayNode(); for (Activity activity : activities) { @@ -1275,10 +1275,10 @@ activityJSON.put("x", MonitoringController.getActivityCoordinate(ba.getStartXcoord())); activityJSON.put("y", MonitoringController.getActivityCoordinate(ba.getStartYcoord())); } else if (activity.isOptionsWithSequencesActivity()) { - activityJSON.put("x", MonitoringController - .getActivityCoordinate(((OptionsWithSequencesActivity) activity).getStartXcoord())); - activityJSON.put("y", MonitoringController - .getActivityCoordinate(((OptionsWithSequencesActivity) activity).getStartYcoord())); + activityJSON.put("x", MonitoringController.getActivityCoordinate( + ((OptionsWithSequencesActivity) activity).getStartXcoord())); + activityJSON.put("y", MonitoringController.getActivityCoordinate( + ((OptionsWithSequencesActivity) activity).getStartYcoord())); } else if ((parentActivity != null) && (parentActivity.isOptionsActivity() || parentActivity.isParallelActivity() || parentActivity.isFloatingActivity())) { // Optional Activity children had coordinates relative to parent @@ -1318,7 +1318,7 @@ // insert the searched learner as the first one if ((searchedLearnerProgress != null) && (searchedLearnerProgress.getCurrentActivity() != null) && activity.getActivityId() - .equals(searchedLearnerProgress.getCurrentActivity().getActivityId())) { + .equals(searchedLearnerProgress.getCurrentActivity().getActivityId())) { // put the searched learner in front latestLearners = MonitoringController.insertHighlightedLearner(searchedLearnerProgress.getUser(), latestLearners, MonitoringController.LATEST_LEARNER_PROGRESS_ACTIVITY_DISPLAY_LIMIT); @@ -1478,8 +1478,8 @@ result = true; } else if (precedingActivity.isComplexActivity()) { // check descendants of a complex activity - ComplexActivity complexActivity = (ComplexActivity) monitoringService - .getActivityById(precedingActivity.getActivityId()); + ComplexActivity complexActivity = (ComplexActivity) monitoringService.getActivityById( + precedingActivity.getActivityId()); if (containsActivity(complexActivity, activityAid, monitoringService)) { result = true; } @@ -1502,8 +1502,8 @@ return true; } if (childActivity.isComplexActivity()) { - ComplexActivity childComplexActivity = (ComplexActivity) monitoringService - .getActivityById(childActivity.getActivityId()); + ComplexActivity childComplexActivity = (ComplexActivity) monitoringService.getActivityById( + childActivity.getActivityId()); if (containsActivity(childComplexActivity, targetActivityId, monitoringService)) { return true; } @@ -1659,8 +1659,8 @@ @RequestMapping(path = "/isLearningDesignHasGroupings", method = RequestMethod.GET) @ResponseBody public String isLearningDesignHasGroupings(@RequestParam long learningDesignId) { - List groupingActivities = monitoringService - .getGroupingActivitiesByLearningDesignId(learningDesignId); + List groupingActivities = monitoringService.getGroupingActivitiesByLearningDesignId( + learningDesignId); for (GroupingActivity activity : groupingActivities) { if (!activity.getCreateGrouping().isUsedForBranching()) { return Boolean.TRUE.toString(); @@ -1700,17 +1700,17 @@ List resultContributeActivities = new ArrayList<>(); for (ContributeActivityDTO contributeActivity : contributeActivities) { if (contributeActivity.getContributeEntries() != null) { - Iterator entryIterator = contributeActivity - .getContributeEntries().iterator(); + Iterator entryIterator = contributeActivity.getContributeEntries() + .iterator(); while (entryIterator.hasNext()) { ContributeActivityDTO.ContributeEntry contributeEntry = entryIterator.next(); // extra filtering for chosen branching: do not show in Sequence tab if all users were assigned - if (skipCompletedBranching - && ContributionTypes.CHOSEN_BRANCHING.equals(contributeEntry.getContributionType())) { + if (skipCompletedBranching && ContributionTypes.CHOSEN_BRANCHING.equals( + contributeEntry.getContributionType())) { Set learners = new HashSet<>(lesson.getLessonClass().getLearners()); - ChosenBranchingActivity branching = (ChosenBranchingActivity) monitoringService - .getActivityById(contributeActivity.getActivityID()); + ChosenBranchingActivity branching = (ChosenBranchingActivity) monitoringService.getActivityById( + contributeActivity.getActivityID()); for (SequenceActivity branch : (Set) (Set) branching.getActivities()) { Group group = branch.getSoleGroupForBranch(); if (group != null) { @@ -1760,8 +1760,8 @@ * THIS IS A HACK to retrieve the first tool activity manually so it can be cast as a ToolActivity - if it is * one */ - Activity firstActivity = activityDAO - .getActivityByActivityId(lesson.getLearningDesign().getFirstActivity().getActivityId()); + Activity firstActivity = activityDAO.getActivityByActivityId( + lesson.getLearningDesign().getFirstActivity().getActivityId()); List activities = new ArrayList<>(); sortActivitiesByLearningDesignOrder(firstActivity, activities); @@ -1778,8 +1778,8 @@ Set sequenceActivities = new TreeSet<>(new ActivityOrderComparator()); sequenceActivities.addAll((Set) (Set) branchingActivity.getActivities()); for (Activity sequenceActivityNotInitialized : sequenceActivities) { - SequenceActivity sequenceActivity = (SequenceActivity) monitoringService - .getActivityById(sequenceActivityNotInitialized.getActivityId()); + SequenceActivity sequenceActivity = (SequenceActivity) monitoringService.getActivityById( + sequenceActivityNotInitialized.getActivityId()); Set childActivities = new TreeSet<>(new ActivityOrderComparator()); childActivities.addAll(sequenceActivity.getActivities()); Index: lams_monitoring/web/monitor.jsp =================================================================== diff -u -re0ca5962f24c57a3a693dc5046f8489ab23f5776 -r99df1f178e0956c7f6691ee7c0eda8459ce1b2a2 --- lams_monitoring/web/monitor.jsp (.../monitor.jsp) (revision e0ca5962f24c57a3a693dc5046f8489ab23f5776) +++ lams_monitoring/web/monitor.jsp (.../monitor.jsp) (revision 99df1f178e0956c7f6691ee7c0eda8459ce1b2a2) @@ -10,943 +10,950 @@ - - - <fmt:message key="monitor.title" /> - - - - - - - - - - - - - + + + <fmt:message key="monitor.title" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - -
-
- - -
-
- - - + + + + + +
+
+ + +
+
- - + + - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - -
- -
-
- -
-
- - - - -
-
- -
-
-
- -
-
- - -
-
-
-
-
- - -
- - -
- - - - -
:
-
-
- - - - - - - - - - - - - - - -
- -
- - - - - -
-
- -
:
-
- - - - - -
- style="display: none" - + + + + + + + + + + + + +
+ +
+ + + + + +
+
+ + +
:
+
+ + + + + +
+ style="display: none" + > - -
- - -
- - -
:
-
-
+ + + + + +
:
+
+ - + -
- + + + + +
+
+ + + +
+ +
-
- -
-
-
- -

-
-
-
- - + +
+
+
+ +

- +
+
+ +
+
- - -
-
-
- -
- -
-
+ +
+ +
+
-
- - - - + + + + + + + + + + + + + +
-
- - +
+ + + + - - - - - - - - - - - - - -
+
+ + -
-
- -
-
-
-
- +
+ +
+
+
+
+
-
-
-
-
-
- - - - - - + + + + + + + + + + + + + + + + +
-
- - +
+
+
+
+ + + + + + - - - - - - - - - - - - - - - - -
+
+ + -
-
- -
-
-
-
- -
+
+
+ +
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + +
 
+
+
+
+
-
- + + + +
+
+
+ + + + + + +
+
+ +
+
+
+
- + - - - - - - - - - - - - - -
 
-
-
-
-
- -
-
-
+
+
+ + +
+
- - - - - -
-
- -
-
-
- - - - - - - -
-
-
-
-
-
- - +
+
+ +
+
+ +
+
-
-
- + -
- +
+
-
-
- - - - + + + \ No newline at end of file