diff --git a/src/main/java/org/olat/course/assessment/manager/AssessmentToolManagerImpl.java b/src/main/java/org/olat/course/assessment/manager/AssessmentToolManagerImpl.java index b7c49473981e6530e0ed3504ba620fd35b209f68..2592754470ff3ebac83f5b12aa0ddc7c27529164 100644 --- a/src/main/java/org/olat/course/assessment/manager/AssessmentToolManagerImpl.java +++ b/src/main/java/org/olat/course/assessment/manager/AssessmentToolManagerImpl.java @@ -29,7 +29,6 @@ import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; -import org.olat.core.util.CodeHelper; import org.olat.course.assessment.AssessmentToolManager; import org.olat.course.assessment.model.CourseStatistics; import org.olat.course.assessment.model.SearchAssessedIdentityParams; @@ -102,8 +101,7 @@ public class AssessmentToolManagerImpl implements AssessmentToolManager { .append(" )"); } sf.append(" ) group by infos.resource.key"); - - long start = System.nanoTime(); + TypedQuery<Object[]> infos = dbInstance.getCurrentEntityManager() .createQuery(sf.toString(), Object[].class) .setParameter("resourceKey", courseEntry.getOlatResource().getKey()) @@ -111,7 +109,6 @@ public class AssessmentToolManagerImpl implements AssessmentToolManager { if(!params.isAdmin()) { infos.setParameter("identityKey", coach.getKey()); } - CodeHelper.printNanoTime(start, "Infos takes:"); Object[] result = infos.getSingleResult(); Long initalLaunch = (Long)result[0]; diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessedIdentityListController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessedIdentityListController.java index ea00b09130c048d9ba7e4b953bb560334685afd6..dc76d2b72aa7d572ea3df6833cc76884922a004c 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessedIdentityListController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessedIdentityListController.java @@ -51,7 +51,6 @@ import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.event.GenericEventListener; import org.olat.course.CourseFactory; import org.olat.course.ICourse; -import org.olat.course.assessment.AssessedIdentitiesTableDataModel; import org.olat.course.assessment.AssessmentMainController; import org.olat.course.assessment.AssessmentToolManager; import org.olat.course.assessment.IdentityAssessmentEditController; @@ -73,9 +72,6 @@ import org.springframework.beans.factory.annotation.Autowired; * */ public class AssessedIdentityListController extends FormBasicController implements GenericEventListener { - - public static final int USER_PROPS_OFFSET = 500; - public static final String usageIdentifyer = AssessedIdentitiesTableDataModel.usageIdentifyer; private FlexiTableElement tableEl; private AssessedUserTableModel usersTableModel; @@ -108,7 +104,7 @@ public class AssessedIdentityListController extends FormBasicController implemen this.courseEntry = courseEntry; this.assessmentCallback = assessmentCallback; isAdministrativeUser = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles()); - userPropertyHandlers = UserManager.getInstance().getUserPropertyHandlersFor(usageIdentifyer, isAdministrativeUser); + userPropertyHandlers = userManager.getUserPropertyHandlersFor(AssessmentToolConstants.usageIdentifyer, isAdministrativeUser); initForm(ureq); updateModel(); @@ -124,10 +120,10 @@ public class AssessedIdentityListController extends FormBasicController implemen FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(UserCols.username, "select")); - int colIndex = USER_PROPS_OFFSET; + int colIndex = AssessmentToolConstants.USER_PROPS_OFFSET; for (int i = 0; i < userPropertyHandlers.size(); i++) { UserPropertyHandler userPropertyHandler = userPropertyHandlers.get(i); - boolean visible = UserManager.getInstance().isMandatoryUserProperty(usageIdentifyer , userPropertyHandler); + boolean visible = userManager.isMandatoryUserProperty(AssessmentToolConstants.usageIdentifyer , userPropertyHandler); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(visible, userPropertyHandler.i18nColumnDescriptorLabelKey(), colIndex++, "select", false, null)); } @@ -253,7 +249,7 @@ public class AssessedIdentityListController extends FormBasicController implemen case certificate: return certificates.get(row.getIdentityKey()); } } - int propPos = col - USER_PROPS_OFFSET; + int propPos = col - AssessmentToolConstants.USER_PROPS_OFFSET; return row.getIdentityProp(propPos); } diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseOverviewController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseOverviewController.java index d5a5ed57779554edac1b28b81befd402c7f87dda..31f93a4ebaa0f428db900d0ccd89a9f2b75945a3 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseOverviewController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseOverviewController.java @@ -39,18 +39,15 @@ public class AssessmentCourseOverviewController extends BasicController { private final VelocityContainer mainVC; private final AssessmentToReviewSmallController toReviewCtrl; private final AssessmentCourseStatisticsSmallController statisticsCtrl; - - private RepositoryEntry courseEntry; - private final AssessmentToolSecurityCallback assessmentCallback; + public AssessmentCourseOverviewController(UserRequest ureq, WindowControl wControl, RepositoryEntry courseEntry, AssessmentToolSecurityCallback assessmentCallback) { super(ureq, wControl); - this.assessmentCallback = assessmentCallback; mainVC = createVelocityContainer("course_overview"); - toReviewCtrl = new AssessmentToReviewSmallController(ureq, getWindowControl(), assessmentCallback); + toReviewCtrl = new AssessmentToReviewSmallController(ureq, getWindowControl(), courseEntry, assessmentCallback); listenTo(toReviewCtrl); mainVC.put("toReview", toReviewCtrl.getInitialComponent()); diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseController.java index 10b84b1c6374ed3e557d08d2cfeb1836e9f6ad67..2b6f282b067d603ce793bc73cc1caef459b1efb2 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseController.java @@ -27,19 +27,28 @@ import java.util.concurrent.ConcurrentMap; import java.util.function.Function; import java.util.stream.Collectors; +import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.components.link.LinkFactory; +import org.olat.core.gui.components.stack.TooledStackedPanel; +import org.olat.core.gui.components.stack.TooledStackedPanel.Align; import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.Identity; import org.olat.core.util.Util; -import org.olat.course.assessment.AssessedIdentitiesTableDataModel; import org.olat.course.assessment.AssessmentMainController; import org.olat.course.assessment.AssessmentToolManager; import org.olat.course.assessment.bulk.PassedCellRenderer; @@ -65,20 +74,22 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class AssessmentIdentitiesCourseController extends FormBasicController { - public static final int USER_PROPS_OFFSET = 500; - public static final String usageIdentifyer = AssessedIdentitiesTableDataModel.usageIdentifyer; - private final RepositoryEntry courseEntry; private final boolean isAdministrativeUser; private List<UserPropertyHandler> userPropertyHandlers; private final AssessmentToolSecurityCallback assessmentCallback; - + + private Link nextLink, previousLink; private FlexiTableElement tableEl; + private TooledStackedPanel stackPanel; private AssessmentIdentitiesCourseTableModel usersTableModel; + private AssessmentIdentityCourseNodeController currentIdentityCtrl; @Autowired private UserManager userManager; @Autowired + private BaseSecurity securityManager; + @Autowired private CoachingService coachingService; @Autowired private BaseSecurityModule securityModule; @@ -87,17 +98,18 @@ public class AssessmentIdentitiesCourseController extends FormBasicController { @Autowired private AssessmentToolManager assessmentToolManager; - public AssessmentIdentitiesCourseController(UserRequest ureq, WindowControl wControl, RepositoryEntry courseEntry, - AssessmentToolSecurityCallback assessmentCallback) { + public AssessmentIdentitiesCourseController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, + RepositoryEntry courseEntry, AssessmentToolSecurityCallback assessmentCallback) { super(ureq, wControl, "identity_course"); setTranslator(Util.createPackageTranslator(AssessmentMainController.class, getLocale(), getTranslator())); setTranslator(userManager.getPropertyHandlerTranslator(getTranslator())); + this.stackPanel = stackPanel; this.courseEntry = courseEntry; this.assessmentCallback = assessmentCallback; isAdministrativeUser = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles()); - userPropertyHandlers = userManager.getUserPropertyHandlersFor(usageIdentifyer, isAdministrativeUser); + userPropertyHandlers = userManager.getUserPropertyHandlersFor(AssessmentToolConstants.usageIdentifyer, isAdministrativeUser); initForm(ureq); loadModel(); @@ -112,10 +124,10 @@ public class AssessmentIdentitiesCourseController extends FormBasicController { columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.username, "select")); } - int colIndex = USER_PROPS_OFFSET; + int colIndex = AssessmentToolConstants.USER_PROPS_OFFSET; for (int i = 0; i < userPropertyHandlers.size(); i++) { UserPropertyHandler userPropertyHandler = userPropertyHandlers.get(i); - boolean visible = UserManager.getInstance().isMandatoryUserProperty(usageIdentifyer , userPropertyHandler); + boolean visible = UserManager.getInstance().isMandatoryUserProperty(AssessmentToolConstants.usageIdentifyer , userPropertyHandler); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(visible, userPropertyHandler.i18nColumnDescriptorLabelKey(), colIndex++, "select", false, null)); } @@ -165,9 +177,89 @@ public class AssessmentIdentitiesCourseController extends FormBasicController { protected void formOK(UserRequest ureq) { // } + + @Override + public void event(UserRequest ureq, Component source, Event event) { + if(previousLink == source) { + doPrevious(ureq); + } else if(nextLink == source) { + doNext(ureq); + } + super.event(ureq, source, event); + } - + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(tableEl == source) { + if(event instanceof SelectionEvent) { + SelectionEvent se = (SelectionEvent)event; + String cmd = se.getCommand(); + AssessedIdentityCourseRow row = usersTableModel.getObject(se.getIndex()); + if("select".equals(cmd)) { + doSelect(ureq, row); + } + } + } + + super.formInnerEvent(ureq, source, event); + } + private void doNext(UserRequest ureq) { + stackPanel.popController(currentIdentityCtrl); + + Identity currentIdentity = currentIdentityCtrl.getAssessedIdentity(); + int index = getIndexOf(currentIdentity); + if(index >= 0) { + int nextIndex = index + 1;//next + if(nextIndex >= 0 && nextIndex < usersTableModel.getRowCount()) { + doSelect(ureq, usersTableModel.getObject(nextIndex)); + } else if(usersTableModel.getRowCount() > 0) { + doSelect(ureq, usersTableModel.getObject(0)); + } + } + } + + private void doPrevious(UserRequest ureq) { + stackPanel.popController(currentIdentityCtrl); + + Identity currentIdentity = currentIdentityCtrl.getAssessedIdentity(); + int index = getIndexOf(currentIdentity); + if(index >= 0) { + int previousIndex = index - 1;//next + if(previousIndex >= 0 && previousIndex < usersTableModel.getRowCount()) { + doSelect(ureq, usersTableModel.getObject(previousIndex)); + } else if(usersTableModel.getRowCount() > 0) { + doSelect(ureq, usersTableModel.getObject(usersTableModel.getRowCount() - 1)); + } + } + } + private int getIndexOf(Identity identity) { + int index = -1; + for(int i=usersTableModel.getRowCount(); i-->0; ) { + Long rowIdentityKey = usersTableModel.getObject(i).getIdentityKey(); + if(rowIdentityKey.equals(identity.getKey())) { + return i; + } + } + return index; + } + private void doSelect(UserRequest ureq, AssessedIdentityCourseRow row) { + removeAsListenerAndDispose(currentIdentityCtrl); + + Identity assessedIdentity = securityManager.loadIdentityByKey(row.getIdentityKey()); + String fullName = userManager.getUserDisplayName(assessedIdentity); + + currentIdentityCtrl = new AssessmentIdentityCourseNodeController(ureq, getWindowControl(), assessedIdentity); + listenTo(currentIdentityCtrl); + stackPanel.pushController(fullName, currentIdentityCtrl); + + previousLink = LinkFactory.createToolLink("previouselement","", this, "o_icon_previous_toolbar"); + previousLink.setTitle(translate("command.previous")); + stackPanel.addTool(previousLink, Align.rightEdge, false, "o_tool_previous"); + nextLink = LinkFactory.createToolLink("nextelement","", this, "o_icon_next_toolbar"); + nextLink.setTitle(translate("command.next")); + stackPanel.addTool(nextLink, Align.rightEdge, false, "o_tool_next"); + } } diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseNodeController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseNodeController.java index 36dd9a568be903b59c9a8b9de2e37b4dc04a40a1..d6cb82e0026d7150d0d8de6d1df3511a12d13470 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseNodeController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseNodeController.java @@ -24,20 +24,29 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityModule; import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.components.link.LinkFactory; +import org.olat.core.gui.components.stack.TooledStackedPanel; +import org.olat.core.gui.components.stack.TooledStackedPanel.Align; import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.Identity; import org.olat.core.util.Util; -import org.olat.course.assessment.AssessedIdentitiesTableDataModel; import org.olat.course.assessment.AssessmentMainController; import org.olat.course.assessment.AssessmentToolManager; import org.olat.course.assessment.bulk.PassedCellRenderer; @@ -61,8 +70,7 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class AssessmentIdentitiesCourseNodeController extends FormBasicController { - public static final int USER_PROPS_OFFSET = 500; - public static final String usageIdentifyer = AssessedIdentitiesTableDataModel.usageIdentifyer; + private final CourseNode courseNode; private final RepositoryEntry courseEntry; @@ -70,28 +78,36 @@ public class AssessmentIdentitiesCourseNodeController extends FormBasicControlle private final List<UserPropertyHandler> userPropertyHandlers; private final AssessmentToolSecurityCallback assessmentCallback; + + private Link nextLink, previousLink; private FlexiTableElement tableEl; + private final TooledStackedPanel stackPanel; private AssessmentIdentitiesCourseNodeTableModel usersTableModel; + private AssessmentIdentityCourseNodeController currentIdentityCtrl; + @Autowired private UserManager userManager; @Autowired + private BaseSecurity securityManager; + @Autowired private BaseSecurityModule securityModule; @Autowired private AssessmentToolManager assessmentToolManager; - public AssessmentIdentitiesCourseNodeController(UserRequest ureq, WindowControl wControl, + public AssessmentIdentitiesCourseNodeController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, RepositoryEntry courseEntry, CourseNode courseNode, AssessmentToolSecurityCallback assessmentCallback) { super(ureq, wControl, "identity_courseelement"); setTranslator(Util.createPackageTranslator(AssessmentMainController.class, getLocale(), getTranslator())); setTranslator(userManager.getPropertyHandlerTranslator(getTranslator())); this.courseNode = courseNode; + this.stackPanel = stackPanel; this.courseEntry = courseEntry; this.assessmentCallback = assessmentCallback; isAdministrativeUser = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles()); - userPropertyHandlers = userManager.getUserPropertyHandlersFor(usageIdentifyer, isAdministrativeUser); + userPropertyHandlers = userManager.getUserPropertyHandlersFor(AssessmentToolConstants.usageIdentifyer, isAdministrativeUser); initForm(ureq); updateModel(); @@ -111,10 +127,10 @@ public class AssessmentIdentitiesCourseNodeController extends FormBasicControlle columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.username, "select")); } - int colIndex = USER_PROPS_OFFSET; + int colIndex = AssessmentToolConstants.USER_PROPS_OFFSET; for (int i = 0; i < userPropertyHandlers.size(); i++) { UserPropertyHandler userPropertyHandler = userPropertyHandlers.get(i); - boolean visible = UserManager.getInstance().isMandatoryUserProperty(usageIdentifyer , userPropertyHandler); + boolean visible = UserManager.getInstance().isMandatoryUserProperty(AssessmentToolConstants.usageIdentifyer , userPropertyHandler); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(visible, userPropertyHandler.i18nColumnDescriptorLabelKey(), colIndex++, "select", false, null)); } AssessableCourseNode assessableNode = null; @@ -172,5 +188,89 @@ public class AssessmentIdentitiesCourseNodeController extends FormBasicControlle protected void formOK(UserRequest ureq) { // } + + @Override + public void event(UserRequest ureq, Component source, Event event) { + if(previousLink == source) { + doPrevious(ureq); + } else if(nextLink == source) { + doNext(ureq); + } + super.event(ureq, source, event); + } + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(tableEl == source) { + if(event instanceof SelectionEvent) { + SelectionEvent se = (SelectionEvent)event; + String cmd = se.getCommand(); + AssessedIdentityCourseElementRow row = usersTableModel.getObject(se.getIndex()); + if("select".equals(cmd)) { + doSelect(ureq, row); + } + } + } + + super.formInnerEvent(ureq, source, event); + } + + private void doNext(UserRequest ureq) { + stackPanel.popController(currentIdentityCtrl); + + Identity currentIdentity = currentIdentityCtrl.getAssessedIdentity(); + int index = getIndexOf(currentIdentity); + if(index >= 0) { + int nextIndex = index + 1;//next + if(nextIndex >= 0 && nextIndex < usersTableModel.getRowCount()) { + doSelect(ureq, usersTableModel.getObject(nextIndex)); + } else if(usersTableModel.getRowCount() > 0) { + doSelect(ureq, usersTableModel.getObject(0)); + } + } + } + + private void doPrevious(UserRequest ureq) { + stackPanel.popController(currentIdentityCtrl); + + Identity currentIdentity = currentIdentityCtrl.getAssessedIdentity(); + int index = getIndexOf(currentIdentity); + if(index >= 0) { + int previousIndex = index - 1;//next + if(previousIndex >= 0 && previousIndex < usersTableModel.getRowCount()) { + doSelect(ureq, usersTableModel.getObject(previousIndex)); + } else if(usersTableModel.getRowCount() > 0) { + doSelect(ureq, usersTableModel.getObject(usersTableModel.getRowCount() - 1)); + } + } + } + + private int getIndexOf(Identity identity) { + int index = -1; + for(int i=usersTableModel.getRowCount(); i-->0; ) { + Long rowIdentityKey = usersTableModel.getObject(i).getIdentityKey(); + if(rowIdentityKey.equals(identity.getKey())) { + return i; + } + } + return index; + } + + private void doSelect(UserRequest ureq, AssessedIdentityCourseElementRow row) { + removeAsListenerAndDispose(currentIdentityCtrl); + + Identity assessedIdentity = securityManager.loadIdentityByKey(row.getIdentityKey()); + String fullName = userManager.getUserDisplayName(assessedIdentity); + + currentIdentityCtrl = new AssessmentIdentityCourseNodeController(ureq, getWindowControl(), assessedIdentity); + listenTo(currentIdentityCtrl); + stackPanel.pushController(fullName, currentIdentityCtrl); + + previousLink = LinkFactory.createToolLink("previouselement","", this, "o_icon_previous_toolbar"); + previousLink.setTitle(translate("command.previous")); + stackPanel.addTool(previousLink, Align.rightEdge, false, "o_tool_previous"); + nextLink = LinkFactory.createToolLink("nextelement","", this, "o_icon_next_toolbar"); + nextLink.setTitle(translate("command.next")); + stackPanel.addTool(nextLink, Align.rightEdge, false, "o_tool_next"); + } } diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseNodeTableModel.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseNodeTableModel.java index c32ba7e2478962c9514e349f1277f2a86f20956a..c26f6963454d6d233d6dadcb142c2ad77413097c 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseNodeTableModel.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseNodeTableModel.java @@ -82,7 +82,7 @@ public class AssessmentIdentitiesCourseNodeTableModel extends DefaultFlexiTableD case lastScoreUpdate: return aEntry == null ? null : aEntry.getLastModified(); } } - int propPos = col - AssessmentIdentitiesCourseNodeController.USER_PROPS_OFFSET; + int propPos = col - AssessmentToolConstants.USER_PROPS_OFFSET; return row.getIdentityProp(propPos); } diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseTableModel.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseTableModel.java index b0e00825ad4a37638ee3e2a7f5faa71643f60198..ae092363e551b9566c34cdc6e0f28091a6bd54de 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseTableModel.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseTableModel.java @@ -74,7 +74,7 @@ public class AssessmentIdentitiesCourseTableModel extends DefaultFlexiTableDataM case lastScoreUpdate: return statement == null ? null : statement.getLastModified(); } } - int propPos = col - AssessmentIdentitiesCourseController.USER_PROPS_OFFSET; + int propPos = col - AssessmentToolConstants.USER_PROPS_OFFSET; return row.getIdentityProp(propPos); } diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseTreeController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseTreeController.java index 3380cef3224fbcf75ead1698cc5e8578b4fc613e..42d7a5784f1dc53d6ce0d3127ef00276e00bb662 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseTreeController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentitiesCourseTreeController.java @@ -31,10 +31,14 @@ import org.olat.core.gui.components.tree.GenericTreeModel; import org.olat.core.gui.components.tree.GenericTreeNode; import org.olat.core.gui.components.tree.MenuTree; import org.olat.core.gui.components.tree.TreeModel; +import org.olat.core.gui.components.tree.TreeNode; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; +import org.olat.core.gui.control.generic.dtabs.Activateable2; +import org.olat.core.id.context.ContextEntry; +import org.olat.core.id.context.StateEntry; import org.olat.course.CourseFactory; import org.olat.course.ICourse; import org.olat.course.nodes.AssessableCourseNode; @@ -50,11 +54,11 @@ import org.olat.repository.RepositoryEntry; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class AssessmentIdentitiesCourseTreeController extends BasicController { +public class AssessmentIdentitiesCourseTreeController extends BasicController implements Activateable2 { private final MenuTree menuTree; private final Panel mainPanel; - private TooledStackedPanel stackPanel; + private final TooledStackedPanel stackPanel; private Controller currentCtrl; private final RepositoryEntry courseEntry; @@ -137,6 +141,16 @@ public class AssessmentIdentitiesCourseTreeController extends BasicController { // } + @Override + public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) { + if(entries == null || entries.isEmpty()) { + TreeNode rootNode = menuTree.getTreeModel().getRootNode(); + if(rootNode.getUserObject() instanceof CourseNode) { + doSelectCourseNode(ureq, (CourseNode)rootNode.getUserObject()); + } + } + } + @Override protected void event(UserRequest ureq, Component source, Event event) { if (source == menuTree) { @@ -154,9 +168,9 @@ public class AssessmentIdentitiesCourseTreeController extends BasicController { ICourse course = CourseFactory.loadCourse(courseEntry); if(course.getRunStructure().getRootNode().equals(courseNode)) { - currentCtrl = new AssessmentIdentitiesCourseController(ureq, getWindowControl(), courseEntry, assessmentCallback); + currentCtrl = new AssessmentIdentitiesCourseController(ureq, getWindowControl(), stackPanel, courseEntry, assessmentCallback); } else { - currentCtrl = new AssessmentIdentitiesCourseNodeController(ureq, getWindowControl(), courseEntry, courseNode, assessmentCallback); + currentCtrl = new AssessmentIdentitiesCourseNodeController(ureq, getWindowControl(), stackPanel, courseEntry, courseNode, assessmentCallback); } listenTo(currentCtrl); mainPanel.setContent(currentCtrl.getInitialComponent()); diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityCourseController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityCourseController.java new file mode 100644 index 0000000000000000000000000000000000000000..c71e1336ca3bad8b44859689a0d8c7d20838acea --- /dev/null +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityCourseController.java @@ -0,0 +1,78 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.assessment.ui.tool; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.controller.BasicController; +import org.olat.core.id.Identity; +import org.olat.course.assessment.AssessedIdentityInfosController; + +/** + * + * Initial date: 09.10.2015<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class AssessmentIdentityCourseController extends BasicController { + + private final Identity assessedIdentity; + + private final VelocityContainer identityAssessmentVC; + private AssessedIdentityInfosController infosController; + + public AssessmentIdentityCourseController(UserRequest ureq, WindowControl wControl, + Identity assessedIdentity) { + super(ureq, wControl); + + this.assessedIdentity = assessedIdentity; + + identityAssessmentVC = createVelocityContainer("identity_personal_infos"); + identityAssessmentVC.contextPut("user", assessedIdentity.getUser()); + + infosController = new AssessedIdentityInfosController(ureq, wControl, assessedIdentity); + listenTo(infosController); + identityAssessmentVC.put("identityInfos", infosController.getInitialComponent()); + + putInitialPanel(identityAssessmentVC); + } + + public Identity getAssessedIdentity() { + return assessedIdentity; + } + + @Override + protected void doDispose() { + // + } + + @Override + protected void event(UserRequest ureq, Component source, Event event) { + // + } + + + + + +} diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityCourseNodeController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityCourseNodeController.java new file mode 100644 index 0000000000000000000000000000000000000000..da662678e67a34f35e777ed5755f8564a58b49f0 --- /dev/null +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentIdentityCourseNodeController.java @@ -0,0 +1,78 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.assessment.ui.tool; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.controller.BasicController; +import org.olat.core.id.Identity; +import org.olat.course.assessment.AssessedIdentityInfosController; + +/** + * + * Initial date: 09.10.2015<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class AssessmentIdentityCourseNodeController extends BasicController { + + private final Identity assessedIdentity; + + private final VelocityContainer identityAssessmentVC; + private AssessedIdentityInfosController infosController; + + public AssessmentIdentityCourseNodeController(UserRequest ureq, WindowControl wControl, + Identity assessedIdentity) { + super(ureq, wControl); + + this.assessedIdentity = assessedIdentity; + + identityAssessmentVC = createVelocityContainer("identity_personal_infos"); + identityAssessmentVC.contextPut("user", assessedIdentity.getUser()); + + infosController = new AssessedIdentityInfosController(ureq, wControl, assessedIdentity); + listenTo(infosController); + identityAssessmentVC.put("identityInfos", infosController.getInitialComponent()); + + putInitialPanel(identityAssessmentVC); + } + + public Identity getAssessedIdentity() { + return assessedIdentity; + } + + @Override + protected void doDispose() { + // + } + + @Override + protected void event(UserRequest ureq, Component source, Event event) { + // + } + + + + + +} diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToReviewSmallController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToReviewSmallController.java index 8974ee968e999d8c69c5e43299f50523851e70e1..4a23c4b9ee9402595fa79d8ac181a10ef834c483 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToReviewSmallController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToReviewSmallController.java @@ -19,12 +19,45 @@ */ package org.olat.course.assessment.ui.tool; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.olat.basesecurity.BaseSecurityModule; +import org.olat.core.commons.persistence.SortKey; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiColumnDef; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; +import org.olat.core.id.Identity; +import org.olat.core.util.Util; +import org.olat.core.util.nodes.INode; +import org.olat.core.util.tree.TreeVisitor; +import org.olat.core.util.tree.Visitor; +import org.olat.course.CourseFactory; +import org.olat.course.Structure; +import org.olat.course.assessment.AssessmentMainController; +import org.olat.course.assessment.AssessmentToolManager; +import org.olat.course.assessment.model.SearchAssessedIdentityParams; +import org.olat.course.nodes.CourseNode; +import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback; +import org.olat.repository.RepositoryEntry; +import org.olat.user.UserManager; +import org.olat.user.UserPropertiesRow; +import org.olat.user.propertyhandlers.UserPropertyHandler; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -34,19 +67,98 @@ import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback; */ public class AssessmentToReviewSmallController extends FormBasicController { - private final AssessmentToolSecurityCallback assessmentCallback;; + + + private final RepositoryEntry courseEntry; + private final boolean isAdministrativeUser; + private final AssessmentToolSecurityCallback assessmentCallback; + + private FlexiTableElement tableEl; + private UsersToReviewTableModel usersTableModel; + private final List<UserPropertyHandler> userPropertyHandlers; + private final Map<String,String> nodeIdentToNodeShortTitles; + + @Autowired + private UserManager userManager; + @Autowired + private BaseSecurityModule securityModule; + @Autowired + private AssessmentToolManager assessmentToolManager; public AssessmentToReviewSmallController(UserRequest ureq, WindowControl wControl, - AssessmentToolSecurityCallback assessmentCallback) { - super(ureq, wControl); + RepositoryEntry courseEntry, AssessmentToolSecurityCallback assessmentCallback) { + super(ureq, wControl, "overview_to_review"); + setTranslator(Util.createPackageTranslator(AssessmentMainController.class, getLocale(), getTranslator())); + setTranslator(userManager.getPropertyHandlerTranslator(getTranslator())); + + this.courseEntry = courseEntry; this.assessmentCallback = assessmentCallback; + isAdministrativeUser = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles()); + userPropertyHandlers = userManager.getUserPropertyHandlersFor(AssessmentToolConstants.reducedUsageIdentifyer, isAdministrativeUser); + + nodeIdentToNodeShortTitles = new HashMap<>(); + Structure structure = CourseFactory.loadCourse(courseEntry).getRunStructure(); + new TreeVisitor(new Visitor() { + @Override + public void visit(INode node) { + if(node instanceof CourseNode) { + CourseNode tNode = (CourseNode)node; + nodeIdentToNodeShortTitles.put(tNode.getIdent(), tNode.getShortTitle()); + } + } + }, structure.getRootNode(), false).visitAll(); + initForm(ureq); + loadModel(); } @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - // + //add the table + FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); + if(isAdministrativeUser) { + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ToReviewCols.username, "select")); + } + + int colIndex = AssessmentToolConstants.USER_PROPS_OFFSET; + for (int i = 0; i < userPropertyHandlers.size(); i++) { + UserPropertyHandler userPropertyHandler = userPropertyHandlers.get(i); + boolean visible = UserManager.getInstance().isMandatoryUserProperty(AssessmentToolConstants.reducedUsageIdentifyer , userPropertyHandler); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(visible, userPropertyHandler.i18nColumnDescriptorLabelKey(), colIndex++, "select", false, null)); + } + + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(ToReviewCols.toReview, "select", + new ElementToReviewCellRenderer(nodeIdentToNodeShortTitles, getTranslator()))); + + usersTableModel = new UsersToReviewTableModel(columnsModel); + tableEl = uifactory.addTableElement(getWindowControl(), "table", usersTableModel, 20, false, getTranslator(), formLayout); + tableEl.setNumOfRowsEnabled(false); + tableEl.setExportEnabled(false); + tableEl.setCustomizeColumns(false); + } + + private void loadModel() { + SearchAssessedIdentityParams params = new SearchAssessedIdentityParams(courseEntry, null, null, assessmentCallback); + List<AssessmentEntry> entries = assessmentToolManager.getAssessmentEntries(getIdentity(), params, AssessmentEntryStatus.inReview); + List<UserToReviewRow> rows = new ArrayList<>(); + + Map<Long,UserToReviewRow> identityKeyToRow = new HashMap<>(); + for(AssessmentEntry entry:entries) { + Identity assessedIdentity = entry.getIdentity(); + if(identityKeyToRow.containsKey(assessedIdentity.getKey())) { + identityKeyToRow.get(assessedIdentity.getKey()) + .getNodeIndents().add(entry.getSubIdent()); + } else { + UserToReviewRow row = new UserToReviewRow(entry.getIdentity(), userPropertyHandlers, getLocale()); + row.getNodeIndents().add(entry.getSubIdent()); + rows.add(row); + identityKeyToRow.put(assessedIdentity.getKey(), row); + } + } + + usersTableModel.setObjects(rows); + tableEl.reset(); } @Override @@ -58,9 +170,68 @@ public class AssessmentToReviewSmallController extends FormBasicController { protected void formOK(UserRequest ureq) { // } + + public static class UserToReviewRow extends UserPropertiesRow implements ToReviewRow { + + private List<String> nodeIndents = new ArrayList<>(3); + + public UserToReviewRow(Identity identity, List<UserPropertyHandler> userPropertyHandlers, Locale locale) { + super(identity, userPropertyHandlers, locale); + } + public List<String> getNodeIndents() { + return nodeIndents; + } + } - - + public class UsersToReviewTableModel extends DefaultFlexiTableDataModel<UserToReviewRow> implements SortableFlexiTableDataModel<UserToReviewRow> { + + public UsersToReviewTableModel(FlexiTableColumnModel columnModel) { + super(columnModel); + } + + @Override + public void sort(SortKey sortKey) { + // + } + + @Override + public Object getValueAt(int row, int col) { + UserToReviewRow identityRow = getObject(row); + return getValueAt(identityRow, col); + } -} + @Override + public Object getValueAt(UserToReviewRow row, int col) { + if(col >= 0 && col < ToReviewCols.values().length) { + switch(ToReviewCols.values()[col]) { + case username: return row.getIdentityName(); + case toReview: return row; + } + } + int propPos = col - AssessmentToolConstants.USER_PROPS_OFFSET; + return row.getIdentityProp(propPos); + } + + @Override + public DefaultFlexiTableDataModel<UserToReviewRow> createCopyWithEmptyList() { + return new UsersToReviewTableModel(getTableColumnModel()); + } + } + + public enum ToReviewCols implements FlexiColumnDef { + + username("table.header.name"), + toReview("table.header.elements.toReview"); + + private final String i18nKey; + + private ToReviewCols(String i18nKey) { + this.i18nKey = i18nKey; + } + + public String i18nHeaderKey() { + return i18nKey; + } + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToolConstants.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToolConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..1b5de61ac7c2cd5f25c8a5ca8f5d7d3b7d8e771a --- /dev/null +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToolConstants.java @@ -0,0 +1,37 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.assessment.ui.tool; + +import org.olat.course.assessment.AssessedIdentitiesTableDataModel; + +/** + * + * Initial date: 09.10.2015<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class AssessmentToolConstants { + + public static final int USER_PROPS_OFFSET = 500; + public static final String usageIdentifyer = AssessedIdentitiesTableDataModel.class.getCanonicalName(); + + public static final String reducedUsageIdentifyer = AssessmentToReviewSmallController.class.getCanonicalName(); + +} diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToolController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToolController.java index e59a70a5194af06b294169370e9dfa4783871fb8..6d6cd13f79af3da5a104cbf70f7275fe3cc03de8 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToolController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentToolController.java @@ -96,9 +96,11 @@ public class AssessmentToolController extends MainLayoutBasicController implemen private void doSelectUsersView(UserRequest ureq) { removeAsListenerAndDispose(currentCtl); - currentCtl = new AssessmentIdentitiesCourseTreeController(ureq, getWindowControl(), stackPanel, + AssessmentIdentitiesCourseTreeController treeCtrl = new AssessmentIdentitiesCourseTreeController(ureq, getWindowControl(), stackPanel, courseEntry, assessmentCallback); - listenTo(currentCtl); - stackPanel.pushController(translate("users"), currentCtl); + listenTo(treeCtrl); + stackPanel.pushController(translate("users"), treeCtrl); + currentCtl = treeCtrl; + treeCtrl.activate(ureq, null, null); } } diff --git a/src/main/java/org/olat/course/assessment/ui/tool/ElementToReviewCellRenderer.java b/src/main/java/org/olat/course/assessment/ui/tool/ElementToReviewCellRenderer.java new file mode 100644 index 0000000000000000000000000000000000000000..570bff746ae1a38fe01985327c50377977cc5eb5 --- /dev/null +++ b/src/main/java/org/olat/course/assessment/ui/tool/ElementToReviewCellRenderer.java @@ -0,0 +1,64 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.assessment.ui.tool; + +import java.util.List; +import java.util.Map; + +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; +import org.olat.core.gui.render.Renderer; +import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.URLBuilder; +import org.olat.core.gui.translator.Translator; + +/** + * + * Initial date: 09.10.2015<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class ElementToReviewCellRenderer implements FlexiCellRenderer { + + private final Translator translator; + private final Map<String,String> nodeIdentToNodeShortTitles; + + public ElementToReviewCellRenderer(Map<String,String> nodeIdentToNodeShortTitles, Translator translator) { + this.nodeIdentToNodeShortTitles = nodeIdentToNodeShortTitles; + this.translator = translator; + } + + @Override + public void render(Renderer renderer, StringOutput target, Object cellValue, int row, + FlexiTableComponent source, URLBuilder ubu, Translator trans) { + if(cellValue instanceof ToReviewRow) { + ToReviewRow rowToReview = (ToReviewRow)cellValue; + List<String> elements = rowToReview.getNodeIndents(); + if(elements.size() == 1) { + String msg = nodeIdentToNodeShortTitles.get(elements.get(0)); + target.append(msg); + } else { + String msg = translator.translate("elements.to.review", new String[]{ Integer.toString(elements.size()) }); + target.append("<i class='o_icon o_icon_important'> </i> "); + target.append(msg); + } + } + } +} diff --git a/src/main/java/org/olat/course/assessment/ui/tool/ToReviewRow.java b/src/main/java/org/olat/course/assessment/ui/tool/ToReviewRow.java new file mode 100644 index 0000000000000000000000000000000000000000..d1acd51cb0d6104e1402fc3234f0ada1c3b67786 --- /dev/null +++ b/src/main/java/org/olat/course/assessment/ui/tool/ToReviewRow.java @@ -0,0 +1,35 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.assessment.ui.tool; + +import java.util.List; + +/** + * + * + * Initial date: 09.10.2015<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface ToReviewRow { + + public List<String> getNodeIndents(); + +} diff --git a/src/main/java/org/olat/course/assessment/ui/tool/_content/course_overview.html b/src/main/java/org/olat/course/assessment/ui/tool/_content/course_overview.html index ea1d337bdaf52ff4401bfdaa7ec948f1a83d9aa2..37a52450f2be76ef53e3aecf2b25d32016d40535 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/_content/course_overview.html +++ b/src/main/java/org/olat/course/assessment/ui/tool/_content/course_overview.html @@ -1,7 +1,6 @@ <h2>Overview</h2> <div class="row"> <div class="col-sm-6"> - <h4><i class="o_icon o_icon_back_history"> </i> Reviews waiting</h4> #if($r.available("toReview")) $r.render("toReview") #end diff --git a/src/main/java/org/olat/course/assessment/ui/tool/_content/identity_personal_infos.html b/src/main/java/org/olat/course/assessment/ui/tool/_content/identity_personal_infos.html new file mode 100644 index 0000000000000000000000000000000000000000..112054f786de0b7104215f974d556c283c09a671 --- /dev/null +++ b/src/main/java/org/olat/course/assessment/ui/tool/_content/identity_personal_infos.html @@ -0,0 +1,4 @@ + +#if($r.available("identityInfos")) + $r.render("identityInfos") +#end diff --git a/src/main/java/org/olat/course/assessment/ui/tool/_content/overview_to_review.html b/src/main/java/org/olat/course/assessment/ui/tool/_content/overview_to_review.html new file mode 100644 index 0000000000000000000000000000000000000000..d8531555a00507e279db2b19eae5a1d408acc00a --- /dev/null +++ b/src/main/java/org/olat/course/assessment/ui/tool/_content/overview_to_review.html @@ -0,0 +1,6 @@ +<div class="panel panel-default"> + <div class="panel-heading"> + <h4 class="panel-title"><i class="o_icon o_icon_back_history"> </i> $r.translate("waiting.review")</h4> + </div> + $r.render("table") +</div> \ No newline at end of file diff --git a/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_de.properties index efe0b7c281985a5045937f7f7b66418dbd0b62f8..a2ad26ca9c27dbd8fd7a8befaab26a5a1d532d5b 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_de.properties @@ -1,14 +1,19 @@ #Mon Mar 02 09:54:04 CET 2009 +command.next=Weiter zu nächste Benutzer +command.previous=Zurück zum letzten Benutzer users=Benutzer table.header.name=Benutzername statistics.small.overview=Statistiken Übersicht - table.header.numOfAssessedIdentities=# Teilnehmer table.header.numOfPassed=Bestanden table.header.scoreAverage=Durschnitt table.header.numOfInitialLaunch=Eingeloggt table.header.assessmentStatus=Status +table.header.elements.toReview=Elements assessment.status.notStart=Nicht gestartet assessment.status.inProgress=Gestartet assessment.status.inReview=Korrigieren assessment.status.done=Bewertet +table.entries=Entries +waiting.review=Pending reviews +elements.to.review=<i class="o_icon o_icon_warning"> </i> {0} pending diff --git a/src/main/java/org/olat/course/nodes/iq/IQRunController.java b/src/main/java/org/olat/course/nodes/iq/IQRunController.java index ddca53a0de8f382d9b4477642fd0cfdbadfa7855..2fc737b7b532f97c06451e88961427d953261935 100644 --- a/src/main/java/org/olat/course/nodes/iq/IQRunController.java +++ b/src/main/java/org/olat/course/nodes/iq/IQRunController.java @@ -86,6 +86,7 @@ import org.olat.ims.qti.process.ImsRepositoryResolver; import org.olat.instantMessaging.InstantMessagingService; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.iq.IQDisplayController; import org.olat.modules.iq.IQManager; import org.olat.modules.iq.IQSecurityCallback; @@ -468,21 +469,27 @@ public class IQRunController extends BasicController implements GenericEventList if (type.equals(AssessmentInstance.QMD_ENTRY_TYPE_ASSESS)) { AssessmentContext ac = ai.getAssessmentContext(); AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager(); - Float score = new Float(ac.getScore()); - Boolean passed = new Boolean(ac.isPassed()); - ScoreEvaluation sceval = new ScoreEvaluation(score, passed, am.getNodeFullyAssessed(courseNode, - getIdentity()), new Long(ai.getAssessID())); - AssessableCourseNode acn = (AssessableCourseNode)courseNode; // assessment nodes are assesable - boolean incrementUserAttempts = true; - acn.updateUserScoreEvaluation(sceval, userCourseEnv, getIdentity(), incrementUserAttempts); + Boolean fullyAssed = am.getNodeFullyAssessed(courseNode, getIdentity()); + + String correctionMode = courseNode.getModuleConfiguration().getStringValue(IQEditController.CONFIG_CORRECTION_MODE); + AssessmentEntryStatus assessmentStatus; + if(IQEditController.CORRECTION_MANUAL.equals(correctionMode)) { + assessmentStatus = AssessmentEntryStatus.inReview; + } else { + assessmentStatus = AssessmentEntryStatus.done; + } + + ScoreEvaluation sceval = new ScoreEvaluation(ac.getScore(), ac.isPassed(), assessmentStatus, fullyAssed, ai.getAssessID()); + AssessableCourseNode acn = (AssessableCourseNode)courseNode; // assessment nodes are assesable + acn.updateUserScoreEvaluation(sceval, userCourseEnv, getIdentity(), true); // Mark publisher for notifications Long courseId = userCourseEnv.getCourseEnvironment().getCourseResourceableId(); assessmentNotificationsHandler.markPublisherNews(getIdentity(), courseId); if(!assessmentStopped) { - assessmentStopped = true; - AssessmentEvent assessmentStoppedEvent = new AssessmentEvent(AssessmentEvent.TYPE.STOPPED, userSession); - singleUserEventCenter.deregisterFor(this, assessmentInstanceOres); + assessmentStopped = true; + AssessmentEvent assessmentStoppedEvent = new AssessmentEvent(AssessmentEvent.TYPE.STOPPED, userSession); + singleUserEventCenter.deregisterFor(this, assessmentInstanceOres); singleUserEventCenter.fireEventToListenersOf(assessmentStoppedEvent, assessmentEventOres); } } else if (type.equals(AssessmentInstance.QMD_ENTRY_TYPE_SURVEY)) { diff --git a/src/main/java/org/olat/course/run/CourseRuntimeController.java b/src/main/java/org/olat/course/run/CourseRuntimeController.java index 35f3246131af6975e1c053a3d9d7c2a0e9274d7a..cd4426391370c8c65116d4b66015b5afffc4a7de 100644 --- a/src/main/java/org/olat/course/run/CourseRuntimeController.java +++ b/src/main/java/org/olat/course/run/CourseRuntimeController.java @@ -423,7 +423,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im assessmentLink.setElementCssClass("o_sel_course_assessment_tool"); tools.addComponent(assessmentLink); - assessment_v2_Link = LinkFactory.createToolLink("assessment", translate("command.openassessment") + " v2", this, "o_icon_rocket"); + assessment_v2_Link = LinkFactory.createToolLink("assessment", translate("command.openassessment") + " v2", this, "o_icon_assessment_tool"); assessment_v2_Link.setElementCssClass("o_sel_course_assessment_tool"); tools.addComponent(assessment_v2_Link); @@ -929,6 +929,22 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im //the wrong link to the wrong person } } + } else if ("assessmentToolv2".equalsIgnoreCase(type)) { + //check the security before, the link is perhaps in the wrong hands + if(reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) { + try { + Activateable2 assessmentCtrl = doAssessmentTool_v2(ureq); + List<ContextEntry> subEntries; + if(entries.size() > 1 && entries.get(1).getOLATResourceable().getResourceableTypeName().equals(type)) { + subEntries = entries.subList(2, entries.size()); + } else { + subEntries = entries.subList(1, entries.size()); + } + assessmentCtrl.activate(ureq, subEntries, entries.get(0).getTransientState()); + } catch (OLATSecurityException e) { + //the wrong link to the wrong person + } + } } else if ("TestStatistics".equalsIgnoreCase(type) || "SurveyStatistics".equalsIgnoreCase(type)) { //check the security before, the link is perhaps in the wrong hands if(reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) { @@ -1324,7 +1340,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private Activateable2 doAssessmentTool_v2(UserRequest ureq) { if(delayedClose == Delayed.assessmentTool || requestForClose(ureq)) { - OLATResourceable ores = OresHelper.createOLATResourceableType("assessmentTool"); + OLATResourceable ores = OresHelper.createOLATResourceableType("assessmentToolv2"); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl swControl = addToHistory(ureq, ores, null); @@ -1342,9 +1358,9 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im listenTo(ctrl); assessmentTool_v2_Ctr = pushController(ureq, translate("command.openassessment"), ctrl); currentToolCtr = assessmentTool_v2_Ctr; - setActiveTool(assessmentLink); + setActiveTool(assessment_v2_Link); ctrl.initToolbar(); - return assessmentToolCtr; + return assessmentTool_v2_Ctr; } else { delayedClose = Delayed.assessmentTool; diff --git a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml index 341d44841c45a252f403f665908e0534ca73de2c..baf6a3f7c292af7b6956689e528117dde4cd0ef4 100644 --- a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml +++ b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml @@ -812,6 +812,23 @@ </bean> </entry> + <entry key="org.olat.course.assessment.ui.tool.AssessmentToReviewSmallController"> + <bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext"> + <property name="propertyHandlers"> + <list> + <ref bean="userPropertyFirstName" /> + <ref bean="userPropertyLastName" /> + </list> + </property> + <property name="mandatoryProperties"> + <set> + <ref bean="userPropertyFirstName" /> + <ref bean="userPropertyLastName" /> + </set> + </property> + </bean> + </entry> + <entry key="org.olat.admin.user.bulkChange.UserBulkChangeStep00"> <bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext"> <property name="propertyHandlers">