From 09eba4ec840c2d1c1ed5987a1b008b66c557e3d2 Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Tue, 28 Jun 2016 15:59:00 +0200 Subject: [PATCH] OO-2057,OO-1593: assessment tool with details in learn resources for QTI 2.1 and Binder resources --- .../AssessedIdentityLargeInfosController.java | 1 + .../ui/tool/_i18n/LocalStrings_en.properties | 21 +- .../olat/course/nodes/IQTESTCourseNode.java | 5 +- .../qti/repository/handlers/QTIHandler.java | 14 +- .../manager/AssessmentTestSessionDAO.java | 23 +- .../model/jpa/AssessmentTestSessionImpl.java | 6 - .../handlers/QTI21AssessmentTestHandler.java | 12 + .../ui}/QTI21AssessmentDetailsController.java | 42 +-- .../qti21/ui}/QTI21TestSessionTableModel.java | 2 +- .../qti21/ui/_content/assessment_details.html | 1 + .../qti21/ui/_i18n/LocalStrings_de.properties | 16 +- .../editor/_i18n/LocalStrings_en.properties | 99 +++---- ...ssedIdentityRepositoryEntryController.java | 21 +- .../ui/_content/identity_personal_infos.html | 3 + .../modules/portfolio/PortfolioService.java | 7 + .../handler/BinderTemplateHandler.java | 31 +- .../modules/portfolio/manager/BinderDAO.java | 18 +- .../portfolio/ui/BinderController.java | 6 + .../portfolio/ui/BinderPickerController.java | 266 ++++++++++++++++++ .../portfolio/ui/BinderRuntimeController.java | 141 +++++++++- .../PortfolioAssessmentDetailsController.java | 242 ++++++++++++++++ .../ui/_content/assessment_infos.html | 48 ++++ .../modules/portfolio/ui/_content/run.html | 2 + .../ui/_i18n/LocalStrings_de.properties | 21 +- .../ui/_i18n/LocalStrings_en.properties | 20 +- .../olat/repository/handlers/BlogHandler.java | 10 + .../repository/handlers/CourseHandler.java | 10 + .../repository/handlers/GlossaryHandler.java | 10 + .../repository/handlers/ImsCPHandler.java | 10 + .../repository/handlers/PodcastHandler.java | 10 + .../repository/handlers/PortfolioHandler.java | 13 +- .../handlers/RepositoryHandler.java | 27 +- .../repository/handlers/SCORMCPHandler.java | 10 + .../handlers/SharedFolderHandler.java | 10 + .../repository/handlers/VideoHandler.java | 14 +- .../handlers/WebDocumentHandler.java | 10 + .../olat/repository/handlers/WikiHandler.java | 10 + .../ui/author/AuthorListController.java | 2 +- .../RepositoryEditDescriptionController.java | 4 +- 39 files changed, 1084 insertions(+), 134 deletions(-) rename src/main/java/org/olat/{course/nodes/iq => ims/qti21/ui}/QTI21AssessmentDetailsController.java (84%) rename src/main/java/org/olat/{course/nodes/iq => ims/qti21/ui}/QTI21TestSessionTableModel.java (98%) create mode 100644 src/main/java/org/olat/ims/qti21/ui/_content/assessment_details.html create mode 100644 src/main/java/org/olat/modules/portfolio/ui/BinderPickerController.java create mode 100644 src/main/java/org/olat/modules/portfolio/ui/PortfolioAssessmentDetailsController.java create mode 100644 src/main/java/org/olat/modules/portfolio/ui/_content/assessment_infos.html create mode 100644 src/main/java/org/olat/modules/portfolio/ui/_content/run.html diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessedIdentityLargeInfosController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessedIdentityLargeInfosController.java index 78e7f306a13..21377155747 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessedIdentityLargeInfosController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessedIdentityLargeInfosController.java @@ -48,6 +48,7 @@ public class AssessedIdentityLargeInfosController extends BasicController { portraitCtr = new DisplayPortraitController(ureq, getWindowControl(), assessedIdentity, true, true); mainVC.put("portrait", portraitCtr.getInitialComponent()); + userShortDescrCtr = new UserShortDescription(ureq, getWindowControl(), assessedIdentity); mainVC.put("userShortDescription", userShortDescrCtr.getInitialComponent()); diff --git a/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_en.properties index 0ac70567fb1..f8c8f7ed80b 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_en.properties @@ -1,12 +1,12 @@ -#Fri May 06 21:35:18 CEST 2016 -assessment.status.notStart=$org.olat.modules.assessment.ui\:assessment.status.notStart +#Tue Jun 28 15:08:56 CEST 2016 +assessment.status.done=$org.olat.modules.assessment.ui\:assessment.status.done assessment.status.inProgress=$org.olat.modules.assessment.ui\:assessment.status.inProgress assessment.status.inReview=$org.olat.modules.assessment.ui\:assessment.status.inReview -assessment.status.done=$org.olat.modules.assessment.ui\:assessment.status.done -assessment.tool.numOfAssessedIdentities=$org.olat.modules.assessment.ui\:assessment.tool.numOfAssessedIdentities +assessment.status.notStart=$org.olat.modules.assessment.ui\:assessment.status.notStart assessment.tool.numOfAssessedGroups=$org.olat.modules.assessment.ui\:assessment.tool.numOfAssessedGroups -assessment.tool.numOfPassed=$org.olat.modules.assessment.ui\:assessment.tool.numOfPassed +assessment.tool.numOfAssessedIdentities=$org.olat.modules.assessment.ui\:assessment.tool.numOfAssessedIdentities assessment.tool.numOfFailed=$org.olat.modules.assessment.ui\:assessment.tool.numOfFailed +assessment.tool.numOfPassed=$org.olat.modules.assessment.ui\:assessment.tool.numOfPassed assessment.tool.overview=Overview certificate=Certificates certificates.wizard.title=$org.olat.course.certificate.ui\:certificates.wizard.title @@ -14,23 +14,24 @@ command.next=To the next user command.previous=Back to previous user elements.to.review=<i class\="o_icon o_icon_warning"> </i> {0} pending filter=$org.olat.modules.assessment.ui\:filter -filter.passed=$org.olat.modules.assessment.ui\:filter.passed +filter.done=$org.olat.modules.assessment.ui\:filter.done filter.failed=$org.olat.modules.assessment.ui\:filter.failed +filter.groups=$org.olat.modules.assessment.ui\:filter.groups filter.inProgress=$org.olat.modules.assessment.ui\:filter.inProgress filter.inReview=$org.olat.modules.assessment.ui\:filter.inReview -filter.done=$org.olat.modules.assessment.ui\:filter.done -filter.groups=$org.olat.modules.assessment.ui\:filter.groups +filter.passed=$org.olat.modules.assessment.ui\:filter.passed generate.certificate=$org.olat.course.certificate.ui\:generate.certificate no.certificate=No certificate available previous=Previous statistics.small.overview=Statistics overview sub.details=Details table.entries=Entries +table.header.assessmentStatus=$org.olat.modules.assessment.ui\:table.header.assessmentStatus table.header.elements.toReview=Elements +table.header.name=User name table.header.numOfAssessedIdentities=$org.olat.modules.assessment.ui\:table.header.numOfAssessedIdentities +table.header.numOfInitialLaunch=$org.olat.modules.assessment.ui\:table.header.numOfInitialLaunch table.header.numOfPassed=$org.olat.modules.assessment.ui\:table.header.numOfPassed table.header.scoreAverage=$org.olat.modules.assessment.ui\:table.header.scoreAverage -table.header.numOfInitialLaunch=$org.olat.modules.assessment.ui\:table.header.numOfInitialLaunch -table.header.assessmentStatus=$org.olat.modules.assessment.ui\:table.header.assessmentStatus users=Users waiting.review=$org.olat.modules.assessment.ui\:waiting.review diff --git a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java index bb908314db2..7fa24cd3170 100644 --- a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java +++ b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java @@ -60,7 +60,6 @@ import org.olat.course.nodes.iq.CourseIQSecurityCallback; import org.olat.course.nodes.iq.IQEditController; import org.olat.course.nodes.iq.IQPreviewController; import org.olat.course.nodes.iq.IQRunController; -import org.olat.course.nodes.iq.QTI21AssessmentDetailsController; import org.olat.course.nodes.iq.QTI21AssessmentRunController; import org.olat.course.properties.CoursePropertyManager; import org.olat.course.run.environment.CourseEnvironment; @@ -87,6 +86,7 @@ import org.olat.ims.qti.statistics.QTIType; import org.olat.ims.qti.statistics.ui.QTI12PullTestsToolController; import org.olat.ims.qti.statistics.ui.QTI12StatisticsToolController; import org.olat.ims.qti21.model.QTI21StatisticSearchParams; +import org.olat.ims.qti21.ui.QTI21AssessmentDetailsController; import org.olat.ims.qti21.ui.statistics.QTI21StatisticResourceResult; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; @@ -682,7 +682,8 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); if(ImsQTI21Resource.TYPE_NAME.equals(resource.getResourceableTypeName())) { - detailsCtrl = new QTI21AssessmentDetailsController(ureq, wControl, userCourseEnvironment, this); + RepositoryEntry courseEntry = userCourseEnvironment.getCourseEnvironment().getCourseGroupManager().getCourseEntry(); + detailsCtrl = new QTI21AssessmentDetailsController(ureq, wControl, courseEntry, getIdent() ,assessedIdentity); } else if(OnyxModule.isOnyxTest(ref.getOlatResource())) { detailsCtrl = new QTIResultDetailsController(courseResourceableId, getIdent(), assessedIdentity, ref, AssessmentInstance.QMD_ENTRY_TYPE_ASSESS, ureq, wControl); } else { diff --git a/src/main/java/org/olat/ims/qti/repository/handlers/QTIHandler.java b/src/main/java/org/olat/ims/qti/repository/handlers/QTIHandler.java index 316c03fb296..9830b61a238 100644 --- a/src/main/java/org/olat/ims/qti/repository/handlers/QTIHandler.java +++ b/src/main/java/org/olat/ims/qti/repository/handlers/QTIHandler.java @@ -33,6 +33,8 @@ import java.util.Locale; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.stack.TooledStackedPanel; +import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.layout.MainLayoutController; import org.olat.core.gui.translator.Translator; @@ -67,7 +69,12 @@ import org.olat.resource.references.ReferenceManager; * */ public abstract class QTIHandler extends FileHandler { - + + @Override + public boolean supportsAssessmentDetails() { + return false; + } + @Override public boolean isPostCreateWizardAvailable() { return false; @@ -134,6 +141,11 @@ public abstract class QTIHandler extends FileHandler { @Override public abstract MainLayoutController createLaunchController(RepositoryEntry re, RepositoryEntrySecurity reSecurity, UserRequest ureq, WindowControl wControl); + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } + @Override public boolean readyToDelete(RepositoryEntry entry, Identity identity, Roles roles, Locale locale, ErrorList errors) { ReferenceManager refM = CoreSpringFactory.getImpl(ReferenceManager.class); diff --git a/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java b/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java index 8d39924a86c..1340cfbaaac 100644 --- a/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java +++ b/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java @@ -216,12 +216,25 @@ public class AssessmentTestSessionDAO { } public List<AssessmentTestSession> getUserTestSessions(RepositoryEntryRef courseEntry, String courseSubIdent, IdentityRef identity) { - return dbInstance.getCurrentEntityManager() - .createNamedQuery("loadTestSessionsByUserAndRepositoryEntryAndSubIdent", AssessmentTestSession.class) + StringBuilder sb = new StringBuilder(); + sb.append("select session from qtiassessmenttestsession session") + .append(" left join fetch session.testEntry testEntry") + .append(" left join fetch testEntry.olatResource testResource") + .append(" where session.repositoryEntry.key=:repositoryEntryKey and session.identity.key=:identityKey and "); + if(StringHelper.containsNonWhitespace(courseSubIdent)) { + sb.append("session.subIdent=:subIdent"); + } else { + sb.append("session.subIdent is null"); + } + + TypedQuery<AssessmentTestSession> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), AssessmentTestSession.class) .setParameter("repositoryEntryKey", courseEntry.getKey()) - .setParameter("identityKey", identity.getKey()) - .setParameter("subIdent", courseSubIdent) - .getResultList(); + .setParameter("identityKey", identity.getKey()); + if(StringHelper.containsNonWhitespace(courseSubIdent)) { + query.setParameter("subIdent", courseSubIdent); + } + return query.getResultList(); } public int deleteTestSession(AssessmentTestSession testSession) { diff --git a/src/main/java/org/olat/ims/qti21/model/jpa/AssessmentTestSessionImpl.java b/src/main/java/org/olat/ims/qti21/model/jpa/AssessmentTestSessionImpl.java index 8136899e768..f8cf975f8de 100644 --- a/src/main/java/org/olat/ims/qti21/model/jpa/AssessmentTestSessionImpl.java +++ b/src/main/java/org/olat/ims/qti21/model/jpa/AssessmentTestSessionImpl.java @@ -30,8 +30,6 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @@ -54,10 +52,6 @@ import org.olat.repository.RepositoryEntry; */ @Entity(name="qtiassessmenttestsession") @Table(name="o_qti_assessmenttest_session") -@NamedQueries({ - @NamedQuery(name="loadTestSessionsByUserAndRepositoryEntryAndSubIdent", query="select session from qtiassessmenttestsession session left join fetch session.testEntry testEntry left join fetch testEntry.olatResource testResource where session.repositoryEntry.key=:repositoryEntryKey and session.identity.key=:identityKey and session.subIdent=:subIdent") - -}) public class AssessmentTestSessionImpl implements AssessmentTestSession, Persistable { private static final long serialVersionUID = -6069133323360142500L; diff --git a/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java b/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java index dc3651d211a..a8b2dc2d24e 100644 --- a/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java +++ b/src/main/java/org/olat/ims/qti21/repository/handlers/QTI21AssessmentTestHandler.java @@ -77,6 +77,7 @@ import org.olat.ims.qti21.model.xml.ManifestBuilder; import org.olat.ims.qti21.model.xml.OnyxToQtiWorksHandler; import org.olat.ims.qti21.pool.QTI21QPoolServiceProvider; import org.olat.ims.qti21.ui.AssessmentTestDisplayController; +import org.olat.ims.qti21.ui.QTI21AssessmentDetailsController; import org.olat.ims.qti21.ui.QTI21RuntimeController; import org.olat.ims.qti21.ui.editor.AssessmentTestComposerController; import org.olat.modules.assessment.manager.AssessmentEntryDAO; @@ -328,6 +329,11 @@ public class QTI21AssessmentTestHandler extends FileHandler { public EditionSupport supportsEdit(OLATResourceable resource) { return EditionSupport.yes; } + + @Override + public boolean supportsAssessmentDetails() { + return true; + } @Override public MainLayoutController createLaunchController(RepositoryEntry re, RepositoryEntrySecurity reSecurity, @@ -350,6 +356,12 @@ public class QTI21AssessmentTestHandler extends FileHandler { return editorCtrl; } + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, + TooledStackedPanel toolbar, Identity assessedIdentity) { + return new QTI21AssessmentDetailsController(ureq, wControl, re, null, assessedIdentity); + } + @Override public StepsMainRunController createWizardController(OLATResourceable res, UserRequest ureq, WindowControl wControl) { return null; diff --git a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentDetailsController.java b/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java similarity index 84% rename from src/main/java/org/olat/course/nodes/iq/QTI21AssessmentDetailsController.java rename to src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java index eca74171061..a5afd0a4f41 100644 --- a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentDetailsController.java +++ b/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java @@ -17,9 +17,10 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.course.nodes.iq; +package org.olat.ims.qti21.ui; import java.io.File; +import java.net.URI; import java.util.List; import org.olat.core.gui.UserRequest; @@ -39,20 +40,17 @@ import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.id.Identity; -import org.olat.course.nodes.IQTESTCourseNode; -import org.olat.course.nodes.iq.QTI21TestSessionTableModel.TSCols; -import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.fileresource.FileResourceManager; import org.olat.ims.qti21.AssessmentTestSession; import org.olat.ims.qti21.QTI21DeliveryOptions.ShowResultsOnFinish; import org.olat.ims.qti21.QTI21Service; -import org.olat.ims.qti21.ui.AssessmentResultController; +import org.olat.ims.qti21.ui.QTI21TestSessionTableModel.TSCols; import org.olat.repository.RepositoryEntry; import org.springframework.beans.factory.annotation.Autowired; /** * - * Initial date: 19.05.2015<br> + * Initial date: 28.06.2016<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ @@ -62,23 +60,23 @@ public class QTI21AssessmentDetailsController extends FormBasicController { private QTI21TestSessionTableModel tableModel; private Identity assessedIdentity; - private RepositoryEntry courseEntry; - private IQTESTCourseNode courseNode; + private RepositoryEntry entry; + private final String subIdent; private CloseableModalController cmc; private AssessmentResultController resultCtrl; @Autowired - private QTI21Service qtiService; + protected QTI21Service qtiService; public QTI21AssessmentDetailsController(UserRequest ureq, WindowControl wControl, - UserCourseEnvironment userCourseEnvironment, IQTESTCourseNode courseNode) { + RepositoryEntry assessableEntry, String subIdent, Identity assessedIdentity) { super(ureq, wControl, "assessment_details"); - this.courseNode = courseNode; - assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - courseEntry = userCourseEnvironment.getCourseEnvironment().getCourseGroupManager().getCourseEntry(); - + entry = assessableEntry; + this.subIdent = subIdent; + this.assessedIdentity = assessedIdentity; + initForm(ureq); updateModel(); } @@ -99,8 +97,8 @@ public class QTI21AssessmentDetailsController extends FormBasicController { // } - private void updateModel() { - List<AssessmentTestSession> sessions = qtiService.getAssessmentTestSessions(courseEntry, courseNode.getIdent(), assessedIdentity); + protected void updateModel() { + List<AssessmentTestSession> sessions = qtiService.getAssessmentTestSessions(entry, subIdent, assessedIdentity); tableModel.setObjects(sessions); tableEl.reset(); } @@ -141,13 +139,15 @@ public class QTI21AssessmentDetailsController extends FormBasicController { // } - private void doOpenResult(UserRequest ureq, AssessmentTestSession row) { + private void doOpenResult(UserRequest ureq, AssessmentTestSession session) { if(resultCtrl != null) return; - - String mapperUri = null;//TODO qti + FileResourceManager frm = FileResourceManager.getInstance(); - File fUnzippedDirRoot = frm.unzipFileResource(row.getTestEntry().getOlatResource()); - resultCtrl = new AssessmentResultController(ureq, getWindowControl(), assessedIdentity, row, + File fUnzippedDirRoot = frm.unzipFileResource(session.getTestEntry().getOlatResource()); + URI assessmentObjectUri = qtiService.createAssessmentObjectUri(fUnzippedDirRoot); + String mapperUri = registerCacheableMapper(null, "QTI21Resources::" + session.getTestEntry().getKey(), new ResourcesMapper(assessmentObjectUri)); + + resultCtrl = new AssessmentResultController(ureq, getWindowControl(), assessedIdentity, session, ShowResultsOnFinish.details, fUnzippedDirRoot, mapperUri); listenTo(resultCtrl); cmc = new CloseableModalController(getWindowControl(), "close", resultCtrl.getInitialComponent(), diff --git a/src/main/java/org/olat/course/nodes/iq/QTI21TestSessionTableModel.java b/src/main/java/org/olat/ims/qti21/ui/QTI21TestSessionTableModel.java similarity index 98% rename from src/main/java/org/olat/course/nodes/iq/QTI21TestSessionTableModel.java rename to src/main/java/org/olat/ims/qti21/ui/QTI21TestSessionTableModel.java index 126070d2834..12bd97dd8a3 100644 --- a/src/main/java/org/olat/course/nodes/iq/QTI21TestSessionTableModel.java +++ b/src/main/java/org/olat/ims/qti21/ui/QTI21TestSessionTableModel.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.course.nodes.iq; +package org.olat.ims.qti21.ui; import java.util.Date; diff --git a/src/main/java/org/olat/ims/qti21/ui/_content/assessment_details.html b/src/main/java/org/olat/ims/qti21/ui/_content/assessment_details.html new file mode 100644 index 00000000000..0b8ce06d66d --- /dev/null +++ b/src/main/java/org/olat/ims/qti21/ui/_content/assessment_details.html @@ -0,0 +1 @@ +$r.render("sessions") \ No newline at end of file diff --git a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_de.properties index 55528359aad..22802558bfd 100644 --- a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_de.properties @@ -1,4 +1,4 @@ -#Sat May 07 16:18:43 CEST 2016 +#Tue Jun 28 15:07:17 CEST 2016 actualPoints=$org.olat.modules.iq\:actualPoints assessment.comment.legend=Pers\u00F6nliche Notizen assessment.item.modal.feedback=Feedback @@ -40,10 +40,14 @@ confirm.advance.testpart.text=Wollen sie wirklich diese Test Part verlassen und confirm.advance.testpart.title=Test Part weiter gehen confirm.cancel.test=$org.olat.modules.iq\:confirmCancel confirm.suspend.test=$org.olat.modules.iq\:confirmSuspend +debug.outcomes=Output Daten +debug.responses=Antworten Daten exploded.msg=Explodiert form.metadata.title=Title head.assessment.details=$org.olat.ims.qti\:head.ass.details head.assessment.overview=$org.olat.ims.qti\:head.ass.details +interaction.order.drag.msg=Ziehen Sie die nicht verwendete Elemente von hier... +interaction.order.drop.msg=Drop and order your selected items here... passed.no=$org.olat.course.nodes.iq\:passed.no passed.yes=$org.olat.course.nodes.iq\:passed.yes passed.yourpassed=$org.olat.course.nodes.iq\:passed.yourpassed @@ -62,19 +66,16 @@ qti.form.summary.compact=$org.olat.course.nodes.iq\:qti.form.summary.compact qti.form.summary.detailed=$org.olat.course.nodes.iq\:qti.form.summary.detailed qti.form.summary.none=$org.olat.course.nodes.iq\:qti.form.summary.none qti.form.summary.section=$org.olat.course.nodes.iq\:qti.form.summary.section -interaction.order.drag.msg=Ziehen Sie die nicht verwendete Elemente von hier... -interaction.order.drop.msg=Drop and order your selected items here... question.progress.answered=Antwortet question.progress.noMaxScore=$org.olat.modules.iq\:noMaxScore question.progress.score=$org.olat.modules.iq\:actualPoints -debug.outcomes=Output Daten -debug.responses=Antworten Daten results.duration=Dauer results.end.time=Enddatum results.entry.time=Startdatum results.score.yourscore=$org.olat.course.nodes.iq\:score.yourscore -results.summary.title=$org.olat.course.nodes\:personal.title results.session.status=Status +results.session.status.pendingResponseProcessing=$\:results.session.status.pendingSubmission +results.summary.title=$org.olat.course.nodes\:personal.title review.responses=Ihre Antworten \u00FCberpr\u00FCfen review.responses.desc=Sie k\u00F6nnen Ihre Antworten von ein Teil oder alle Fragen \u00FCberpr\u00FCfen. Sie finden die Liste herunter. score.max=$org.olat.ims.qti\:score.max @@ -82,6 +83,9 @@ serialize.error=Unerwarte Fehler w\u00E4hrend Speicherung von Datei submit=Antwort senden suspend.test=$org.olat.modules.iq\:suspendAssess tab.options=Optionen +table.header.lastModified=$org.olat.course.nodes.iq\:table.header.lastModified +table.header.results=$org.olat.course.nodes.iq\:table.header.results + terminated.msg=Der Test ist beendet. test.complete=Test abgeschlossen test.entry.page.text=Der Test hat bis {0} Teile. diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties index 93018a9e529..b7b5ba8efe9 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties @@ -1,105 +1,106 @@ -#Sat Jan 22 17:01:28 CET 2011 +#Tue Jun 28 15:08:20 CEST 2016 answers=Answers change.elements=Edition correct.answers=Correct -delete.section=$org.olat.ims.qti.editor\:delete.section +cut.value=Cut value delete.item=$org.olat.ims.qti.editor\:delete.item +delete.section=$org.olat.ims.qti.editor\:delete.section editor.sc.title=Single choice editor.unkown.title=Unkown interaction -error.cannot.create.section=A section cannot be created everywhere! +error.cannot.create.section=A section cannot be created everywhere\! +error.cannot.delete=You cannot delete this object. error.double=Need to be a double -error.need.correct.answer=You need a least one correct answer. error.import.question=An unexpected error during import of a question -error.cannot.delete=You cannot delete this object. -essay.expectedLength=Number of letters -error.lock.title=Test locked error.lock=This test/questionnaire is being edited by user {0} at the moment and therefore locked. -essay.min.strings=Min. words +error.lock.title=Test locked +error.need.correct.answer=You need a least one correct answer. +essay.expectedLength=Number of letters essay.max.strings=Max. words +essay.min.strings=Min. words essay.rows=Height (number of lines) export.qpool.successful=$org.olat.ims.qti.editor\:export.qpool.successful -inherit=Inherit fib.alternative=Alternative +fib.caseSensitive=Case sensitive +fib.expectedLength=Gap size fib.placeholder=Placeholder fib.solution=Solution -fib.expectedLength=Gap size -fib.caseSensitive=Case sensitive +fib.tolerance.low=Lower bound fib.tolerance.mode=Tolerance mode -fib.tolerance.mode.exact=Exact fib.tolerance.mode.absolute=Absolute +fib.tolerance.mode.exact=Exact fib.tolerance.mode.relative=Relative -fib.tolerance.low=Lower bound fib.tolerance.up=Upper bound form.choice=Choice -form.feedback=Feedback -form.kprim=Kprim form.essay=Essay -form.hotspot=Hotspot +form.feedback=Feedback form.fib=Gap texts +form.hotspot=Hotspot form.imd.alignment=Check-box alignment form.imd.alignment.left=Left form.imd.alignment.right=Right -form.imd.correct.spots=Correct spots -form.imd.title=Title -form.imd.descr=Question +form.imd.answer=Answer form.imd.background=Background form.imd.correct.kprim=$org.olat.ims.qti.editor\:questionform_correct_kprim -form.imd.wrong.kprim=$org.olat.ims.qti.editor\:questionform_wrong_kprim -form.imd.answer=Answer -form.imd.hint.title=Hint title +form.imd.correct.spots=Correct spots +form.imd.correct.text=Correct feedback +form.imd.correct.title=Correct title +form.imd.descr=Question +form.imd.empty.text=Empty feedback +form.imd.empty.title=Empty title form.imd.hint.text=Hint +form.imd.hint.title=Hint title +form.imd.incorrect.text=Incorrect feedback +form.imd.incorrect.title=Incorrect title form.imd.layout=$org.olat.ims.qti.editor\:form.imd.layout form.imd.layout.horizontal=$org.olat.ims.qti.editor\:form.imd.layout.horizontal form.imd.layout.vertical=$org.olat.ims.qti.editor\:form.imd.layout.vertical -form.imd.correct.title=Correct title -form.imd.correct.text=Correct feedback -form.imd.empty.title=Empty title -form.imd.empty.text=Empty feedback -form.imd.incorrect.title=Incorrect title -form.imd.incorrect.text=Incorrect feedback form.imd.limittries=$org.olat.ims.qti.editor\:form.imd.limittries form.imd.rubric=Rubric form.imd.shuffle=Shuffle +form.imd.title=Title +form.imd.wrong.kprim=$org.olat.ims.qti.editor\:questionform_wrong_kprim +form.kprim=Kprim form.metadata=Metadata -form.metadata.title=Title form.metadata.description=Description +form.metadata.title=Title form.score=Score -form.section.shuffle=Random order of questions? +form.score.answer.correct=Correct +form.score.answer.points=Points +form.score.answer.summary=Answer summary +form.score.assessment.all.correct=All correct answers +form.score.assessment.mode=Method of assessment +form.score.assessment.per.answer=Score per answer form.section.selection_pre=Number of questions in this section form.section.selection_pre.hover=Select whether all or just a specified number of questions should be displayed in the test. +form.section.shuffle=Random order of questions? form.section.visible=Visible +form.test.correct.text=Correct feedback +form.test.correct.title=Correct title +form.test.export.score=Overall score of this test +form.test.incorrect.text=Incorrect feedback +form.test.incorrect.title=Incorrect title form.testPart.navigationMode=Navigation mode form.testPart.navigationMode.linear=Linear form.testPart.navigationMode.nonlinear=Non linear -form.test.correct.title=Correct title -form.test.correct.text=Correct feedback -form.test.incorrect.title=Incorrect title -form.test.incorrect.text=Incorrect feedback -form.test.export.score=Overall score of this test -form.score.assessment.mode=Method of assessment -form.score.assessment.all.correct=All correct answers -form.score.assessment.per.answer=Score per answer -form.score.answer.correct=Correct -form.score.answer.summary=Answer summary -form.score.answer.points=Points form.unkown=Unkown +inherit=Inherit item.session.control.allow.comment=Allow comment -item.session.control.show.solution=Show solution item.session.control.attempts=Attempts -cut.value=Cut value -min.score=Min. score +item.session.control.show.solution=Show solution max.score=Max. score +min.score=Min. score +new.circle=Circle new.elements=New elements new.essay=Essay new.fib=Gap text new.fib.numerical=Numerical input new.hotspot=Hotspot -new.sc=Single choice -new.mc=Multiple choice new.kprim=KPrim -new.section=Section -new.circle=Circle +new.mc=Multiple choice new.rectangle=Rectangle +new.sc=Single choice +new.section=Section +new.spots=Add spots new.testpart=Test part preview=Preview time.limit.max=Time limit (minute) @@ -110,6 +111,6 @@ tools.export.header=$org.olat.ims.qti.editor\:tools.export.header tools.export.qpool=$org.olat.ims.qti.editor\:tools.export.qpool tools.import.qpool=$org.olat.ims.qti.editor\:tools.import.qpool tools.import.table=$org.olat.ims.qti.editor\:tools.import.table +warning.feedback.cutvalue=The feedback is based on the cut value. You need to define it first. warning.in.use=The resource is already used for assessment purpose. Editing is limited. warning.unkown.assessment.item=This question type cannot be processed with the OpenOLAT editor. -warning.feedback.cutvalue=The feedback is based on the cut value. You need to define it first. diff --git a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityRepositoryEntryController.java b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityRepositoryEntryController.java index 64ce9bfb689..a9c46f470c2 100644 --- a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityRepositoryEntryController.java +++ b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityRepositoryEntryController.java @@ -35,6 +35,9 @@ import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; import org.olat.course.assessment.ui.tool.AssessedIdentityLargeInfosController; import org.olat.repository.RepositoryEntry; +import org.olat.repository.handlers.RepositoryHandler; +import org.olat.repository.handlers.RepositoryHandlerFactory; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -49,12 +52,16 @@ public class AssessedIdentityRepositoryEntryController extends BasicController i private final TooledStackedPanel stackPanel; private final VelocityContainer identityAssessmentVC; private Link nextLink, previousLink; - + + private Controller detailsCtrl; private AssessmentForm currentNodeCtrl; private AssessedIdentityLargeInfosController infosController; + + @Autowired + private RepositoryHandlerFactory repositoryHandlerFactory; public AssessedIdentityRepositoryEntryController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, - RepositoryEntry testEntry, Identity assessedIdentity, AssessableResource element) { + RepositoryEntry assessableEntry, Identity assessedIdentity, AssessableResource element) { super(ureq, wControl); this.stackPanel = stackPanel; @@ -67,7 +74,15 @@ public class AssessedIdentityRepositoryEntryController extends BasicController i listenTo(infosController); identityAssessmentVC.put("identityInfos", infosController.getInitialComponent()); - currentNodeCtrl = new AssessmentForm(ureq, getWindowControl(), assessedIdentity, testEntry, element, false); + RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(assessableEntry); + if(handler.supportsAssessmentDetails()) { + detailsCtrl = handler.createAssessmentDetailsController(assessableEntry, ureq, getWindowControl(), stackPanel, assessedIdentity); + listenTo(detailsCtrl); + identityAssessmentVC.put("details", detailsCtrl.getInitialComponent()); + + } + + currentNodeCtrl = new AssessmentForm(ureq, getWindowControl(), assessedIdentity, assessableEntry, element, false); listenTo(currentNodeCtrl); identityAssessmentVC.put("assessmentForm", currentNodeCtrl.getInitialComponent()); diff --git a/src/main/java/org/olat/modules/assessment/ui/_content/identity_personal_infos.html b/src/main/java/org/olat/modules/assessment/ui/_content/identity_personal_infos.html index bafb0690172..62fb40303ba 100644 --- a/src/main/java/org/olat/modules/assessment/ui/_content/identity_personal_infos.html +++ b/src/main/java/org/olat/modules/assessment/ui/_content/identity_personal_infos.html @@ -1,6 +1,9 @@ #if($r.available("identityInfos")) $r.render("identityInfos") #end +#if($r.available("details")) + $r.render("details") +#end #if($r.available("assessmentForm")) $r.render("assessmentForm") #end \ No newline at end of file diff --git a/src/main/java/org/olat/modules/portfolio/PortfolioService.java b/src/main/java/org/olat/modules/portfolio/PortfolioService.java index ce7c79262ec..cb9f27b3c78 100644 --- a/src/main/java/org/olat/modules/portfolio/PortfolioService.java +++ b/src/main/java/org/olat/modules/portfolio/PortfolioService.java @@ -111,6 +111,13 @@ public interface PortfolioService { */ public Binder getBinder(Identity owner, BinderRef templateBinder, RepositoryEntryRef courseEntry, String subIdent); + /** + * + * @param owner + * @param courseEntry + * @param subIdent If the subIdent is null, it will be search with subIdent is null! + * @return + */ public List<Binder> getBinders(Identity owner, RepositoryEntryRef courseEntry, String subIdent); /** diff --git a/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateHandler.java b/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateHandler.java index f9f32609bec..a41b1228944 100644 --- a/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateHandler.java +++ b/src/main/java/org/olat/modules/portfolio/handler/BinderTemplateHandler.java @@ -49,7 +49,9 @@ import org.olat.modules.portfolio.BinderSecurityCallbackFactory; import org.olat.modules.portfolio.PortfolioService; import org.olat.modules.portfolio.PortfolioV2Module; import org.olat.modules.portfolio.ui.BinderController; +import org.olat.modules.portfolio.ui.BinderPickerController; import org.olat.modules.portfolio.ui.BinderRuntimeController; +import org.olat.modules.portfolio.ui.PortfolioAssessmentDetailsController; import org.olat.repository.ErrorList; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryService; @@ -123,6 +125,11 @@ public class BinderTemplateHandler implements RepositoryHandler { return EditionSupport.embedded; } + @Override + public boolean supportsAssessmentDetails() { + return true; + } + @Override public VFSContainer getMediaContainer(RepositoryEntry repoEntry) { return FileResourceManager.getInstance() @@ -161,16 +168,28 @@ public class BinderTemplateHandler implements RepositoryHandler { public Controller create(UserRequest uureq, WindowControl wwControl, TooledStackedPanel toolbarPanel, RepositoryEntry entry, RepositoryEntrySecurity security, AssessmentMode assessmentMode) { PortfolioService portfolioService = CoreSpringFactory.getImpl(PortfolioService.class); - Binder binder = portfolioService.getBinderByResource(entry.getOlatResource()); - CoreSpringFactory.getImpl(UserCourseInformationsManager.class) - .updateUserCourseInformations(entry.getOlatResource(), uureq.getIdentity()); - BinderConfiguration bConfig = BinderConfiguration.createTemplateConfig(); - BinderSecurityCallback secCallback = BinderSecurityCallbackFactory.getCallbackForTemplate(reSecurity); - return new BinderController(uureq, wwControl, toolbarPanel, secCallback, binder, bConfig); + if(reSecurity.isGroupParticipant() || reSecurity.isCourseParticipant()) { + //pick up the template + + return new BinderPickerController(uureq, wwControl, entry); + } else { + Binder binder = portfolioService.getBinderByResource(entry.getOlatResource()); + CoreSpringFactory.getImpl(UserCourseInformationsManager.class) + .updateUserCourseInformations(entry.getOlatResource(), uureq.getIdentity()); + BinderConfiguration bConfig = BinderConfiguration.createTemplateConfig(); + BinderSecurityCallback secCallback = BinderSecurityCallbackFactory.getCallbackForTemplate(reSecurity); + return new BinderController(uureq, wwControl, toolbarPanel, secCallback, binder, bConfig); + } } }); } + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, + TooledStackedPanel toolbar, Identity assessedIdentity) { + return new PortfolioAssessmentDetailsController(ureq, wControl, toolbar, re, assessedIdentity); + } + @Override public String getSupportedType() { return BinderTemplateResource.TYPE_NAME; diff --git a/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java b/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java index 864ee164a81..4f5ef667657 100644 --- a/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java +++ b/src/main/java/org/olat/modules/portfolio/manager/BinderDAO.java @@ -342,15 +342,21 @@ public class BinderDAO { sb.append("select binder from pfbinder as binder") .append(" inner join binder.baseGroup as baseGroup") .append(" inner join baseGroup.members as membership on (membership.identity.key=:identityKey and membership.role='").append(PortfolioRoles.owner.name()).append("')") - .append(" where binder.entry.key=:entryKey and binder.subIdent=:subIdent"); + .append(" where binder.entry.key=:entryKey and "); + if(StringHelper.containsNonWhitespace(subIdent)) { + sb.append("binder.subIdent=:subIdent"); + } else { + sb.append("binder.subIdent is null"); + } - List<Binder> binders = dbInstance.getCurrentEntityManager() + TypedQuery<Binder> binders = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), Binder.class) .setParameter("identityKey", owner.getKey()) - .setParameter("entryKey", entry.getKey()) - .setParameter("subIdent", subIdent) - .getResultList(); - return binders; + .setParameter("entryKey", entry.getKey()); + if(StringHelper.containsNonWhitespace(subIdent)) { + binders.setParameter("subIdent", subIdent); + } + return binders.getResultList(); } public Group getGroup(BinderRef binder) { diff --git a/src/main/java/org/olat/modules/portfolio/ui/BinderController.java b/src/main/java/org/olat/modules/portfolio/ui/BinderController.java index 070c4461666..c5db7dd8858 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/BinderController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/BinderController.java @@ -100,6 +100,12 @@ public class BinderController extends BasicController implements TooledControlle stackPanel.addTool(segmentButtonsCmp, true); stackPanel.addTool(editBinderMetadataLink, Align.right); } + + protected void setSegmentButtonsVisible(boolean enabled) { + if(segmentButtonsCmp != null) { + segmentButtonsCmp.setVisible(enabled); + } + } @Override protected void doDispose() { diff --git a/src/main/java/org/olat/modules/portfolio/ui/BinderPickerController.java b/src/main/java/org/olat/modules/portfolio/ui/BinderPickerController.java new file mode 100644 index 00000000000..94695a21ee0 --- /dev/null +++ b/src/main/java/org/olat/modules/portfolio/ui/BinderPickerController.java @@ -0,0 +1,266 @@ +/** + * <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.modules.portfolio.ui; + +import java.util.Date; + +import org.olat.NewControllerFactory; +import org.olat.core.gui.UserRequest; +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.FormLink; +import org.olat.core.gui.components.form.flexible.elements.StaticTextElement; +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.link.Link; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; +import org.olat.core.util.Formatter; +import org.olat.core.util.StringHelper; +import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.AssessmentService; +import org.olat.modules.portfolio.Binder; +import org.olat.modules.portfolio.PortfolioService; +import org.olat.modules.portfolio.handler.BinderTemplateResource; +import org.olat.portfolio.EPLoggingAction; +import org.olat.repository.RepositoryEntry; +import org.olat.util.logging.activity.LoggingResourceable; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 28.06.2016<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class BinderPickerController extends FormBasicController { + + private Binder copyBinder; + private Binder templateBinder; + private RepositoryEntry templateEntry; + + private FormLink newMapLink; + private FormLink selectMapLink; + private StaticTextElement newMapMsgEl; + private FormLayoutContainer infosContainer; + private FormLayoutContainer assessmentInfosContainer; + + private Formatter formatter; + + private StaticTextElement deadlineDateText; + + @Autowired + private AssessmentService assessmentService; + @Autowired + private PortfolioService portfolioService; + + public BinderPickerController(UserRequest ureq, WindowControl wControl, RepositoryEntry templateEntry) { + super(ureq, wControl, "run"); + this.templateEntry = templateEntry; + + formatter = Formatter.getInstance(getLocale()); + if(templateEntry != null && BinderTemplateResource.TYPE_NAME.equals(templateEntry.getOlatResource().getResourceableTypeName())) { + templateBinder = portfolioService.getBinderByResource(templateEntry.getOlatResource()); + } + + initForm(ureq); + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + infosContainer = FormLayoutContainer.createDefaultFormLayout("infos", getTranslator()); + formLayout.add(infosContainer); + + String assessmentPage = velocity_root + "/assessment_infos.html"; + assessmentInfosContainer = FormLayoutContainer.createCustomFormLayout("assessmentInfos", getTranslator(), assessmentPage); + assessmentInfosContainer.setVisible(false); + formLayout.add(assessmentInfosContainer); + + if(templateBinder != null) { + updateUI(); + } + } + + protected void updateUI() { + if(templateBinder != null) { + copyBinder = portfolioService.getBinder(getIdentity(), templateBinder, templateEntry, null); + } + + if(copyBinder == null) { + updateEmptyUI(); + } else { + updateSelectedUI(); + } + + if(selectMapLink != null) { + selectMapLink.setVisible(copyBinder != null); + } + if(newMapLink != null) { + newMapLink.setVisible(copyBinder == null); + } + if(newMapMsgEl != null) { + newMapMsgEl.setVisible(copyBinder == null); + } + } + + private void updateEmptyUI() { + String title = ""; + if(templateBinder != null) { + title = StringHelper.escapeHtml(templateBinder.getTitle()); + } + + String msg = translate("map.available", new String[]{ title }); + if(newMapMsgEl == null) { + newMapMsgEl = uifactory.addStaticTextElement("map.available", msg, infosContainer); + } + newMapMsgEl.setLabel(null, null); + + FormLayoutContainer buttonGroupLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); + buttonGroupLayout.setRootForm(mainForm); + infosContainer.add(buttonGroupLayout); + if(newMapLink == null) { + newMapLink = uifactory.addFormLink("map.new", buttonGroupLayout, Link.BUTTON); + newMapLink.setElementCssClass("o_sel_ep_new_map_template"); + } + } + + private void updateSelectedUI() { + if(selectMapLink == null) { + selectMapLink = uifactory.addFormLink("select", "select.mymap", "select.mymap", infosContainer, Link.LINK); + selectMapLink.setElementCssClass("o_sel_ep_select_map"); + } else { + selectMapLink.setVisible(true); + } + + if(copyBinder != null) { + updateSelectedBinderUI(); + } + } + + private void updateSelectedBinderUI() { + String copyTitle = StringHelper.escapeHtml(copyBinder.getTitle()); + ((Link)selectMapLink.getComponent()).setCustomDisplayText(copyTitle); + + updateCopyDate(copyBinder.getCopyDate()); + updateAssessmentInfos(copyBinder.getReturnDate()); + updateDeadlineText(copyBinder.getDeadLine()); + } + + private void updateCopyDate(Date copyDate) { + if(copyDate != null) { + String copyDateStr = formatter.formatDateAndTime(copyDate); + uifactory.addStaticTextElement("map.copyDate", copyDateStr, infosContainer); + } + } + + /** + * Show absolute deadline when task is taken. nothing if taken map still has a deadline configured. + * @param deadline + */ + private void updateDeadlineText(Date deadlineDate) { + if (deadlineDateText != null && deadlineDate != null) { + String deadline = formatter.formatDateAndTime(deadlineDate); + deadlineDateText.setValue(deadline); + deadlineDateText.setLabel("map.deadline.absolut.label", null); + } + } + + private void updateAssessmentInfos(Date returnDate) { + if(returnDate != null) { + String rDate = formatter.formatDateAndTime(returnDate); + uifactory.addStaticTextElement("map.returnDate", rDate, infosContainer); + + AssessmentEntry assessmentEntry = assessmentService.loadAssessmentEntry(getIdentity(), templateEntry, null, templateEntry); + + assessmentInfosContainer.contextPut("hasScoreField", Boolean.FALSE); + /* score + if(courseNode.hasScoreConfigured()) { + Float score = scoreEval.getScore(); + Float minScore = courseNode.getMinScoreConfiguration(); + Float maxScore = courseNode.getMaxScoreConfiguration(); + assessmentInfosContainer.contextPut("scoreMin", AssessmentHelper.getRoundedScore(minScore)); + assessmentInfosContainer.contextPut("scoreMax", AssessmentHelper.getRoundedScore(maxScore)); + assessmentInfosContainer.contextPut("score", AssessmentHelper.getRoundedScore(score)); + } + */ + + //passed + assessmentInfosContainer.contextPut("hasPassedField", Boolean.TRUE); + //if(courseNode.hasPassedConfigured()) { + Boolean passed = assessmentEntry.getPassed(); + assessmentInfosContainer.contextPut("passed", passed); + assessmentInfosContainer.contextPut("hasPassedValue", new Boolean(passed != null)); + //Float cutValue = courseNode.getCutValueConfiguration(); + //assessmentInfosContainer.contextPut("passedCutValue", AssessmentHelper.getRoundedScore(cutValue)); + //} + + // get comment + String comment = assessmentEntry.getComment(); + assessmentInfosContainer.contextPut("hasCommentField", new Boolean(comment != null)); + if (comment != null) { + assessmentInfosContainer.contextPut("comment", comment); + } + assessmentInfosContainer.setVisible(true); + } else { + assessmentInfosContainer.setVisible(false); + } + } + + @Override + protected void doDispose() { + // + } + + @Override + protected void formOK(UserRequest ureq) { + // + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(source == newMapLink) { + if(templateBinder != null) { + copyBinder = portfolioService.assignBinder(getIdentity(), templateBinder, templateEntry, null, null); + if(copyBinder != null) { + showInfo("map.copied", StringHelper.escapeHtml(templateBinder.getTitle())); + ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapPortfolioOres(copyBinder)); + ThreadLocalUserActivityLogger.log(EPLoggingAction.EPORTFOLIO_TASK_STARTED, getClass()); + } + } + + updateUI(); + } else if (source == selectMapLink) { + String resourceUrl; + if(copyBinder != null) { + resourceUrl = "[HomeSite:" + getIdentity().getKey() + "][PortfolioV2:0][MyBinders:0][Binder:" + copyBinder.getKey() + "]"; + } else { + return; + } + BusinessControl bc = BusinessControlFactory.getInstance().createFromString(resourceUrl); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); + NewControllerFactory.getInstance().launch(ureq, bwControl); + } + } +} diff --git a/src/main/java/org/olat/modules/portfolio/ui/BinderRuntimeController.java b/src/main/java/org/olat/modules/portfolio/ui/BinderRuntimeController.java index 9f3c836377a..12be6344389 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/BinderRuntimeController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/BinderRuntimeController.java @@ -20,10 +20,25 @@ package org.olat.modules.portfolio.ui; import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.dropdown.Dropdown; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.components.link.LinkFactory; +import org.olat.core.gui.components.stack.PopEvent; +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.generic.dtabs.Activateable2; +import org.olat.core.id.OLATResourceable; +import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; +import org.olat.core.util.resource.OresHelper; +import org.olat.modules.assessment.ui.AssessableResource; +import org.olat.modules.assessment.ui.AssessmentToolController; +import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback; import org.olat.repository.RepositoryEntry; import org.olat.repository.model.RepositoryEntrySecurity; import org.olat.repository.ui.RepositoryEntryRuntimeController; +import org.olat.util.logging.activity.LoggingResourceable; /** * @@ -33,11 +48,135 @@ import org.olat.repository.ui.RepositoryEntryRuntimeController; */ public class BinderRuntimeController extends RepositoryEntryRuntimeController { + private Link assessmentLink; + + private AssessmentToolController assessmentToolCtrl; + public BinderRuntimeController(UserRequest ureq, WindowControl wControl, RepositoryEntry re, RepositoryEntrySecurity reSecurity, RuntimeControllerCreator runtimeControllerCreator) { super(ureq, wControl, re, reSecurity, runtimeControllerCreator); } + + @Override + protected void initRuntimeTools(Dropdown toolsDropdown) { + if (reSecurity.isEntryAdmin()) { + membersLink = LinkFactory.createToolLink("members", translate("details.members"), this, "o_sel_repo_members"); + membersLink.setIconLeftCSS("o_icon o_icon-fw o_icon_membersmanagement"); + toolsDropdown.addComponent(membersLink); + } + + if (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach()) { + assessmentLink = LinkFactory.createToolLink("assessment", translate("command.openassessment"), this, "o_icon_assessment_tool"); + assessmentLink.setElementCssClass("o_sel_course_assessment_tool"); + toolsDropdown.addComponent(assessmentLink); + } + + if (reSecurity.isEntryAdmin()) { + RepositoryEntry re = getRepositoryEntry(); + ordersLink = LinkFactory.createToolLink("bookings", translate("details.orders"), this, "o_sel_repo_booking"); + ordersLink.setIconLeftCSS("o_icon o_icon-fw o_icon_booking"); + boolean booking = acService.isResourceAccessControled(re.getOlatResource(), null); + ordersLink.setEnabled(booking); + toolsDropdown.addComponent(ordersLink); + } + } + + @Override + protected void event(UserRequest ureq, Component source, Event event) { + if(assessmentLink == source) { + doAssessmentTool(ureq); + } else if(source == toolbarPanel) { + if(event instanceof PopEvent) { + if(toolbarPanel.getRootController() == getRuntimeController()) { + enableRuntimeNavBar(true); + } + } + } + super.event(ureq, source, event); + } + + private Activateable2 doAssessmentTool(UserRequest ureq) { + OLATResourceable ores = OresHelper.createOLATResourceableType("TestStatistics"); + ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); + WindowControl swControl = addToHistory(ureq, ores, null); + + if (reSecurity.isEntryAdmin() || reSecurity.isCourseCoach() || reSecurity.isGroupCoach()) { + AssessmentToolSecurityCallback secCallback + = new AssessmentToolSecurityCallback(reSecurity.isEntryAdmin(), reSecurity.isEntryAdmin(), + reSecurity.isCourseCoach(), reSecurity.isGroupCoach(), null); + + AssessableResource el = getAssessableElement(); + AssessmentToolController ctrl = new AssessmentToolController(ureq, swControl, toolbarPanel, + getRepositoryEntry(), el, secCallback); + listenTo(ctrl); + assessmentToolCtrl = pushController(ureq, "Statistics", ctrl); + currentToolCtr = assessmentToolCtrl; + setActiveTool(assessmentLink); + enableRuntimeNavBar(false); + return assessmentToolCtrl; + } + return null; + } - + @Override + protected void doAccess(UserRequest ureq) { + super.doAccess(ureq); + enableRuntimeNavBar(false); + } + + @Override + protected void doEdit(UserRequest ureq) { + super.doEdit(ureq); + enableRuntimeNavBar(false); + } + + @Override + protected void doDetails(UserRequest ureq) { + super.doDetails(ureq); + enableRuntimeNavBar(false); + } + + @Override + protected void doEditSettings(UserRequest ureq) { + super.doEditSettings(ureq); + enableRuntimeNavBar(false); + } + + @Override + protected void doCatalog(UserRequest ureq) { + super.doCatalog(ureq); + enableRuntimeNavBar(false); + } + + @Override + protected Activateable2 doMembers(UserRequest ureq) { + Activateable2 controller = super.doMembers(ureq); + enableRuntimeNavBar(false); + return controller; + } + @Override + protected void doOrders(UserRequest ureq) { + super.doOrders(ureq); + enableRuntimeNavBar(false); + } + + @Override + protected void launchContent(UserRequest ureq, RepositoryEntrySecurity security) { + super.launchContent(ureq, security); + enableRuntimeNavBar(true); + } + + private AssessableResource getAssessableElement() { + boolean hasScore = false; + boolean hasPassed = true; + return new AssessableResource(hasScore, hasPassed, true, true, null, null, null); + } + + private void enableRuntimeNavBar(boolean enabled) { + Controller runner = getRuntimeController(); + if(runner instanceof BinderController) { + ((BinderController)runner).setSegmentButtonsVisible(enabled); + } + } } diff --git a/src/main/java/org/olat/modules/portfolio/ui/PortfolioAssessmentDetailsController.java b/src/main/java/org/olat/modules/portfolio/ui/PortfolioAssessmentDetailsController.java new file mode 100644 index 00000000000..8a7c2892186 --- /dev/null +++ b/src/main/java/org/olat/modules/portfolio/ui/PortfolioAssessmentDetailsController.java @@ -0,0 +1,242 @@ +/** + * <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.modules.portfolio.ui; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.olat.core.gui.UserRequest; +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.FormLink; +import org.olat.core.gui.components.form.flexible.elements.StaticTextElement; +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.link.Link; +import org.olat.core.gui.components.stack.BreadcrumbPanel; +import org.olat.core.gui.components.stack.TooledStackedPanel; +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.generic.closablewrapper.CloseableCalloutWindowController; +import org.olat.core.id.Identity; +import org.olat.core.util.Formatter; +import org.olat.core.util.StringHelper; +import org.olat.course.nodes.portfolio.DeadlineController; +import org.olat.modules.portfolio.Binder; +import org.olat.modules.portfolio.BinderConfiguration; +import org.olat.modules.portfolio.BinderSecurityCallback; +import org.olat.modules.portfolio.BinderSecurityCallbackFactory; +import org.olat.modules.portfolio.PortfolioService; +import org.olat.modules.portfolio.handler.BinderTemplateResource; +import org.olat.modules.portfolio.model.AccessRights; +import org.olat.repository.RepositoryEntry; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 28.06.2016<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class PortfolioAssessmentDetailsController extends FormBasicController { + + private Binder templateBinder; + private List<Binder> binders; + private Map<Binder, MapElements> binderToElements = new HashMap<Binder, MapElements>(); + + private DeadlineController deadlineCtr; + private CloseableCalloutWindowController deadlineCalloutCtr; + private final BreadcrumbPanel stackPanel; + + @Autowired + private PortfolioService portfolioService; + + public PortfolioAssessmentDetailsController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel, RepositoryEntry templateEntry, + Identity assessedIdentity) { + super(ureq, wControl); + + this.stackPanel = stackPanel; + + if(templateEntry != null && BinderTemplateResource.TYPE_NAME.equals(templateEntry.getOlatResource().getResourceableTypeName())) { + templateBinder = portfolioService.getBinderByResource(templateEntry.getOlatResource()); + binders = portfolioService.getBinders(assessedIdentity, templateEntry, null); + } + initForm(ureq); + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + if(binders == null || binders.isEmpty()) { + setFormWarning("no.map"); + } else if(binders != null && binders.size() > 0) { + initBindersForm(formLayout); + } + } + + protected void initBindersForm(FormItemContainer formLayout) { + Formatter formatter = Formatter.getInstance(getLocale()); + + int count = 0; + for(Binder binder:binders) { + MapElements mapElements = new MapElements(); + + if(binders.size() > 1 || !binder.getTemplate().equals(templateBinder)) { + String templateTitle = binder.getTemplate().getTitle(); + uifactory.addStaticTextElement("map.template." + count, "map.template", templateTitle, formLayout); + } + + String copyDate = ""; + if(binder.getCopyDate() != null) { + copyDate = formatter.formatDateAndTime(binder.getCopyDate()); + } + uifactory.addStaticTextElement("map.copyDate." + count, "map.copyDate", copyDate, formLayout); + + String returnDate = ""; + if(binder.getReturnDate() != null) { + returnDate = formatter.formatDateAndTime(binder.getReturnDate()); + } + uifactory.addStaticTextElement("map.returnDate." + count, "map.returnDate", returnDate, formLayout); + + String deadLine = ""; + if(binder.getDeadLine() != null) { + deadLine = formatter.formatDateAndTime(binder.getDeadLine()); + } + mapElements.deadlineEl = uifactory.addStaticTextElement("map.deadline." + count, "map.deadline", deadLine, formLayout); + + + FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons." + count, getTranslator()); + buttonsCont.setRootForm(mainForm); + formLayout.add(buttonsCont); + + mapElements.changeDeadlineLink = uifactory + .addFormLink("map.binder.change." + count, "map.binder.change", "map.deadline.change", null, buttonsCont, Link.BUTTON); + mapElements.changeDeadlineLink.setUserObject(binder); + + mapElements.openMapLink = uifactory.addFormLink("open.binder." + count, "open.binder", "open.map", null, buttonsCont, Link.BUTTON); + mapElements.openMapLink.setUserObject(binder); + + count++; + if(count != binders.size()) { + uifactory.addSpacerElement("spacer-" + count, formLayout, false); + } + + binderToElements.put(binder, mapElements); + } + } + + @Override + protected void doDispose() { + // + } + + @Override + protected void formOK(UserRequest ureq) { + // + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(source instanceof FormLink) { + FormLink link = (FormLink)source; + String cmd = link.getCmd(); + if("map.binder.change".equals(cmd)) { + if (deadlineCalloutCtr == null) { + Binder map = (Binder)link.getUserObject(); + popupDeadlineBox(ureq, map); + } else { + // close on second click + closeDeadlineBox(); + } + } else if(link.getName().startsWith("open.binder")) { + Binder map = (Binder)link.getUserObject(); + doOpenMap(ureq, map); + } + } + super.formInnerEvent(ureq, source, event); + } + + private void doOpenMap(UserRequest ureq, Binder binder) { + if(stackPanel instanceof TooledStackedPanel) { + List<AccessRights> rights = portfolioService.getAccessRights(binder, getIdentity()); + BinderSecurityCallback secCallback = BinderSecurityCallbackFactory.getCallbackForCoach(rights); + BinderConfiguration config = BinderConfiguration.createConfig(binder); + BinderController binderCtrl = new BinderController(ureq, getWindowControl(), (TooledStackedPanel)stackPanel, secCallback, binder, config); + String displayName = StringHelper.escapeHtml(binder.getTitle()); + stackPanel.pushController(displayName, binderCtrl); + binderCtrl.activate(ureq, null, null); + } + } + + /** + * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, + * org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event) + */ + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if (source == deadlineCalloutCtr && event == CloseableCalloutWindowController.CLOSE_WINDOW_EVENT) { + removeAsListenerAndDispose(deadlineCalloutCtr); + deadlineCalloutCtr = null; + } else if (source == deadlineCtr) { + String deadLine = ""; + if(deadlineCtr.getBinder() != null) { + Binder binder = deadlineCtr.getBinder(); + if(binder.getDeadLine() != null) { + Formatter formatter = Formatter.getInstance(getLocale()); + deadLine = formatter.formatDateAndTime(binder.getDeadLine()); + } + binderToElements.get(binder).deadlineEl.setValue(deadLine); + } + closeDeadlineBox(); + } + } + + private void popupDeadlineBox(UserRequest ureq, Binder binder) { + String title = translate("map.deadline.change"); + + removeAsListenerAndDispose(deadlineCtr); + deadlineCtr = new DeadlineController(ureq, getWindowControl(), binder); + listenTo(deadlineCtr); + + removeAsListenerAndDispose(deadlineCalloutCtr); + FormLink changeDeadlineLink = binderToElements.get(binder).changeDeadlineLink; + deadlineCalloutCtr = new CloseableCalloutWindowController(ureq, getWindowControl(), deadlineCtr.getInitialComponent(), + changeDeadlineLink, title, true, "o_ep_deadline_callout"); + listenTo(deadlineCalloutCtr); + deadlineCalloutCtr.activate(); + } + + private void closeDeadlineBox() { + if (deadlineCalloutCtr != null){ + deadlineCalloutCtr.deactivate(); + removeAsListenerAndDispose(deadlineCalloutCtr); + deadlineCalloutCtr = null; + } + } + + private static class MapElements { + private FormLink openMapLink; + private FormLink changeDeadlineLink; + private StaticTextElement deadlineEl; + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/modules/portfolio/ui/_content/assessment_infos.html b/src/main/java/org/olat/modules/portfolio/ui/_content/assessment_infos.html new file mode 100644 index 00000000000..e4155ebeadd --- /dev/null +++ b/src/main/java/org/olat/modules/portfolio/ui/_content/assessment_infos.html @@ -0,0 +1,48 @@ +#if ($hasPassedField) + +<div class="panel panel-default o_personal"> + <div class="panel-heading"> + <h4 class="panel-title">$r.translate("score.title")</h4> + </div> + <table class="table"> + <tbody> + + + #if ($hasPassedField) + <tr class="o_state #if ($hasPassedValue && $passed) o_passed #elseif($hasPassedValue && !$passed) o_failed #else o_unknown #end"> + <th>$r.translate("passed.yourpassed")</th> + <td> + #if($hasPassedValue && $passed) + <i class="o_icon o_icon_passed"></i> $r.translate("map.passed") + #elseif($hasPassedValue && !$passed) + <i class="o_icon o_icon_failed"></i> $r.translate("map.not.passed") + #else + <div class="o_noinfo">$r.translate("map.not.rated.yet")</div> + #end + </td> + </tr> + #end + </tbody> + </table> +</div> +#end + +#if ($comment && !$comment.isEmpty()) +<div class="panel panel-default o_comment"> + <div class="panel-heading" data-toggle="collapse" data-target="#collapseComment"> + <h4 class="panel-title"> + <i id="collapseCommentToggler" class="o_icon o_icon-fw o_icon_close_togglebox"> </i> $r.translate("map.comment")</h4> + </div> + <div id="collapseComment" class="panel-collapse collapse in"><div class="panel-body">$comment</div></div> +</div> +<script type="text/javascript"> + /* <![CDATA[ */ + jQuery('#collapseComment').on('hide.bs.collapse', function () { + jQuery('#collapseCommentToggler').removeClass('o_icon_close_togglebox').addClass('o_icon_open_togglebox'); + }) + jQuery('#collapseComment').on('show.bs.collapse', function () { + jQuery('#collapseCommentToggler').removeClass('o_icon_open_togglebox').addClass('o_icon_close_togglebox'); + }) + /* ]]> */ +</script> +#end \ No newline at end of file diff --git a/src/main/java/org/olat/modules/portfolio/ui/_content/run.html b/src/main/java/org/olat/modules/portfolio/ui/_content/run.html new file mode 100644 index 00000000000..8d4386aad30 --- /dev/null +++ b/src/main/java/org/olat/modules/portfolio/ui/_content/run.html @@ -0,0 +1,2 @@ +$r.render("assessmentInfos") +$r.render("infos") \ No newline at end of file diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties index c0d2a02ad9c..a63d9f74a3f 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_de.properties @@ -1,4 +1,4 @@ -#Fri Jun 24 10:55:46 CEST 2016 +#Tue Jun 28 15:07:32 CEST 2016 access=Zugang access.rights.coach=Betreuer access.rights.coach.long=als Betreuer (lesen / kommentieren / bewerten) @@ -18,8 +18,8 @@ artefact.collect.link=Link artefact.descr=Beschreibung artefact.file=Datei artefact.source=Quelle -artefatct.text=Text artefact.title=Titel +artefatct.text=Text author=Autor begin.date=Beginn binder.by=von {0} @@ -30,6 +30,7 @@ binder.status=Status categories=Kategorien categories.hint=Kategorien Hinweis close=Schliessen +command.openassessment=Bewertungswerkzeug create.binder=Mappe erstellen create.empty.binder=Leere Mappe erstellen create.empty.binder.from.course=Mappe f\u00FCr Portfolioaufgabe aus Kurs erstellen @@ -56,6 +57,16 @@ goto.my.pages=zeige meine Eintr\u00E4ge goto.my.shared.items=zu meinen freigegebenen Mappen goto.shared.with.me=zeige an mich freigegebene Mappen import.artefactV1=Artefakte importieren +map.available=$org.olat.course.nodes.portfolio\:map.available +map.comment=$org.olat.course.assessment\:map.comment +map.copyDate=$org.olat.course.nodes.portfolio\:map.copyDate +map.deadline=$org.olat.course.nodes.portfolio\:map.deadline +map.deadline.change=$org.olat.course.nodes.portfolio\:map.deadline.change +map.new=$org.olat.course.nodes.portfolio\:map.new +map.not.passed=$org.olat.course.assessment\:map.not.passed +map.not.rated.yet=$org.olat.course.assessment\:map.not.rated.yet +map.passed=$org.olat.course.assessment\:map.passed +map.returnDate=$org.olat.course.nodes.portfolio\:map.returnDate media.center=Mediencenter media.center.text=Hier k\u00F6nnen Sie Mediendateien, Dokumente oder andere Artefakte hinzuf\u00FCgen. Verwenden Sie die Medien um Ihre Eintr\u00E4ge zu illustrieren und zu erg\u00E4nzen. meta.last.modified=zuletzt bearbeitet am {0} @@ -69,14 +80,17 @@ my.shared.items=Von mir freigegeben my.shared.items.text=Die Liste aller Eintr\u00E4ge, die Sie an andere Benutzer freigegeben haben. new.section.desc=Beschreibung des Bereiches new.section.title=Bereich +no.map=$org.olat.course.nodes.portfolio\:no.map open=\u00D6ffnen open.full.page=Den ganzen Eintrag lesen +open.map=$org.olat.course.nodes.portfolio\:open.map page.binders=Mappe page.sections=Sektion page.summary=$\:summary page.title=$\:title passed.false=$org.olat.course.assessment\:passed.false passed.true=$org.olat.course.assessment\:passed.true +passed.yourpassed=$org.olat.course.assessment\:passed.yourpassed portfolio.assessment=Bewertung portfolio.entries=Eintr\u00E4ge portfolio.overview=\u00DCberblick @@ -87,14 +101,15 @@ portfolio.root.breadcrump=Portfolio portfoliotask=Portfolioaufgabe portfoliotask.none=Keine publish=Eintrag publizieren -publish.confirm.title=Publizieren publish.confirm.descr=Wollen Sie diesen Eintrag "{0}" publizieren? +publish.confirm.title=Publizieren publish.status.title=Freigabe Status der Mappe "{0}" reopen=Neu \u00F6ffnen section.delete=Bereich l\u00F6schen section.edit=Bereich bearbeiten section.score=Punkte section.status=Status +select.mymap=$org.olat.course.nodes.portfolio\:select.mymap shared.with.me=Mit mir geteilt shared.with.me.text=Liste aller Mappen, die von anderen Benutzern an mich freigegeben wurden. status.closed=geschlossen diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties index bc22437af3a..c459db2053e 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Thu Jun 23 19:16:35 CEST 2016 +#Tue Jun 28 15:08:23 CEST 2016 access=Access access.rights.coach=Coach access.rights.coach.long=as coach (read / comment / assess) @@ -20,6 +20,7 @@ artefact.file=File artefact.source=Source artefact.text=Text artefact.title=Title +artefatct.text=Text author=Author begin.date=Begin binder.by=by {0} @@ -30,6 +31,7 @@ binder.status=Status categories=Categories categories.hint=Categories hint close=Close +command.openassessment=Assessment tool create.binder=Create binder create.empty.binder=New empty binder create.empty.binder.from.course=New binder from course portfolio task @@ -57,6 +59,16 @@ goto.my.pages=show my entries goto.my.shared.items=go to my shares goto.shared.with.me=go to shared items import.artefactV1=Import artefacts +map.available=$org.olat.course.nodes.portfolio\:map.available +map.comment=$org.olat.course.assessment\:map.comment +map.copyDate=$org.olat.course.nodes.portfolio\:map.copyDate +map.deadline=$org.olat.course.nodes.portfolio\:map.deadline +map.deadline.change=$org.olat.course.nodes.portfolio\:map.deadline.change +map.new=$org.olat.course.nodes.portfolio\:map.new +map.not.passed=$org.olat.course.assessment\:map.not.passed +map.not.rated.yet=$org.olat.course.assessment\:map.not.rated.yet +map.passed=$org.olat.course.assessment\:map.passed +map.returnDate=$org.olat.course.nodes.portfolio\:map.returnDate media.center=Media center media.center.text=Search, create, add media files or other artefacts that you want to use within your entries for illustration purpose. meta.last.modified=last modified {0} @@ -70,14 +82,17 @@ my.shared.items=Shared by me my.shared.items.text=Show all the entries that I shared with other people. new.section.desc=Description of the section new.section.title=Section +no.map=$org.olat.course.nodes.portfolio\:no.map open=Open open.full.page=Read the whole page +open.map=$org.olat.course.nodes.portfolio\:open.map page.binders=Binder page.sections=Section page.summary=$\:summary page.title=$\:title passed.false=$org.olat.course.assessment\:passed.false passed.true=$org.olat.course.assessment\:passed.true +passed.yourpassed=$org.olat.course.assessment\:passed.yourpassed portfolio.assessment=Grading portfolio.entries=Entries portfolio.overview=Overview @@ -88,14 +103,15 @@ portfolio.root.breadcrump=Portfolio portfoliotask=Portfolio Task portfoliotask.none=None publish=Publish entry -publish.confirm.title=Publish publish.confirm.descr=Do you want to publish this entry "{0}"? +publish.confirm.title=Publish publish.status.title=Publish status of binder "{0}" reopen=Reopen section.delete=Delete section section.edit=Edit section section.score=Score section.status=Status +select.mymap=$org.olat.course.nodes.portfolio\:select.mymap shared.with.me=Shared with me shared.with.me.text=Show all the items that are shared with me by other people. status.closed=closed diff --git a/src/main/java/org/olat/repository/handlers/BlogHandler.java b/src/main/java/org/olat/repository/handlers/BlogHandler.java index 62491738009..a50c3db3a6e 100644 --- a/src/main/java/org/olat/repository/handlers/BlogHandler.java +++ b/src/main/java/org/olat/repository/handlers/BlogHandler.java @@ -182,6 +182,11 @@ public class BlogHandler implements RepositoryHandler { }); } + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } + @Override public String getSupportedType() { return BlogFileResource.TYPE_NAME; @@ -214,6 +219,11 @@ public class BlogHandler implements RepositoryHandler { public EditionSupport supportsEdit(OLATResourceable resource) { return EditionSupport.embedded; } + + @Override + public boolean supportsAssessmentDetails() { + return false; + } @Override public StepsMainRunController createWizardController(OLATResourceable res, UserRequest ureq, WindowControl wControl) { diff --git a/src/main/java/org/olat/repository/handlers/CourseHandler.java b/src/main/java/org/olat/repository/handlers/CourseHandler.java index c99f5e4c87c..5c024507e8c 100644 --- a/src/main/java/org/olat/repository/handlers/CourseHandler.java +++ b/src/main/java/org/olat/repository/handlers/CourseHandler.java @@ -469,6 +469,11 @@ public class CourseHandler implements RepositoryHandler { public EditionSupport supportsEdit(OLATResourceable resource) { return EditionSupport.yes; } + + @Override + public boolean supportsAssessmentDetails() { + return false; + } @Override public MainLayoutController createLaunchController(RepositoryEntry re, RepositoryEntrySecurity reSecurity, UserRequest ureq, WindowControl wControl) { @@ -483,6 +488,11 @@ public class CourseHandler implements RepositoryHandler { }, true, true); } + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } + @Override public MediaResource getAsMediaResource(OLATResourceable res, boolean backwardsCompatible) { RepositoryEntry re = RepositoryManager.getInstance().lookupRepositoryEntry(res, true); diff --git a/src/main/java/org/olat/repository/handlers/GlossaryHandler.java b/src/main/java/org/olat/repository/handlers/GlossaryHandler.java index 4ed4a5945ac..4dd84090d84 100644 --- a/src/main/java/org/olat/repository/handlers/GlossaryHandler.java +++ b/src/main/java/org/olat/repository/handlers/GlossaryHandler.java @@ -155,6 +155,11 @@ public class GlossaryHandler implements RepositoryHandler { return EditionSupport.embedded; } + @Override + public boolean supportsAssessmentDetails() { + return false; + } + @Override public VFSContainer getMediaContainer(RepositoryEntry repoEntry) { return FileResourceManager.getInstance() @@ -201,6 +206,11 @@ public class GlossaryHandler implements RepositoryHandler { } }); } + + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } @Override public MediaResource getAsMediaResource(OLATResourceable res, boolean backwardsCompatible) { diff --git a/src/main/java/org/olat/repository/handlers/ImsCPHandler.java b/src/main/java/org/olat/repository/handlers/ImsCPHandler.java index aec017612ee..da6457fecbf 100644 --- a/src/main/java/org/olat/repository/handlers/ImsCPHandler.java +++ b/src/main/java/org/olat/repository/handlers/ImsCPHandler.java @@ -182,6 +182,11 @@ public class ImsCPHandler extends FileHandler { public EditionSupport supportsEdit(OLATResourceable resource) { return EditionSupport.yes; } + + @Override + public boolean supportsAssessmentDetails() { + return false; + } @Override public StepsMainRunController createWizardController(OLATResourceable res, UserRequest ureq, WindowControl wControl) { @@ -230,6 +235,11 @@ public class ImsCPHandler extends FileHandler { return new CPEditMainController(ureq, wControl, toolbar, cpRoot, re.getOlatResource()); } + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } + protected String getDeletedFilePrefix() { return "del_imscp_"; } diff --git a/src/main/java/org/olat/repository/handlers/PodcastHandler.java b/src/main/java/org/olat/repository/handlers/PodcastHandler.java index 5100020280d..8feec9aa4fd 100644 --- a/src/main/java/org/olat/repository/handlers/PodcastHandler.java +++ b/src/main/java/org/olat/repository/handlers/PodcastHandler.java @@ -175,6 +175,11 @@ public class PodcastHandler implements RepositoryHandler { } }); } + + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } @Override public String getSupportedType() { @@ -208,6 +213,11 @@ public class PodcastHandler implements RepositoryHandler { public EditionSupport supportsEdit(OLATResourceable resource) { return EditionSupport.embedded; } + + @Override + public boolean supportsAssessmentDetails() { + return false; + } @Override public StepsMainRunController createWizardController(OLATResourceable res, UserRequest ureq, WindowControl wControl) { diff --git a/src/main/java/org/olat/repository/handlers/PortfolioHandler.java b/src/main/java/org/olat/repository/handlers/PortfolioHandler.java index 668f769db2d..0fa6333f86d 100644 --- a/src/main/java/org/olat/repository/handlers/PortfolioHandler.java +++ b/src/main/java/org/olat/repository/handlers/PortfolioHandler.java @@ -161,6 +161,11 @@ public class PortfolioHandler implements RepositoryHandler { return EditionSupport.embedded; } + @Override + public boolean supportsAssessmentDetails() { + return false; + } + @Override public VFSContainer getMediaContainer(RepositoryEntry repoEntry) { return FileResourceManager.getInstance() @@ -215,7 +220,7 @@ public class PortfolioHandler implements RepositoryHandler { } @Override - public Controller createEditorController(RepositoryEntry re, UserRequest ureq, WindowControl control, TooledStackedPanel toolbar) { + public Controller createEditorController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar) { return null; } @@ -237,6 +242,12 @@ public class PortfolioHandler implements RepositoryHandler { }); } + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, + TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } + @Override public String getSupportedType() { return EPTemplateMapResource.TYPE_NAME; diff --git a/src/main/java/org/olat/repository/handlers/RepositoryHandler.java b/src/main/java/org/olat/repository/handlers/RepositoryHandler.java index f5e43b0a43d..1d4427f91b4 100644 --- a/src/main/java/org/olat/repository/handlers/RepositoryHandler.java +++ b/src/main/java/org/olat/repository/handlers/RepositoryHandler.java @@ -90,7 +90,7 @@ public interface RepositoryHandler { /** * * @param initialAuthor - * @param initialAuthorAlt TODO + * @param initialAuthorAlt * @param displayname * @param description * @param withReferences if true import references @@ -110,8 +110,6 @@ public interface RepositoryHandler { */ public RepositoryEntry copy(Identity author, RepositoryEntry source, RepositoryEntry target); - - /** * @return true if this handler supports donwloading Resourceables of its type. */ @@ -122,6 +120,13 @@ public interface RepositoryHandler { */ public EditionSupport supportsEdit(OLATResourceable resource); + /** + * If the resource handler can deliver an assessment details controller, + * it returns true. + * @return + */ + public boolean supportsAssessmentDetails(); + /** * Return the container where image and files can be saved for the description field. * the folder MUST be under the root folder has its name "media". @@ -132,7 +137,7 @@ public interface RepositoryHandler { /** * Called if a user launches a Resourceable that this handler can handle. - * @param reSecurity TODO + * @param reSecurity The permissions wrapper * @param ureq * @param wControl * @param res @@ -147,7 +152,7 @@ public interface RepositoryHandler { * can only be called when the current user is either olat admin or in the owning group of this resource * @param ureq * @param wControl - * @param toolbar TODO + * @param toolbar * @param res * @return Controler able to edit resourceable. */ @@ -172,6 +177,18 @@ public interface RepositoryHandler { return new CreateRepositoryEntryController(ureq, wControl, this); } + /** + * Return the details controller for the assessed identity. + * + * @param re + * @param ureq + * @param wControl + * @param toolbar + * @param assessedIdentity + * @return + */ + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity); + /** * Called if a user downloads a Resourceable that this handler can handle. * @param res diff --git a/src/main/java/org/olat/repository/handlers/SCORMCPHandler.java b/src/main/java/org/olat/repository/handlers/SCORMCPHandler.java index 1190950e469..aade598ba55 100644 --- a/src/main/java/org/olat/repository/handlers/SCORMCPHandler.java +++ b/src/main/java/org/olat/repository/handlers/SCORMCPHandler.java @@ -156,6 +156,11 @@ public class SCORMCPHandler extends FileHandler { public EditionSupport supportsEdit(OLATResourceable resource) { return EditionSupport.no; } + + @Override + public boolean supportsAssessmentDetails() { + return false; + } @Override public StepsMainRunController createWizardController(OLATResourceable res, UserRequest ureq, WindowControl wControl) { @@ -183,6 +188,11 @@ public class SCORMCPHandler extends FileHandler { } }); } + + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } @Override public Controller createEditorController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar) { diff --git a/src/main/java/org/olat/repository/handlers/SharedFolderHandler.java b/src/main/java/org/olat/repository/handlers/SharedFolderHandler.java index e96a47608f7..d9ada15d8dc 100644 --- a/src/main/java/org/olat/repository/handlers/SharedFolderHandler.java +++ b/src/main/java/org/olat/repository/handlers/SharedFolderHandler.java @@ -141,6 +141,11 @@ public class SharedFolderHandler implements RepositoryHandler { public EditionSupport supportsEdit(OLATResourceable resource) { return EditionSupport.embedded; } + + @Override + public boolean supportsAssessmentDetails() { + return false; + } /** * @see org.olat.repository.handlers.RepositoryHandler#getCreateWizardController(org.olat.core.id.OLATResourceable, org.olat.core.gui.UserRequest, org.olat.core.gui.control.WindowControl) @@ -193,6 +198,11 @@ public class SharedFolderHandler implements RepositoryHandler { return runtime; } + + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } /** * @see org.olat.repository.handlers.RepositoryHandler#getAsMediaResource(org.olat.core.id.OLATResourceable diff --git a/src/main/java/org/olat/repository/handlers/VideoHandler.java b/src/main/java/org/olat/repository/handlers/VideoHandler.java index da84c074cd4..e0191d3e440 100644 --- a/src/main/java/org/olat/repository/handlers/VideoHandler.java +++ b/src/main/java/org/olat/repository/handlers/VideoHandler.java @@ -41,8 +41,6 @@ import org.olat.core.gui.media.NotFoundMediaResource; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.AssertException; -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; import org.olat.core.util.FileUtils; import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.LockResult; @@ -74,8 +72,6 @@ import org.olat.resource.OLATResourceManager; * */ public class VideoHandler extends FileHandler { - - private static final OLog log = Tracing.createLoggerFor(VideoHandler.class); @Override public boolean isCreate() { @@ -166,6 +162,11 @@ public class VideoHandler extends FileHandler { public EditionSupport supportsEdit(OLATResourceable resource) { return EditionSupport.no; } + + @Override + public boolean supportsAssessmentDetails() { + return false; + } @Override public StepsMainRunController createWizardController(OLATResourceable res, UserRequest ureq, WindowControl wControl) { @@ -187,6 +188,11 @@ public class VideoHandler extends FileHandler { public Controller createEditorController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar) { throw new AssertException("a web document is not editable!!! res-id:"+re.getResourceableId()); } + + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } protected String getDeletedFilePrefix() { return "del_video_"; diff --git a/src/main/java/org/olat/repository/handlers/WebDocumentHandler.java b/src/main/java/org/olat/repository/handlers/WebDocumentHandler.java index d55cb957349..b56744eceda 100644 --- a/src/main/java/org/olat/repository/handlers/WebDocumentHandler.java +++ b/src/main/java/org/olat/repository/handlers/WebDocumentHandler.java @@ -208,6 +208,11 @@ public class WebDocumentHandler extends FileHandler { public EditionSupport supportsEdit(OLATResourceable resource) { return EditionSupport.no; } + + @Override + public boolean supportsAssessmentDetails() { + return false; + } @Override public StepsMainRunController createWizardController(OLATResourceable res, UserRequest ureq, WindowControl wControl) { @@ -231,6 +236,11 @@ public class WebDocumentHandler extends FileHandler { public Controller createEditorController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar) { throw new AssertException("a web document is not editable!!! res-id:"+re.getResourceableId()); } + + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } protected String getDeletedFilePrefix() { return "del_webdoc_"; diff --git a/src/main/java/org/olat/repository/handlers/WikiHandler.java b/src/main/java/org/olat/repository/handlers/WikiHandler.java index ca2199ab97a..8cee4fe6edb 100644 --- a/src/main/java/org/olat/repository/handlers/WikiHandler.java +++ b/src/main/java/org/olat/repository/handlers/WikiHandler.java @@ -200,6 +200,11 @@ public class WikiHandler implements RepositoryHandler { return EditionSupport.embedded; } + @Override + public boolean supportsAssessmentDetails() { + return false; + } + @Override public VFSContainer getMediaContainer(RepositoryEntry repoEntry) { return FileResourceManager.getInstance() @@ -262,6 +267,11 @@ public class WikiHandler implements RepositoryHandler { public Controller createEditorController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar) { return null; } + + @Override + public Controller createAssessmentDetailsController(RepositoryEntry re, UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbar, Identity assessedIdentity) { + return null; + } @Override public MediaResource getAsMediaResource(OLATResourceable res, boolean backwardsCompatible) { diff --git a/src/main/java/org/olat/repository/ui/author/AuthorListController.java b/src/main/java/org/olat/repository/ui/author/AuthorListController.java index 37187d4bb89..273895ee06b 100644 --- a/src/main/java/org/olat/repository/ui/author/AuthorListController.java +++ b/src/main/java/org/olat/repository/ui/author/AuthorListController.java @@ -198,7 +198,7 @@ public class AuthorListController extends FormBasicController implements Activat RepositoryHandler handler = orderedHandler.getHandler(); if(handler != null && handler.isCreate()) { - // for each 10-group, crate a separator + // for each 10-group, create a separator int group = orderedHandler.getOrder() / 10; if (group > lastGroup) { createDropdown.addComponent(new Spacer("spacer" + orderedHandler.getOrder())); diff --git a/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java b/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java index c850d6cdee7..9f6c6de0626 100644 --- a/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java +++ b/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java @@ -114,6 +114,8 @@ public class RepositoryEditDescriptionController extends FormBasicController { private RepositoryManager repositoryManager; @Autowired private RepositoryEntryLifecycleDAO lifecycleDao; + @Autowired + private RepositoryHandlerFactory repositoryHandlerFactory; /** * Create a repository add controller that adds the given resourceable. @@ -198,7 +200,7 @@ public class RepositoryEditDescriptionController extends FormBasicController { location = uifactory.addTextElement("cif.location", "cif.location", 255, repositoryEntry.getLocation(), descCont); location.setEnabled(!RepositoryEntryManagedFlag.isManaged(repositoryEntry, RepositoryEntryManagedFlag.location)); - RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry); + RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(repositoryEntry); mediaContainer = handler.getMediaContainer(repositoryEntry); if(mediaContainer != null && mediaContainer.getName().equals("media")) { mediaContainer = mediaContainer.getParentContainer(); -- GitLab