Index: lams_tool_assessment/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -rea8629a2ce87bf6bf4b91e1b1d47b908a3dd2e74 -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision ea8629a2ce87bf6bf4b91e1b1d47b908a3dd2e74) +++ lams_tool_assessment/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -132,7 +132,7 @@ label.learning.blockui.time.is.over = Time is over. Processing your answers... label.learning.blockui.are.you.ready = You are going to participate in activity that has time limitation. Are you ready to start? monitoring.tab.summary = Summary -monitoring.tab.statistics = Stats +monitoring.tab.statistics = Analytics monitoring.tab.edit.activity = Edit Activity monitoring.label.group = Group monitoring.label.user.name = Name @@ -245,7 +245,7 @@ label.authoring.advance.numbered.questions = Enable questions' numbering label.learning.draft.autosaved = Draft autosaved label.waiting.for.leader = Please, wait while somebody will become a group leader and enter this activity. -label.users.from.group = Other learners participating in current group: +label.users.from.group = Other learners in your group: label.use.select.leader.tool.output = Use leaders from Select Leader tool label.group.leader = Group leader: {0} label.refresh = Refresh @@ -275,7 +275,7 @@ label.activity.completion = End of activity label.notifications = Notifications label.ask.for.hedging.justification = Ask for hedging justification? -label.number.learners.per.session = Number of learners per session +label.number.learners.per.session = Number of learners in group label.tool.output = Tool Output output.desc.best.score = Best score label.tool.output.has.been.changed = Tool Output has been changed @@ -352,7 +352,7 @@ message.qb.modified.update = The question in Question Bank will be updated message.qb.modified.version = A new version of the question will be created in Question Bank message.qb.modified.new = A new question will be created in Question Bank -label.qb.stats = Question indexes +label.qb.stats = Item analysis label.qb.participant.count = Test participant count label.qb.difficulty.index = Difficulty index label.qb.discrimination.index = Discrimination index @@ -428,3 +428,12 @@ label.authoring.basic.question.version.stats.tooltip = See this version's stats page label.export.questions = Questions label.export.group = Group +label.number.learners.per.activity = Total number of learners +label.activity.stats = Activity stats +label.group.stats = Group stats +label.median.mark = Median: +label.modes.mark = Mode: +label.qb.stats.tooltip = Item analysis is a technique that analyses the student answers to evaluate the effectiveness of questions in an exam. +label.qb.difficulty.index.tooltip = The difficulty index represents a percentage of the students responses that answered the question correctly. This metric takes a value between 0 and 1. High values indicate that the question is easy, while low values indicate that is difficult. +label.qb.discrimination.index.tooltip = Discrimination index measures how well a question distinguishes between students with more knowledge or skill from those with less. Values close to +1 indicate that the question does a good job of discriminating between high performers and low performers. +label.qb.point.biserial.tooltip = Point-biserial measures the correlation between the scores on the entire exam and the scores on the single question (where 1 = correct answer and 0 = incorrect answer). A large correlation indicates that a question is measuring the same construct as the overall exam measures. Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/GradeStatsDTO.java =================================================================== diff -u -r6cda19702eb2790fece3c55bddb223147417af5d -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/GradeStatsDTO.java (.../GradeStatsDTO.java) (revision 6cda19702eb2790fece3c55bddb223147417af5d) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/GradeStatsDTO.java (.../GradeStatsDTO.java) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -18,6 +18,9 @@ private Long sessionId; private String sessionName; + private int numberOfLearners; + private boolean leaderFinished; + private int count; private Float min; private Float max; @@ -80,6 +83,22 @@ return sessionName; } + public int getNumberOfLearners() { + return numberOfLearners; + } + + public void setNumberOfLearners(int numberOfLearners) { + this.numberOfLearners = numberOfLearners; + } + + public boolean isLeaderFinished() { + return leaderFinished; + } + + public void setLeaderFinished(boolean leaderFinished) { + this.leaderFinished = leaderFinished; + } + public List getAssessmentResults() { return assessmentResults; } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -r6cda19702eb2790fece3c55bddb223147417af5d -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 6cda19702eb2790fece3c55bddb223147417af5d) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -25,6 +25,7 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; +import java.security.InvalidParameterException; import java.sql.Timestamp; import java.time.LocalDateTime; import java.util.ArrayList; @@ -1214,7 +1215,24 @@ } else { sessionDto = new GradeStatsDTO(sessionId, session.getSessionName()); + if (session.getAssessment().isUseSelectLeaderToolOuput()) { + sessionDto.setNumberOfLearners(session.getAssessmentUsers().size()); + + AssessmentUser leader = session.getGroupLeader(); + if (leader != null) { + if (leader.isSessionFinished()) { + sessionDto.setLeaderFinished(true); + } else { + AssessmentResult result = getLastAssessmentResult(session.getAssessment().getUid(), + leader.getUserId()); + if (result != null && result.getFinishDate() != null) { + leader.setSessionFinished(true); + } + } + } + } } + sessionDtos.add(sessionDto); } @@ -3981,4 +3999,65 @@ result.putAll(answeredQuestions); return result; } + + @Override + public void changeLeaderForGroup(long toolSessionId, long leaderUserId) { + AssessmentSession session = getSessionBySessionId(toolSessionId); + if (AssessmentConstants.COMPLETED == session.getStatus()) { + throw new InvalidParameterException("Attempting to assing a new leader with user ID " + leaderUserId + + " to a finished session wtih ID " + toolSessionId); + } + + AssessmentUser existingLeader = session.getGroupLeader(); + if (existingLeader == null || existingLeader.getUserId().equals(leaderUserId)) { + return; + } + Assessment assessment = session.getAssessment(); + AssessmentUser newLeader = getUserByIdAndContent(leaderUserId, assessment.getContentId()); + if (newLeader == null) { + User user = userManagementService.getUserById(Long.valueOf(leaderUserId).intValue()); + newLeader = new AssessmentUser(user.getUserDTO(), session); + createUser(newLeader); + + if (log.isDebugEnabled()) { + log.debug("Created user with ID " + leaderUserId + " to become a new leader for session with ID " + + toolSessionId); + } + } else if (!newLeader.getSession().getSessionId().equals(toolSessionId)) { + throw new InvalidParameterException("User with ID " + leaderUserId + " belongs to session with ID " + + newLeader.getSession().getSessionId() + " and not to session with ID " + toolSessionId); + } else { + AssessmentResult newLeaderResult = getLastAssessmentResult(assessment.getUid(), leaderUserId); + if (newLeaderResult != null) { + assessmentDao.delete(newLeaderResult); + } + } + + AssessmentResult existingLeaderResult = getLastAssessmentResult(assessment.getUid(), + existingLeader.getUserId()); + if (existingLeaderResult != null) { + if (existingLeaderResult.getFinishDate() != null) { + throw new InvalidParameterException("Attempting to assing a finished result of leader with user ID " + + existingLeader.getUserId() + " to a new leader with user ID " + leaderUserId + + " in session wtih ID " + toolSessionId); + } + + existingLeaderResult.setUser(newLeader); + assessmentDao.update(existingLeaderResult); + } + + session.setGroupLeader(newLeader); + assessmentDao.update(session); + + if (log.isDebugEnabled()) { + log.debug("User with ID " + leaderUserId + " became a new leader for session with ID " + toolSessionId); + } + + Set userIds = session.getAssessmentUsers().stream().collect( + Collectors.mapping(assessmentUser -> assessmentUser.getUserId().intValue(), Collectors.toSet())); + + ObjectNode jsonCommand = JsonNodeFactory.instance.objectNode(); + jsonCommand.put("hookTrigger", "assessment-leader-change-refresh-" + toolSessionId); + learnerService.createCommandForLearners(assessment.getContentId(), userIds, jsonCommand.toString()); + } } \ No newline at end of file Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java =================================================================== diff -u -r30b838c2ace64169f440c86a9756fd0959cf2323 -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 30b838c2ace64169f440c86a9756fd0959cf2323) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java (.../IAssessmentService.java) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -34,11 +34,10 @@ import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.tool.assessment.dto.AssessmentResultDTO; import org.lamsfoundation.lams.tool.assessment.dto.AssessmentUserDTO; -import org.lamsfoundation.lams.tool.assessment.dto.LeaderResultsDTO; +import org.lamsfoundation.lams.tool.assessment.dto.GradeStatsDTO; import org.lamsfoundation.lams.tool.assessment.dto.QuestionDTO; import org.lamsfoundation.lams.tool.assessment.dto.QuestionSummary; import org.lamsfoundation.lams.tool.assessment.dto.ReflectDTO; -import org.lamsfoundation.lams.tool.assessment.dto.SessionDTO; import org.lamsfoundation.lams.tool.assessment.dto.UserSummary; import org.lamsfoundation.lams.tool.assessment.model.Assessment; import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestion; @@ -398,8 +397,10 @@ * @param contentId * @return */ - List getSessionDtos(Long contentId, boolean includeStatistics); + List getSessionDtos(Long contentId, boolean includeStatistics); + GradeStatsDTO getStatsDtoForActivity(Long contentId); + /** * Prepares question results to be displayed in "Learner Summary" table. Shows all of them in case there is at least * one random question present, and just questions from the question list if no random questions. @@ -457,35 +458,28 @@ * @param sessionDtos * @return */ - List exportSummary(Assessment assessment, List sessionDtos); + List exportSummary(Assessment assessment, List sessionDtos); /** * Gets the basic statistics for the grades for the Leaders when an Assessment is done using * Group Leaders. So the averages, etc are for the whole Assessment, not for a Group. - * - * @param contentId - * @return */ - LeaderResultsDTO getLeaderResultsDTOForLeaders(Long contentId); + GradeStatsDTO getStatsDtoForLeaders(Long contentId); /** * Prepares data for the marks summary graph on the statistics page * - * @param assessment - * @param sessionDtos - * @return */ - List getMarksArray(Long sessionId); + List getMarksArray(Long sessionId); + List getMarksArrayByContentId(Long toolContentId); + /** * Prepares data for the marks summary graph on the statistics page, using the grades for the Leaders * when an Assessment is done using Group Leaders. So the grades are for the whole Assessment, not for a Group. * - * @param assessment - * @param sessionDtos - * @return */ - List getMarksArrayForLeaders(Long contentId); + List getMarksArrayForLeaders(Long contentId); void changeQuestionResultMark(Long questionResultUid, float newMark); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java =================================================================== diff -u -r6cda19702eb2790fece3c55bddb223147417af5d -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 6cda19702eb2790fece3c55bddb223147417af5d) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -1063,6 +1063,26 @@ service.saveOrUpdateAssessment(assessment); } + @RequestMapping(path = "/displayChangeLeaderForGroupDialogFromActivity") + public String displayChangeLeaderForGroupDialogFromActivity( + // tell Change Leader dialog in Leader Selection tool which learner has already reached this activity + @RequestParam(name = AssessmentConstants.PARAM_TOOL_SESSION_ID) long toolSessionId) { + String availableLearners = service.getUsersBySession(toolSessionId).stream() + .collect(Collectors.mapping(user -> Long.toString(user.getUserId()), Collectors.joining(","))); + + return new StringBuilder("redirect:").append(Configuration.get(ConfigurationKeys.SERVER_URL)) + .append("tool/lalead11/monitoring/displayChangeLeaderForGroupDialogFromActivity.do?toolSessionId=") + .append(toolSessionId).append("&availableLearners=").append(availableLearners).toString(); + } + + @RequestMapping(path = "/changeLeaderForGroup", method = RequestMethod.POST) + @ResponseBody + @ResponseStatus(HttpStatus.OK) + public void changeLeaderForGroup(@RequestParam(name = AssessmentConstants.PARAM_TOOL_SESSION_ID) long toolSessionId, + @RequestParam long leaderUserId) { + service.changeLeaderForGroup(toolSessionId, leaderUserId); + } + @SuppressWarnings("unchecked") private SessionMap getSessionMap(HttpServletRequest request) { String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); Index: lams_tool_assessment/web/pages/learning/learning.jsp =================================================================== diff -u -r30b838c2ace64169f440c86a9756fd0959cf2323 -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_assessment/web/pages/learning/learning.jsp (.../learning.jsp) (revision 30b838c2ace64169f440c86a9756fd0959cf2323) +++ lams_tool_assessment/web/pages/learning/learning.jsp (.../learning.jsp) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -274,15 +274,19 @@ function learnerAutosave(){ - // if (isWaitingForConfirmation) return; - + //copy value from CKEditor (only available in essay type of questions) to textarea before ajax submit $("textarea[id^='question']").each(function() { var ckeditorData = CKEDITOR.instances[this.name].getData(); //skip out empty values - this.value = ((ckeditorData == null) || (ckeditorData.replace(/ | |
|\s|

|<\/p>|\xa0/g, "").length == 0)) ? "" : ckeditorData; + this.value = ((ckeditorData == null) || (ckeditorData.replace(/ | |
|\s|

|<\/p>|\xa0/g, "").length == 0)) ? "" : ckeditorData; }); + + + // copy value from lams:textarea (only available in essay and mark hedging type of questions) to hidden input before ajax submit + $("textarea[name$=__textarea]").change(); + //ajax form submit $('#answers').ajaxSubmit({ url: "?sessionMapID=${sessionMapID}&date=" + new Date().getTime(), @@ -327,6 +331,10 @@ } } disableButtons(); + + // copy value from lams:textarea (only available in essay and mark hedging type of questions) to hidden input before submit + $("textarea[name$=__textarea]").change(); + var myForm = $("#answers"); myForm.attr("action", "&isTimelimitExpired=" + isTimelimitExpired); myForm.submit(); Index: lams_tool_assessment/web/pages/monitoring/summary.jsp =================================================================== diff -u -ra8acfcc470265c2243ccba63e9b38cab20d306bd -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_assessment/web/pages/monitoring/summary.jsp (.../summary.jsp) (revision a8acfcc470265c2243ccba63e9b38cab20d306bd) +++ lams_tool_assessment/web/pages/monitoring/summary.jsp (.../summary.jsp) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -662,9 +662,42 @@ } }); } - + // END OF TIME LIMIT + + function showChangeLeaderModal(toolSessionId) { + $('#change-leader-modals').empty() + .load('',{ + toolSessionID : toolSessionId + }); + } + + function onChangeLeaderCallback(response, leaderUserId, toolSessionId){ + if (response.isSuccessful) { + $.ajax({ + 'url' : '', + 'type': 'post', + 'cache' : 'false', + 'data': { + 'toolSessionID' : toolSessionId, + 'leaderUserId' : leaderUserId, + '' : '' + }, + success : function(){ + alert(""); + location.reload(); + }, + error : function(){ + alert(""); + } + }); + + } else { + alert(""); + } + } +

@@ -735,20 +768,36 @@ - -
-
- - - : - - -
- -
- + + +
+
+ + + : + + + + + +
+ +
+ + +
+ +
+
+
@@ -834,3 +883,5 @@ <%@ include file="parts/timeLimit.jsp"%> <%@ include file="parts/dateRestriction.jsp"%> + +
\ No newline at end of file Index: lams_tool_doku/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r8d372a4476d25a498b5af8c04e82576edc7b0976 -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_doku/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8d372a4476d25a498b5af8c04e82576edc7b0976) +++ lams_tool_doku/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -64,7 +64,7 @@ label.team.leader = Team leader: label.monitoring.team.leader = team leader label.waiting.for.leader = Please, wait while somebody will become a group leader and enter this activity. -label.users.from.group = Other learners participating in current group: +label.users.from.group = Other learners in your group: label.refresh = Refresh label.shared.pad.id = Shared pad id that allows using the same pad between several doKu activities label.allow.multiple.leaders = All leaders participate together (applicable only for non-grouped doKu activities) Index: lams_tool_laqa/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -rf86004309489cb81f283d1962b481b4bbb3facd6 -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_laqa/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision f86004309489cb81f283d1962b481b4bbb3facd6) +++ lams_tool_laqa/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -168,7 +168,7 @@ label.learning.rating = Rating button.submit = Finish label.waiting.for.leader = Please, wait while somebody will become a group leader and enter this activity. -label.users.from.group = Other learners participating in current group: +label.users.from.group = Other learners in your group: label.use.select.leader.tool.output = Use leaders from Select Leader tool label.group.leader = Group leader: {0} label.modify.users.response = Modify learner's response Index: lams_tool_sbmt/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -rf86004309489cb81f283d1962b481b4bbb3facd6 -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_sbmt/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision f86004309489cb81f283d1962b481b4bbb3facd6) +++ lams_tool_sbmt/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -147,7 +147,7 @@ errors.maxfilesize = Uploaded file exceeded maximum size: {0} label.add = Add label.waiting.for.leader = Please, wait while somebody will become a group leader and enter this activity. -label.users.from.group = Other learners participating in current group: +label.users.from.group = Other learners in your group: label.refresh = Refresh label.waiting.for.leader.finish = Please wait until a group leader finishes the activity. label.select.leader = Leader selection Index: lams_tool_scratchie/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r281e19ba98aa6bf38fc1f25507a9098304d668fb -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_scratchie/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 281e19ba98aa6bf38fc1f25507a9098304d668fb) +++ lams_tool_scratchie/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -142,7 +142,7 @@ label.monitoring.team.leader = team leader label.authoring.import.qti = Import IMS QTI label.waiting.for.leader = Please, wait while somebody will become a group leader and enter this activity. -label.users.from.group = Other learners participating in current group: +label.users.from.group = Other learners in your group: label.total = Total label.report.by.team.tra = Report by team label.table.below.shows.which.answer.teams.selected.first.try = The table below shows which answer the teams selected on the first try Index: lams_tool_vote/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -rf86004309489cb81f283d1962b481b4bbb3facd6 -r8d440baa0d18441b56553aabcc56e1981a84b206 --- lams_tool_vote/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision f86004309489cb81f283d1962b481b4bbb3facd6) +++ lams_tool_vote/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8d440baa0d18441b56553aabcc56e1981a84b206) @@ -133,7 +133,7 @@ monitor.summary.date.restriction.set = Deadline has been set monitor.summary.date.restriction.removed = Deadline has been removed label.waiting.for.leader = Please, wait while somebody will become a group leader and enter this activity. -label.users.from.group = Other learners participating in current group: +label.users.from.group = Other learners in your group: label.use.select.leader.tool.output = Use leaders from Select Leader tool label.group.leader = Group leader: {0} button.submitActivity = Finish