From 32356fbc58796a852621de736bcb97f73a342a6d Mon Sep 17 00:00:00 2001 From: srosse <stephane.rosse@frentix.com> Date: Fri, 19 Jul 2019 19:07:21 +0200 Subject: [PATCH] OO-4160: implement delete curriculum with confirmation --- .../modules/curriculum/CurriculumService.java | 3 + .../curriculum/manager/CurriculumDAO.java | 8 ++ .../manager/CurriculumServiceImpl.java | 13 ++ .../ui/ConfirmCurriculumDeleteController.java | 127 ++++++++++++++++++ .../ui/CurriculumListManagerController.java | 26 +++- .../_content/confirm_delete_curriculum.html | 4 + .../ui/_i18n/LocalStrings_de.properties | 4 + .../ui/_i18n/LocalStrings_en.properties | 4 + .../ui/_i18n/LocalStrings_en.properties | 2 +- 9 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/olat/modules/curriculum/ui/ConfirmCurriculumDeleteController.java create mode 100644 src/main/java/org/olat/modules/curriculum/ui/_content/confirm_delete_curriculum.html diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumService.java b/src/main/java/org/olat/modules/curriculum/CurriculumService.java index a4bcc8571e8..ff15ce66fba 100644 --- a/src/main/java/org/olat/modules/curriculum/CurriculumService.java +++ b/src/main/java/org/olat/modules/curriculum/CurriculumService.java @@ -66,6 +66,9 @@ public interface CurriculumService { public Curriculum getCurriculum(CurriculumRef ref); public Curriculum updateCurriculum(Curriculum curriculum); + + public void deleteCurriculum(CurriculumRef curriculum); + public List<Curriculum> getCurriculums(Collection<? extends CurriculumRef> refs); diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java index 75960f18f01..e308f50cfc3 100644 --- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java +++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java @@ -27,6 +27,7 @@ import java.util.stream.Collectors; import javax.persistence.TypedQuery; +import org.olat.basesecurity.Group; import org.olat.basesecurity.GroupRoles; import org.olat.basesecurity.IdentityRef; import org.olat.basesecurity.OrganisationRoles; @@ -342,6 +343,13 @@ public class CurriculumDAO { return dbInstance.getCurrentEntityManager().merge(curriculum); } + public void delete(CurriculumImpl curriculum) { + Group group = curriculum.getGroup(); + groupDao.removeMemberships(group); + dbInstance.getCurrentEntityManager().remove(curriculum); + groupDao.removeGroup(group); + } + public List<Identity> getMembersIdentity(CurriculumRef curriculum, String role) { StringBuilder sb = new StringBuilder(256); sb.append("select ident from curriculum cur") diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java index 97969f7a7cb..af7adb3108d 100644 --- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java +++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java @@ -72,6 +72,7 @@ import org.olat.modules.curriculum.model.CurriculumElementRepositoryEntryViews; import org.olat.modules.curriculum.model.CurriculumElementSearchInfos; import org.olat.modules.curriculum.model.CurriculumElementSearchParams; import org.olat.modules.curriculum.model.CurriculumElementWebDAVInfos; +import org.olat.modules.curriculum.model.CurriculumImpl; import org.olat.modules.curriculum.model.CurriculumInfos; import org.olat.modules.curriculum.model.CurriculumMember; import org.olat.modules.curriculum.model.CurriculumRefImpl; @@ -141,6 +142,18 @@ public class CurriculumServiceImpl implements CurriculumService, OrganisationDat return curriculumDao.update(curriculum); } + @Override + public void deleteCurriculum(CurriculumRef curriculumRef) { + CurriculumImpl curriculum = (CurriculumImpl)getCurriculum(curriculumRef); + for(CurriculumElement rootElement:curriculum.getRootElements()) { + deleteCurriculumElement(rootElement); + } + dbInstance.commit(); + curriculum = (CurriculumImpl)getCurriculum(curriculumRef); + curriculumDao.delete(curriculum); + dbInstance.commit(); + } + @Override public List<Curriculum> getCurriculums(Collection<? extends CurriculumRef> refs) { return curriculumDao.loadByKeys(refs); diff --git a/src/main/java/org/olat/modules/curriculum/ui/ConfirmCurriculumDeleteController.java b/src/main/java/org/olat/modules/curriculum/ui/ConfirmCurriculumDeleteController.java new file mode 100644 index 00000000000..cebd7316093 --- /dev/null +++ b/src/main/java/org/olat/modules/curriculum/ui/ConfirmCurriculumDeleteController.java @@ -0,0 +1,127 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.curriculum.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.elements.MultipleSelectionElement; +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.core.util.StringHelper; +import org.olat.modules.curriculum.CurriculumService; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 19 juil. 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class ConfirmCurriculumDeleteController extends FormBasicController { + + private static final String[] onKeys = new String[]{ "on" }; + + private FormLink deleteButton; + private MultipleSelectionElement acknowledgeEl; + + private final CurriculumRow rowToDelete; + + @Autowired + private CurriculumService curriculumService; + + public ConfirmCurriculumDeleteController(UserRequest ureq, WindowControl wControl, CurriculumRow rowToDelete) { + super(ureq, wControl, "confirm_delete_curriculum"); + this.rowToDelete = rowToDelete; + initForm(ureq); + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + if(formLayout instanceof FormLayoutContainer) { + String[] args = new String[] { + StringHelper.escapeHtml(rowToDelete.getDisplayName()), + Long.toString(rowToDelete.getNumOfElements()) + }; + String msg = translate("confirmation.delete.curriculum", args); + ((FormLayoutContainer)formLayout).contextPut("msg", msg); + } + + FormLayoutContainer layoutCont = FormLayoutContainer.createDefaultFormLayout("confirm", getTranslator()); + formLayout.add("confirm", layoutCont); + layoutCont.setRootForm(mainForm); + + uifactory.addStaticTextElement("curriculum.displayName", "curriculum.displayName", + StringHelper.escapeHtml(rowToDelete.getDisplayName()), layoutCont); + + String[] onValues = new String[]{ translate("delete.curriculum.acknowledge") }; + acknowledgeEl = uifactory.addCheckboxesHorizontal("acknowledge", "confirmation", layoutCont, onKeys, onValues); + + FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); + layoutCont.add(buttonsCont); + uifactory.addFormCancelButton("cancel", buttonsCont, ureq, getWindowControl()); + deleteButton = uifactory.addFormLink("delete", buttonsCont, Link.BUTTON); + } + + @Override + protected void doDispose() { + // + } + + @Override + protected boolean validateFormLogic(UserRequest ureq) { + boolean allOk = super.validateFormLogic(ureq); + + acknowledgeEl.clearError(); + if(!acknowledgeEl.isAtLeastSelected(1)) { + acknowledgeEl.setErrorKey("form.legende.mandatory", null); + allOk &= false; + } + + return allOk; + } + + @Override + protected void formOK(UserRequest ureq) { + // + } + + @Override + protected void formCancelled(UserRequest ureq) { + fireEvent(ureq, Event.CANCELLED_EVENT); + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(deleteButton == source) { + if(validateFormLogic(ureq)) { + curriculumService.deleteCurriculum(rowToDelete); + fireEvent(ureq, Event.DONE_EVENT); + } + } + super.formInnerEvent(ureq, source, event); + } +} diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java index 7aec2e708bb..de294f91f37 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java +++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListManagerController.java @@ -58,6 +58,7 @@ import org.olat.core.gui.media.MediaResource; import org.olat.core.id.Roles; 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.resource.OresHelper; import org.olat.modules.curriculum.Curriculum; import org.olat.modules.curriculum.CurriculumElementMembership; @@ -93,6 +94,7 @@ public class CurriculumListManagerController extends FormBasicController impleme private EditCurriculumController newCurriculumCtrl; private ImportCurriculumController importCurriculumCtrl; private EditCurriculumOverviewController editCurriculumCtrl; + private ConfirmCurriculumDeleteController deleteCurriculumCtrl; private CloseableCalloutWindowController toolsCalloutCtrl; private int counter = 0; @@ -254,7 +256,8 @@ public class CurriculumListManagerController extends FormBasicController impleme } cmc.deactivate(); cleanUp(); - } else if(editCurriculumCtrl == source || importCurriculumCtrl == source) { + } else if(editCurriculumCtrl == source || importCurriculumCtrl == source + || deleteCurriculumCtrl == source) { if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) { loadModel(tableEl.getQuickSearchString(), false); } @@ -268,9 +271,11 @@ public class CurriculumListManagerController extends FormBasicController impleme private void cleanUp() { removeAsListenerAndDispose(importCurriculumCtrl); + removeAsListenerAndDispose(deleteCurriculumCtrl); removeAsListenerAndDispose(newCurriculumCtrl); removeAsListenerAndDispose(cmc); importCurriculumCtrl = null; + deleteCurriculumCtrl = null; newCurriculumCtrl = null; cmc = null; } @@ -358,6 +363,23 @@ public class CurriculumListManagerController extends FormBasicController impleme } } + private void doDeleteCurriculum(UserRequest ureq, CurriculumRow row) { + removeAsListenerAndDispose(deleteCurriculumCtrl); + + Curriculum curriculum = curriculumService.getCurriculum(row); + if(curriculum == null) { + showWarning("warning.curriculum.deleted"); + } else { + deleteCurriculumCtrl = new ConfirmCurriculumDeleteController(ureq, getWindowControl(), row); + listenTo(deleteCurriculumCtrl); + + String title = translate("delete.curriculum.title", new String[] { StringHelper.escapeHtml(row.getDisplayName()) }); + cmc = new CloseableModalController(getWindowControl(), "close", deleteCurriculumCtrl.getInitialComponent(), true, title); + listenTo(cmc); + cmc.activate(); + } + } + private void doExportCurriculum(UserRequest ureq, CurriculumRow row) { Curriculum curriculum = curriculumService.getCurriculum(row); MediaResource mr = new ExportCurriculumMediaResource(curriculum); @@ -453,7 +475,7 @@ public class CurriculumListManagerController extends FormBasicController impleme doEditCurriculum(ureq, row); } else if(deleteLink == source) { close(); - showWarning("Not implemented"); + doDeleteCurriculum(ureq, row); } else if(exportLink == source) { close(); doExportCurriculum(ureq, row); diff --git a/src/main/java/org/olat/modules/curriculum/ui/_content/confirm_delete_curriculum.html b/src/main/java/org/olat/modules/curriculum/ui/_content/confirm_delete_curriculum.html new file mode 100644 index 00000000000..2e8fdedae59 --- /dev/null +++ b/src/main/java/org/olat/modules/curriculum/ui/_content/confirm_delete_curriculum.html @@ -0,0 +1,4 @@ +<div class="o_error"> + <p><i class="o_icon o_icon-lg o_icon_important"> </i> $msg</p> +</div> +$r.render("confirm") \ No newline at end of file diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties index ca81e116e4d..c0b4bf63024 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties @@ -16,9 +16,11 @@ confirm.remove.member.title=Mitglieder entfernen confirm.remove.member.text=Wollen Sie wirklich diese Mitglieder entfernen? confirm.remove.resource.title=Lernresourcen entfernen confirm.remove.resource.text=Wollen Sie wirklich diese Lernresourcen entfernen? +confirmation=Best\u00E4tigung confirmation.delete.type=Wollen Sie wirklich den Typ "{0}" l\u00F6schen? confirmation.delete.type.title=Typ "{0}" l\u00F6schen confirmation.delete.element=Wollen Sie wirklich dieses Curriculum Element "{0}" l\u00F6schen? +confirmation.delete.curriculum=Wollen Sie wirklich dieses Curriculum "{0}" l\u00F6schen? Er enth\u00E4lt <strong>{1} Elementen</strong>. confirmation.delete.element.title=Curriculum Element "{0}" l\u00F6schen copy.element=Element kopieren copy.element.title=Element "{0}" kopieren @@ -53,6 +55,8 @@ curriculum.key=ID curriculum.metadata=Metadaten curriculum.organisation=Organisation curriculum.search=Suchen +delete.curriculum.acknowledge=Ich verstehe, dass das Curriculum und alle seine Elementen werden definitive gel\u00F6scht. +delete.curriculum.title=Curriculum "{0}" l\u00F6schen details=Infoseite details.copy=Kopieren details.delete=L\u00F6schen diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties index fdad3d3de55..543913620d4 100644 --- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_en.properties @@ -16,6 +16,8 @@ confirm.remove.member.text=Do you really want to remove this member(s)? confirm.remove.member.title=Remove member confirm.remove.resource.text=Do you really want to remove this learn resource(s)? confirm.remove.resource.title=Remove learn resources +confirmation=Confirmation +confirmation.delete.curriculum=Do you really want to delete this curriculum "{0}"? It contains <strong>{1} elements</strong>. confirmation.delete.element=Do you really want to delete this curriculum element "{0}"? confirmation.delete.element.title=Delete curriculum element "{0}" confirmation.delete.type=Do you really want to delete this type "{0}"? @@ -53,6 +55,8 @@ curriculum.key=ID curriculum.metadata=Metadata curriculum.organisation=Organisation curriculum.search=Search +delete.binder.acknowledge=I understand that the curriculum and all its elements will be definitely deleted. +delete.curriculum.title=Delete curriculum "{0}" details=Info page details.copy=Copy details.delete=Delete diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties index 7bf718c0d54..f40e2186857 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties @@ -144,7 +144,7 @@ delete.assignment.in.use.confirm.descr=$\:delete.assignment.confirm.descr <div c delete.assignment.template.confirm.descr=Do you really want to delete this template "{0}"? delete.assignment.template.confirm.title=Delete template delete.binder=Delete binder -delete.binder.acknowledge=I understand that the binder and all its entries will be definetly deleted. +delete.binder.acknowledge=I understand that the binder and all its entries will be definitely deleted. delete.binder.acknowledge.2=I understand that the binder cannot be restored again. delete.binder.success=Binder is successfully deleted. delete.binder.warning=Do you really want to delete the binder "{0}"? It contains <strong>{1}</strong> sections, <strong>{2}</strong> entries and <strong>{3}</strong> comments. -- GitLab