/** * <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.repository.ui.author; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.olat.basesecurity.GroupRoles; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; 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.FormEvent; import org.olat.core.gui.components.form.flexible.impl.elements.table.DateFlexiCellRenderer; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlexiCellRenderer; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.closablewrapper.CloseableCalloutWindowController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.course.CourseModule; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryManagedFlag; import org.olat.repository.handlers.RepositoryHandler; import org.olat.repository.model.SearchAuthorRepositoryEntryViewParams; import org.olat.repository.model.SearchAuthorRepositoryEntryViewParams.OrderBy; import org.olat.repository.ui.author.AuthoringEntryDataModel.Cols; /** * * Initial date: 1 déc. 2016<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ public class AuthorDeletedListController extends AuthorListController { private DToolsController dToolsCtrl; private FormLink restoreButton, deletePermanentlyButton; private ConfirmRestoreController confirmRestoreCtrl; private ConfirmDeletePermanentlyController confirmDeletePermanentlyCtrl; public AuthorDeletedListController(UserRequest ureq, WindowControl wControl, String i18nName, SearchAuthorRepositoryEntryViewParams searchParams, boolean withSearch) { super(ureq, wControl, i18nName, searchParams, withSearch); } @Override protected void initTools() { // } @Override protected void initActionsColumns(FlexiTableColumnModel columnsModel) { columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.deletedBy.i18nKey(), Cols.deletedBy.ordinal(), true, OrderBy.deletedBy.name())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.deletionDate.i18nKey(), Cols.deletionDate.ordinal(), true, OrderBy.deletionDate.name(), new DateFlexiCellRenderer(getLocale()))); DefaultFlexiColumnModel detailsColumn = new DefaultFlexiColumnModel(Cols.detailsSupported.i18nKey(), Cols.detailsSupported.ordinal(), "details", new StaticFlexiCellRenderer("", "details", "o_icon o_icon-lg o_icon_details", translate("details"))); detailsColumn.setExportable(false); columnsModel.addFlexiColumnModel(detailsColumn); if(hasAuthorRight) { DefaultFlexiColumnModel toolsColumn = new DefaultFlexiColumnModel(Cols.tools.i18nKey(), Cols.tools.ordinal()); toolsColumn.setExportable(false); columnsModel.addFlexiColumnModel(toolsColumn); } } @Override protected void initBatchButtons(FormItemContainer formLayout) { restoreButton = uifactory.addFormLink("tools.restore", formLayout, Link.BUTTON); if(isOlatAdmin) { deletePermanentlyButton = uifactory.addFormLink("tools.delete.permanently", formLayout, Link.BUTTON); } } @Override protected void event(UserRequest ureq, Controller source, Event event) { if(confirmDeletePermanentlyCtrl == source) { cmc.deactivate(); if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) { reloadRows(); } cleanUp(); } else if(confirmRestoreCtrl == source) { if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) { if(cmc != null) { cmc.deactivate(); } reloadRows(); cleanUp(); } else if(event == Event.CANCELLED_EVENT) { if(cmc != null) { cmc.deactivate(); } cleanUp(); } } else if(dToolsCtrl == source) { if(event == Event.DONE_EVENT) { toolsCalloutCtrl.deactivate(); cleanUp(); } } super.event(ureq, source, event); } @Override protected void cleanUp() { removeAsListenerAndDispose(confirmDeletePermanentlyCtrl); removeAsListenerAndDispose(confirmRestoreCtrl); confirmDeletePermanentlyCtrl = null; confirmRestoreCtrl = null; super.cleanUp(); } @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(restoreButton == source) { List<AuthoringEntryRow> rows = getMultiSelectedRows(); if(!rows.isEmpty()) { doRestore(ureq, rows); } else { showWarning("bulk.update.nothing.selected"); } } else if(deletePermanentlyButton == source) { List<AuthoringEntryRow> rows = getMultiSelectedRows(); if(!rows.isEmpty()) { doDeletePermanently(ureq, rows); } else { showWarning("bulk.update.nothing.selected"); } } else if(source instanceof FormLink) { FormLink link = (FormLink)source; String cmd = link.getCmd(); if("tools".equals(cmd)) { AuthoringEntryRow row = (AuthoringEntryRow)link.getUserObject(); doOpenTools(ureq, row, link); return;// override the event } } super.formInnerEvent(ureq, source, event); } private void doOpenTools(UserRequest ureq, AuthoringEntryRow row, FormLink link) { removeAsListenerAndDispose(dToolsCtrl); removeAsListenerAndDispose(toolsCalloutCtrl); RepositoryEntry entry = repositoryService.loadByKey(row.getKey()); if(entry == null) { tableEl.reloadData(); showWarning("repositoryentry.not.existing"); } else { dToolsCtrl = new DToolsController(ureq, getWindowControl(), row, entry); listenTo(dToolsCtrl); toolsCalloutCtrl = new CloseableCalloutWindowController(ureq, getWindowControl(), dToolsCtrl.getInitialComponent(), link.getFormDispatchId(), "", true, ""); listenTo(toolsCalloutCtrl); toolsCalloutCtrl.activate(); } } private void doRestore(UserRequest ureq, List<AuthoringEntryRow> rows) { Roles roles = ureq.getUserSession().getRoles(); List<Long> deleteableRowKeys = new ArrayList<>(rows.size()); for(AuthoringEntryRow row:rows) { boolean managed = RepositoryEntryManagedFlag.isManaged(row.getManagedFlags(), RepositoryEntryManagedFlag.delete); boolean canDelete = roles.isOLATAdmin() || repositoryService.hasRole(getIdentity(), row, GroupRoles.owner.name()) || repositoryManager.isInstitutionalRessourceManagerFor(getIdentity(), roles, row); if(canDelete && !managed) { deleteableRowKeys.add(row.getKey()); } } List<RepositoryEntry> entriesToRestore = repositoryManager.lookupRepositoryEntries(deleteableRowKeys); if(entriesToRestore.isEmpty()) { showWarning("bulk.update.nothing.applicable.selected"); } else { removeAsListenerAndDispose(confirmRestoreCtrl); removeAsListenerAndDispose(cmc); confirmRestoreCtrl = new ConfirmRestoreController(ureq, getWindowControl(), entriesToRestore); listenTo(confirmRestoreCtrl); String title = translate("tools.restore"); cmc = new CloseableModalController(getWindowControl(), translate("close"), confirmRestoreCtrl.getInitialComponent(), true, title); listenTo(cmc); cmc.activate(); } } private void doDeletePermanently(UserRequest ureq, List<AuthoringEntryRow> rows) { Roles roles = ureq.getUserSession().getRoles(); List<Long> deleteableRowKeys = new ArrayList<>(rows.size()); for(AuthoringEntryRow row:rows) { boolean managed = RepositoryEntryManagedFlag.isManaged(row.getManagedFlags(), RepositoryEntryManagedFlag.delete); boolean canDelete = roles.isOLATAdmin() || repositoryManager.isInstitutionalRessourceManagerFor(getIdentity(), roles, row); if(canDelete && !managed) { deleteableRowKeys.add(row.getKey()); } } List<RepositoryEntry> entriesToDelete = repositoryManager.lookupRepositoryEntries(deleteableRowKeys); if(entriesToDelete.isEmpty()) { showWarning("bulk.update.nothing.applicable.selected"); } else { removeAsListenerAndDispose(confirmDeletePermanentlyCtrl); removeAsListenerAndDispose(cmc); confirmDeletePermanentlyCtrl = new ConfirmDeletePermanentlyController(ureq, getWindowControl(), entriesToDelete, rows.size() != entriesToDelete.size()); listenTo(confirmDeletePermanentlyCtrl); String title = translate("details.delete"); cmc = new CloseableModalController(getWindowControl(), translate("close"), confirmDeletePermanentlyCtrl.getInitialComponent(), true, title); listenTo(cmc); cmc.activate(); } } private class DToolsController extends BasicController { private final AuthoringEntryRow row; private final VelocityContainer mainVC; private boolean isOwner; private boolean isAuthor; public DToolsController(UserRequest ureq, WindowControl wControl, AuthoringEntryRow row, RepositoryEntry entry) { super(ureq, wControl); setTranslator(AuthorDeletedListController.this.getTranslator()); this.row = row; Identity identity = getIdentity(); Roles roles = ureq.getUserSession().getRoles(); boolean isInstitutionalResourceManager = !roles.isGuestOnly() && repositoryManager.isInstitutionalRessourceManagerFor(identity, roles, entry); isOwner = isOlatAdmin || repositoryService.hasRole(identity, entry, GroupRoles.owner.name()) || isInstitutionalResourceManager; isAuthor = isOlatAdmin || roles.isAuthor() || isInstitutionalResourceManager; RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler(entry); mainVC = createVelocityContainer("tools"); List<String> links = new ArrayList<>(); boolean copyManaged = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.copy); boolean canCopy = (isAuthor || isOwner) && (entry.getCanCopy() || isOwner) && !copyManaged; boolean canDownload = entry.getCanDownload() && handler.supportsDownload(); // disable download for courses if not author or owner if (entry.getOlatResource().getResourceableTypeName().equals(CourseModule.getCourseTypeName()) && !(isOwner || isAuthor)) { canDownload = false; } // always enable download for owners if (isOwner && handler.supportsDownload()) { canDownload = true; } if(canCopy || canDownload) { if (canCopy) { addLink("details.copy", "copy", "o_icon o_icon-fw o_icon_copy", links); } if(canDownload) { addLink("details.download", "download", "o_icon o_icon-fw o_icon_download", links); } } if(isOwner) { addLink("tools.restore", "restore", "o_icon o_icon-fw o_icon_restore", links); } if(isOlatAdmin && !RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.delete)) { addLink("details.delete", "delete", "o_icon o_icon-fw o_icon_delete_item", links); } mainVC.contextPut("links", links); putInitialPanel(mainVC); } private void addLink(String name, String cmd, String iconCSS, List<String> links) { Link link = LinkFactory.createLink(name, cmd, getTranslator(), mainVC, this, Link.LINK); if(iconCSS != null) { link.setIconLeftCSS(iconCSS); } mainVC.put(name, link); links.add(name); } @Override protected void event(UserRequest ureq, Component source, Event event) { fireEvent(ureq, Event.DONE_EVENT); if(source instanceof Link) { Link link = (Link)source; String cmd = link.getCommand(); if("copy".equals(cmd)) { doCopy(ureq, row); } else if("download".equals(cmd)) { doDownload(ureq, row); } else if("restore".equals(cmd)) { doRestore(ureq, Collections.singletonList(row)); } else if("delete".equals(cmd)) { doDeletePermanently(ureq, Collections.singletonList(row)); } } } @Override protected void doDispose() { // } } }