From ba0378ba2072f486cf1ef37d96ac9504307991e3 Mon Sep 17 00:00:00 2001 From: uhensler <urs.hensler@frentix.com> Date: Wed, 28 Aug 2019 15:41:57 +0200 Subject: [PATCH] OO-4206: Restrict the selection of new course nodes to learning path supporting nodes --- .../ConditionNodeAccessProvider.java | 5 ++ .../org/olat/course/config/CourseConfig.java | 5 +- .../course/editor/ChooseNodeController.java | 10 +++- .../course/editor/NodeEditController.java | 33 +++++----- .../course/editor/_content/create_node.html | 18 +++--- .../LearningPathNodeAccessProvider.java | 51 ++++++++++++++-- .../learningpath/LearningPathNodeHandler.java | 41 +++++++++++++ .../UnsupportedLearningPathNodeHandler.java | 55 +++++++++++++++++ ...bbableLeaningPathNodeConfigController.java | 16 ++--- .../ui/_i18n/LocalStrings_de.properties | 1 + .../ui/_i18n/LocalStrings_en.properties | 1 + .../course/nodeaccess/NodeAccessProvider.java | 2 + .../NodeAccessProviderIdentifier.java | 4 +- .../course/nodeaccess/NodeAccessService.java | 12 ++-- .../course/nodeaccess/NodeAccessType.java | 43 +++++++++++++ .../manager/NodeAccessServiceImpl.java | 21 +++++-- .../nodeaccess/model/NodeAccessTypeImpl.java | 43 +++++++++++++ .../ui/NodeAccessSettingsController.java | 11 ++-- .../org/olat/course/nodes/SPCourseNode.java | 2 +- .../olat/course/nodes/VideoCourseNode.java | 2 +- .../nodes/sp/SPLearningPathNodeHandler.java | 60 +++++++++++++++++++ .../nodes/st/STCourseNodeEditController.java | 12 ++-- .../nodes/st/STLearningPathNodeHandler.java | 59 ++++++++++++++++++ .../video/VideoLearningPathNodeHandler.java | 60 +++++++++++++++++++ ...CreateCourseRepositoryEntryController.java | 16 +++++ .../CreateRepositoryEntryController.java | 2 +- 26 files changed, 515 insertions(+), 70 deletions(-) create mode 100644 src/main/java/org/olat/course/learningpath/LearningPathNodeHandler.java create mode 100644 src/main/java/org/olat/course/learningpath/manager/UnsupportedLearningPathNodeHandler.java create mode 100644 src/main/java/org/olat/course/nodeaccess/NodeAccessType.java create mode 100644 src/main/java/org/olat/course/nodeaccess/model/NodeAccessTypeImpl.java create mode 100644 src/main/java/org/olat/course/nodes/sp/SPLearningPathNodeHandler.java create mode 100644 src/main/java/org/olat/course/nodes/st/STLearningPathNodeHandler.java create mode 100644 src/main/java/org/olat/course/nodes/video/VideoLearningPathNodeHandler.java diff --git a/src/main/java/org/olat/course/condition/ConditionNodeAccessProvider.java b/src/main/java/org/olat/course/condition/ConditionNodeAccessProvider.java index 8539e3cb2e0..35990dbbb82 100644 --- a/src/main/java/org/olat/course/condition/ConditionNodeAccessProvider.java +++ b/src/main/java/org/olat/course/condition/ConditionNodeAccessProvider.java @@ -52,6 +52,11 @@ public class ConditionNodeAccessProvider implements NodeAccessProvider { return translator.translate("access.provider.name"); } + @Override + public boolean isSupported(String courseNodeType) { + return true; + } + @Override public TabbableController createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) { return null; diff --git a/src/main/java/org/olat/course/config/CourseConfig.java b/src/main/java/org/olat/course/config/CourseConfig.java index d2fd125ca3a..40e16246b07 100644 --- a/src/main/java/org/olat/course/config/CourseConfig.java +++ b/src/main/java/org/olat/course/config/CourseConfig.java @@ -32,6 +32,7 @@ import java.util.Map; import org.olat.core.util.StringHelper; import org.olat.course.certificate.RecertificationTimeUnit; import org.olat.course.condition.ConditionNodeAccessProvider; +import org.olat.course.nodeaccess.NodeAccessType; /** * Description: <br> @@ -311,8 +312,8 @@ public class CourseConfig implements Serializable, Cloneable { configuration.put(NODE_ACCESS_TYPE, nodeAccessType); } - public String getNodeAccessType() { - return (String) configuration.get(NODE_ACCESS_TYPE); + public NodeAccessType getNodeAccessType() { + return NodeAccessType.of((String) configuration.get(NODE_ACCESS_TYPE)); } public boolean isChatEnabled() { diff --git a/src/main/java/org/olat/course/editor/ChooseNodeController.java b/src/main/java/org/olat/course/editor/ChooseNodeController.java index 59eed28ef73..25ea9cc17d1 100644 --- a/src/main/java/org/olat/course/editor/ChooseNodeController.java +++ b/src/main/java/org/olat/course/editor/ChooseNodeController.java @@ -35,12 +35,15 @@ import org.olat.core.gui.control.controller.BasicController; import org.olat.core.id.OLATResourceable; import org.olat.course.CourseFactory; import org.olat.course.ICourse; +import org.olat.course.nodeaccess.NodeAccessService; +import org.olat.course.nodeaccess.NodeAccessType; import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.CourseNodeConfiguration; import org.olat.course.nodes.CourseNodeFactory; import org.olat.course.nodes.CourseNodeGroup; import org.olat.course.tree.CourseEditorTreeModel; import org.olat.course.tree.CourseEditorTreeNode; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -55,6 +58,9 @@ public class ChooseNodeController extends BasicController { private final CourseEditorTreeNode currentNode; private Link multiSpsLink, multiCheckListLink; + + @Autowired + private NodeAccessService nodeAccessService; public ChooseNodeController(UserRequest ureq, WindowControl wControl, OLATResourceable courseOres, CourseEditorTreeNode currentNode) { @@ -71,10 +77,12 @@ public class ChooseNodeController extends BasicController { VelocityContainer mainVC = createVelocityContainer("create_node"); Map<String, CourseNodeTypesGroup> linkNames = new HashMap<>(); + ICourse course = CourseFactory.loadCourse(courseOres); CourseNodeFactory cnf = CourseNodeFactory.getInstance(); for (String courseNodeAlias : cnf.getRegisteredCourseNodeAliases()) { CourseNodeConfiguration cnConfig = cnf.getCourseNodeConfiguration(courseNodeAlias); - if(cnConfig.isDeprecated()) { + boolean supportedNodeAccessType = nodeAccessService.isSupported(NodeAccessType.of(course), courseNodeAlias); + if(cnConfig.isDeprecated() || !supportedNodeAccessType) { continue; } diff --git a/src/main/java/org/olat/course/editor/NodeEditController.java b/src/main/java/org/olat/course/editor/NodeEditController.java index 07fca36fe1c..72eda40b868 100644 --- a/src/main/java/org/olat/course/editor/NodeEditController.java +++ b/src/main/java/org/olat/course/editor/NodeEditController.java @@ -44,6 +44,7 @@ import org.olat.course.condition.Condition; import org.olat.course.condition.ConditionEditController; import org.olat.course.condition.ConditionNodeAccessProvider; import org.olat.course.nodeaccess.NodeAccessService; +import org.olat.course.nodeaccess.NodeAccessType; import org.olat.course.nodes.CourseNode; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.tree.CourseEditorTreeModel; @@ -132,20 +133,22 @@ public class NodeEditController extends ActivateableTabbableDefaultController im // Visibility and no-access explanation component visibilityVc = createVelocityContainer("visibilityedit"); - String nodeAccessType = course.getCourseConfig().getNodeAccessType(); - if (!ConditionNodeAccessProvider.TYPE.equals(nodeAccessType)) { - TabbableController nodeAccessCtrl = nodeAccessService.createEditController(ureq, getWindowControl(), - nodeAccessType, courseNode); - this.nodeAccessCtrl = nodeAccessCtrl; - listenTo(nodeAccessCtrl); - } else { - // Visibility precondition - Condition visibCondition = luNode.getPreConditionVisibility(); - visibilityCondContr = new ConditionEditController(ureq, getWindowControl(), euce, visibCondition, - AssessmentHelper.getAssessableNodes(editorModel, luNode)); - //set this useractivity logger for the visibility condition controller - listenTo(visibilityCondContr); - visibilityVc.put("visibilityCondition", visibilityCondContr.getInitialComponent()); + NodeAccessType nodeAccessType = course.getCourseConfig().getNodeAccessType(); + if (nodeAccessService.isSupported(nodeAccessType, courseNode)) { + if (!ConditionNodeAccessProvider.TYPE.equals(nodeAccessType.getType())) { + TabbableController nodeAccessCtrl = nodeAccessService.createEditController(ureq, getWindowControl(), + nodeAccessType, courseNode); + this.nodeAccessCtrl = nodeAccessCtrl; + listenTo(nodeAccessCtrl); + } else { + // Visibility precondition + Condition visibCondition = luNode.getPreConditionVisibility(); + visibilityCondContr = new ConditionEditController(ureq, getWindowControl(), euce, visibCondition, + AssessmentHelper.getAssessableNodes(editorModel, luNode)); + //set this useractivity logger for the visibility condition controller + listenTo(visibilityCondContr); + visibilityVc.put("visibilityCondition", visibilityCondContr.getInitialComponent()); + } } // No-Access-Explanation @@ -235,7 +238,7 @@ public class NodeEditController extends ActivateableTabbableDefaultController im public void addTabs(TabbedPane tabbedPane) { myTabbedPane = tabbedPane; tabbedPane.addTab(translate(PANE_TAB_GENERAL), descriptionVc); - if (nodeAccessCtrl!= null) { + if (nodeAccessCtrl != null) { nodeAccessCtrl.addTabs(tabbedPane); } if (visibilityCondContr !=null) { diff --git a/src/main/java/org/olat/course/editor/_content/create_node.html b/src/main/java/org/olat/course/editor/_content/create_node.html index 6d786404711..a527111d0a3 100644 --- a/src/main/java/org/olat/course/editor/_content/create_node.html +++ b/src/main/java/org/olat/course/editor/_content/create_node.html @@ -2,14 +2,16 @@ <div class="o_info">$r.translate("header.insertnodes.desc")</div> #foreach($name in $groupNames) #set($group = $linkNames.get("$name")) - <div class="o_block"> - <h4>$r.translate($group.name)</h4> - - <div class="row"> - #foreach($nodeType in $group.nodeTypes) - <div class="col-sm-6">$r.render($nodeType)</div> - #end + #if($r.isNotNull($group)) + <div class="o_block"> + <h4>$r.translate($group.name)</h4> + + <div class="row"> + #foreach($nodeType in $group.nodeTypes) + <div class="col-sm-6">$r.render($nodeType)</div> + #end + </div> </div> - </div> + #end #end </div> \ No newline at end of file diff --git a/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java b/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java index 89978971940..2c830c4c381 100644 --- a/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java +++ b/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java @@ -19,19 +19,25 @@ */ package org.olat.course.learningpath; +import java.util.HashMap; +import java.util.List; import java.util.Locale; +import java.util.Map; + +import javax.annotation.PostConstruct; import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.tabbable.TabbableController; import org.olat.core.gui.translator.Translator; import org.olat.core.util.Util; -import org.olat.course.assessment.AssessmentAction; +import org.olat.course.learningpath.manager.UnsupportedLearningPathNodeHandler; import org.olat.course.learningpath.ui.LeaningPathNodeConfigController; -import org.olat.course.learningpath.ui.LeaningPathNodeConfigController.LearningPathControllerConfig; import org.olat.course.learningpath.ui.TabbableLeaningPathNodeConfigController; import org.olat.course.nodeaccess.NodeAccessProvider; import org.olat.course.nodes.CourseNode; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** @@ -43,6 +49,36 @@ import org.springframework.stereotype.Service; @Service public class LearningPathNodeAccessProvider implements NodeAccessProvider { + private static final String UNSUPPORTED_LEARNING_PATH_TYPE = UnsupportedLearningPathNodeHandler.NODE_TYPE; + + @Autowired + private List<LearningPathNodeHandler> loadedLearningPathNodeHandlers; + private Map<String, LearningPathNodeHandler> learningPathNodeHandlers = new HashMap<>(); + private LearningPathNodeHandler nonLearningPathNodeHandler; + + @PostConstruct + void initProviders() { + for (LearningPathNodeHandler handler: loadedLearningPathNodeHandlers) { + if (UNSUPPORTED_LEARNING_PATH_TYPE.equals(handler.acceptCourseNodeType())) { + nonLearningPathNodeHandler = handler; + } else { + learningPathNodeHandlers.put(handler.acceptCourseNodeType(), handler); + } + } + } + + private LearningPathNodeHandler getLearningPathNodeHandler(String courseNodeType) { + LearningPathNodeHandler handler = learningPathNodeHandlers.get(courseNodeType); + if (handler == null) { + handler = nonLearningPathNodeHandler; + } + return handler; + } + + private LearningPathNodeHandler getLearningPathNodeHandler(CourseNode courseNode) { + return getLearningPathNodeHandler(courseNode.getType()); + } + @Override public String getType() { return "learningpath"; @@ -54,12 +90,15 @@ public class LearningPathNodeAccessProvider implements NodeAccessProvider { return translator.translate("access.provider.name"); } + @Override + public boolean isSupported(String courseNodeType) { + return getLearningPathNodeHandler(courseNodeType).isSupported(); + } + @Override public TabbableController createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) { - LearningPathControllerConfig ctrlConfig = LeaningPathNodeConfigController.builder() - .addAssessmentAction(AssessmentAction.nodeClicked) - .build(); - return new TabbableLeaningPathNodeConfigController(ureq, wControl, courseNode.getModuleConfiguration(), ctrlConfig); + Controller configCtrl = getLearningPathNodeHandler(courseNode).createEditController(ureq, wControl, courseNode); + return new TabbableLeaningPathNodeConfigController(ureq, wControl, configCtrl); } } diff --git a/src/main/java/org/olat/course/learningpath/LearningPathNodeHandler.java b/src/main/java/org/olat/course/learningpath/LearningPathNodeHandler.java new file mode 100644 index 00000000000..b9af39fffa3 --- /dev/null +++ b/src/main/java/org/olat/course/learningpath/LearningPathNodeHandler.java @@ -0,0 +1,41 @@ +/** + * <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.learningpath; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.course.nodes.CourseNode; + +/** + * + * Initial date: 28 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public interface LearningPathNodeHandler { + + public String acceptCourseNodeType(); + + public boolean isSupported(); + + public Controller createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode); + +} diff --git a/src/main/java/org/olat/course/learningpath/manager/UnsupportedLearningPathNodeHandler.java b/src/main/java/org/olat/course/learningpath/manager/UnsupportedLearningPathNodeHandler.java new file mode 100644 index 00000000000..1a19f66eff3 --- /dev/null +++ b/src/main/java/org/olat/course/learningpath/manager/UnsupportedLearningPathNodeHandler.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.learningpath.manager; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.course.learningpath.LearningPathNodeHandler; +import org.olat.course.nodes.CourseNode; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 28 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +@Service +public class UnsupportedLearningPathNodeHandler implements LearningPathNodeHandler { + + public static final String NODE_TYPE = "unsupported.learning.path.nodes"; + + @Override + public String acceptCourseNodeType() { + return NODE_TYPE; + } + + @Override + public boolean isSupported() { + return false; + } + + @Override + public Controller createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) { + return null; + } + +} diff --git a/src/main/java/org/olat/course/learningpath/ui/TabbableLeaningPathNodeConfigController.java b/src/main/java/org/olat/course/learningpath/ui/TabbableLeaningPathNodeConfigController.java index 2e6ff757ed1..60a351dc987 100644 --- a/src/main/java/org/olat/course/learningpath/ui/TabbableLeaningPathNodeConfigController.java +++ b/src/main/java/org/olat/course/learningpath/ui/TabbableLeaningPathNodeConfigController.java @@ -28,8 +28,6 @@ import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.tabbable.ActivateableTabbableDefaultController; import org.olat.course.editor.NodeEditController; -import org.olat.course.learningpath.ui.LeaningPathNodeConfigController.LearningPathControllerConfig; -import org.olat.modules.ModuleConfiguration; /** * @@ -43,18 +41,17 @@ public class TabbableLeaningPathNodeConfigController extends ActivateableTabbabl private final static String[] paneKeys = { PANE_TAB_LEARNIN_PATH }; private final VelocityContainer configVC; - private final LeaningPathNodeConfigController configController; + private final Controller configCtrl; private TabbedPane tabPane; - public TabbableLeaningPathNodeConfigController(UserRequest ureq, WindowControl wControl, - ModuleConfiguration configs, LearningPathControllerConfig ctrlConfig) { + public TabbableLeaningPathNodeConfigController(UserRequest ureq, WindowControl wControl, Controller configCtrl) { super(ureq, wControl); + this.configCtrl = configCtrl; - configController = new LeaningPathNodeConfigController(ureq, wControl, configs, ctrlConfig); - listenTo(configController); + listenTo(configCtrl); configVC = createVelocityContainer("config"); - configVC.put("config", configController.getInitialComponent()); + configVC.put("config", configCtrl.getInitialComponent()); } @Override @@ -75,8 +72,7 @@ public class TabbableLeaningPathNodeConfigController extends ActivateableTabbabl @Override public void event(UserRequest ureq, Controller source, Event event) { - if (source == configController && event.equals(Event.DONE_EVENT)) { - configController.getUpdatedConfig(); + if (source == configCtrl && event.equals(Event.DONE_EVENT)) { fireEvent(ureq, NodeEditController.NODECONFIG_CHANGED_EVENT); } } diff --git a/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_de.properties index a215c355cba..e82e8016417 100644 --- a/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_de.properties @@ -7,4 +7,5 @@ config.estimated.duration=Zeitvorgabe (Minuten) congig.obligation=Pflicht config.obligation.mandatory=Obligatorisch config.obligation.optional=Freiwillig +no.configurations=In diesen Kursbaustein stehen keine Konfigurationen zum Lernpfad zu Verf\u00FCgung. pane.tab.learning.path=Lernpfad \ No newline at end of file diff --git a/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_en.properties index 84f81bf0b93..389a8ac4102 100644 --- a/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_en.properties @@ -7,4 +7,5 @@ config.estimated.duration=Estimated duration (minutes) config.obligation=Obligation config.obligation.mandatory=Mandatory config.obligation.optional=Optional +no.configuration=No configurations for the learning path are available in this course element. pane.tab.learning.path=Learning path \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodeaccess/NodeAccessProvider.java b/src/main/java/org/olat/course/nodeaccess/NodeAccessProvider.java index 8e5c1f96421..9a2385f6846 100644 --- a/src/main/java/org/olat/course/nodeaccess/NodeAccessProvider.java +++ b/src/main/java/org/olat/course/nodeaccess/NodeAccessProvider.java @@ -32,6 +32,8 @@ import org.olat.course.nodes.CourseNode; */ public interface NodeAccessProvider extends NodeAccessProviderIdentifier { + public boolean isSupported(String courseNodeType); + public TabbableController createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode); } diff --git a/src/main/java/org/olat/course/nodeaccess/NodeAccessProviderIdentifier.java b/src/main/java/org/olat/course/nodeaccess/NodeAccessProviderIdentifier.java index 0795049a71b..e3c6bbc1481 100644 --- a/src/main/java/org/olat/course/nodeaccess/NodeAccessProviderIdentifier.java +++ b/src/main/java/org/olat/course/nodeaccess/NodeAccessProviderIdentifier.java @@ -27,9 +27,7 @@ import java.util.Locale; * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com * */ -public interface NodeAccessProviderIdentifier { - - public String getType(); +public interface NodeAccessProviderIdentifier extends NodeAccessType { public String getDisplayName(Locale locale); diff --git a/src/main/java/org/olat/course/nodeaccess/NodeAccessService.java b/src/main/java/org/olat/course/nodeaccess/NodeAccessService.java index 2254cb7f873..396b1f66b62 100644 --- a/src/main/java/org/olat/course/nodeaccess/NodeAccessService.java +++ b/src/main/java/org/olat/course/nodeaccess/NodeAccessService.java @@ -35,17 +35,21 @@ import org.olat.course.nodes.CourseNode; public interface NodeAccessService { public List<? extends NodeAccessProviderIdentifier> getNodeAccessProviderIdentifer(); + + public boolean isSupported(NodeAccessType type, String courseNodeType); + + public boolean isSupported(NodeAccessType type, CourseNode courseNode); /** * Creates the controller to edit the configurations of the node. * - * @param ureq - * @param windowControl - * @param nodeAccessType + * @param ureq + * @param windowControl + * @param type * @param courseNode * @return */ - public TabbableController createEditController(UserRequest ureq, WindowControl wControl, String nodeAccessType, + public TabbableController createEditController(UserRequest ureq, WindowControl wControl, NodeAccessType type, CourseNode courseNode); } diff --git a/src/main/java/org/olat/course/nodeaccess/NodeAccessType.java b/src/main/java/org/olat/course/nodeaccess/NodeAccessType.java new file mode 100644 index 00000000000..a73f2b25fa8 --- /dev/null +++ b/src/main/java/org/olat/course/nodeaccess/NodeAccessType.java @@ -0,0 +1,43 @@ +/** + * <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.nodeaccess; + +import org.olat.course.ICourse; +import org.olat.course.nodeaccess.model.NodeAccessTypeImpl; + +/** + * + * Initial date: 28 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public interface NodeAccessType { + + public String getType(); + + public static NodeAccessType of(String type) { + return new NodeAccessTypeImpl(type); + } + + public static NodeAccessType of(ICourse course) { + return course.getCourseConfig().getNodeAccessType(); + } + +} diff --git a/src/main/java/org/olat/course/nodeaccess/manager/NodeAccessServiceImpl.java b/src/main/java/org/olat/course/nodeaccess/manager/NodeAccessServiceImpl.java index 225b06007fa..3d44caded7b 100644 --- a/src/main/java/org/olat/course/nodeaccess/manager/NodeAccessServiceImpl.java +++ b/src/main/java/org/olat/course/nodeaccess/manager/NodeAccessServiceImpl.java @@ -29,6 +29,7 @@ import org.olat.core.logging.Tracing; import org.olat.course.nodeaccess.NodeAccessProvider; import org.olat.course.nodeaccess.NodeAccessProviderIdentifier; import org.olat.course.nodeaccess.NodeAccessService; +import org.olat.course.nodeaccess.NodeAccessType; import org.olat.course.nodes.CourseNode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -47,13 +48,13 @@ public class NodeAccessServiceImpl implements NodeAccessService { @Autowired private List<NodeAccessProvider> nodeAccessProviders; - private NodeAccessProvider getNodeAccessProvider(String nodeAccessType) { + private NodeAccessProvider getNodeAccessProvider(NodeAccessType type) { for (NodeAccessProvider provider : nodeAccessProviders) { - if (provider.getType().equals(nodeAccessType)) { + if (provider.getType().equals(type.getType())) { return provider; } } - log.error("No node access provider found for type '{}'!", nodeAccessType); + log.error("No node access provider found for type '{}'!", type.getType()); return null; } @@ -63,9 +64,19 @@ public class NodeAccessServiceImpl implements NodeAccessService { } @Override - public TabbableController createEditController(UserRequest ureq, WindowControl wControl, String nodeAccessType, + public boolean isSupported(NodeAccessType type, String courseNodeType) { + return getNodeAccessProvider(type).isSupported(courseNodeType); + } + + @Override + public boolean isSupported(NodeAccessType type, CourseNode courseNode) { + return isSupported(type, courseNode.getType()); + } + + @Override + public TabbableController createEditController(UserRequest ureq, WindowControl wControl, NodeAccessType type, CourseNode courseNode) { - return getNodeAccessProvider(nodeAccessType).createEditController(ureq, wControl, courseNode); + return getNodeAccessProvider(type).createEditController(ureq, wControl, courseNode); } } diff --git a/src/main/java/org/olat/course/nodeaccess/model/NodeAccessTypeImpl.java b/src/main/java/org/olat/course/nodeaccess/model/NodeAccessTypeImpl.java new file mode 100644 index 00000000000..32133f8df60 --- /dev/null +++ b/src/main/java/org/olat/course/nodeaccess/model/NodeAccessTypeImpl.java @@ -0,0 +1,43 @@ +/** + * <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.nodeaccess.model; + +import org.olat.course.nodeaccess.NodeAccessType; + +/** + * + * Initial date: 28 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class NodeAccessTypeImpl implements NodeAccessType { + + private final String type; + + public NodeAccessTypeImpl(String type) { + this.type = type; + } + + @Override + public String getType() { + return type; + } + +} diff --git a/src/main/java/org/olat/course/nodeaccess/ui/NodeAccessSettingsController.java b/src/main/java/org/olat/course/nodeaccess/ui/NodeAccessSettingsController.java index 35a350a5ac1..aa838643123 100644 --- a/src/main/java/org/olat/course/nodeaccess/ui/NodeAccessSettingsController.java +++ b/src/main/java/org/olat/course/nodeaccess/ui/NodeAccessSettingsController.java @@ -19,6 +19,8 @@ */ package org.olat.course.nodeaccess.ui; +import static org.olat.course.nodeaccess.NodeAccessType.of; + import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.SingleSelection; @@ -27,9 +29,9 @@ import org.olat.core.gui.components.util.KeyValues; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.course.CourseFactory; -import org.olat.course.ICourse; import org.olat.course.nodeaccess.NodeAccessProviderIdentifier; import org.olat.course.nodeaccess.NodeAccessService; +import org.olat.course.nodeaccess.NodeAccessType; import org.olat.repository.RepositoryEntry; import org.springframework.beans.factory.annotation.Autowired; @@ -43,15 +45,14 @@ public class NodeAccessSettingsController extends FormBasicController { private SingleSelection nodeAccessEl; - private final String nodeAccessType; + private final NodeAccessType nodeAccessType; @Autowired private NodeAccessService nodeAccessService; public NodeAccessSettingsController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) { super(ureq, wControl); - ICourse course = CourseFactory.loadCourse(entry); - this.nodeAccessType = course.getCourseConfig().getNodeAccessType(); + this.nodeAccessType = of(CourseFactory.loadCourse(entry)); initForm(ureq); } @@ -66,7 +67,7 @@ public class NodeAccessSettingsController extends FormBasicController { nodeAccessEl = uifactory.addDropdownSingleselect("settings.type", "settings.type", formLayout, nodeAccessKV.keys(), nodeAccessKV.values()); nodeAccessEl.setEnabled(false); - nodeAccessEl.select(nodeAccessType, true); + nodeAccessEl.select(nodeAccessType.getType(), true); } @Override diff --git a/src/main/java/org/olat/course/nodes/SPCourseNode.java b/src/main/java/org/olat/course/nodes/SPCourseNode.java index 691604097fe..cd791439539 100644 --- a/src/main/java/org/olat/course/nodes/SPCourseNode.java +++ b/src/main/java/org/olat/course/nodes/SPCourseNode.java @@ -61,7 +61,7 @@ import org.olat.repository.RepositoryEntry; public class SPCourseNode extends AbstractAccessableCourseNode { private static final long serialVersionUID = -4565145351110778757L; - private static final String TYPE = "sp"; + public static final String TYPE = "sp"; /** * Default constructor for course node of type single page diff --git a/src/main/java/org/olat/course/nodes/VideoCourseNode.java b/src/main/java/org/olat/course/nodes/VideoCourseNode.java index 2381044205c..b3bbb36fcb2 100644 --- a/src/main/java/org/olat/course/nodes/VideoCourseNode.java +++ b/src/main/java/org/olat/course/nodes/VideoCourseNode.java @@ -58,7 +58,7 @@ import org.olat.repository.handlers.RepositoryHandlerFactory; public class VideoCourseNode extends AbstractAccessableCourseNode { private static final long serialVersionUID = -3808867902051897291L; - private static final String TYPE = "video"; + public static final String TYPE = "video"; public VideoCourseNode() { super(TYPE); diff --git a/src/main/java/org/olat/course/nodes/sp/SPLearningPathNodeHandler.java b/src/main/java/org/olat/course/nodes/sp/SPLearningPathNodeHandler.java new file mode 100644 index 00000000000..0d4674e6875 --- /dev/null +++ b/src/main/java/org/olat/course/nodes/sp/SPLearningPathNodeHandler.java @@ -0,0 +1,60 @@ +/** + * <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.nodes.sp; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.course.assessment.AssessmentAction; +import org.olat.course.learningpath.LearningPathNodeHandler; +import org.olat.course.learningpath.ui.LeaningPathNodeConfigController; +import org.olat.course.learningpath.ui.LeaningPathNodeConfigController.LearningPathControllerConfig; +import org.olat.course.nodes.CourseNode; +import org.olat.course.nodes.SPCourseNode; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 28 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +@Service +public class SPLearningPathNodeHandler implements LearningPathNodeHandler { + + @Override + public String acceptCourseNodeType() { + return SPCourseNode.TYPE; + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public Controller createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) { + LearningPathControllerConfig ctrlConfig = LeaningPathNodeConfigController.builder() + .addAssessmentAction(AssessmentAction.nodeClicked) + .build(); + return new LeaningPathNodeConfigController(ureq, wControl, courseNode.getModuleConfiguration(), ctrlConfig); + } + +} diff --git a/src/main/java/org/olat/course/nodes/st/STCourseNodeEditController.java b/src/main/java/org/olat/course/nodes/st/STCourseNodeEditController.java index f8efa68091c..20682cddd06 100644 --- a/src/main/java/org/olat/course/nodes/st/STCourseNodeEditController.java +++ b/src/main/java/org/olat/course/nodes/st/STCourseNodeEditController.java @@ -136,6 +136,7 @@ public class STCourseNodeEditController extends ActivateableTabbableDefaultContr private UserCourseEnvironment euce; private TabbedPane myTabbedPane; + private int highScoreTabPos; private CourseEditorTreeModel editorModel; private final Long repoKey; @@ -436,18 +437,16 @@ public class STCourseNodeEditController extends ActivateableTabbableDefaultContr private void updateHighscoreTab() { AssessmentConfig assessmentConfig = courseAssessmentService.getAssessmentConfig(stNode); - myTabbedPane.setEnabled(5, assessmentConfig.hasScore()); + myTabbedPane.setEnabled(highScoreTabPos, assessmentConfig.hasScore()); } - /** - * @see org.olat.core.gui.control.generic.tabbable.TabbableDefaultController#addTabs(org.olat.core.gui.components.TabbedPane) - */ + @Override public void addTabs(TabbedPane tabbedPane) { myTabbedPane = tabbedPane; tabbedPane.addTab(translate(PANE_TAB_ACCESSIBILITY), accessibilityCondContr.getWrappedDefaultAccessConditionVC(translate("condition.accessibility.title"))); tabbedPane.addTab(translate(PANE_TAB_ST_CONFIG), configvc); tabbedPane.addTab(translate(PANE_TAB_ST_SCORECALCULATION), score); - tabbedPane.addTab(translate(PANE_TAB_HIGHSCORE) , highScoreNodeConfigController.getInitialComponent()); + highScoreTabPos = tabbedPane.addTab(translate(PANE_TAB_HIGHSCORE) , highScoreNodeConfigController.getInitialComponent()); updateHighscoreTab(); if(editorEnabled) { @@ -455,9 +454,6 @@ public class STCourseNodeEditController extends ActivateableTabbableDefaultContr } } - /** - * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) - */ @Override protected void doDispose() { //child controllers registered with listenTo() get disposed in BasicController diff --git a/src/main/java/org/olat/course/nodes/st/STLearningPathNodeHandler.java b/src/main/java/org/olat/course/nodes/st/STLearningPathNodeHandler.java new file mode 100644 index 00000000000..afd7745fcfb --- /dev/null +++ b/src/main/java/org/olat/course/nodes/st/STLearningPathNodeHandler.java @@ -0,0 +1,59 @@ +/** + * <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.nodes.st; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.messages.MessageUIFactory; +import org.olat.core.gui.translator.Translator; +import org.olat.core.util.Util; +import org.olat.course.learningpath.LearningPathNodeHandler; +import org.olat.course.learningpath.ui.TabbableLeaningPathNodeConfigController; +import org.olat.course.nodes.CourseNode; +import org.olat.course.nodes.STCourseNode; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 28 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +@Service +public class STLearningPathNodeHandler implements LearningPathNodeHandler { + + @Override + public String acceptCourseNodeType() { + return STCourseNode.TYPE; + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public Controller createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) { + Translator translator = Util.createPackageTranslator(TabbableLeaningPathNodeConfigController.class, ureq.getLocale()); + return MessageUIFactory.createInfoMessage(ureq, wControl, null, translator.translate("no.configurations")); + } + +} diff --git a/src/main/java/org/olat/course/nodes/video/VideoLearningPathNodeHandler.java b/src/main/java/org/olat/course/nodes/video/VideoLearningPathNodeHandler.java new file mode 100644 index 00000000000..0ba8cefb528 --- /dev/null +++ b/src/main/java/org/olat/course/nodes/video/VideoLearningPathNodeHandler.java @@ -0,0 +1,60 @@ +/** + * <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.nodes.video; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.course.assessment.AssessmentAction; +import org.olat.course.learningpath.LearningPathNodeHandler; +import org.olat.course.learningpath.ui.LeaningPathNodeConfigController; +import org.olat.course.learningpath.ui.LeaningPathNodeConfigController.LearningPathControllerConfig; +import org.olat.course.nodes.CourseNode; +import org.olat.course.nodes.VideoCourseNode; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 28 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +@Service +public class VideoLearningPathNodeHandler implements LearningPathNodeHandler { + + @Override + public String acceptCourseNodeType() { + return VideoCourseNode.TYPE; + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public Controller createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) { + LearningPathControllerConfig ctrlConfig = LeaningPathNodeConfigController.builder() + .addAssessmentAction(AssessmentAction.nodeClicked) + .build(); + return new LeaningPathNodeConfigController(ureq, wControl, courseNode.getModuleConfiguration(), ctrlConfig); + } + +} diff --git a/src/main/java/org/olat/repository/ui/author/CreateCourseRepositoryEntryController.java b/src/main/java/org/olat/repository/ui/author/CreateCourseRepositoryEntryController.java index ad24e1da458..aa0fca7c41b 100644 --- a/src/main/java/org/olat/repository/ui/author/CreateCourseRepositoryEntryController.java +++ b/src/main/java/org/olat/repository/ui/author/CreateCourseRepositoryEntryController.java @@ -21,8 +21,10 @@ package org.olat.repository.ui.author; import org.apache.logging.log4j.Logger; 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.SingleSelection; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.util.KeyValues; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; @@ -64,6 +66,20 @@ public class CreateCourseRepositoryEntryController extends CreateRepositoryEntry nodeAccessEl = uifactory.addDropdownSingleselect("cif.node.access", "cif.node.access", formLayout, nodeAccessKV.keys(), nodeAccessKV.values()); nodeAccessEl.select(CourseConfig.NODE_ACCESS_TYPE_DEFAULT, true); + nodeAccessEl.addActionListener(FormEvent.ONCHANGE); + } + + private void updateUI() { + boolean hasWizard = nodeAccessEl.isOneSelected() && CourseConfig.NODE_ACCESS_TYPE_DEFAULT.equals(nodeAccessEl.getSelectedKey()); + wizardButton.setVisible(hasWizard); + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if (source == nodeAccessEl) { + updateUI(); + } + super.formInnerEvent(ureq, source, event); } @Override diff --git a/src/main/java/org/olat/repository/ui/author/CreateRepositoryEntryController.java b/src/main/java/org/olat/repository/ui/author/CreateRepositoryEntryController.java index a3f4c77f2fe..f4b6a87aee0 100644 --- a/src/main/java/org/olat/repository/ui/author/CreateRepositoryEntryController.java +++ b/src/main/java/org/olat/repository/ui/author/CreateRepositoryEntryController.java @@ -71,7 +71,7 @@ public class CreateRepositoryEntryController extends FormBasicController impleme public static final Event CREATION_WIZARD = new Event("start_wizard"); - private FormLink wizardButton; + protected FormLink wizardButton; private TextElement displaynameEl; private SingleSelection organisationEl; private FormLayoutContainer exampleHelpEl; -- GitLab