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 e584aa1e4b41bc0c0da1d6e8bb92701ab39f95a7..0241757504fcbbb8ba9b3d2065f757095f6b880e 100644 --- a/src/main/java/org/olat/course/nodes/gta/GTAManager.java +++ b/src/main/java/org/olat/course/nodes/gta/GTAManager.java @@ -347,6 +347,12 @@ public interface GTAManager { public Task updateTask(Task task, TaskProcess newStatus, int iteration, GTACourseNode cNode); + public Task allowResetTask(Task task, Identity allower, GTACourseNode cNode); + + public Task resetTask(Task task, GTACourseNode cNode, CourseEnvironment courseEnv); + + public Task resetTaskRefused(Task task, GTACourseNode cNode); + public void log(String step, String operation, Task assignedTask, Identity actor, Identity assessedIdentity, BusinessGroup assessedGroup, CourseEnvironment courseEnv, GTACourseNode cNode); diff --git a/src/main/java/org/olat/course/nodes/gta/Task.java b/src/main/java/org/olat/course/nodes/gta/Task.java index 74abe1bb54ef7bc6d240b40ffdac747a0a1491de..e29fe4c5552a4d9fecc00b65249a073be0fcdf7c 100644 --- a/src/main/java/org/olat/course/nodes/gta/Task.java +++ b/src/main/java/org/olat/course/nodes/gta/Task.java @@ -44,6 +44,10 @@ public interface Task extends TaskRef { public Date getGraduationDate(); + public Date getAllowResetDate(); + + public Identity getAllowResetIdentity(); + public TaskList getTaskList(); public Identity getIdentity(); 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 2251948e19406cc62acabcb72a2b0e70908b6637..d19b9cdab4bfd465766c7d30956dca1a2333ae8f 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 @@ -48,6 +48,7 @@ import org.olat.core.commons.services.notifications.SubscriptionContext; import org.olat.core.id.Identity; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.FileUtils; import org.olat.core.util.StringHelper; import org.olat.core.util.io.SystemFilenameFilter; import org.olat.core.util.vfs.VFSContainer; @@ -1060,6 +1061,9 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { if(currentTask.getTaskStatus() == TaskProcess.assignment) { TaskProcess nextStep = nextStep(currentTask.getTaskStatus(), cNode); ((TaskImpl)currentTask).setTaskStatus(nextStep); + if(taskFile != null) { + ((TaskImpl)currentTask).setTaskName(taskFile.getName()); + } } currentTask = dbInstance.getCurrentEntityManager().merge(currentTask); syncAssessmentEntry((TaskImpl)currentTask, cNode); @@ -1432,7 +1436,42 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { TaskImpl taskImpl = (TaskImpl)task; taskImpl.setSubmissionDate(new Date()); return updateTask(task, review, cNode); - } + } + + @Override + public Task allowResetTask(Task task, Identity allower, GTACourseNode cNode) { + TaskImpl taskImpl = (TaskImpl)task; + taskImpl.setAllowResetDate(new Date()); + taskImpl.setAllowResetIdentity(allower); + return updateTask(task, task.getTaskStatus(), cNode); + } + + @Override + public Task resetTask(Task task, GTACourseNode cNode, CourseEnvironment courseEnv) { + TaskImpl taskImpl = (TaskImpl)task; + taskImpl.setTaskName(null); + taskImpl.setAllowResetDate(null); + Task updatedTask = updateTask(task, TaskProcess.assignment, cNode); + + File submissionDir = null; + if(updatedTask.getBusinessGroup() != null) { + submissionDir = getSubmitDirectory(courseEnv, cNode, updatedTask.getBusinessGroup()); + } else if(updatedTask.getIdentity() != null) { + submissionDir = getSubmitDirectory(courseEnv, cNode, updatedTask.getIdentity()); + } + if(submissionDir != null) { + FileUtils.deleteDirsAndFiles(submissionDir, true, false); + } + return updatedTask; + } + + @Override + public Task resetTaskRefused(Task task, GTACourseNode cNode) { + TaskImpl taskImpl = (TaskImpl)task; + taskImpl.setAllowResetDate(null); + taskImpl.setAllowResetIdentity(null); + return updateTask(task, task.getTaskStatus(), cNode); + } @Override public Task submitRevisions(Task task, GTACourseNode cNode) { diff --git a/src/main/java/org/olat/course/nodes/gta/model/TaskDueDateImpl.java b/src/main/java/org/olat/course/nodes/gta/model/TaskDueDateImpl.java index f4fde0fdaaba1fdd24df2d3fac0bff747e265f88..5ea86b0b07205bfaeaec480bd38bec119110805c 100644 --- a/src/main/java/org/olat/course/nodes/gta/model/TaskDueDateImpl.java +++ b/src/main/java/org/olat/course/nodes/gta/model/TaskDueDateImpl.java @@ -97,6 +97,9 @@ public class TaskDueDateImpl implements TaskDueDate, CreateInfo, Persistable, Mo @Temporal(TemporalType.TIMESTAMP) @Column(name="g_collection_date", nullable=true, insertable=true, updatable=false) private Date collectionDate; + @Temporal(TemporalType.TIMESTAMP) + @Column(name="g_allow_reset_date", nullable=true, insertable=true, updatable=true) + private Date allowResetDate; @Temporal(TemporalType.TIMESTAMP) @Column(name="g_acceptation_date", nullable=true, insertable=true, updatable=false) @@ -141,6 +144,10 @@ public class TaskDueDateImpl implements TaskDueDate, CreateInfo, Persistable, Mo @ManyToOne(targetEntity=BusinessGroupImpl.class,fetch=FetchType.LAZY,optional=true) @JoinColumn(name="fk_businessgroup", nullable=true, insertable=true, updatable=false) private BusinessGroup businessGroup; + + @ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_allow_reset_identity", nullable=true, insertable=true, updatable=false) + private Identity allowResetIdentity; @Override public Long getKey() { @@ -237,6 +244,24 @@ public class TaskDueDateImpl implements TaskDueDate, CreateInfo, Persistable, Mo this.collectionDate = collectionDate; } + @Override + public Date getAllowResetDate() { + return allowResetDate; + } + + public void setAllowResetDate(Date allowResetDate) { + this.allowResetDate = allowResetDate; + } + + @Override + public Identity getAllowResetIdentity() { + return allowResetIdentity; + } + + public void setAllowResetIdentity(Identity allowResetIdentity) { + this.allowResetIdentity = allowResetIdentity; + } + @Override public Date getAcceptationDate() { return acceptationDate; diff --git a/src/main/java/org/olat/course/nodes/gta/model/TaskImpl.java b/src/main/java/org/olat/course/nodes/gta/model/TaskImpl.java index 844e1b02b8ce9b1faf31340d0c2371260c27b8dc..0f9c1ee1e6ef30aa41a007ee0acad103ee115da6 100644 --- a/src/main/java/org/olat/course/nodes/gta/model/TaskImpl.java +++ b/src/main/java/org/olat/course/nodes/gta/model/TaskImpl.java @@ -99,6 +99,9 @@ public class TaskImpl implements Task, CreateInfo, Persistable, ModifiedInfo { @Temporal(TemporalType.TIMESTAMP) @Column(name="g_collection_date", nullable=true, insertable=true, updatable=true) private Date collectionDate; + @Temporal(TemporalType.TIMESTAMP) + @Column(name="g_allow_reset_date", nullable=true, insertable=true, updatable=true) + private Date allowResetDate; @Temporal(TemporalType.TIMESTAMP) @Column(name="g_acceptation_date", nullable=true, insertable=true, updatable=true) @@ -144,6 +147,10 @@ public class TaskImpl implements Task, CreateInfo, Persistable, ModifiedInfo { @JoinColumn(name="fk_businessgroup", nullable=true, insertable=true, updatable=false) private BusinessGroup businessGroup; + @ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_allow_reset_identity", nullable=true, insertable=true, updatable=true) + private Identity allowResetIdentity; + @Override public Long getKey() { return key; @@ -239,6 +246,24 @@ public class TaskImpl implements Task, CreateInfo, Persistable, ModifiedInfo { this.collectionDate = collectionDate; } + @Override + public Date getAllowResetDate() { + return allowResetDate; + } + + public void setAllowResetDate(Date allowResetDate) { + this.allowResetDate = allowResetDate; + } + + @Override + public Identity getAllowResetIdentity() { + return allowResetIdentity; + } + + public void setAllowResetIdentity(Identity allowResetIdentity) { + this.allowResetIdentity = allowResetIdentity; + } + @Override public Date getAcceptationDate() { return acceptationDate; diff --git a/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java b/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java new file mode 100644 index 0000000000000000000000000000000000000000..e6b488731a4947562384b8b58dfa6704dcfaf9ca --- /dev/null +++ b/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java @@ -0,0 +1,95 @@ +package org.olat.course.nodes.gta.ui; + +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.FormLink; +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.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.course.nodes.GTACourseNode; +import org.olat.course.nodes.gta.GTAManager; +import org.olat.course.nodes.gta.Task; +import org.olat.course.run.environment.CourseEnvironment; +import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 10 août 2017<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class ConfirmResetTaskController extends FormBasicController { + + private FormLink dontResetButton; + + private Task task; + private final GTACourseNode gtaNode; + private final CourseEnvironment courseEnv; + + @Autowired + private GTAManager gtaManager; + @Autowired + private UserManager userManager; + + public ConfirmResetTaskController(UserRequest ureq, WindowControl wControl, Task task, + GTACourseNode gtaNode, CourseEnvironment courseEnv) { + super(ureq, wControl, "participant_reset_task"); + this.task = task; + this.gtaNode = gtaNode; + this.courseEnv = courseEnv; + initForm(ureq); + } + + public Task getTask() { + return task; + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + if(formLayout instanceof FormLayoutContainer) { + FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout; + String allower = userManager.getUserDisplayName(task.getAllowResetIdentity()); + String message = translate("participant.confirm.reset.task.text", new String[] { allower, task.getTaskName() }); + layoutCont.contextPut("msg", message); + } + + FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); + formLayout.add(buttonsCont); + uifactory.addFormCancelButton("cancel", buttonsCont, ureq, getWindowControl()); + dontResetButton = uifactory.addFormLink("participant.confirm.reset.task.nok", buttonsCont, Link.BUTTON); + uifactory.addFormSubmitButton("participant.confirm.reset.task.ok", buttonsCont); + } + + @Override + protected void doDispose() { + // + } + + @Override + protected void formOK(UserRequest ureq) { + task = gtaManager.resetTask(task, gtaNode, courseEnv); + gtaManager.log("Reset task", "reset task", task, getIdentity(), getIdentity(), null, courseEnv, gtaNode); + fireEvent(ureq, Event.DONE_EVENT); + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(dontResetButton == source) { + task = gtaManager.resetTaskRefused(task, gtaNode); + gtaManager.log("Refuse reset task", "refuse reset task", task, getIdentity(), getIdentity(), null, courseEnv, gtaNode); + fireEvent(ureq, Event.DONE_EVENT); + } + super.formInnerEvent(ureq, source, event); + } + + @Override + protected void formCancelled(UserRequest ureq) { + fireEvent(ureq, Event.CANCELLED_EVENT); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java index 7ac6a6269cc5de82100ef3019cf66a7e6133bf36..a58ec486c55fc11ed6ca06768588ad751d30c714 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java @@ -246,10 +246,14 @@ public abstract class GTAAbstractController extends BasicController implements G mainVC.contextPut("changelogconfig", courseModule.isDisplayChangeLog()); + resetTask(ureq, task); + nodeLog(); collapsedContents(task); } + protected abstract void resetTask(UserRequest ureq, Task task); + protected final void collapsedContents(Task currentTask) { TaskProcess status = null; TaskProcess previousStatus = null; diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java index 198e40d767ade0a3b4474847e3167276885ae977..ef3b134b070c677a3269e5f231a3c64b30c641b0 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java @@ -178,14 +178,14 @@ public class GTAAssessmentDetailsController extends BasicController implements A private void doSelectBusinessGroup(UserRequest ureq, BusinessGroup group) { removeAsListenerAndDispose(coachingCtrl); - coachingCtrl = new GTACoachController(ureq, getWindowControl(), courseEnv, gtaNode, coachCourseEnv, group, true, true, true); + coachingCtrl = new GTACoachController(ureq, getWindowControl(), courseEnv, gtaNode, coachCourseEnv, group, true, true, true, true); listenTo(coachingCtrl); mainVC.put("selection", coachingCtrl.getInitialComponent()); } private void doSelectParticipant(UserRequest ureq, Identity identity) { removeAsListenerAndDispose(coachingCtrl); - coachingCtrl = new GTACoachController(ureq, getWindowControl(), courseEnv, gtaNode, coachCourseEnv, identity, false, false, true); + coachingCtrl = new GTACoachController(ureq, getWindowControl(), courseEnv, gtaNode, coachCourseEnv, identity, false, false, true, true); listenTo(coachingCtrl); mainVC.put("selection", coachingCtrl.getInitialComponent()); } 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 e9e2dfae3a5fa4d530b77adc25819f20d60b064b..5a3c760ce268634ebf0aba34f2abd31dce68d77f 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 @@ -40,6 +40,7 @@ import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.id.Identity; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; +import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.io.SystemFilenameFilter; import org.olat.core.util.mail.ContactList; @@ -82,12 +83,15 @@ public class GTACoachController extends GTAAbstractController implements Assessm private GTACoachedParticipantGradingController participantGradingCtrl; private GTACoachRevisionAndCorrectionsController revisionDocumentsCtrl; private ConfirmRevisionsController confirmRevisionsCtrl; - private DialogBoxController confirmReviewDocumentCtrl, confirmCollectCtrl, confirmBackToSubmissionCtrl; + private DialogBoxController confirmReviewDocumentCtrl, confirmCollectCtrl, confirmBackToSubmissionCtrl, confirmResetTaskCtrl; private ContactFormController emailController; private CloseableModalController cmc; - private Link reviewedButton, needRevisionsButton, emailLink, collectSubmissionsLink, backToSubmissionLink; + private Link reviewedButton, needRevisionsButton, emailLink, collectSubmissionsLink, backToSubmissionLink, resetTaskButton; + + private final boolean isAdmin; + private final boolean withReset; private final UserCourseEnvironment coachCourseEnv; @Autowired @@ -95,14 +99,16 @@ public class GTACoachController extends GTAAbstractController implements Assessm public GTACoachController(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv, GTACourseNode gtaNode, UserCourseEnvironment coachCourseEnv, BusinessGroup assessedGroup, - boolean withTitle, boolean withGrading, boolean withSubscription) { - this(ureq, wControl, courseEnv, gtaNode, coachCourseEnv, assessedGroup, null, withTitle, withGrading, withSubscription); + boolean withTitle, boolean withGrading, boolean withSubscription, boolean withReset) { + this(ureq, wControl, courseEnv, gtaNode, coachCourseEnv, assessedGroup, null, + withTitle, withGrading, withSubscription, withReset); } public GTACoachController(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv, GTACourseNode gtaNode, UserCourseEnvironment coachCourseEnv, Identity assessedIdentity, - boolean withTitle, boolean withGrading, boolean withSubscription) { - this(ureq, wControl, courseEnv, gtaNode, coachCourseEnv, null, assessedIdentity, withTitle, withGrading, withSubscription); + boolean withTitle, boolean withGrading, boolean withSubscription, boolean withReset) { + this(ureq, wControl, courseEnv, gtaNode, coachCourseEnv, null, assessedIdentity, + withTitle, withGrading, withSubscription, withReset); } /** @@ -118,9 +124,11 @@ public class GTACoachController extends GTAAbstractController implements Assessm */ private GTACoachController(UserRequest ureq, WindowControl wControl, CourseEnvironment courseEnv, GTACourseNode gtaNode, UserCourseEnvironment coachCourseEnv, BusinessGroup assessedGroup, Identity assessedIdentity, - boolean withTitle, boolean withGrading, boolean withSubscription) { + boolean withTitle, boolean withGrading, boolean withSubscription, boolean withReset) { super(ureq, wControl, gtaNode, courseEnv, null, assessedGroup, assessedIdentity, withTitle, withGrading, withSubscription); this.coachCourseEnv = coachCourseEnv; + this.withReset = withReset; + isAdmin = coachCourseEnv.isAdmin(); initContainer(ureq); process(ureq); } @@ -157,6 +165,12 @@ public class GTACoachController extends GTAAbstractController implements Assessm } } + if(withReset) { + resetTaskButton = LinkFactory.createCustomLink("coach.reset.button", "reset", "coach.reset.button", Link.BUTTON, mainVC, this); + resetTaskButton.setElementCssClass("o_sel_course_gta_reset"); + resetTaskButton.setVisible(false); + } + putInitialPanel(mainVC); } @@ -176,7 +190,7 @@ public class GTACoachController extends GTAAbstractController implements Assessm listenTo(assignedTaskCtrl); mainVC.put("assignedTask", assignedTaskCtrl.getInitialComponent()); } - + return assignedTask; } @@ -446,6 +460,15 @@ public class GTACoachController extends GTAAbstractController implements Assessm mainVC.put("grading", participantGradingCtrl.getInitialComponent()); } } + + @Override + protected void resetTask(UserRequest ureq, Task task) { + resetTaskButton.setUserObject(task); + boolean allowed = isAdmin && task != null && StringHelper.containsNonWhitespace(task.getTaskName()) + && (task.getTaskStatus() == TaskProcess.assignment || task.getTaskStatus() == TaskProcess.submit) + && GTACourseNode.GTASK_ASSIGNEMENT_TYPE_MANUAL.equals(gtaNode.getModuleConfiguration().getStringValue(GTACourseNode.GTASK_ASSIGNEMENT_TYPE)); + resetTaskButton.setVisible(allowed); + } @Override protected void processEvent(TaskMultiUserEvent event) { @@ -517,6 +540,8 @@ public class GTACoachController extends GTAAbstractController implements Assessm doConfirmCollectTask(ureq, (Task)collectSubmissionsLink.getUserObject()); } else if(backToSubmissionLink == source) { doConfirmBackToSubmission(ureq, (Task)backToSubmissionLink.getUserObject()); + } else if(resetTaskButton == source) { + doConfirmResetTask(ureq, (Task)resetTaskButton.getUserObject()); } super.event(ureq, source, event); } @@ -553,11 +578,16 @@ public class GTACoachController extends GTAAbstractController implements Assessm Task assignedTask = (Task)confirmCollectCtrl.getUserObject(); doCollectTask(ureq, assignedTask); } - } else if(confirmBackToSubmissionCtrl == source) { + } else if(confirmBackToSubmissionCtrl == source) { if(DialogBoxUIFactory.isOkEvent(event) || DialogBoxUIFactory.isYesEvent(event)) { Task assignedTask = (Task)confirmBackToSubmissionCtrl.getUserObject(); doBackToSubmission(ureq, assignedTask); } + } else if(confirmResetTaskCtrl == source) { + if(DialogBoxUIFactory.isOkEvent(event) || DialogBoxUIFactory.isYesEvent(event)) { + Task assignedTask = (Task)confirmResetTaskCtrl.getUserObject(); + doAllowResetTask(ureq, assignedTask); + } } else if(source == cmc) { doCloseMailForm(false); } else if (source == emailController) { @@ -725,6 +755,28 @@ public class GTACoachController extends GTAAbstractController implements Assessm } } + private void doConfirmResetTask(UserRequest ureq, Task assignedTask) { + String toName = null; + if (assessedGroup != null) { + toName = assessedGroup.getName(); + } else if (assessedIdentity != null) { + toName = userManager.getUserDisplayName(assessedIdentity); + } + + String title = translate("coach.reset.task.confirm.title"); + String text = translate("coach.reset.task.confirm.text", new String[]{ toName }); + confirmResetTaskCtrl = activateOkCancelDialog(ureq, title, text, confirmResetTaskCtrl); + confirmResetTaskCtrl.setUserObject(assignedTask); + listenTo(confirmResetTaskCtrl); + } + + private void doAllowResetTask(UserRequest ureq, Task assignedTask) { + gtaManager.allowResetTask(assignedTask, getIdentity(), gtaNode); + gtaManager.log("Allow reset task", "Allow the user to reset the task", assignedTask, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode); + cleanUpProcess(); + process(ureq); + } + private void doOpenMailForm(UserRequest ureq) { // build recipient list ContactList contactList = null; diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachSelectionController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachSelectionController.java index 1db0a9b946caa210edf3ab9e83c94f7e5d1ff39c..ca06397e1a290a0d4647c54fdc6cb7a003c02361 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachSelectionController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachSelectionController.java @@ -242,7 +242,7 @@ public class GTACoachSelectionController extends BasicController implements Acti removeAsListenerAndDispose(coachingCtrl); WindowControl swControl = addToHistory(ureq, OresHelper.clone(group), null); - coachingCtrl = new GTACoachController(ureq, swControl, courseEnv, gtaNode, coachCourseEnv, group, true, true, false); + coachingCtrl = new GTACoachController(ureq, swControl, courseEnv, gtaNode, coachCourseEnv, group, true, true, false, false); listenTo(coachingCtrl); mainVC.put("selection", coachingCtrl.getInitialComponent()); return coachingCtrl; @@ -251,7 +251,7 @@ public class GTACoachSelectionController extends BasicController implements Acti private Activateable2 doSelectParticipant(UserRequest ureq, Identity identity) { removeAsListenerAndDispose(coachingCtrl); WindowControl swControl = addToHistory(ureq, OresHelper.createOLATResourceableInstance("Identity", identity.getKey()), null); - coachingCtrl = new GTACoachController(ureq, swControl, courseEnv, gtaNode, coachCourseEnv, identity, true, true, false); + coachingCtrl = new GTACoachController(ureq, swControl, courseEnv, gtaNode, coachCourseEnv, identity, true, true, false, false); listenTo(coachingCtrl); mainVC.put("selection", coachingCtrl.getInitialComponent()); return coachingCtrl; diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupListController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupListController.java index 885473c6de793d40656364ea0c5c5b4dbfb614ef..dd1d2d2781ec410ea1df3d1f792231b1c65efc07 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupListController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupListController.java @@ -205,7 +205,7 @@ public class GTACoachedGroupListController extends GTACoachedListController { } else { removeAsListenerAndDispose(coachingCtrl); - coachingCtrl = new GTACoachController(ureq, getWindowControl(), courseEnv, gtaNode, coachCourseEnv, businessGroup, true, true, true); + coachingCtrl = new GTACoachController(ureq, getWindowControl(), courseEnv, gtaNode, coachCourseEnv, businessGroup, true, true, true, false); listenTo(coachingCtrl); stackPanel.pushController(businessGroup.getName(), coachingCtrl); } 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 7e4e6cda5aec9c109f364828660f017095591201..4dc9e33ebb55a3ca624030e2133d4b24fe1da81d 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 @@ -39,6 +39,7 @@ 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.CloseableCalloutWindowController; +import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.dtabs.Activateable2; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; @@ -80,13 +81,15 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class GTAParticipantController extends GTAAbstractController implements Activateable2 { - private Link submitButton, openGroupButton, changeGroupLink; + private Link submitButton, openGroupButton, changeGroupLink, resetTaskButton; + private CloseableModalController cmc; private MSCourseNodeRunController gradingCtrl; private SubmitDocumentsController submitDocCtrl; private DialogBoxController confirmSubmitDialog; private GTAAssignedTaskController assignedTaskCtrl; private GTAAvailableTaskController availableTaskCtrl; + private ConfirmResetTaskController confirmResetTaskCtrl; private CloseableCalloutWindowController chooserCalloutCtrl; private BusinessGroupChooserController businessGroupChooserCtrl; private GTAParticipantRevisionAndCorrectionsController revisionDocumentsCtrl; @@ -107,6 +110,11 @@ public class GTAParticipantController extends GTAAbstractController implements A @Override protected void initContainer(UserRequest ureq) { mainVC = createVelocityContainer("run"); + + resetTaskButton = LinkFactory.createCustomLink("participant.reset.button", "reset", "participant.reset.button", Link.BUTTON, mainVC, this); + resetTaskButton.setElementCssClass("o_sel_course_gta_reset"); + resetTaskButton.setVisible(false); + putInitialPanel(mainVC); initFlow() ; } @@ -375,6 +383,17 @@ public class GTAParticipantController extends GTAAbstractController implements A } } + private void doConfirmResetTask(UserRequest ureq, Task task) { + if(confirmResetTaskCtrl != null) return; + confirmResetTaskCtrl = new ConfirmResetTaskController(ureq, getWindowControl(), task, gtaNode, courseEnv); + listenTo(confirmResetTaskCtrl); + + String title = translate("participant.confirm.reset.task.title"); + cmc = new CloseableModalController(getWindowControl(), translate("close"), confirmResetTaskCtrl.getInitialComponent(), true, title); + listenTo(cmc); + cmc.activate(); + } + @Override protected Task stepReviewAndCorrection(UserRequest ureq, Task assignedTask) { assignedTask = super.stepReviewAndCorrection(ureq, assignedTask); @@ -585,6 +604,16 @@ public class GTAParticipantController extends GTAAbstractController implements A return assignedTask; } + @Override + protected void resetTask(UserRequest ureq, Task task) { + resetTaskButton.setUserObject(task); + boolean allowed = task != null && StringHelper.containsNonWhitespace(task.getTaskName()) + && (task.getTaskStatus() == TaskProcess.assignment || task.getTaskStatus() == TaskProcess.submit) + && task.getAllowResetDate() != null + && GTACourseNode.GTASK_ASSIGNEMENT_TYPE_MANUAL.equals(gtaNode.getModuleConfiguration().getStringValue(GTACourseNode.GTASK_ASSIGNEMENT_TYPE)); + resetTaskButton.setVisible(allowed); + } + @Override protected void nodeLog() { if(businessGroupTask) { @@ -682,6 +711,8 @@ public class GTAParticipantController extends GTAAbstractController implements A } else if(submitButton == source) { Task assignedTask = submitDocCtrl.getAssignedTask(); doConfirmSubmit(ureq, assignedTask); + } else if(resetTaskButton == source) { + doConfirmResetTask(ureq, (Task)resetTaskButton.getUserObject()); } super.event(ureq, source, event); } @@ -716,6 +747,13 @@ public class GTAParticipantController extends GTAAbstractController implements A doSubmitDocuments(ureq, task); } cleanUpPopups(); + } else if(confirmResetTaskCtrl == source) { + if(event == Event.DONE_EVENT) { + cleanUpProcess(); + process(ureq); + } + cmc.deactivate(); + cleanUpPopups(); } else if(submitDocCtrl == source) { boolean hasUploadDocuments = submitDocCtrl.hasUploadDocuments(); if(event instanceof SubmitEvent) { @@ -729,6 +767,8 @@ public class GTAParticipantController extends GTAAbstractController implements A if(submitButton != null) { submitButton.setCustomEnabledLinkCSS(hasUploadDocuments ? "btn btn-primary" : "btn btn-default"); } + } else if(cmc == source) { + cleanUpPopups(); } super.event(ureq, source, event); } @@ -772,11 +812,15 @@ public class GTAParticipantController extends GTAAbstractController implements A private void cleanUpPopups() { removeAsListenerAndDispose(businessGroupChooserCtrl); + removeAsListenerAndDispose(confirmResetTaskCtrl); removeAsListenerAndDispose(confirmSubmitDialog); removeAsListenerAndDispose(chooserCalloutCtrl); + removeAsListenerAndDispose(cmc); businessGroupChooserCtrl = null; + confirmResetTaskCtrl = null; confirmSubmitDialog = null; chooserCalloutCtrl = null; + cmc = null; } private void doOpenBusinessGroup(UserRequest ureq) { diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_content/coach.html b/src/main/java/org/olat/course/nodes/gta/ui/_content/coach.html index 01dc853ba301ac5da8fcba18ff1938e2c964a6f5..e93a9a127ea0fc649426dac600e9fc6d3f405c88 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/_content/coach.html +++ b/src/main/java/org/olat/course/nodes/gta/ui/_content/coach.html @@ -181,6 +181,11 @@ /* ]]> */</script> #end </div> +#if($r.visible("coach.reset.button")) +<div class="o_button_group"> + $r.render("coach.reset.button") +</div> +#end #if($userLog || $groupLog) <div class="o_box"> #o_togglebox_start("o_course_run_log" $r.translate("log.title")) diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_content/participant_reset_task.html b/src/main/java/org/olat/course/nodes/gta/ui/_content/participant_reset_task.html new file mode 100644 index 0000000000000000000000000000000000000000..cd0f75f521f6388cc3365a0821dbeedcb9b60a02 --- /dev/null +++ b/src/main/java/org/olat/course/nodes/gta/ui/_content/participant_reset_task.html @@ -0,0 +1,6 @@ +<div><p>$msg</p></div> +<div class="o_button_group"> + $r.render("buttons") +</div> + + diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_content/run.html b/src/main/java/org/olat/course/nodes/gta/ui/_content/run.html index f02deed09583058541697f98bbfa9540da725da2..8ee353138715e5516bd2c9e24868c7f148a16717 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/_content/run.html +++ b/src/main/java/org/olat/course/nodes/gta/ui/_content/run.html @@ -41,6 +41,11 @@ $r.render("availableTasks") #elseif($r.available("myAssignedTask")) $r.render("myAssignedTask") + #if($r.visible("participant.reset.button")) + <div class="o_button_group"> + $r.render("participant.reset.button") + </div> + #end #end </div> </div> 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 4bbde7169b5bb034d1528da2af8709b5109946f7..bbc8ec7fb29afee177195f1b484ff014be6d19d1 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 @@ -1,4 +1,4 @@ -#Fri Sep 30 15:06:39 CEST 2016 +#Thu Aug 10 14:27:32 CEST 2017 add.solution=Musterl\u00F6sung hochladen add.task=Aufgabe hinzuf\u00FCgen assessment.group.tool=Gruppe bewerten @@ -42,6 +42,9 @@ coach.feedback.documents.desc=Die hier eingestellten Dokumente werden f\u00FCr d coach.feedback.documents.title=Dokumente f\u00FCr Feedback vorbereiten coach.need.revision.button=Ben\u00F6tigt \u00DCberarbeitung coach.reopen=Neu er\u00F6ffnen +coach.reset.button=Daten von Aufgabe zur\u00FCcksetzen +coach.reset.task.confirm.text=Wollen Sie "{0}" erlauben seine Aufgabe zur\u00FCckzusetzen? +coach.reset.task.confirm.title=Daten von Aufgabe zur\u00FCcksetzen coach.reviewed.button=Abgabe akzeptieren coach.reviewed.confirm.text=Bitte best\u00E4tigen Sie dass die Abgabe akzeptiert wird. Die Aufgabe wird damit f\u00FCr den Benutzer beendet, und er erh\u00E4lt keine weitere \u00DCberarbeitungsm\u00F6glichkeit. coach.reviewed.confirm.title=Best\u00E4tigung\: Abgabe akzeptiert @@ -77,12 +80,12 @@ document.date=Datum document.open.editor=Dokument erstellen download.task=Aufgabe herunterladen download.task.infos={0} ({1} MB) +duedate.standard=Standard Datum\: {0} duedates=Verl\u00E4ngern duedates.user=Verl\u00E4ngern f\u00FCr "{0}" -duedate.standard=Standard Datum: {0} edit.task=Aufgabe bearbeiten -editor.title=Abgabe Konfiguration editor.revisions.title=R\u00FCckgabe Konfiguration +editor.title=Abgabe Konfiguration embedded.editor=Abgabe mit OpenOLAT Texteditor enabled=eingeschaltet error.assignment.closed=Zuweisung ist geschlossen. @@ -114,8 +117,9 @@ group.comment=Gruppe Kommentar group.passed=Gruppe bestanden group.score=Gruppe Punkte group.title=Leistungs\u00FCbersicht +highscore.forminfo=Die HighScore Funktionalit\u00E4t bezieht sich auf die einzelnen Mitglieder einer Gruppe. Ein Vergleich auf Ebene der Gruppen ist nicht m\u00F6glich. info.title=$org.olat.course.nodes.ms\:info.title -lastmodified= am {0} +lastmodified=am {0} log.title=\u00C4nderungsverlauf mail.confirm.assignment.body=Zuweisung war erfolgreich mail.confirm.assignment.subject=Zuweisung @@ -124,38 +128,43 @@ mailto.user=E-Mail an Benutzer max.documents=Max. Anzahl von Dokumenten no.submission=Nicht abgegeben notifications.accepted=Ihre Aufgabe "{0}" im Kurs "{1}" wurde akzeptiert. -notifications.assessment.score.passed=Für die Aufgabe "{0}" im Kurs "{1}" haben Sie eine Bewertung erhalten. Ihre Punktzahl beträgt {2} Punkte und Sie haben {3}. -notifications.assessment.score=Für die Aufgabe "{0}" im Kurs "{1}" haben Sie eine Bewertung erhalten. Ihre Punktzahl beträgt {2} Punkte. -notifications.assessment.passed=Für die Aufgabe "{0}" im Kurs "{1}" haben Sie eine Bewertung erhalten. Sie haben {3}. -notifications.assessment.doc=Für die Aufgabe "{0}" im Kurs "{1}" stehen bereit Bewertungsdokumente zum Download: "{2}". -notifications.assessment.passed.true=bestanden +notifications.assessment.doc=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" stehen bereit Bewertungsdokumente zum Download\: "{2}". +notifications.assessment.passed=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" haben Sie eine Bewertung erhalten. Sie haben {3}. notifications.assessment.passed.false=nicht bestanden +notifications.assessment.passed.true=bestanden +notifications.assessment.score=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" haben Sie eine Bewertung erhalten. Ihre Punktzahl betr\u00E4gt {2} Punkte. +notifications.assessment.score.passed=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" haben Sie eine Bewertung erhalten. Ihre Punktzahl betr\u00E4gt {2} Punkte und Sie haben {3}. +notifications.correction=F\u00FCr Ihre Aufgabe "{0}" im Kurs "{1}" wurde eine \u00DCberarbeitung angefordert. +notifications.correction.doc=Sie haben ein Feedback f\u00FCr die Aufgabe "{0}" im Kurs "{1}" von {3} erhalten\: "{2}". +notifications.correction.duedate=$\:notifications.correction Die \u00DCberarbeitungsfrist wurde auf den {3} gesetzt. notifications.group.header=Gruppenaufgabe in Kurs "{0}" notifications.group.header.task=Gruppenaufgabe "{0}" in Kurs "{1}" notifications.individual.header=Aufgabe in Kurs "{0}" notifications.individual.header.task=Aufgabe "{0}" in Kurs "{1}" -notifications.solution=Im Kurs "{0}" steht die folgende Musterlösung zum Download bereit: "{1}". -notifications.solution.task=Für die Aufgabe "{0}" im Kurs "{1}" steht die folgende Musterlösung zum Download bereit: "{2}". -notifications.correction=Für Ihre Aufgabe "{0}" im Kurs "{1}" wurde eine Überarbeitung angefordert. -notifications.correction.duedate=$\:notifications.correction Die Überarbeitungsfrist wurde auf den {3} gesetzt. -notifications.correction.doc=Sie haben ein Feedback für die Aufgabe "{0}" im Kurs "{1}" von {3} erhalten: "{2}". -notifications.submission.individual=Die Aufgabe "{0}" im Kurs "{1}" wurde von "{2}" abgegeben. +notifications.revision.group=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" wurde eine neue \u00DCberarbeitungen f\u00FCr die Gruppe "{2}" abgegeben. +notifications.revision.group.doc=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" wurde eine neue \u00DCberarbeitungen "{2}" f\u00FCr die Gruppe "{3}" hochgeladen. +notifications.revision.individual=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" wurde eine neue \u00DCberarbeitungen von "{2}" abgegeben. +notifications.revision.individual.doc=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" wurde eine neue \u00DCberarbeitungen "{2}" von "{3}" hochgeladen. +notifications.solution=Im Kurs "{0}" steht die folgende Musterl\u00F6sung zum Download bereit\: "{1}". +notifications.solution.task=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" steht die folgende Musterl\u00F6sung zum Download bereit\: "{2}". notifications.submission.group=Die Aufgabe "{0}" im Kurs "{1}" wurde f\u00FCr Gruppe "{2}" abgegeben. -notifications.submission.group.doc==Für die Aufgabe "{0}" im Kurs "{1}" wurde eine neue Dokument "{2}" von "{3}" f\u00FCr Gruppe "{4}" hochgeladen. -notifications.submission.individual.doc=Für die Aufgabe "{0}" im Kurs "{1}" wurde eine neue Dokument "{2}" von "{3}" hochgeladen. -notifications.revision.group=Für die Aufgabe "{0}" im Kurs "{1}" wurde eine neue \u00DCberarbeitungen f\u00FCr die Gruppe "{2}" abgegeben. -notifications.revision.individual=Für die Aufgabe "{0}" im Kurs "{1}" wurde eine neue \u00DCberarbeitungen von "{2}" abgegeben. -notifications.revision.group.doc=Für die Aufgabe "{0}" im Kurs "{1}" wurde eine neue \u00DCberarbeitungen "{2}" f\u00FCr die Gruppe "{3}" hochgeladen. -notifications.revision.individual.doc=Für die Aufgabe "{0}" im Kurs "{1}" wurde eine neue \u00DCberarbeitungen "{2}" von "{3}" hochgeladen. +notifications.submission.group.doc=\=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" wurde eine neue Dokument "{2}" von "{3}" f\u00FCr Gruppe "{4}" hochgeladen. +notifications.submission.individual=Die Aufgabe "{0}" im Kurs "{1}" wurde von "{2}" abgegeben. +notifications.submission.individual.doc=F\u00FCr die Aufgabe "{0}" im Kurs "{1}" wurde eine neue Dokument "{2}" von "{3}" hochgeladen. open.group=Gruppe \u00F6ffnen pane.tab.accessibility=Zugang pane.tab.assignment=Aufgabenstellung pane.tab.grading=Bewertung +pane.tab.highscore=HighScore pane.tab.review=R\u00FCckgabe und Feedback pane.tab.solutions=Musterl\u00F6sung pane.tab.submission=Abgabe pane.tab.workflow=Workflow -pane.tab.highscore=HighScore +participant.confirm.reset.task.nok=Nein, ich behalte meine Aufgabe +participant.confirm.reset.task.ok=Ja, Aufgabe zur\u00FCcksetzen +participant.confirm.reset.task.text=Sie w\u00FCrden von {0} erlaubt Ihre Aufgabe "{1}" zur\u00FCckzusetzen. Alle dokumenten dass Sie schon hochgeladet haben werden gel\u00F6scht. +participant.confirm.reset.task.title=Aufgabe zur\u00FCcksetzen +participant.reset.button=Daten zur\u00FCcksetzen passed.false=$org.olat.course.assessment\:passed.false passed.true=$org.olat.course.assessment\:passed.true preview=$org.olat.course.nodes.ta\:form.task.preview @@ -298,8 +307,8 @@ task.type.title=Aufgabentyp upload.document=Dokument hochladen uploaded.by=hochgeladen von {0} user.visibility=$org.olat.course.assessment.ui.tool\:user.visibility -user.visibility.visible=$org.olat.course.assessment.ui.tool\:user.visibility.visible user.visibility.hidden=$org.olat.course.assessment.ui.tool\:user.visibility.hidden +user.visibility.visible=$org.olat.course.assessment.ui.tool\:user.visibility.visible 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. @@ -312,4 +321,3 @@ warning.tasks.in.process.delete.title=$\:warning.tasks.in.process.title warning.tasks.in.process.text=Es gibt bereits Benutzer die den Aufgabenprozess gestartet haben. \u00C4nderungen an der Workflow-Konfiguration kann f\u00FCr diese Benutzer zu Problemen f\u00FChren. Informationen dazu finden Sie im <a href\="{0}" target\="_blank"><i class\='o_icon o_icon_help'> </i> Handbuch</a>. warning.tasks.in.process.title=Aufgabenprozess bereits gestartet warning.tasks.submitted=Sie k\u00F6nnen diese Aufgabe nicht mehr bearbeiten, sie wurde bereits abgegeben. -highscore.forminfo=Die HighScore Funktionalität bezieht sich auf die einzelnen Mitglieder einer Gruppe. Ein Vergleich auf Ebene der Gruppen ist nicht möglich. 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 7ae1dcdf12e3e8a89e4ae23f665f7e9108fc59b3..98882d865a51619d52f643a5716f97aece74df87 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 @@ -1,9 +1,10 @@ -#Wed Jan 11 13:33:58 CET 2017 +#Thu Aug 10 14:29:45 CEST 2017 add.solution=Add solution add.task=Add task assessment.group.tool=Grade group assignment.config.title=Task assignment configuration assignment.deadline=Assignment deadline +assignment.duedate=$\:assignment.deadline before=beforehand bulk.download.title=Download all submitted files bulk.review=Download review @@ -41,6 +42,9 @@ coach.feedback.documents.desc=Uploaded documents are visible to the participants coach.feedback.documents.title=Prepare feedback documents coach.need.revision.button=Needs revision coach.reopen=Reopen +coach.reset.button=Reset data of task +coach.reset.task.confirm.text=Do you want to allow "{0}" to reset its task? +coach.reset.task.confirm.title=Reset data of task coach.reviewed.button=Submission accepted coach.reviewed.confirm.text=Please confirm your acceptance of the submitted documents. The task is now closed for the user, and there is no revision option available. coach.reviewed.confirm.title=Confirm acceptance of submitted documents @@ -76,9 +80,12 @@ document.date=Date document.open.editor=Open editor download.task=Download task download.task.infos={0} ({1} MB) +duedate.standard=Standard date\: {0} +duedates=Prolongate +duedates.user=Prolongate for "{0}" edit.task=Edit task -editor.title=Submission configuration editor.revisions.title=Revision configuration +editor.title=Submission configuration embedded.editor=Submit with OpenOLAT text editor enabled=enabled error.assignment.closed=Assignment is closed @@ -110,8 +117,9 @@ group.comment=Group comment group.passed=Group passed group.score=Group score group.title=Score summary +highscore.forminfo=The high-score feature refers to the members of a group. A comparison on group level is not available. info.title=$org.olat.course.nodes.ms\:info.title -lastmodified= at {0} +lastmodified=at {0} log.title=Change log mail.confirm.assignment.body=Assignment was successful mail.confirm.assignment.subject=Assignment @@ -120,38 +128,43 @@ mailto.user=Mail to user max.documents=Max. number of documents no.submission=No submission notifications.accepted=Your task "{0}" in the course "{1}" has been accepted. -notifications.assessment.score.passed=You have got a grading for the task "{0}" in the course "{1}". Your score ist {2} and you have {3}. -notifications.assessment.score=You have got a grading for the task "{0}" in the course "{1}". Your score ist {2}. +notifications.assessment.doc=You have got a grading document for the task "{0}" in the course "{1}"\: "{2}". notifications.assessment.passed=You have got a grading for the task "{0}" in the course "{1}". You have {3}. -notifications.assessment.doc=You have got a grading document for the task "{0}" in the course "{1}": "{2}". -notifications.solution=In the course "{0}" the following sample solution is available for download: "{1}". -notifications.solution.task=For the task "{0}" in the course "{1}" the following sample solution is available for download: "{2}". -notifications.assessment.passed.true=passed notifications.assessment.passed.false=failed +notifications.assessment.passed.true=passed +notifications.assessment.score=You have got a grading for the task "{0}" in the course "{1}". Your score ist {2}. +notifications.assessment.score.passed=You have got a grading for the task "{0}" in the course "{1}". Your score ist {2} and you have {3}. +notifications.correction=You have received a feedback for the task "{0}" in the course "{1}". +notifications.correction.doc=You have received a feedback for the task "{0}" in the course "{1}" by {3}\: "{2}". +notifications.correction.duedate=$\:notifications.correction The deadline for the revision is set to the {2}. notifications.group.header=Group task in course "{0}" notifications.group.header.task=Group task "{0}" in course "{1}" notifications.individual.header=Task in course "{0}" notifications.individual.header.task=Task "{0}" in course "{1}" -notifications.correction=You have received a feedback for the task "{0}" in the course "{1}". -notifications.correction.duedate=$\:notifications.correction The deadline for the revision is set to the {2}. -notifications.correction.doc=You have received a feedback for the task "{0}" in the course "{1}" by {3}: "{2}". -notifications.submission.individual=The task "{0}" in course "{1}" was submitted by "{2}". -notifications.submission.group=The task "{0}" in course "{1}" was submitted for the group "{2}". -notifications.submission.group.doc==For the task "{0}" in course "{1}" was a new document "{2}" submitted by "{3}" for the group "{4}". -notifications.submission.individual.doc=For the task "{0}" in course "{1}" was a new document "{2}" submitted by "{3}". notifications.revision.group=For the task "{0}" in course "{1}" was a new revision submitted for the group "{2}". -notifications.revision.individual=For the task "{0}" in course "{1}" was a new revision submitted by "{2}". notifications.revision.group.doc=For the task "{0}" in course "{1}" was a new revision "{2}" submitted for the group "{3}". +notifications.revision.individual=For the task "{0}" in course "{1}" was a new revision submitted by "{2}". notifications.revision.individual.doc=For the task "{0}" in course "{1}" was a new revision "{2}" submitted by "{3}". +notifications.solution=In the course "{0}" the following sample solution is available for download\: "{1}". +notifications.solution.task=For the task "{0}" in the course "{1}" the following sample solution is available for download\: "{2}". +notifications.submission.group=The task "{0}" in course "{1}" was submitted for the group "{2}". +notifications.submission.group.doc=\=For the task "{0}" in course "{1}" was a new document "{2}" submitted by "{3}" for the group "{4}". +notifications.submission.individual=The task "{0}" in course "{1}" was submitted by "{2}". +notifications.submission.individual.doc=For the task "{0}" in course "{1}" was a new document "{2}" submitted by "{3}". open.group=Open group pane.tab.accessibility=Access pane.tab.assignment=Assignment pane.tab.grading=Grading +pane.tab.highscore=HighScore pane.tab.review=Revisions and feedback pane.tab.solutions=Sample solutions pane.tab.submission=Submission pane.tab.workflow=Workflow -pane.tab.highscore=HighScore +participant.confirm.reset.task.nok=No, I keep the task +participant.confirm.reset.task.ok=Yes, the task can be reseted +participant.confirm.reset.task.text=You are allowed by {0} to reset your "{1}". All documents you already downloaded will be deleted. +participant.confirm.reset.task.title=Reset +participant.reset.button=Reset task passed.false=$org.olat.course.assessment\:passed.false passed.true=$org.olat.course.assessment\:passed.true preview=$org.olat.course.nodes.ta\:form.task.preview @@ -187,6 +200,7 @@ review.and.correction=Return and feedback review.enabled=Enable return box for reviews and feedback revision.enabled=Enable drop box for revisions by participants, can be set by coach revision.period=Revision phase +revisions.duedate=Revision until... run.assignment.due.date=Due date\: {0} run.assignment.title=Task assignment run.coach=Correct @@ -204,6 +218,7 @@ run.review.waiting=Your coach is now reviewing the submitted work. You will get run.revised.description=The following revised documents have been submitted by you\: run.revised.nofiles=The revision was submitted without documents run.revision=Revision phase +run.revision.due.date=Revision deadline\: {0} run.revision.period.description=$\:run.corrections.rejected Create or upload a revised document. run.run=Task run.solution=Sample solution @@ -229,12 +244,13 @@ run.submitted.nofiles=The submission was done without documents 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=Sample solutions visible for all after the date is reached, inclusive the one which don't have submitted their task. sampling=Type of sampling sampling.reuse=Your task will be assigned to more than one user / group sampling.unique=Your task will be assigned to only one single user / group save.done=Save as done selected.group=The group for this task is\: <i class\="o_icon o_icon_group"> </i> "{0}" +solution.duedate=Solution until... solution.file=File solution.list.description=Select "$\:add.solution" or "$\:create.solution" to add a solution or "$\:replace" or "$org.olat.core\:edit" to modify an existing solution. Please note that solutions are not assigned to a particular task. solution.list.title=Upload sample solutions @@ -242,6 +258,7 @@ solution.title=Title submission=Submission submission.add.title=Add document submission.confirmation=The submission of $numberOfFiles file(s) ($filename) for $first $last ($email) at $date, $time has been confirmed. +submission.duedate=$\:submit.deadline submission.email.confirmation=Send text additionally as email submission.enabled=Enable solution drop box for participants submission.mail.subject=OpenOLAT-confirmation-E-Mail @@ -255,12 +272,14 @@ submit.submit.title=Step 2\: Submit documents table.header.author=Author table.header.comment=Comment table.header.details.gta=$org.olat.course.nodes.ta\:table.header.details.ta +table.header.duedates=Deadlines table.header.edit=Action table.header.group.name=Group table.header.group.step=Step table.header.group.taskName=Task table.header.passed=Passed table.header.score=Points +table.header.submissionDate=Submission date table.header.uploaded.by=Uploaded by task.alreadyChosen=$org.olat.course.nodes.ta\:task.chosen task.assigned.description=The following task has been assigned to you\: @@ -288,8 +307,8 @@ task.type.title=Task type upload.document=Upload document uploaded.by=uploaded by {0} user.visibility=$org.olat.course.assessment.ui.tool\:user.visibility -user.visibility.visible=$org.olat.course.assessment.ui.tool\:user.visibility.visible user.visibility.hidden=$org.olat.course.assessment.ui.tool\:user.visibility.hidden +user.visibility.visible=$org.olat.course.assessment.ui.tool\:user.visibility.visible wait.for.solutions=The sample solution will be displayed at the date specified above. 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. @@ -302,4 +321,3 @@ warning.tasks.in.process.delete.title=$\:warning.tasks.in.process.title 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. Please refer to the <a href\="{0}" target\="_blank"><i class\='o_icon o_icon_help'> </i> manual</a> for more information. warning.tasks.in.process.title=Task already started warning.tasks.submitted=You cannot edit this task anymore, it has already been submitted. -highscore.forminfo=The high-score feature refers to the members of a group. A comparison on group level is not available. \ No newline at end of file diff --git a/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql index 86c43c0d8c0cbeeeb1590e20cc1a5fa01645dbdb..f799c67ddf197b71d4ac73a317ca1b45ff1b2db2 100644 --- a/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql +++ b/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql @@ -242,6 +242,11 @@ alter table o_gta_task_revision_date ENGINE = InnoDB; alter table o_gta_task_revision_date add constraint gtaskrev_to_task_idx foreign key (fk_task) references o_gta_task (id); +alter table o_gta_task add column g_allow_reset_date datetime default null; +alter table o_gta_task add column fk_allow_reset_identity bigint default null; + +alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_allow_reset_identity) references o_bs_identity (id); + diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index 538c65bf2139144e99cd8f10ad0d3d3750bb2552..bcf6000daf67153f12b3874d0b58543d3aa8974c 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -1861,6 +1861,7 @@ create table o_gta_task ( g_acceptation_date datetime, g_solution_date datetime, g_graduation_date datetime, + g_allow_reset_date datetime, g_assignment_due_date datetime, g_submission_due_date datetime, g_revisions_due_date datetime, @@ -1869,6 +1870,7 @@ create table o_gta_task ( fk_tasklist bigint not null, fk_identity bigint, fk_businessgroup bigint, + fk_allow_reset_identity bigint, primary key (id) ); @@ -2633,6 +2635,7 @@ create index idx_checkbox_uuid_idx on o_cl_checkbox (c_checkboxid); alter table o_gta_task add constraint gtask_to_tasklist_idx foreign key (fk_tasklist) references o_gta_task_list (id); alter table o_gta_task add constraint gtask_to_identity_idx foreign key (fk_identity) references o_bs_identity (id); alter table o_gta_task add constraint gtask_to_bgroup_idx foreign key (fk_businessgroup) references o_gp_business (group_id); +alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_allow_reset_identity) references o_bs_identity (id); alter table o_gta_task_list add constraint gta_list_to_repo_entry_idx foreign key (fk_entry) references o_repositoryentry (repositoryentry_id); diff --git a/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql index 435c868534c03684a8617ceb733256c6e6619110..8bf3d7e7bd2c6be012b569ee8b34d2ec06741394 100644 --- a/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql +++ b/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql @@ -243,3 +243,10 @@ create table o_gta_task_revision_date ( alter table o_gta_task_revision_date add constraint gtaskrev_to_task_idx foreign key (fk_task) references o_gta_task (id); create index idx_gtaskrev_to_task_idx on o_gta_task_revision_date (fk_task); +alter table o_gta_task add g_allow_reset_date date default null; +alter table o_gta_task add fk_allow_reset_identity number(20) default null; + +alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_allow_reset_identity) references o_bs_identity (id); +create index idx_gtaskreset_to_allower_idx on o_gta_task (fk_allow_reset_identity); + + diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql index e18daca74715502707a0d9b5483838b7a74f991a..4bcffaa396f0e9e4c7a18c5e6dec639e0302ea77 100644 --- a/src/main/resources/database/oracle/setupDatabase.sql +++ b/src/main/resources/database/oracle/setupDatabase.sql @@ -1885,6 +1885,7 @@ create table o_gta_task ( g_acceptation_date date, g_solution_date date, g_graduation_date date, + g_allow_reset_date date, g_assignment_due_date date, g_submission_due_date date, g_revisions_due_date date, @@ -1892,6 +1893,7 @@ create table o_gta_task ( fk_tasklist number(20) not null, fk_identity number(20), fk_businessgroup number(20), + fk_allow_reset_identity number(20), primary key (id) ); @@ -2702,6 +2704,8 @@ alter table o_gta_task add constraint gtask_to_identity_idx foreign key (fk_iden create index idx_gtask_to_identity_idx on o_gta_task (fk_identity); alter table o_gta_task add constraint gtask_to_bgroup_idx foreign key (fk_businessgroup) references o_gp_business (group_id); create index idx_gtask_to_bgroup_idx on o_gta_task (fk_businessgroup); +alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_allow_reset_identity) references o_bs_identity (id); +create index idx_gtaskreset_to_allower_idx on o_gta_task (fk_allow_reset_identity); alter table o_gta_task_list add constraint gta_list_to_repo_entry_idx foreign key (fk_entry) references o_repositoryentry (repositoryentry_id); create index idx_gta_list_to_repo_entry_idx on o_gta_task_list (fk_entry); diff --git a/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql index 7380438f3ec6e5ac8a9121b35d193b822ee49779..d069ff1f39e62639f73dc29e2fd9cf847c9e531a 100644 --- a/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql +++ b/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql @@ -243,8 +243,10 @@ create table o_gta_task_revision_date ( alter table o_gta_task_revision_date add constraint gtaskrev_to_task_idx foreign key (fk_task) references o_gta_task (id); create index idx_gtaskrev_to_task_idx on o_gta_task_revision_date (fk_task); +alter table o_gta_task add column g_allow_reset_date timestamp default null; +alter table o_gta_task add column fk_allow_reset_identity int8 default null; - - +alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_allow_reset_identity) references o_bs_identity (id); +create index idx_gtaskreset_to_allower_idx on o_gta_task (fk_allow_reset_identity); diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql index d34929ad20e73a407240da5709f378c99f68fcad..e18ef22948b7e80b8e8e72d66ccfc09d1ba6aabd 100644 --- a/src/main/resources/database/postgresql/setupDatabase.sql +++ b/src/main/resources/database/postgresql/setupDatabase.sql @@ -1858,6 +1858,7 @@ create table o_gta_task ( g_acceptation_date timestamp, g_solution_date timestamp, g_graduation_date timestamp, + g_allow_reset_date timestamp, g_assignment_due_date timestamp, g_submission_due_date timestamp, g_revisions_due_date timestamp, @@ -1866,6 +1867,7 @@ create table o_gta_task ( fk_tasklist int8 not null, fk_identity int8, fk_businessgroup int8, + fk_allow_reset_identity int8, primary key (id) ); @@ -2551,6 +2553,8 @@ alter table o_gta_task add constraint gtask_to_identity_idx foreign key (fk_iden create index idx_gtask_to_identity_idx on o_gta_task (fk_identity); alter table o_gta_task add constraint gtask_to_bgroup_idx foreign key (fk_businessgroup) references o_gp_business (group_id); create index idx_gtask_to_bgroup_idx on o_gta_task (fk_businessgroup); +alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_allow_reset_identity) references o_bs_identity (id); +create index idx_gtaskreset_to_allower_idx on o_gta_task (fk_allow_reset_identity); alter table o_gta_task_list add constraint gta_list_to_repo_entry_idx foreign key (fk_entry) references o_repositoryentry (repositoryentry_id); create index idx_gta_list_to_repo_entry_idx on o_gta_task_list (fk_entry);