diff --git a/src/main/java/org/olat/course/nodes/gta/GTAManager.java b/src/main/java/org/olat/course/nodes/gta/GTAManager.java index 9b0334970eefe008602ccaf0eae8a78440fc1d8c..e6dcadd23f18b8781c8180fb42ba9d444d91e24e 100644 --- a/src/main/java/org/olat/course/nodes/gta/GTAManager.java +++ b/src/main/java/org/olat/course/nodes/gta/GTAManager.java @@ -140,6 +140,7 @@ public interface GTAManager { public List<IdentityRef> getDuplicatedMemberships(GTACourseNode gtaNode); + public boolean isAnyTasks(RepositoryEntryRef entry, GTACourseNode gtaNode); public TaskList createIfNotExists(RepositoryEntry entry, GTACourseNode cNode); diff --git a/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java b/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java index 1ae23958994302d3507e462b14f3bc5207d130b9..785044fce24232d64413f8a5d7573c3741bea32c 100644 --- a/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java +++ b/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java @@ -417,6 +417,17 @@ public class GTAManagerImpl implements GTAManager { return new Membership(coach, participant); } + @Override + public boolean isAnyTasks(RepositoryEntryRef entry, GTACourseNode cNode) { + String q = "select count(task) from gtatask task inner join task.taskList tasklist where tasklist.entry.key=:entryKey and tasklist.courseNodeIdent=:courseNodeIdent"; + List<Number> numOfTasks = dbInstance.getCurrentEntityManager() + .createQuery(q, Number.class) + .setParameter("entryKey", entry.getKey()) + .setParameter("courseNodeIdent", cNode.getIdent()) + .getResultList(); + return numOfTasks != null && !numOfTasks.isEmpty() && numOfTasks.get(0) != null && numOfTasks.get(0).intValue() > 0; + } + @Override public TaskList createIfNotExists(RepositoryEntry entry, GTACourseNode cNode) { TaskList tasks = getTaskList(entry, cNode); diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAAssignedTaskController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAAssignedTaskController.java index 1a71cb27edcc6d8bd1890e33f5c08e0ac3ec1683..fd50504d58ca2fd546676daaa684e85bb71f46e1 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTAAssignedTaskController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAAssignedTaskController.java @@ -49,52 +49,69 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class GTAAssignedTaskController extends BasicController { - private final Link downloadButton, downloadLink; + private Link downloadButton, downloadLink; - private final File taskFile; + private File taskFile; @Autowired private GTAManager gtaManager; + /** + * + * @param ureq + * @param wControl + * @param task The task + * @param taskDef The task definition if any + * @param courseEnv The course environment + * @param gtaNode The course node + * @param i18nDescription The description of the step + * @param i18nWarning The warning message if the assignee wasn't able to choose a task + * @param message + */ public GTAAssignedTaskController(UserRequest ureq, WindowControl wControl, Task task, TaskDefinition taskDef, CourseEnvironment courseEnv, GTACourseNode gtaNode, - String i18nDescription, String message) { + String i18nDescription, String i18nWarning, String message) { super(ureq, wControl); - - File taskDir = gtaManager.getTasksDirectory(courseEnv, gtaNode); - taskFile = new File(taskDir, task.getTaskName()); VelocityContainer mainVC = createVelocityContainer("assigned_task"); mainVC.contextPut("description", translate(i18nDescription)); if(StringHelper.containsNonWhitespace(message)) { mainVC.contextPut("message", message); } - - double fileSizeInMB = taskFile.length() / (1024.0d * 1024.0d); - String[] infos = new String[] { taskFile.getName(), TaskHelper.format(fileSizeInMB) }; - String taskInfos = translate("download.task.infos", infos); - String cssIcon = CSSHelper.createFiletypeIconCssClassFor(taskFile.getName()); - if(taskDef != null) { - mainVC.contextPut("taskDescription", taskDef.getDescription()); - } - // two links to same file: explicit button and task name - downloadButton = LinkFactory.createCustomLink("download.task", "download.task", null, Link.BUTTON + Link.NONTRANSLATED, mainVC, this); - downloadButton.setCustomDisplayText(translate("download.task")); - downloadButton.setTitle(taskInfos); - downloadButton.setIconLeftCSS("o_icon o_icon_download"); - downloadButton.setTarget("_blank"); - downloadLink = LinkFactory.createCustomLink("download.link", "download.link", null, Link.NONTRANSLATED, mainVC, this); - if(taskDef != null) { - downloadLink.setCustomDisplayText(StringHelper.escapeHtml(taskDef.getTitle())); - downloadLink.setIconLeftCSS("o_icon " + cssIcon); + File taskDir = gtaManager.getTasksDirectory(courseEnv, gtaNode); + + if(task == null || !StringHelper.containsNonWhitespace(task.getTaskName())) { + mainVC.contextPut("warningMsg", translate(i18nWarning)); } else { - downloadLink.setCustomDisplayText(StringHelper.escapeHtml(taskFile.getName())); - downloadLink.setIconLeftCSS("o_icon " + cssIcon + " o_icon_warning"); - downloadLink.setEnabled(false); + taskFile = new File(taskDir, task.getTaskName()); + + double fileSizeInMB = taskFile.length() / (1024.0d * 1024.0d); + String[] infos = new String[] { taskFile.getName(), TaskHelper.format(fileSizeInMB) }; + String taskInfos = translate("download.task.infos", infos); + String cssIcon = CSSHelper.createFiletypeIconCssClassFor(taskFile.getName()); + if(taskDef != null) { + mainVC.contextPut("taskDescription", taskDef.getDescription()); + } + // two links to same file: explicit button and task name + downloadButton = LinkFactory.createCustomLink("download.task", "download.task", null, Link.BUTTON + Link.NONTRANSLATED, mainVC, this); + downloadButton.setCustomDisplayText(translate("download.task")); + downloadButton.setTitle(taskInfos); + downloadButton.setIconLeftCSS("o_icon o_icon_download"); + downloadButton.setTarget("_blank"); + + downloadLink = LinkFactory.createCustomLink("download.link", "download.link", null, Link.NONTRANSLATED, mainVC, this); + if(taskDef != null) { + downloadLink.setCustomDisplayText(StringHelper.escapeHtml(taskDef.getTitle())); + downloadLink.setIconLeftCSS("o_icon " + cssIcon); + } else { + downloadLink.setCustomDisplayText(StringHelper.escapeHtml(taskFile.getName())); + downloadLink.setIconLeftCSS("o_icon " + cssIcon + " o_icon_warning"); + downloadLink.setEnabled(false); + } + downloadLink.setTitle(taskInfos); + downloadLink.setTarget("_blank"); } - downloadLink.setTitle(taskInfos); - downloadLink.setTarget("_blank"); putInitialPanel(mainVC); } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java index cfdbfd493627ab0faf4bccf9be4e65d86aafa041..e8edd9d04a85258e21d02b8ab64c7a4877fb76f7 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java @@ -153,7 +153,7 @@ public class GTACoachController extends GTAAbstractController { TaskDefinition taskDef = getTaskDefinition(assignedTask); assignedTaskCtrl = new GTAAssignedTaskController(ureq, getWindowControl(), assignedTask, taskDef, courseEnv, gtaNode, - "coach.task.assigned.description", null); + "coach.task.assigned.description", "warning.no.task.choosed.coach", null); listenTo(assignedTaskCtrl); mainVC.put("assignedTask", assignedTaskCtrl.getInitialComponent()); } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java index 56a932640ea7891ad5960245a3bd4b4106b559dc..fa7c0bdfec57133e57ac98f10bcc84a96757c49d 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java @@ -193,7 +193,7 @@ public class GTAParticipantController extends GTAAbstractController { TaskDefinition taskDef = getTaskDefinition(assignedTask); assignedTaskCtrl = new GTAAssignedTaskController(ureq, getWindowControl(), assignedTask, taskDef, courseEnv, gtaNode, - "task.assigned.description", message); + "task.assigned.description", "warning.no.task.choosed", message); listenTo(assignedTaskCtrl); mainVC.put("myAssignedTask", assignedTaskCtrl.getInitialComponent()); } 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 b7cf37ab60a1597ea1fc2f9aef687f4916aaf1dc..aa1411823df1ccfd754abde86d98e3b2f387d623 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 @@ -40,12 +40,15 @@ import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; +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.condition.AreaSelectionController; import org.olat.course.condition.GroupSelectionController; import org.olat.course.editor.CourseEditorEnv; import org.olat.course.nodes.GTACourseNode; +import org.olat.course.nodes.gta.GTAManager; import org.olat.course.nodes.gta.GTARelativeToDates; import org.olat.course.nodes.gta.GTAType; import org.olat.group.BusinessGroupService; @@ -71,6 +74,7 @@ public class GTAWorkflowEditController extends FormBasicController { private final String[] relativeDatesValues; private CloseableModalController cmc; + private DialogBoxController confirmChangesCtrl; private AreaSelectionController areaSelectionCtrl; private GroupSelectionController groupSelectionCtrl; @@ -89,6 +93,8 @@ public class GTAWorkflowEditController extends FormBasicController { private List<Long> areaKeys; private List<Long> groupKeys; + @Autowired + private GTAManager gtaManager; @Autowired private BGAreaManager areaManager; @Autowired @@ -458,6 +464,22 @@ public class GTAWorkflowEditController extends FormBasicController { @Override protected void formOK(UserRequest ureq) { + RepositoryEntry entry = courseEditorEnv.getCourseGroupManager().getCourseEntry(); + if(gtaManager.isAnyTasks(entry, gtaNode)) { + doConfirmChanges(ureq); + } else { + commitChanges(); + fireEvent(ureq, Event.DONE_EVENT); + } + } + + private void doConfirmChanges(UserRequest ureq) { + String title = translate("warning.tasks.in.process.title"); + String text = translate("warning.tasks.in.process.text"); + confirmChangesCtrl = activateOkCancelDialog(ureq, title, text, confirmChangesCtrl); + } + + private void commitChanges() { if(typeEl.isSelected(0)) { config.setStringValue(GTACourseNode.GTASK_TYPE, GTAType.group.name()); config.setList(GTACourseNode.GTASK_AREAS, areaKeys); @@ -519,7 +541,6 @@ public class GTAWorkflowEditController extends FormBasicController { } config.setBooleanEntry(GTACourseNode.GTASK_GRADING, gradingEl.isAtLeastSelected(1)); - fireEvent(ureq, Event.DONE_EVENT); } private void setRelativeDates(TextElement daysEl, String daysKey, SingleSelection relativeToEl, String relativeToKey) { @@ -586,7 +607,6 @@ public class GTAWorkflowEditController extends FormBasicController { revisionEl.select(keys[0], review); } - @Override protected void event(UserRequest ureq, Controller source, Event event) { if(groupSelectionCtrl == source) { @@ -619,6 +639,11 @@ public class GTAWorkflowEditController extends FormBasicController { cmc.deactivate(); cleanUp(); } + } else if(confirmChangesCtrl == source) { + if(DialogBoxUIFactory.isOkEvent(event) || DialogBoxUIFactory.isYesEvent(event)) { + commitChanges(); + fireEvent(ureq, Event.DONE_EVENT); + } } else if(cmc == source) { cleanUp(); } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_content/assigned_task.html b/src/main/java/org/olat/course/nodes/gta/ui/_content/assigned_task.html index b8dfe463fa2ddcdc2504040564b2bac76fcab972..bdb466fd4c4f2036b6a11e2639210b4663ea5bd9 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/_content/assigned_task.html +++ b/src/main/java/org/olat/course/nodes/gta/ui/_content/assigned_task.html @@ -1,12 +1,19 @@ #if($message && !$message.isEmpty()) <div class="o_info">$r.xssScan($message)</div> #end +#if($warningMsg && !$warningMsg.isEmpty()) + <div class="o_warning">$r.xssScan($warningMsg)</div> +#end +#if($r.available("download.task")) <div>$description <div class="pull-right"> $r.render("download.task") </div> </div> -<h5> - $r.render("download.link") -</h5> -<p>$r.xssScan($taskDescription)</p> +#end +#if($r.available("download.link")) + <h5>$r.render("download.link")</h5> +#end +#if($taskDescription && !$taskDescription.isEmpty()) + <p>$r.xssScan($taskDescription)</p> +#end diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties index afc7b466c69d6e418f0ebfdb0ef82297a6c1cfdd..fc37cad40baa90a9425938d5a5143fd4c5906569 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties @@ -215,4 +215,8 @@ uploaded.by=hochgeladen von {0} wait.for.solutions=Die Musterl\u00F6sung wird zum angegebenen Zeitpunkt freigegeben. warning.group.pick.task=Dies ist eine Gruppenaufgabe\! Die hier getroffene Auswahl ist f\u00FCr alle Mitglieder der Gruppe "{0}" g\u00FCltig\! Stellen Sie sicher, dass diese Auswahl zuvor innerhalb Ihrer Gruppe diskutiert wurde\! Nur ein Gruppenmitglied kann die Gruppenaufgabe ausw\u00E4hlen. warning.group.submit=Dies ist eine Gruppenaufgabe\! Das abgegebene Dokument ist f\u00FCr alle Mitglieder der Gruppe "{0}" g\u00FCltig\! Stellen Sie sicher dass diese L\u00F6sung zuvor innerhalb Ihrer Gruppe diskutiert wurde\! Nur ein Gruppenmitglied kann eine L\u00F6sung im Namen aller Gruppenmitglieder abgeben. -warning.group.task=Dies ist eine Gruppenaufgabe\! Aufgabenzuweisung, Abgabe sowie die Bewertung werden f\u00FCr die Gruppe vorgenommen. Besprechen Sie mit den anderen Teilnehmern ihrer Gruppe wie sie gemeinsam die Aufgabe ausw\u00E4hlen und bearbeiten wollen. \ No newline at end of file +warning.group.task=Dies ist eine Gruppenaufgabe\! Aufgabenzuweisung, Abgabe sowie die Bewertung werden f\u00FCr die Gruppe vorgenommen. Besprechen Sie mit den anderen Teilnehmern ihrer Gruppe wie sie gemeinsam die Aufgabe ausw\u00E4hlen und bearbeiten wollen. +warning.no.task.choosed=Wie es scheint war es Ihnen aufgrund von Änderungen am Kurselement nicht möglich eine Aufgabe für dieses Aufgabenelement auszuwählen. +warning.no.task.choosed.coach=Wie es scheint war es der Assignee aufgrund von Änderungen am Kurselement nicht möglich eine Aufgabe für dieses Aufgabenelement auszuwählen. +warning.tasks.in.process.title=Aufgabenprozess bereits gestartet +warning.tasks.in.process.text=Es gibt bereits Benutzer die den Aufgabenprozess gestartet haben. Änderungen an der Workflow-Konfiguration kann für diese Benutzer zu Problemen führen. 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 7d600cae283441cfaf793cc56e1dca564724423a..fe2e356111cda6c1b8cebdb050a89b0edfd95831 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 @@ -216,3 +216,9 @@ wait.for.solutions=The sample solution will be displayed at the date specified a warning.group.pick.task=This is a group task\! The selection made here is valid for all members of the group "{0}"\! Make sure you discussed this selection within the group prior to selecting a task\! Only one member of the group can select the task for the group. warning.group.submit=This is a group task\! The submitted document is valid for all members of the group "{0}"\! Make sure you discussed this solution document prior to uploading it here\! Only one member of the group can submit a solution on behalf of all group members. warning.group.task=This is a group task\! The task assignment, submission of documents and grading are performed as a group. Contact your group peers on how to proceed on deciding for a task and to collaboratively solve the task. +warning.no.task.choosed=It seems that due to a change in the course element configuration, you weren't able to choose a task for this task element. +warning.no.task.choosed.coach=It seems that due to a change in the course element configuration, the assignee wasn't able to choose a task for this task element. +warning.tasks.in.process.title=Already started +warning.tasks.in.process.text=There are already users who have started the task process. Changing the workflow configuration could result in problems for these users. + +