Index: lams_central/web/includes/javascript/authoring/authoringGeneral.js =================================================================== diff -u -r6ea65384311c0e9e85c3783f311f594f79aa63d0 -r735e5ff1a7439c3b86b3448b18e324ea20eef5d0 --- lams_central/web/includes/javascript/authoring/authoringGeneral.js (.../authoringGeneral.js) (revision 6ea65384311c0e9e85c3783f311f594f79aa63d0) +++ lams_central/web/includes/javascript/authoring/authoringGeneral.js (.../authoringGeneral.js) (revision 735e5ff1a7439c3b86b3448b18e324ea20eef5d0) @@ -1,4 +1,4 @@ -/** +/** * This file contains main methods for Authoring. */ Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/controller/LearnerController.java =================================================================== diff -u -r72bf0041a18e7e902404c65e55e167bf6ff84269 -r735e5ff1a7439c3b86b3448b18e324ea20eef5d0 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/controller/LearnerController.java (.../LearnerController.java) (revision 72bf0041a18e7e902404c65e55e167bf6ff84269) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/controller/LearnerController.java (.../LearnerController.java) (revision 735e5ff1a7439c3b86b3448b18e324ea20eef5d0) @@ -52,6 +52,7 @@ import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.GateActivity; import org.lamsfoundation.lams.learningdesign.ScheduleGateActivity; +import org.lamsfoundation.lams.learningdesign.ToolActivity; import org.lamsfoundation.lams.learningdesign.dto.ActivityURL; import org.lamsfoundation.lams.learningdesign.dto.GateActivityDTO; import org.lamsfoundation.lams.lesson.CompletedActivityProgress; @@ -431,6 +432,9 @@ activityJSON.put("name", activity.getTitle()); int status = activity.getActivityId().equals(currentActivityId) ? 0 : activity.getStatus(); activityJSON.put("status", status); + if (activity.getIconURL() != null) { + activityJSON.put("iconURL", activity.getIconURL()); + } // URL in learner mode String url = activity.getUrl(); @@ -457,15 +461,15 @@ String type = "a"; if (actType.contains("gate")) { type = "g"; + GateActivity activityObject = (GateActivity) learnerService.getActivity(activity.getActivityId()); + activityJSON.put("gateOpen", activityObject.getGateOpen()); + } else if (actType.contains("grouping")) { + activityJSON.put("isGrouping", true); + } else if (actType.contains("optionswithsequences") || actType.contains("branching")) { + type = "b"; } else if (actType.contains("options") || actType.contains("ordered")) { type = "o"; - } else if (actType.contains("branching")) { - type = "b"; } else { - if (activity.getIconURL() != null) { - activityJSON.put("iconURL", activity.getIconURL()); - } - if (status == 1) { GradebookUserActivity activityMark = gradebookService.getGradebookUserActivity(activity.getActivityId(), learnerId); @@ -475,127 +479,125 @@ } } - Long activityMaxMark = lamsCoreToolService.getActivityMaxPossibleMark(activity.getActivityId()); - if (activityMaxMark != null) { - activityJSON.put("maxMark", activityMaxMark); - } - if (activity.getDuration() != null) { - activityJSON.put("duration", DateUtil.convertTimeToString(activity.getDuration())); - } + Long activityMaxMark = lamsCoreToolService.getActivityMaxPossibleMark(activity.getActivityId()); + if (activityMaxMark != null) { + activityJSON.put("maxMark", activityMaxMark); + } + if (activity.getDuration() != null) { + activityJSON.put("duration", DateUtil.convertTimeToString(activity.getDuration())); + } - activityJSON.put("type", type); - activityJSON.put("isGrouping", actType.contains("grouping")); + activityJSON.put("type", type); + activityJSON.put("isGrouping", actType.contains("grouping")); - if (activity.getChildActivities() != null) { - for (ActivityURL childActivity : activity.getChildActivities()) { - activityJSON.withArray("childActivities") - .add(activityProgressToJSON(childActivity, currentActivityId, lessonId, learnerId, - monitorMode)); + if (activity.getChildActivities() != null) { + for (ActivityURL childActivity : activity.getChildActivities()) { + activityJSON.withArray("childActivities") + .add(activityProgressToJSON(childActivity, currentActivityId, lessonId, learnerId, + monitorMode)); + } } + + return activityJSON; } - return activityJSON; - } - - private ObjectNode getProgressBarMessages() { - ObjectNode progressBarMessages = JsonNodeFactory.instance.objectNode(); - for (String key : MONITOR_MESSAGE_KEYS) { - String value = messageService.getMessage(key); - progressBarMessages.put(key, value); + private ObjectNode getProgressBarMessages () { + ObjectNode progressBarMessages = JsonNodeFactory.instance.objectNode(); + for (String key : MONITOR_MESSAGE_KEYS) { + String value = messageService.getMessage(key); + progressBarMessages.put(key, value); + } + for (String key : LEARNER_MESSAGE_KEYS) { + String value = messageService.getMessage(key); + progressBarMessages.put(key, value); + } + return progressBarMessages; } - for (String key : LEARNER_MESSAGE_KEYS) { - String value = messageService.getMessage(key); - progressBarMessages.put(key, value); - } - return progressBarMessages; - } - /** - * Gets the lesson details based on lesson id or the current tool session - */ - @RequestMapping("/getLessonDetails") - @ResponseBody - public String getLessonDetails(HttpServletRequest request, HttpServletResponse response) throws IOException { + /** + * Gets the lesson details based on lesson id or the current tool session + */ + @RequestMapping("/getLessonDetails") @ResponseBody public String getLessonDetails (HttpServletRequest + request, HttpServletResponse response) throws IOException { - ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); - Lesson lesson = null; + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + Lesson lesson = null; - Long lessonID = WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID, true); - if (lessonID != null) { - lesson = lessonService.getLesson(lessonID); + Long lessonID = WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID, true); + if (lessonID != null) { + lesson = lessonService.getLesson(lessonID); - } else { - Long toolSessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); - ToolSession toolSession = lamsToolService.getToolSession(toolSessionId); - lesson = toolSession.getLesson(); - } + } else { + Long toolSessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + ToolSession toolSession = lamsToolService.getToolSession(toolSessionId); + lesson = toolSession.getLesson(); + } - responseJSON.put(AttributeNames.PARAM_LESSON_ID, lesson.getLessonId()); - responseJSON.put(AttributeNames.PARAM_TITLE, lesson.getLessonName()); - responseJSON.put("allowRestart", lesson.getAllowLearnerRestart()); - responseJSON.put(AttributeNames.PARAM_PRESENCE_ENABLED, lesson.getLearnerPresenceAvailable()); - responseJSON.put(AttributeNames.PARAM_PRESENCE_IM_ENABLED, lesson.getLearnerImAvailable()); + responseJSON.put(AttributeNames.PARAM_LESSON_ID, lesson.getLessonId()); + responseJSON.put(AttributeNames.PARAM_TITLE, lesson.getLessonName()); + responseJSON.put("allowRestart", lesson.getAllowLearnerRestart()); + responseJSON.put(AttributeNames.PARAM_PRESENCE_ENABLED, lesson.getLearnerPresenceAvailable()); + responseJSON.put(AttributeNames.PARAM_PRESENCE_IM_ENABLED, lesson.getLearnerImAvailable()); - response.setContentType("application/json;charset=utf-8"); + response.setContentType("application/json;charset=utf-8"); - return responseJSON.toString(); - } + return responseJSON.toString(); + } - @RequestMapping("/isNextGateActivityOpen") - @ResponseBody - public String isNextGateActivityOpen(@RequestParam(required = false) Long toolSessionId, - @RequestParam(required = false) Long activityId, HttpSession session, Locale locale) { + @RequestMapping("/isNextGateActivityOpen") @ResponseBody public String isNextGateActivityOpen + (@RequestParam(required = false) Long toolSessionId, @RequestParam(required = false) Long + activityId, HttpSession session, Locale locale){ - UserDTO userDto = (UserDTO) session.getAttribute(AttributeNames.USER); - if (userDto == null) { - throw new IllegalArgumentException("No user is logged in"); - } + UserDTO userDto = (UserDTO) session.getAttribute(AttributeNames.USER); + if (userDto == null) { + throw new IllegalArgumentException("No user is logged in"); + } - Integer userId = userDto.getUserID(); - GateActivityDTO gateDto = null; - if (toolSessionId != null) { - gateDto = learnerService.isNextGateActivityOpenByToolSessionId(userId, toolSessionId); - } else if (activityId != null) { - gateDto = learnerService.isNextGateActivityOpenByActivityId(userId, activityId); - } else { - throw new IllegalArgumentException("Either tool session ID or activity ID has to be provided"); - } + Integer userId = userDto.getUserID(); + GateActivityDTO gateDto = null; + if (toolSessionId != null) { + gateDto = learnerService.isNextGateActivityOpenByToolSessionId(userId, toolSessionId); + } else if (activityId != null) { + gateDto = learnerService.isNextGateActivityOpenByActivityId(userId, activityId); + } else { + throw new IllegalArgumentException("Either tool session ID or activity ID has to be provided"); + } - ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); - if (gateDto == null) { - responseJSON.put("status", "open"); - } else { - responseJSON.put("status", "closed"); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + if (gateDto == null) { + responseJSON.put("status", "open"); + } else { + responseJSON.put("status", "closed"); - String message = null; - GateActivity gate = gateDto.getGate(); - if (gate.isScheduleGate()) { - ScheduleGateActivity scheduleGate = (ScheduleGateActivity) gate; - if (!Boolean.TRUE.equals(scheduleGate.getGateActivityCompletionBased())) { - Lesson lesson = gate.getLearningDesign().getLessons().iterator().next(); - User user = userManagementService.getUserById(userId); - TimeZone userTimeZone = TimeZone.getTimeZone(user.getTimeZone()); + String message = null; + GateActivity gate = gateDto.getGate(); + if (gate.isScheduleGate()) { + ScheduleGateActivity scheduleGate = (ScheduleGateActivity) gate; + if (!Boolean.TRUE.equals(scheduleGate.getGateActivityCompletionBased())) { + Lesson lesson = gate.getLearningDesign().getLessons().iterator().next(); + User user = userManagementService.getUserById(userId); + TimeZone userTimeZone = TimeZone.getTimeZone(user.getTimeZone()); - Calendar openTime = new GregorianCalendar(userTimeZone); - Date lessonStartTime = DateUtil.convertToTimeZoneFromDefault(userTimeZone, - lesson.getStartDateTime()); - openTime.setTime(lessonStartTime); - openTime.add(Calendar.MINUTE, scheduleGate.getGateStartTimeOffset().intValue()); - String openDateString = DateUtil.convertToStringForJSON(openTime.getTime(), locale); - message = messageService.getMessage("label.gate.closed.preceding.activity.schedule", - new Object[] { openDateString }); + Calendar openTime = new GregorianCalendar(userTimeZone); + Date lessonStartTime = DateUtil.convertToTimeZoneFromDefault(userTimeZone, + lesson.getStartDateTime()); + openTime.setTime(lessonStartTime); + openTime.add(Calendar.MINUTE, scheduleGate.getGateStartTimeOffset().intValue()); + String openDateString = DateUtil.convertToStringForJSON(openTime.getTime(), locale); + message = messageService.getMessage("label.gate.closed.preceding.activity.schedule", + new Object[] { openDateString }); + } + } else if (gate.isConditionGate()) { + message = messageService.getMessage("label.gate.closed.preceding.activity.condition"); } - } else if (gate.isConditionGate()) { - message = messageService.getMessage("label.gate.closed.preceding.activity.condition"); - } - if (message == null) { - message = messageService.getMessage("label.gate.closed.preceding.activity"); + if (message == null) { + message = messageService.getMessage("label.gate.closed.preceding.activity"); + } + + responseJSON.put("message", message); } - responseJSON.put("message", message); + return responseJSON.toString(); } - - return responseJSON.toString(); - } -} \ No newline at end of file + } \ No newline at end of file Index: lams_learning/web/css/components-learner.css =================================================================== diff -u -r0a4686c3282eeb4f688ffb52a17818d8de6bbfd5 -r735e5ff1a7439c3b86b3448b18e324ea20eef5d0 --- lams_learning/web/css/components-learner.css (.../components-learner.css) (revision 0a4686c3282eeb4f688ffb52a17818d8de6bbfd5) +++ lams_learning/web/css/components-learner.css (.../components-learner.css) (revision 735e5ff1a7439c3b86b3448b18e324ea20eef5d0) @@ -94,30 +94,38 @@ } .component-page-wrapper .component-sidebar .progress-bar-items > li a { - text-decoration: none; color: var(--bs-gray-dark); } .component-page-wrapper .component-sidebar .progress-bar-items > li > .progress-bar-icon { margin-right: .5rem; } +.component-page-wrapper .component-sidebar .progress-bar-items > li > img.progress-bar-icon { + width: 30px; + height: 30px; +} + .component-page-wrapper .component-sidebar .progress-bar-items > li.progress-bar-item-incomplete, -.component-page-wrapper .component-sidebar .progress-bar-items > li.progress-bar-item-incomplete > .progress-bar-icon { +.component-page-wrapper .component-sidebar .progress-bar-items > li.progress-bar-item-incomplete > i.progress-bar-icon { color: var(--bs-gray-700); } .component-page-wrapper .component-sidebar .progress-bar-items > li.progress-bar-item-complete, -.component-page-wrapper .component-sidebar .progress-bar-items > li.progress-bar-item-complete > .progress-bar-icon { +.component-page-wrapper .component-sidebar .progress-bar-items > li.progress-bar-item-complete > i.progress-bar-icon { color: var(--bs-green); } .component-page-wrapper .component-sidebar .progress-bar-items > li.support-bar-item, .component-page-wrapper .component-sidebar .progress-bar-items > li.progress-bar-item-current, -.component-page-wrapper .component-sidebar .progress-bar-items > li.progress-bar-item-current > .progress-bar-icon { +.component-page-wrapper .component-sidebar .progress-bar-items > li.progress-bar-item-current > i.progress-bar-icon { color: var(--bs-black); } +.component-page-wrapper .component-sidebar .progress-bar-items > li.progress-bar-item-current > .progress-bar-activity-name { + font-weight: bold; +} + .component-page-wrapper .component-sidebar .progress-bar-items > li:hover { background-color: var(--bs-white); } Index: lams_learning/web/includes/javascript/learnerPage.js =================================================================== diff -u -r0a4686c3282eeb4f688ffb52a17818d8de6bbfd5 -r735e5ff1a7439c3b86b3448b18e324ea20eef5d0 --- lams_learning/web/includes/javascript/learnerPage.js (.../learnerPage.js) (revision 0a4686c3282eeb4f688ffb52a17818d8de6bbfd5) +++ lams_learning/web/includes/javascript/learnerPage.js (.../learnerPage.js) (revision 735e5ff1a7439c3b86b3448b18e324ea20eef5d0) @@ -21,16 +21,24 @@ let supportBarItems = $('.component-page-wrapper .component-sidebar #support-bar').removeClass('d-none') .find('#support-bar-items').empty(); $.each(result.support, function (activityIndex, activityData) { - let activityItem = $('
  • ').attr('role', 'presentation') - .addClass('support-bar-item progress-bar-item-openable') - .prepend('').appendTo(supportBarItems); + let activityItem = $('
  • ').attr('role', 'presentation').addClass('support-bar-item progress-bar-item-openable'), + activityIconUrl = getActivityIconUrl(activityData), + activityIcon = null; + + if (activityIconUrl) { + activityIcon = $('').attr('src', LAMS_URL + activityIconUrl); + } else { + activityIcon = $(''); + } + let activityLink = $('').text(activityData.name).attr({ 'target': '_blank', 'href': activityData.url, 'role': 'menuitem', 'title': 'Open completed activity' }); - activityItem.addClass('progress-bar-item-openable').append(activityLink); + activityItem.addClass('progress-bar-item-openable').append(activityIcon).append(activityLink) + .appendTo(supportBarItems); }); } @@ -39,26 +47,30 @@ $.each(result.activities, function (activityIndex, activityData) { let activityItem = $('
  • ').attr('role', 'presentation').appendTo(progressBarItems), activityName = !activityData.name && activityData.type === 'g' ? 'Gate' : activityData.name, + activityIconUrl = getActivityIconUrl(activityData), + activityIcon = null; + + if (activityIconUrl) { + activityIcon = $('').attr('src', LAMS_URL + activityIconUrl); + } else { activityIcon = $(''); + } if (activityData.status === 0) { - activityItem.addClass('progress-bar-item-current').text(activityName).prepend(activityIcon); - if (activityData.type === 'g') { - activityIcon.addClass('fa-hourglass-half'); - } else { + activityItem.addClass('progress-bar-item-current').append(activityIcon) + .append($('').text(activityName)); + if (!activityIconUrl) { activityIcon.addClass('fa-pen-to-square'); } } else if (activityData.status === 1) { completedActivityCount++; activityItem.addClass('progress-bar-item-complete').prepend(activityIcon); - if (activityData.type === 'g') { - activityIcon.addClass('fa-hourglass-full'); - } else { + if (!activityIconUrl) { activityIcon.addClass('fa-square-check'); } if (activityData.url) { - let activityLink = $('').text(activityName).attr({ + let activityLink = $('').text(activityName).attr({ 'target': '_blank', 'href': activityData.url, 'role': 'menuitem', @@ -67,10 +79,9 @@ activityItem.addClass('progress-bar-item-openable').append(activityLink); } } else { - activityItem.addClass('progress-bar-item-incomplete').text(activityName).prepend(activityIcon); - if (activityData.type === 'g') { - activityIcon.addClass('fa-hourglass-start'); - } else { + activityItem.addClass('progress-bar-item-incomplete').append(activityIcon) + .append($('').text(activityName)); + if (!activityIconUrl) { activityIcon.addClass('fa-square'); } } @@ -108,4 +119,22 @@ } }); } +} + +function getActivityIconUrl(activityData){ + if (activityData.iconURL){ + return activityData.iconURL; + } + if (activityData.type === 'g') { + return 'images/svg/gate' + (activityData.gateOpen ? 'Open' : 'Closed') + '.svg'; + } + if (activityData.isGrouping) { + return 'images/svg/grouping.svg'; + } + if (activityData.type === 'b') { + return 'images/svg/branchingStart.svg'; + } + if (activityData.type === 'o') { + return 'images/svg/optional.svg'; + } } \ No newline at end of file