diff --git a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties index 25f6d1efc90da5bee93e99b17c6d7c42732879e2..212e46ad6d99ed5c8f2f44440ad7ca0fad57fa48 100644 --- a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties @@ -478,15 +478,22 @@ publish.wizard.title=Publizieren published.latest=Der Kurs wurde zuletzt am {0} publiziert. published.never.yet=Der Kurs wurde noch nie publiziert status=Status -table.empty=In diesem Kurs gibt es keine Kursbausteine. +table.empty=Dieser Kurs hat keine Kurselemente. +table.header.comment=$org.olat.course.nodes.ms\:form.comment table.header.deleted=Gel\u00F6scht table.header.dirty=Unpublizierte \u00C4nderungen table.header.display=$\:nodeConfigForm.display_options table.header.hints=Hinweis +table.header.individual.documents=$org.olat.course.nodes.ms\:form.individual.assessment.docs table.header.learning.objectives=$\:nodeConfigForm.learningobjectives table.header.long.title=$\:nodeConfigForm.displaytitle table.header.new=Neu -table.header.node=Kursbaustein +table.header.node=Kurselemente +table.header.passed.cut=$org.olat.course.nodes.ms\:form.cut +table.header.passed=$org.olat.course.nodes.ms\:form.passed +table.header.score.max=$org.olat.course.nodes.ms\:form.max +table.header.score.min=$org.olat.course.nodes.ms\:form.min +table.header.score=$org.olat.course.nodes.ms\:form.score table.header.short.title=$\:nodeConfigForm.menutitle target.node.child=Untergeordnet target.node.first.node=Anfang diff --git a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties index e4a643729f0ba7509e7160d0d6c1669361598b40..4fa1ff81b026c7f8cd2c511ea5fd5f0a629a7e90 100644 --- a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties @@ -478,14 +478,21 @@ published.latest=This course was last published on {0}. published.never.yet=This course has never been published. status=Status table.empty=That course does not contain any course element. +table.header.comment=$org.olat.course.nodes.ms\:form.comment table.header.deleted=Deleted table.header.dirty=Unpublished changes table.header.display=$\:nodeConfigForm.display_options table.header.hints=Hint +table.header.individual.documents=$org.olat.course.nodes.ms\:form.individual.assessment.docs table.header.learning.objectives=$\:nodeConfigForm.learningobjectives table.header.long.title=$\:nodeConfigForm.displaytitle table.header.new=New -table.header.node=Kursbaustein +table.header.node=Course element +table.header.passed.cut=$org.olat.course.nodes.ms\:form.cut +table.header.passed=$org.olat.course.nodes.ms\:form.passed +table.header.score.max=$org.olat.course.nodes.ms\:form.max +table.header.score.min=$org.olat.course.nodes.ms\:form.min +table.header.score=$org.olat.course.nodes.ms\:form.score table.header.short.title=$\:nodeConfigForm.menutitle target.node.child=Subordinate target.node.first.node=Beginning diff --git a/src/main/java/org/olat/course/editor/overview/OnOffCellRenderer.java b/src/main/java/org/olat/course/editor/overview/OnOffCellRenderer.java new file mode 100644 index 0000000000000000000000000000000000000000..19c42c135e7ebca02eb380bde59712c1a98d9389 --- /dev/null +++ b/src/main/java/org/olat/course/editor/overview/OnOffCellRenderer.java @@ -0,0 +1,55 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.editor.overview; + +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; +import org.olat.core.gui.render.Renderer; +import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.URLBuilder; +import org.olat.core.gui.translator.Translator; + +/** + * + * Initial date: 31 Jan 2020<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class OnOffCellRenderer implements FlexiCellRenderer { + + private final Translator translator; + + public OnOffCellRenderer(Translator translator) { + this.translator = translator; + } + + @Override + public void render(Renderer renderer, StringOutput target, Object cellValue, int row, FlexiTableComponent source, + URLBuilder ubu, Translator trans) { + if(cellValue instanceof Boolean) { + Boolean bool = (Boolean)cellValue; + if(bool.booleanValue()) { + target.append(translator.translate("on")); + } else { + target.append(translator.translate("off")); + } + } + } +} diff --git a/src/main/java/org/olat/course/editor/overview/OverviewDataModel.java b/src/main/java/org/olat/course/editor/overview/OverviewDataModel.java index 7dfe82bdb35b78c52471863c2986227e71fb32be..45f085ec0721d78b634fb41b63dee941da8f9c78 100644 --- a/src/main/java/org/olat/course/editor/overview/OverviewDataModel.java +++ b/src/main/java/org/olat/course/editor/overview/OverviewDataModel.java @@ -72,6 +72,27 @@ public class OverviewDataModel extends DefaultFlexiTreeTableDataModel<OverviewRo case start: return row.getStart(); case end: return row.getEnd(); case trigger: return row.getTranslatedTrigger(); + case score: return row.getAssessmentConfig().isAssessable() + ? Boolean.valueOf(row.getAssessmentConfig().hasScore()) + : null; + case scoreMin: return row.getAssessmentConfig().isAssessable() && row.getAssessmentConfig().hasScore() + ? row.getAssessmentConfig().getMinScore() + : null; + case scoreMax: return row.getAssessmentConfig().isAssessable() && row.getAssessmentConfig().hasScore() + ? row.getAssessmentConfig().getMaxScore() + : null; + case passed: return row.getAssessmentConfig().isAssessable() + ? Boolean.valueOf(row.getAssessmentConfig().hasPassed()) + : null; + case passesCut: return row.getAssessmentConfig().isAssessable() && row.getAssessmentConfig().hasPassed() + ? row.getAssessmentConfig().getCutValue() + : null; + case comment: return row.getAssessmentConfig().isAssessable() + ? Boolean.valueOf(row.getAssessmentConfig().hasComment()) + : null; + case individualAsssessmentDocuments: return row.getAssessmentConfig().isAssessable() + ? Boolean.valueOf(row.getAssessmentConfig().hasIndividualAsssessmentDocuments()) + : null; default: return null; } } @@ -95,7 +116,14 @@ public class OverviewDataModel extends DefaultFlexiTreeTableDataModel<OverviewRo obligation("table.header.obligation"), start("table.header.start"), end("table.header.end"), - trigger("table.header.trigger"); + trigger("table.header.trigger"), + score("table.header.score"), + scoreMin("table.header.score.min"), + scoreMax("table.header.score.max"), + passed("table.header.passed"), + passesCut("table.header.passed.cut"), + comment("table.header.comment"), + individualAsssessmentDocuments("table.header.individual.documents"); private final String i18nKey; diff --git a/src/main/java/org/olat/course/editor/overview/OverviewListController.java b/src/main/java/org/olat/course/editor/overview/OverviewListController.java index 35c7f6e0b6ab843fc0d31029a66b3ea6c56a9e73..f14ffbe0b0ccee9ea3ad8f86b62db994f1dc65cd 100644 --- a/src/main/java/org/olat/course/editor/overview/OverviewListController.java +++ b/src/main/java/org/olat/course/editor/overview/OverviewListController.java @@ -51,7 +51,9 @@ import org.olat.core.gui.control.generic.closablewrapper.CloseableModalControlle import org.olat.core.util.Util; import org.olat.core.util.nodes.INode; import org.olat.course.ICourse; +import org.olat.course.assessment.CourseAssessmentService; import org.olat.course.assessment.IndentedNodeRenderer; +import org.olat.course.assessment.handler.AssessmentConfig; import org.olat.course.editor.EditorMainController; import org.olat.course.editor.NodeEditController; import org.olat.course.editor.SelectEvent; @@ -90,6 +92,8 @@ public class OverviewListController extends FormBasicController implements Flexi @Autowired private LearningPathService learningPathService; + @Autowired + private CourseAssessmentService courseAssessmentService; public OverviewListController(UserRequest ureq, WindowControl wControl, ICourse course) { super(ureq, wControl, LAYOUT_BAREBONE); @@ -150,6 +154,33 @@ public class OverviewListController extends FormBasicController implements Flexi columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OverviewCols.trigger)); } + // Assessment configuration + DefaultFlexiColumnModel scoreModel = new DefaultFlexiColumnModel(OverviewCols.score); + scoreModel.setCellRenderer(new OnOffCellRenderer(getTranslator())); + scoreModel.setDefaultVisible(false); + columnsModel.addFlexiColumnModel(scoreModel); + DefaultFlexiColumnModel scoreMinModel = new DefaultFlexiColumnModel(OverviewCols.scoreMin); + scoreMinModel.setDefaultVisible(false); + columnsModel.addFlexiColumnModel(scoreMinModel); + DefaultFlexiColumnModel scoreMaxModel = new DefaultFlexiColumnModel(OverviewCols.scoreMax); + scoreMaxModel.setDefaultVisible(false); + columnsModel.addFlexiColumnModel(scoreMaxModel); + DefaultFlexiColumnModel passedModel = new DefaultFlexiColumnModel(OverviewCols.passed); + passedModel.setCellRenderer(new OnOffCellRenderer(getTranslator())); + passedModel.setDefaultVisible(false); + columnsModel.addFlexiColumnModel(passedModel); + DefaultFlexiColumnModel passedCutModel = new DefaultFlexiColumnModel(OverviewCols.passesCut); + passedCutModel.setDefaultVisible(false); + columnsModel.addFlexiColumnModel(passedCutModel); + DefaultFlexiColumnModel commentModel = new DefaultFlexiColumnModel(OverviewCols.comment); + commentModel.setCellRenderer(new OnOffCellRenderer(getTranslator())); + commentModel.setDefaultVisible(false); + columnsModel.addFlexiColumnModel(commentModel); + DefaultFlexiColumnModel individualDocumentsModel = new DefaultFlexiColumnModel(OverviewCols.individualAsssessmentDocuments); + individualDocumentsModel.setCellRenderer(new OnOffCellRenderer(getTranslator())); + individualDocumentsModel.setDefaultVisible(false); + columnsModel.addFlexiColumnModel(individualDocumentsModel); + dataModel = new OverviewDataModel(columnsModel); tableEl = uifactory.addTableElement(getWindowControl(), "table", dataModel, 250, false, getTranslator(), formLayout); tableEl.setElementCssClass("o_course_edit_overview_table o_course_editor_legend"); @@ -198,6 +229,8 @@ public class OverviewListController extends FormBasicController implements Flexi row.setEnd(learningPathConfigs.getEndDate()); row.setTranslatedTrigger(getTranslatedTrigger(courseNode, learningPathConfigs)); } + AssessmentConfig assessmentConfig = courseAssessmentService.getAssessmentConfig(courseNode); + row.setAssessmentConfig(assessmentConfig); return row; } diff --git a/src/main/java/org/olat/course/editor/overview/OverviewRow.java b/src/main/java/org/olat/course/editor/overview/OverviewRow.java index 270b25d543044572737cb91586808305926de89f..4030220ae1dd817b5d32cbcd8051747cf921ada0 100644 --- a/src/main/java/org/olat/course/editor/overview/OverviewRow.java +++ b/src/main/java/org/olat/course/editor/overview/OverviewRow.java @@ -23,6 +23,7 @@ import java.util.Date; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTreeTableNode; import org.olat.course.assessment.IndentedNodeRenderer.IndentedCourseNode; +import org.olat.course.assessment.handler.AssessmentConfig; import org.olat.course.nodes.CourseNode; import org.olat.course.tree.CourseEditorTreeNode; @@ -36,14 +37,15 @@ public class OverviewRow implements FlexiTreeTableNode, IndentedCourseNode { private final CourseEditorTreeNode editorNode; private final int recursionLevel; + private OverviewRow parent; + private boolean hasChildren; private String translatedDisplayOption; private Integer duration; private String translatedObligation; private Date start; private Date end; private String translatedTrigger; - private OverviewRow parent; - private boolean hasChildren; + private AssessmentConfig assessmentConfig; public OverviewRow(CourseEditorTreeNode editorNode, int recursionLevel) { this.editorNode = editorNode; @@ -70,6 +72,27 @@ public class OverviewRow implements FlexiTreeTableNode, IndentedCourseNode { return getCourseNode().getLongTitle(); } + @Override + public String getCrump() { + return null; + } + + public void setParent(OverviewRow parent) { + this.parent = parent; + if (parent != null) { + parent.hasChildren = true; + } + } + + @Override + public FlexiTreeTableNode getParent() { + return parent; + } + + public boolean hasChildren() { + return hasChildren; + } + public CourseEditorTreeNode getEditorNode() { return editorNode; } @@ -126,25 +149,12 @@ public class OverviewRow implements FlexiTreeTableNode, IndentedCourseNode { this.translatedTrigger = translatedTrigger; } - @Override - public String getCrump() { - return null; + public AssessmentConfig getAssessmentConfig() { + return assessmentConfig; } - public void setParent(OverviewRow parent) { - this.parent = parent; - if (parent != null) { - parent.hasChildren = true; - } - } - - @Override - public FlexiTreeTableNode getParent() { - return parent; - } - - public boolean hasChildren() { - return hasChildren; + public void setAssessmentConfig(AssessmentConfig assessmentConfig) { + this.assessmentConfig = assessmentConfig; } } diff --git a/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java b/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java index 3ebd324eec2b55963fcafc3262f500e3c72355fc..17556334819bdc190af9333ef4221602fe5d13ef 100644 --- a/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java +++ b/src/main/java/org/olat/course/nodes/iq/IQTESTAssessmentConfig.java @@ -72,16 +72,18 @@ public class IQTESTAssessmentConfig implements AssessmentConfig { maxScore = (Float) config.get(IQEditController.CONFIG_KEY_MAXSCORE); } else { RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry(); - if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) { - AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry); - if(assessmentTest != null) { - Double max = QtiNodesExtractor.extractMaxScore(assessmentTest); - if(max != null) { - maxScore = Float.valueOf(max.floatValue()); + if (testEntry != null) { + if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) { + AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry); + if(assessmentTest != null) { + Double max = QtiNodesExtractor.extractMaxScore(assessmentTest); + if(max != null) { + maxScore = Float.valueOf(max.floatValue()); + } } + } else { + maxScore = (Float) config.get(IQEditController.CONFIG_KEY_MAXSCORE); } - } else { - maxScore = (Float) config.get(IQEditController.CONFIG_KEY_MAXSCORE); } } @@ -99,16 +101,18 @@ public class IQTESTAssessmentConfig implements AssessmentConfig { minScore = (Float) config.get(IQEditController.CONFIG_KEY_MINSCORE); } else { RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry(); - if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) { - AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry); - if(assessmentTest != null) { - Double min = QtiNodesExtractor.extractMinScore(assessmentTest); - if(min != null) { - minScore = Float.valueOf(min.floatValue()); + if (testEntry != null) { + if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) { + AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry); + if(assessmentTest != null) { + Double min = QtiNodesExtractor.extractMinScore(assessmentTest); + if(min != null) { + minScore = Float.valueOf(min.floatValue()); + } } + } else { + minScore = (Float) config.get(IQEditController.CONFIG_KEY_MINSCORE); } - } else { - minScore = (Float) config.get(IQEditController.CONFIG_KEY_MINSCORE); } } return minScore; @@ -130,16 +134,18 @@ public class IQTESTAssessmentConfig implements AssessmentConfig { cutValue = (Float) config.get(IQEditController.CONFIG_KEY_CUTVALUE); } else { RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry(); - if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) { - AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry); - if(assessmentTest != null) { - Double cut = QtiNodesExtractor.extractCutValue(assessmentTest); - if(cut != null) { - cutValue = Float.valueOf(cut.floatValue()); + if (testEntry != null) { + if(QTIResourceTypeModule.isQtiWorks(testEntry.getOlatResource())) { + AssessmentTest assessmentTest = courseNode.loadAssessmentTest(testEntry); + if(assessmentTest != null) { + Double cut = QtiNodesExtractor.extractCutValue(assessmentTest); + if(cut != null) { + cutValue = Float.valueOf(cut.floatValue()); + } } + } else { + cutValue = (Float) config.get(IQEditController.CONFIG_KEY_CUTVALUE); } - } else { - cutValue = (Float) config.get(IQEditController.CONFIG_KEY_CUTVALUE); } } return cutValue; diff --git a/src/main/java/org/olat/course/nodes/st/assessment/STAssessmentConfig.java b/src/main/java/org/olat/course/nodes/st/assessment/STAssessmentConfig.java index 646252ed0342aec313eb5dca19a5daa4c0d08b94..cb58c7e80802c7a1551f4190edeaa8e148f42edf 100644 --- a/src/main/java/org/olat/course/nodes/st/assessment/STAssessmentConfig.java +++ b/src/main/java/org/olat/course/nodes/st/assessment/STAssessmentConfig.java @@ -19,7 +19,6 @@ */ package org.olat.course.nodes.st.assessment; -import org.olat.core.logging.OLATRuntimeException; import org.olat.core.util.StringHelper; import org.olat.course.assessment.handler.AssessmentConfig; import org.olat.course.run.scoring.ScoreCalculator; @@ -63,12 +62,12 @@ public class STAssessmentConfig implements AssessmentConfig { @Override public Float getMaxScore() { - throw new OLATRuntimeException(STAssessmentConfig.class, "Max score never defined for ST nodes", null); + return null; } @Override public Float getMinScore() { - throw new OLATRuntimeException(STAssessmentConfig.class, "Min score never defined for ST nodes", null); + return null; } @Override @@ -81,7 +80,10 @@ public class STAssessmentConfig implements AssessmentConfig { @Override public Float getCutValue() { - throw new OLATRuntimeException(STAssessmentConfig.class, "Cut value never defined for ST nodes", null); + if (scoreCalculator != null && ScoreCalculator.PASSED_TYPE_CUTVALUE.equals(scoreCalculator.getPassedType())) { + return Float.valueOf(scoreCalculator.getPassedCutValue()); + } + return null; } @Override