From e992e1b845b7c738ba42511c7bfee56729501346 Mon Sep 17 00:00:00 2001
From: uhensler <urs.hensler@frentix.com>
Date: Mon, 9 Mar 2020 12:19:09 +0100
Subject: [PATCH] OO-4241: Show obligation configuration in learning path tab
 (task course element)

---
 .../course/editor/NodeEditController.java     |  4 ++
 .../learningpath/LearningPathEditConfigs.java |  2 -
 .../LearningPathEditConfigsBuilder.java       | 13 -------
 .../ui/LearningPathNodeConfigController.java  |  1 -
 .../AbstractGTALearningPathNodeHandler.java   |  1 -
 .../nodes/gta/ui/GTAEditController.java       |  8 ++++
 .../gta/ui/GTAWorkflowEditController.java     | 38 +++++++++++++++----
 .../gta/ui/_i18n/LocalStrings_en.properties   |  2 +-
 8 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/src/main/java/org/olat/course/editor/NodeEditController.java b/src/main/java/org/olat/course/editor/NodeEditController.java
index 74a796749a1..6279d5f61ad 100644
--- a/src/main/java/org/olat/course/editor/NodeEditController.java
+++ b/src/main/java/org/olat/course/editor/NodeEditController.java
@@ -129,6 +129,10 @@ public class NodeEditController extends ActivateableTabbableDefaultController im
 			if (nodeAccessCtrl != null) {
 				this.nodeAccessCtrl = nodeAccessCtrl;
 				listenTo(nodeAccessCtrl);
+				if (childTabsController instanceof ControllerEventListener) {
+					ControllerEventListener cel = (ControllerEventListener)childTabsController;
+					nodeAccessCtrl.addControllerListener(cel);
+				}
 			} else if (ConditionNodeAccessProvider.TYPE.equals(nodeAccessType.getType())) {
 				// fallback for legacy access edit controller
 				visibilityEditCtrl = new VisibilityEditController(ureq, getWindowControl(), courseNode,
diff --git a/src/main/java/org/olat/course/learningpath/LearningPathEditConfigs.java b/src/main/java/org/olat/course/learningpath/LearningPathEditConfigs.java
index c16b19b87ea..a3c24e519cd 100644
--- a/src/main/java/org/olat/course/learningpath/LearningPathEditConfigs.java
+++ b/src/main/java/org/olat/course/learningpath/LearningPathEditConfigs.java
@@ -28,8 +28,6 @@ package org.olat.course.learningpath;
  */
 public interface LearningPathEditConfigs {
 	
-	public boolean isObligationVisible();
-	
 	public boolean isTriggerNodeVisited();
 	
 	public boolean isTriggerConfirmed();
diff --git a/src/main/java/org/olat/course/learningpath/LearningPathEditConfigsBuilder.java b/src/main/java/org/olat/course/learningpath/LearningPathEditConfigsBuilder.java
index 1f27a23a760..180ba9f8964 100644
--- a/src/main/java/org/olat/course/learningpath/LearningPathEditConfigsBuilder.java
+++ b/src/main/java/org/olat/course/learningpath/LearningPathEditConfigsBuilder.java
@@ -27,7 +27,6 @@ package org.olat.course.learningpath;
  */
 public class LearningPathEditConfigsBuilder {
 	
-	private boolean obligationVisible = true;
 	private boolean triggerNodeVisited;
 	private boolean triggerConfirmed;
 	private boolean triggerScore;
@@ -39,11 +38,6 @@ public class LearningPathEditConfigsBuilder {
 	LearningPathEditConfigsBuilder() {
 		this.translationsBuilder = new LearningPathTranslationsBuilder(this);
 	}
-
-	public LearningPathEditConfigsBuilder disableObligation() {
-		obligationVisible = false;
-		return this;
-	}
 	
 	public LearningPathEditConfigsBuilder enableNodeVisited() {
 		triggerNodeVisited = true;
@@ -87,7 +81,6 @@ public class LearningPathEditConfigsBuilder {
 	
 	private final static class LearningPathEditConfigsImpl implements LearningPathEditConfigs {
 		
-		private final boolean obligationVisible;
 		private final boolean triggerNodeVisited;
 		private final boolean triggerConfirmed;
 		private final boolean triggerScore;
@@ -97,7 +90,6 @@ public class LearningPathEditConfigsBuilder {
 		private final LearningPathTranslations translations;
 
 		private LearningPathEditConfigsImpl(LearningPathEditConfigsBuilder builder) {
-			this.obligationVisible = builder.obligationVisible;
 			this.triggerNodeVisited = builder.triggerNodeVisited;
 			this.triggerConfirmed = builder.triggerConfirmed;
 			this.triggerScore = builder.triggerScore;
@@ -107,11 +99,6 @@ public class LearningPathEditConfigsBuilder {
 			this.translations = builder.translationsBuilder.build();
 		}
 
-		@Override
-		public boolean isObligationVisible() {
-			return obligationVisible;
-		}
-
 		@Override
 		public boolean isTriggerNodeVisited() {
 			return triggerNodeVisited;
diff --git a/src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java b/src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java
index 25afddffee2..3b38afead51 100644
--- a/src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java
+++ b/src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java
@@ -104,7 +104,6 @@ public class LearningPathNodeConfigController extends FormBasicController {
 		if (Arrays.asList(obligationEl.getKeys()).contains(obligationKey)) {
 			obligationEl.select(obligationKey, true);
 		}
-		obligationEl.setVisible(editConfigs.isObligationVisible());
 		
 		Date startDate = learningPathConfigs.getStartDate();
 		startDateEl = uifactory.addDateChooser("config.start.date", startDate, formLayout);
diff --git a/src/main/java/org/olat/course/nodes/gta/AbstractGTALearningPathNodeHandler.java b/src/main/java/org/olat/course/nodes/gta/AbstractGTALearningPathNodeHandler.java
index 8c553820637..5c38f0ff6f3 100644
--- a/src/main/java/org/olat/course/nodes/gta/AbstractGTALearningPathNodeHandler.java
+++ b/src/main/java/org/olat/course/nodes/gta/AbstractGTALearningPathNodeHandler.java
@@ -38,7 +38,6 @@ import org.olat.repository.RepositoryEntry;
 public abstract class AbstractGTALearningPathNodeHandler implements LearningPathNodeHandler {
 
 	private static final LearningPathEditConfigs EDIT_CONFIGS = LearningPathEditConfigs.builder()
-			.disableObligation()
 			.enableNodeVisited()
 			.enableConfirmed()
 			.enableScore()
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAEditController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAEditController.java
index bd9a8706e6b..7af2fc7c180 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTAEditController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAEditController.java
@@ -214,6 +214,14 @@ public class GTAEditController extends ActivateableTabbableDefaultController {
 		super.event(ureq, source, event);
 	}
 
+	@Override
+	public void dispatchEvent(UserRequest ureq, Controller source, Event event) {
+		super.dispatchEvent(ureq, source, event);
+		if (event == NodeEditController.NODECONFIG_CHANGED_EVENT) {
+			workflowCtrl.onNodeConfigChanged();
+		}
+	}
+
 	public MSEditFormController createManualAssessmentCtrl(UserRequest ureq) {
 		boolean singleIdentityTask = GTAType.individual.name().equals(config.getStringValue(GTACourseNode.GTASK_TYPE));
 		return new MSEditFormController(ureq, getWindowControl(), config, translate("pane.tab.grading"),
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAWorkflowEditController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAWorkflowEditController.java
index 0b012633895..fc9264a4468 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/GTAWorkflowEditController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAWorkflowEditController.java
@@ -45,9 +45,13 @@ import org.olat.core.gui.control.generic.modal.DialogBoxController;
 import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.core.util.Formatter;
 import org.olat.core.util.StringHelper;
+import org.olat.course.CourseFactory;
+import org.olat.course.ICourse;
 import org.olat.course.condition.AreaSelectionController;
 import org.olat.course.condition.GroupSelectionController;
 import org.olat.course.editor.CourseEditorEnv;
+import org.olat.course.learningpath.manager.LearningPathNodeAccessProvider;
+import org.olat.course.nodeaccess.NodeAccessType;
 import org.olat.course.nodes.GTACourseNode;
 import org.olat.course.nodes.MSCourseNode;
 import org.olat.course.nodes.gta.GTAManager;
@@ -97,10 +101,12 @@ public class GTAWorkflowEditController extends FormBasicController {
 	
 	private final GTACourseNode gtaNode;
 	private final ModuleConfiguration config;
+	private boolean optional;
 	private final CourseEditorEnv courseEditorEnv;
 	private List<Long> areaKeys;
 	private List<Long> groupKeys;
 	private final RepositoryEntry courseRe;
+	private final boolean isLearningPath;
 	
 	@Autowired
 	private HelpModule helpModule;
@@ -122,6 +128,10 @@ public class GTAWorkflowEditController extends FormBasicController {
 		//reload to make sure we have the last changes
 		courseRe = repositoryService
 				.loadByKey(courseEditorEnv.getCourseGroupManager().getCourseEntry().getKey());
+		ICourse course = CourseFactory.loadCourse(courseRe);
+		isLearningPath = LearningPathNodeAccessProvider.TYPE.equals(NodeAccessType.of(course).getType());
+		
+		optional = config.getBooleanSafe(MSCourseNode.CONFIG_KEY_OPTIONAL);
 		
 		initForm(ureq);
 	}
@@ -221,13 +231,13 @@ public class GTAWorkflowEditController extends FormBasicController {
 				translate("task.mandatory"), translate("task.optional"),
 		};
 		optionalEl = uifactory.addRadiosHorizontal("obligation", "task.obligation", stepsCont, optionalKeys, optionalValues);
-		optionalEl.addActionListener(FormEvent.ONCHANGE);
-		boolean optional = config.getBooleanSafe(MSCourseNode.CONFIG_KEY_OPTIONAL);
+		optionalEl.addActionListener(FormEvent.ONCHANGE);	
 		if(optional) {
 			optionalEl.select(optionalKeys[1], true);
 		} else {
 			optionalEl.select(optionalKeys[0], true);
 		}
+		optionalEl.setVisible(!isLearningPath);
 
 		relativeDatesEl = uifactory.addCheckboxesHorizontal("relative.dates", "relative.dates", stepsCont, onKeys, new String[]{ "" });
 		relativeDatesEl.addActionListener(FormEvent.ONCHANGE);
@@ -391,7 +401,7 @@ public class GTAWorkflowEditController extends FormBasicController {
 		}
 		
 		boolean solutionVisibleRelToAll = config.getBooleanSafe(GTACourseNode.GTASK_SAMPLE_SOLUTION_VISIBLE_ALL, false);
-		String[] solutionVisibleToAllValues = getSolutionVisibleToAllValues(optional);
+		String[] solutionVisibleToAllValues = getSolutionVisibleToAllValues();
 		solutionVisibleToAllEl = uifactory.addRadiosVertical("visibleall", "sample.solution.visible.for", stepsCont, solutionVisibleToAllKeys, solutionVisibleToAllValues);
 		solutionVisibleToAllEl.setVisible(sample && ((!useRelativeDates && solutionVisibleAfter != null) || optional));
 		if(solutionVisibleRelToAll) {
@@ -418,7 +428,7 @@ public class GTAWorkflowEditController extends FormBasicController {
 		uifactory.addFormSubmitButton("save", "save", buttonCont);
 	}
 	
-	private String[] getSolutionVisibleToAllValues(boolean optional) {
+	private String[] getSolutionVisibleToAllValues() {
 		return new String[] {
 			optional ? translate("sample.solution.visible.all.optional") : translate("sample.solution.visible.all"),
 			translate("sample.solution.visible.upload")
@@ -519,8 +529,9 @@ public class GTAWorkflowEditController extends FormBasicController {
 			config.setList(GTACourseNode.GTASK_GROUPS, new ArrayList<Long>(0));
 		}
 		
-		boolean optional = optionalEl.isSelected(1);
-		config.setBooleanEntry(MSCourseNode.CONFIG_KEY_OPTIONAL, optional);
+		if (optionalEl.isVisible()) {
+			config.setBooleanEntry(MSCourseNode.CONFIG_KEY_OPTIONAL, optional);
+		}
 		
 		boolean relativeDates = relativeDatesEl.isAtLeastSelected(1);
 		config.setBooleanEntry(GTACourseNode.GTASK_RELATIVE_DATES, relativeDates);
@@ -620,6 +631,14 @@ public class GTAWorkflowEditController extends FormBasicController {
 		super.formInnerEvent(ureq, source, event);
 	}
 	
+	public void onNodeConfigChanged() {
+		boolean newOptional = config.getBooleanSafe(MSCourseNode.CONFIG_KEY_OPTIONAL);
+		if (newOptional != optional) {
+			optional = newOptional;
+			updateSolutionDeadline();
+		}
+	}
+	
 	private void updateAssignmentDeadline() {
 		boolean useRelativeDate = relativeDatesEl.isAtLeastSelected(1);
 		boolean assignment = taskAssignmentEl.isAtLeastSelected(1);
@@ -639,13 +658,15 @@ public class GTAWorkflowEditController extends FormBasicController {
 	private void updateSolutionDeadline() {
 		boolean useRelativeDate = relativeDatesEl.isAtLeastSelected(1);
 		boolean solution = sampleEl.isAtLeastSelected(1);
-		boolean optional = optionalEl.isSelected(1);
+		if (optionalEl.isVisible()) {
+			optional = optionalEl.isSelected(1);
+		}
 		solutionVisibleAfterEl.setVisible(solution && !useRelativeDate);
 		solutionVisibleRelCont.setVisible(solution && useRelativeDate);
 		updateDeadline(solutionVisibleRelToEl, false);
 		solutionVisibleToAllEl.setVisible(solution &&
 				((!useRelativeDate && solutionVisibleAfterEl.getDate() != null) || optional));
-		solutionVisibleToAllEl.setKeysAndValues(solutionVisibleToAllKeys, getSolutionVisibleToAllValues(optional), null);
+		solutionVisibleToAllEl.setKeysAndValues(solutionVisibleToAllKeys, getSolutionVisibleToAllValues(), null);
 		if(!solutionVisibleToAllEl.isOneSelected()) {
 			solutionVisibleToAllEl.select(solutionVisibleToAllKeys[1], true);
 		}
@@ -827,4 +848,5 @@ public class GTAWorkflowEditController extends FormBasicController {
 			return values;
 		}
 	}
+
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties
index 1ed4b9216c3..b0d6b634157 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties
@@ -270,7 +270,7 @@ sample.solution=Sample solution
 sample.solution.enabled=Provide sample solutions for participants
 sample.solution.visible.after=Visible after...
 sample.solution.visible.all=Sample solutions visible for all after the date is reached, inclusive the one which don't have submitted their task.
-sample.solution.visible.all.optional=Sample solution visible for all, inclusive the one wo don't submit the task.
+sample.solution.visible.all.optional=Sample solution visible for all, inclusive the one who don't submit the task.
 sample.solution.visible.for=Visible for ...
 sample.solution.visible.upload=Only after submission of a solution to the task
 sampling=Type of sampling
-- 
GitLab