From 6c1f489106d413a3e48065cd9d28fc4f2f769a0b Mon Sep 17 00:00:00 2001 From: uhensler <urs.hensler@frentix.com> Date: Wed, 28 Aug 2019 08:53:38 +0200 Subject: [PATCH] OO-4206: GUI for the configuration of the learning path options --- .../core/gui/components/util/KeyValues.java | 10 +- .../course/assessment/AssessmentAction.java | 33 +++ .../ConditionNodeAccessProvider.java | 9 + .../course/editor/NodeEditController.java | 45 +++-- .../LearningPathNodeAccessProvider.java | 15 ++ .../ui/LeaningPathNodeConfigController.java | 188 +++++++++++++++++- ...bbableLeaningPathNodeConfigController.java | 94 +++++++++ .../learningpath/ui/_content/config.html | 1 + .../ui/_i18n/LocalStrings_de.properties | 11 +- .../ui/_i18n/LocalStrings_en.properties | 11 +- .../course/nodeaccess/NodeAccessProvider.java | 7 + .../course/nodeaccess/NodeAccessService.java | 17 ++ .../manager/NodeAccessServiceImpl.java | 24 +++ 13 files changed, 449 insertions(+), 16 deletions(-) create mode 100644 src/main/java/org/olat/course/assessment/AssessmentAction.java create mode 100644 src/main/java/org/olat/course/learningpath/ui/TabbableLeaningPathNodeConfigController.java create mode 100644 src/main/java/org/olat/course/learningpath/ui/_content/config.html diff --git a/src/main/java/org/olat/core/gui/components/util/KeyValues.java b/src/main/java/org/olat/core/gui/components/util/KeyValues.java index c09e8cc432a..6c9e52a5200 100644 --- a/src/main/java/org/olat/core/gui/components/util/KeyValues.java +++ b/src/main/java/org/olat/core/gui/components/util/KeyValues.java @@ -50,6 +50,14 @@ public class KeyValues { remove(keyValue.getKey()); keyValues.add(keyValue); } + + public void addAll(KeyValues additionalKeyValues) { + if (additionalKeyValues == null) return; + + for (KeyValue additionalKeyValue : additionalKeyValues.keyValues) { + add(additionalKeyValue); + } + } /** * If a key / value pair with the key exists, the existing pair is replaced. If @@ -177,4 +185,4 @@ public class KeyValues { } } -} +} \ No newline at end of file diff --git a/src/main/java/org/olat/course/assessment/AssessmentAction.java b/src/main/java/org/olat/course/assessment/AssessmentAction.java new file mode 100644 index 00000000000..4305bc40c2e --- /dev/null +++ b/src/main/java/org/olat/course/assessment/AssessmentAction.java @@ -0,0 +1,33 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.assessment; + +/** + * + * Initial date: 27 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public enum AssessmentAction { + + nodeClicked, + confirmed + +} diff --git a/src/main/java/org/olat/course/condition/ConditionNodeAccessProvider.java b/src/main/java/org/olat/course/condition/ConditionNodeAccessProvider.java index 0fe0c2acfc9..8539e3cb2e0 100644 --- a/src/main/java/org/olat/course/condition/ConditionNodeAccessProvider.java +++ b/src/main/java/org/olat/course/condition/ConditionNodeAccessProvider.java @@ -21,9 +21,13 @@ package org.olat.course.condition; import java.util.Locale; +import org.olat.core.gui.UserRequest; +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.nodeaccess.NodeAccessProvider; +import org.olat.course.nodes.CourseNode; import org.springframework.stereotype.Service; /** @@ -48,4 +52,9 @@ public class ConditionNodeAccessProvider implements NodeAccessProvider { return translator.translate("access.provider.name"); } + @Override + public TabbableController createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) { + return null; + } + } diff --git a/src/main/java/org/olat/course/editor/NodeEditController.java b/src/main/java/org/olat/course/editor/NodeEditController.java index ff816d6f0d4..07fca36fe1c 100644 --- a/src/main/java/org/olat/course/editor/NodeEditController.java +++ b/src/main/java/org/olat/course/editor/NodeEditController.java @@ -42,15 +42,16 @@ import org.olat.course.ICourse; import org.olat.course.assessment.AssessmentHelper; 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.nodes.CourseNode; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.tree.CourseEditorTreeModel; import org.olat.repository.RepositoryManager; import org.olat.util.logging.activity.LoggingResourceable; +import org.springframework.beans.factory.annotation.Autowired; /** - * Description:<br> - * is the controller for * * @author Felix Jost */ @@ -82,11 +83,15 @@ public class NodeEditController extends ActivateableTabbableDefaultController im private ConditionEditController visibilityCondContr; private NoAccessExplEditController noAccessContr; private TabbedPane myTabbedPane; + private TabbableController nodeAccessCtrl; private TabbableController childTabsCntrllr; /** Event that signals that the node configuration has been changed * */ public static final Event NODECONFIG_CHANGED_EVENT = new Event("nodeconfigchanged"); private static final String[] paneKeys = { PANE_TAB_VISIBILITY, PANE_TAB_GENERAL }; + + @Autowired + private NodeAccessService nodeAccessService; public NodeEditController(UserRequest ureq, WindowControl wControl, CourseEditorTreeModel editorModel, ICourse course, CourseNode luNode, UserCourseEnvironment euce, TabbableController childTabsController) { @@ -127,13 +132,21 @@ public class NodeEditController extends ActivateableTabbableDefaultController im // Visibility and no-access explanation component visibilityVc = createVelocityContainer("visibilityedit"); - // 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()); + 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()); + } // No-Access-Explanation String noAccessExplanation = luNode.getNoAccessExplanation(); @@ -149,7 +162,6 @@ public class NodeEditController extends ActivateableTabbableDefaultController im @Override public void event(UserRequest urequest, Controller source, Event event) { - if (source == visibilityCondContr) { if (event == Event.CHANGED_EVENT) { Condition cond = visibilityCondContr.getCondition(); @@ -162,6 +174,10 @@ public class NodeEditController extends ActivateableTabbableDefaultController im courseNode.setNoAccessExplanation(noAccessExplanation); fireEvent(urequest, NodeEditController.NODECONFIG_CHANGED_EVENT); } + } else if (source == nodeAccessCtrl) { + if (event == NodeEditController.NODECONFIG_CHANGED_EVENT) { + fireEvent(urequest, NodeEditController.NODECONFIG_CHANGED_EVENT); + } } else if (source == childTabsCntrllr) { if (event == NodeEditController.NODECONFIG_CHANGED_EVENT) { //fire child controller request further @@ -217,9 +233,14 @@ public class NodeEditController extends ActivateableTabbableDefaultController im @Override public void addTabs(TabbedPane tabbedPane) { - myTabbedPane = tabbedPane; + myTabbedPane = tabbedPane; tabbedPane.addTab(translate(PANE_TAB_GENERAL), descriptionVc); - tabbedPane.addTab(translate(PANE_TAB_VISIBILITY), visibilityVc); + if (nodeAccessCtrl!= null) { + nodeAccessCtrl.addTabs(tabbedPane); + } + if (visibilityCondContr !=null) { + tabbedPane.addTab(translate(PANE_TAB_VISIBILITY), visibilityVc); + } if (childTabsCntrllr != null) { childTabsCntrllr.addTabs(tabbedPane); } diff --git a/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java b/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java index 4f3bae40b13..89978971940 100644 --- a/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java +++ b/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java @@ -21,10 +21,17 @@ package org.olat.course.learningpath; import java.util.Locale; +import org.olat.core.gui.UserRequest; +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.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.stereotype.Service; /** @@ -47,4 +54,12 @@ public class LearningPathNodeAccessProvider implements NodeAccessProvider { return translator.translate("access.provider.name"); } + @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); + } + } diff --git a/src/main/java/org/olat/course/learningpath/ui/LeaningPathNodeConfigController.java b/src/main/java/org/olat/course/learningpath/ui/LeaningPathNodeConfigController.java index 556b4f26a4e..a31ea79948e 100644 --- a/src/main/java/org/olat/course/learningpath/ui/LeaningPathNodeConfigController.java +++ b/src/main/java/org/olat/course/learningpath/ui/LeaningPathNodeConfigController.java @@ -19,12 +19,198 @@ */ package org.olat.course.learningpath.ui; +import static org.olat.core.gui.components.util.KeyValues.entry; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +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; +import org.olat.core.gui.components.form.flexible.elements.TextElement; +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.util.KeyValues; +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.util.StringHelper; +import org.olat.course.assessment.AssessmentAction; +import org.olat.modules.ModuleConfiguration; + /** * * Initial date: 27 Aug 2019<br> * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com * */ -public class LeaningPathNodeConfigController { +public class LeaningPathNodeConfigController extends FormBasicController { + + public static final String CONFIG_KEY_ESTIMATED_DURATION = "learning.path.estimated.duration"; + public static final String CONFIG_KEY_OBLIGATION = "learning.path.obligation"; + public static final String CONFIG_VALUE_OBLIGATION_MANDATORY = "obligation.mandatory"; + public static final String CONFIG_VALUE_OBLIGATION_OPTIONAL = "obligation.optional"; + public static final String CONFIG_DEFAULT_OBLIGATION = CONFIG_VALUE_OBLIGATION_MANDATORY; + public static final String CONFIG_KEY_DONE_TRIGGER = "learning.path.done.trigger"; + private static final String CONFIG_VALUE_DONE_TRIGGER_NONE = "done.trigger.none"; + public static final String CONFIG_DEFAULT_DONE_TRIGGER = CONFIG_VALUE_DONE_TRIGGER_NONE; + + private TextElement estimatedDurationEl; + private SingleSelection obligationEl; + private SingleSelection doneTriggerEl; + + private final ModuleConfiguration configs; + private final LearningPathControllerConfig ctrlConfig; + + public LeaningPathNodeConfigController(UserRequest ureq, WindowControl wControl, + ModuleConfiguration configs, LearningPathControllerConfig ctrlConfig) { + super(ureq, wControl); + this.configs = configs; + this.ctrlConfig = ctrlConfig; + initForm(ureq); + } + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + String estimatedTime = configs.getStringValue(CONFIG_KEY_ESTIMATED_DURATION); + estimatedDurationEl = uifactory.addTextElement("config.estimated.duration", 128, estimatedTime , formLayout); + + KeyValues obligationKV = new KeyValues(); + obligationKV.add(entry(CONFIG_VALUE_OBLIGATION_MANDATORY, translate("config.obligation.mandatory"))); + obligationKV.add(entry(CONFIG_VALUE_OBLIGATION_OPTIONAL, translate("config.obligation.optional"))); + obligationEl = uifactory.addRadiosHorizontal("config.obligation", formLayout, obligationKV.keys(), obligationKV.values()); + String obligationKey = configs.getStringValue(CONFIG_KEY_OBLIGATION, CONFIG_DEFAULT_OBLIGATION); + if (Arrays.asList(obligationEl.getKeys()).contains(obligationKey)) { + obligationEl.select(obligationKey, true); + } + + KeyValues doneTriggerKV = getDoneTriggerKV(); + doneTriggerEl = uifactory.addDropdownSingleselect("config.done.trigger", formLayout, + doneTriggerKV.keys(), doneTriggerKV.values()); + doneTriggerEl.addActionListener(FormEvent.ONCHANGE); + String doneTriggerKey = configs.getStringValue(CONFIG_KEY_DONE_TRIGGER, CONFIG_DEFAULT_DONE_TRIGGER); + if (Arrays.asList(doneTriggerEl.getKeys()).contains(doneTriggerKey)) { + doneTriggerEl.select(doneTriggerKey, true); + } + + uifactory.addFormSubmitButton("save", formLayout); + } + + private KeyValues getDoneTriggerKV() { + KeyValues doneTriggerKV = new KeyValues(); + if (ctrlConfig.getAssessmentActions().contains(AssessmentAction.nodeClicked)) { + doneTriggerKV.add(entry(AssessmentAction.nodeClicked.name(), translate("config.done.trigger.started"))); + } + if (ctrlConfig.getAssessmentActions().contains(AssessmentAction.confirmed)) { + doneTriggerKV.add(entry(AssessmentAction.confirmed.name(), translate("config.done.trigger.confirmed"))); + } + return doneTriggerKV; + } + + @Override + protected boolean validateFormLogic(UserRequest ureq) { + boolean allOk = true; + + allOk = validateInteger(estimatedDurationEl, 1, 10000, "error.positiv.int"); + + return allOk & super.validateFormLogic(ureq); + } + + public static boolean validateInteger(TextElement el, int min, int max, String i18nKey) { + boolean allOk = true; + el.clearError(); + if(el.isEnabled() && el.isVisible()) { + String val = el.getValue(); + if(StringHelper.containsNonWhitespace(val)) { + + try { + int value = Integer.parseInt(val); + if(min > value) { + el.setErrorKey(i18nKey, null); + allOk = false; + } else if(max < value) { + el.setErrorKey(i18nKey, null); + allOk = false; + } + } catch (NumberFormatException e) { + el.setErrorKey(i18nKey, null); + allOk = false; + } + } + } + return allOk; + } + + @Override + protected void formOK(UserRequest ureq) { + fireEvent(ureq, Event.DONE_EVENT); + } + + protected ModuleConfiguration getUpdatedConfig() { + String estimatedTime = estimatedDurationEl.getValue(); + configs.setStringValue(CONFIG_KEY_ESTIMATED_DURATION, estimatedTime); + + String obligation = obligationEl.isOneSelected() + ? obligationEl.getSelectedKey() + : CONFIG_DEFAULT_OBLIGATION; + configs.setStringValue(CONFIG_KEY_OBLIGATION, obligation); + + String doneTrigger = doneTriggerEl.isOneSelected() + ? doneTriggerEl.getSelectedKey() + : CONFIG_DEFAULT_DONE_TRIGGER; + configs.setStringValue(CONFIG_KEY_DONE_TRIGGER, doneTrigger); + + return configs; + } + + @Override + protected void doDispose() { + // + } + + public interface LearningPathControllerConfig { + + public Set<AssessmentAction> getAssessmentActions(); + + } + + public static ControllerConfigBuilder builder() { + return new ControllerConfigBuilder(); + } + + public static class ControllerConfigBuilder { + + private final Set<AssessmentAction> assessmentActions = new HashSet<>(); + + private ControllerConfigBuilder() { + } + + public ControllerConfigBuilder addAssessmentAction(AssessmentAction action) { + assessmentActions.add(action); + return this; + } + + public LearningPathControllerConfig build() { + return new ControllerConfigImpl(this); + } + + private final static class ControllerConfigImpl implements LearningPathControllerConfig { + + private final Set<AssessmentAction> assessmentActions; + + public ControllerConfigImpl(ControllerConfigBuilder builder) { + this.assessmentActions = new HashSet<>(builder.assessmentActions); + } + + @Override + public Set<AssessmentAction> getAssessmentActions() { + return assessmentActions; + } + + } + + } + } + diff --git a/src/main/java/org/olat/course/learningpath/ui/TabbableLeaningPathNodeConfigController.java b/src/main/java/org/olat/course/learningpath/ui/TabbableLeaningPathNodeConfigController.java new file mode 100644 index 00000000000..2e6ff757ed1 --- /dev/null +++ b/src/main/java/org/olat/course/learningpath/ui/TabbableLeaningPathNodeConfigController.java @@ -0,0 +1,94 @@ +/** + * <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.ui; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.tabbedpane.TabbedPane; +import org.olat.core.gui.components.velocity.VelocityContainer; +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.tabbable.ActivateableTabbableDefaultController; +import org.olat.course.editor.NodeEditController; +import org.olat.course.learningpath.ui.LeaningPathNodeConfigController.LearningPathControllerConfig; +import org.olat.modules.ModuleConfiguration; + +/** + * + * Initial date: 27 Aug 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class TabbableLeaningPathNodeConfigController extends ActivateableTabbableDefaultController { + + private static final String PANE_TAB_LEARNIN_PATH = "pane.tab.learning.path"; + private final static String[] paneKeys = { PANE_TAB_LEARNIN_PATH }; + + private final VelocityContainer configVC; + private final LeaningPathNodeConfigController configController; + private TabbedPane tabPane; + + public TabbableLeaningPathNodeConfigController(UserRequest ureq, WindowControl wControl, + ModuleConfiguration configs, LearningPathControllerConfig ctrlConfig) { + super(ureq, wControl); + + configController = new LeaningPathNodeConfigController(ureq, wControl, configs, ctrlConfig); + listenTo(configController); + + configVC = createVelocityContainer("config"); + configVC.put("config", configController.getInitialComponent()); + } + + @Override + public void addTabs(TabbedPane tabbedPane) { + tabPane = tabbedPane; + tabbedPane.addTab(translate(PANE_TAB_LEARNIN_PATH), configVC); + } + + @Override + public String[] getPaneKeys() { + return paneKeys; + } + + @Override + public TabbedPane getTabbedPane() { + return tabPane; + } + + @Override + public void event(UserRequest ureq, Controller source, Event event) { + if (source == configController && event.equals(Event.DONE_EVENT)) { + configController.getUpdatedConfig(); + fireEvent(ureq, NodeEditController.NODECONFIG_CHANGED_EVENT); + } + } + + @Override + protected void event(UserRequest ureq, Component source, Event event) { + // + } + + @Override + protected void doDispose() { + // + } + +} diff --git a/src/main/java/org/olat/course/learningpath/ui/_content/config.html b/src/main/java/org/olat/course/learningpath/ui/_content/config.html new file mode 100644 index 00000000000..a6a4023478b --- /dev/null +++ b/src/main/java/org/olat/course/learningpath/ui/_content/config.html @@ -0,0 +1 @@ +$r.render("config") \ No newline at end of file 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 71f4b0ce27b..a215c355cba 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 @@ -1 +1,10 @@ -access.provider.name=Lernpfad \ No newline at end of file +access.provider.name=Lernpfad +error.positiv.int=Geben Sie eine positive Zahl ein. +config.done.trigger=Lernfortschritt +config.done.trigger.confirmed=Best\u00E4tigt +config.done.trigger.started=Ge\u00F6ffnet +config.estimated.duration=Zeitvorgabe (Minuten) +congig.obligation=Pflicht +config.obligation.mandatory=Obligatorisch +config.obligation.optional=Freiwillig +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 69e8fe2cc65..84f81bf0b93 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 @@ -1 +1,10 @@ -access.provider.name=Learning path \ No newline at end of file +access.provider.name=Learning path +error.positiv.int=Enter a positive number. +config.done.trigger=Done trigger +config.done.trigger.confirmed=Confirmed +config.done.trigger.started=Opened +config.estimated.duration=Estimated duration (minutes) +config.obligation=Obligation +config.obligation.mandatory=Mandatory +config.obligation.optional=Optional +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 e93c1c0d945..8e5c1f96421 100644 --- a/src/main/java/org/olat/course/nodeaccess/NodeAccessProvider.java +++ b/src/main/java/org/olat/course/nodeaccess/NodeAccessProvider.java @@ -19,6 +19,11 @@ */ package org.olat.course.nodeaccess; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.tabbable.TabbableController; +import org.olat.course.nodes.CourseNode; + /** * * Initial date: 27 Aug 2019<br> @@ -27,4 +32,6 @@ package org.olat.course.nodeaccess; */ public interface NodeAccessProvider extends NodeAccessProviderIdentifier { + public TabbableController createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode); + } diff --git a/src/main/java/org/olat/course/nodeaccess/NodeAccessService.java b/src/main/java/org/olat/course/nodeaccess/NodeAccessService.java index 361c589a9de..2254cb7f873 100644 --- a/src/main/java/org/olat/course/nodeaccess/NodeAccessService.java +++ b/src/main/java/org/olat/course/nodeaccess/NodeAccessService.java @@ -21,6 +21,11 @@ package org.olat.course.nodeaccess; import java.util.List; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.tabbable.TabbableController; +import org.olat.course.nodes.CourseNode; + /** * * Initial date: 27 Aug 2019<br> @@ -31,4 +36,16 @@ public interface NodeAccessService { public List<? extends NodeAccessProviderIdentifier> getNodeAccessProviderIdentifer(); + /** + * Creates the controller to edit the configurations of the node. + * + * @param ureq + * @param windowControl + * @param nodeAccessType + * @param courseNode + * @return + */ + public TabbableController createEditController(UserRequest ureq, WindowControl wControl, String nodeAccessType, + CourseNode courseNode); + } 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 2392b705885..225b06007fa 100644 --- a/src/main/java/org/olat/course/nodeaccess/manager/NodeAccessServiceImpl.java +++ b/src/main/java/org/olat/course/nodeaccess/manager/NodeAccessServiceImpl.java @@ -21,9 +21,15 @@ package org.olat.course.nodeaccess.manager; import java.util.List; +import org.apache.logging.log4j.Logger; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.tabbable.TabbableController; +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.nodes.CourseNode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -36,12 +42,30 @@ import org.springframework.stereotype.Service; @Service public class NodeAccessServiceImpl implements NodeAccessService { + private static final Logger log = Tracing.createLoggerFor(NodeAccessServiceImpl.class); + @Autowired private List<NodeAccessProvider> nodeAccessProviders; + private NodeAccessProvider getNodeAccessProvider(String nodeAccessType) { + for (NodeAccessProvider provider : nodeAccessProviders) { + if (provider.getType().equals(nodeAccessType)) { + return provider; + } + } + log.error("No node access provider found for type '{}'!", nodeAccessType); + return null; + } + @Override public List<? extends NodeAccessProviderIdentifier> getNodeAccessProviderIdentifer() { return nodeAccessProviders; } + @Override + public TabbableController createEditController(UserRequest ureq, WindowControl wControl, String nodeAccessType, + CourseNode courseNode) { + return getNodeAccessProvider(nodeAccessType).createEditController(ureq, wControl, courseNode); + } + } -- GitLab