/**
* <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.course.nodes.pf.ui;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.olat.basesecurity.BaseSecurity;
import org.olat.basesecurity.BaseSecurityModule;
import org.olat.core.commons.services.notifications.PublisherData;
import org.olat.core.commons.services.notifications.SubscriptionContext;
import org.olat.core.commons.services.notifications.ui.ContextualSubscriptionController;
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.FlexiTableElement;
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.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent;
import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlexiCellRenderer;
import org.olat.core.gui.components.form.flexible.impl.elements.table.TextFlexiCellRenderer;
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.ControllerEventListener;
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.id.Identity;
import org.olat.core.id.Roles;
import org.olat.core.id.UserConstants;
import org.olat.core.util.resource.OresHelper;
import org.olat.course.nodes.PFCourseNode;
import org.olat.course.nodes.TitledWrapperHelper;
import org.olat.course.nodes.pf.manager.PFManager;
import org.olat.course.nodes.pf.manager.PFView;
import org.olat.course.nodes.pf.ui.DropBoxTableModel.DropBoxCols;
import org.olat.course.run.environment.CourseEnvironment;
import org.olat.course.run.navigation.NodeRunConstructionResult;
import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.resource.OLATResource;
import org.olat.user.HomePageConfig;
import org.olat.user.HomePageDisplayController;
import org.olat.user.UserManager;
import org.olat.user.UserPropertiesRow;
import org.olat.user.propertyhandlers.UserPropertyHandler;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* @author Fabian Kiefer, fabian.kiefer@frentix.com, http://www.frentix.com
*
*/
public class PFCoachController extends FormBasicController implements ControllerEventListener {
protected static final String USER_PROPS_ID = PFCoachController.class.getCanonicalName();
protected static final int USER_PROPS_OFFSET = 500;
private PFCourseNode pfNode;
private FormLink downloadLink, uploadLink, uploadAllLink;
private Link backLink;
private DropBoxTableModel tableModel;
private FlexiTableElement dropboxTable;
private VelocityContainer mainVC;
private CloseableModalController cmc;
private PFFileUploadController pfFileUploadCtr;
private PFParticipantController pfParticipantController;
private HomePageDisplayController homePageDisplayController;
private ContextualSubscriptionController contextualSubscriptionCtr;
private final List<UserPropertyHandler> userPropertyHandlers;
private final boolean isAdministrativeUser;
private UserCourseEnvironment userCourseEnv;
private CourseEnvironment courseEnv;
private Identity identity;
private PFView pfView;
@Autowired
private PFManager pfManager;
@Autowired
private UserManager userManager;
@Autowired
private BaseSecurityModule securityModule;
@Autowired
private BaseSecurity securityManager;
public PFCoachController(UserRequest ureq, WindowControl wControl, PFCourseNode sfNode,
UserCourseEnvironment userCourseEnv, PFView pfView) {
super(ureq, wControl, "coach");
this.userCourseEnv = userCourseEnv;
this.courseEnv = userCourseEnv.getCourseEnvironment();
this.pfNode = sfNode;
this.identity = ureq.getIdentity();
this.pfView = pfView;
Roles roles = ureq.getUserSession().getRoles();
isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles);
userPropertyHandlers = userManager.getUserPropertyHandlersFor(USER_PROPS_ID, isAdministrativeUser);
setTranslator(userManager.getPropertyHandlerTranslator(getTranslator()));
initForm(ureq);
}
@Override
public void event(UserRequest ureq, Component source, Event event) {
if (source == backLink) {
back();
}
super.event(ureq, source, event);
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if (source == pfFileUploadCtr) {
if (event == Event.DONE_EVENT) {
if (pfFileUploadCtr.isUploadToAll()) {
uploadToSelection(pfFileUploadCtr.getUpLoadFile(), pfFileUploadCtr.getUploadFileName());
showInfo("upload.success");
fireEvent(ureq, Event.CHANGED_EVENT);
} else {
pfManager.uploadFileToDropBox(pfFileUploadCtr.getUpLoadFile(),
pfFileUploadCtr.getUploadFileName(), 4, courseEnv, pfNode, identity);
}
cmc.deactivate();
cleanUpCMC();
}
} else if (source == cmc) {
cleanUpCMC();
}
super.event(ureq, source, event);
}
@Override
protected void doDispose() {
// nothing to dispose
}
public NodeRunConstructionResult createNodeRunConstructionResult(UserRequest ureq) {
// integrate it into the olat menu
Controller ctrl = TitledWrapperHelper.getWrapper(ureq, getWindowControl(), this, pfNode, "o_pf_icon");
return new NodeRunConstructionResult(ctrl);
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if (source == uploadLink) {
doOpenUploadController(ureq, false);
} else if (source == uploadAllLink) {
if (dropboxTable.getMultiSelectedIndex().size() > 0) {
doOpenUploadController(ureq, true);
} else {
showWarning("table.no.selection");
}
} else if (source == downloadLink) {
if (dropboxTable.getMultiSelectedIndex().size() > 0) {
downloadFromSelection(ureq);
} else {
showWarning("table.no.selection");
}
} else if(source == dropboxTable) {
if(event instanceof SelectionEvent) {
SelectionEvent se = (SelectionEvent)event;
DropBoxRow currentObject = (DropBoxRow) tableModel.getObject(se.getIndex());
if ("drop.box".equals(se.getCommand())){
doSelectParticipantFolder (ureq, currentObject.getIdentity(), PFView.displayDrop);
} else if ("return.box".equals(se.getCommand())){
doSelectParticipantFolder (ureq, currentObject.getIdentity(), PFView.displayReturn);
} else if ("open.box".equals(se.getCommand())){
doSelectParticipantFolder (ureq, currentObject.getIdentity(), PFView.dropAndReturn);
} else if ("firstName".equals(se.getCommand()) || "lastName".equals(se.getCommand())) {
doOpenHomePage(ureq, currentObject.getIdentity());
}
}
}
}
private void doSelectParticipantFolder (UserRequest ureq, UserPropertiesRow row, PFView pfView) {
Identity identity = securityManager.loadIdentityByKey(row.getIdentityKey());
removeAsListenerAndDispose(pfParticipantController);
pfParticipantController = new PFParticipantController(ureq, getWindowControl(), pfNode,
userCourseEnv, identity, pfView, true, false);
listenTo(pfParticipantController);
mainVC.put("single", pfParticipantController.getInitialComponent());
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
mainVC = ((FormLayoutContainer) formLayout).getFormItemComponent();
OLATResource course = courseEnv.getCourseGroupManager().getCourseResource();
String businessPath = getWindowControl().getBusinessControl().getAsString();
SubscriptionContext subsContext = new SubscriptionContext(course, pfNode.getIdent());
PublisherData publisherData = new PublisherData(OresHelper.calculateTypeName(PFCourseNode.class),
String.valueOf(course.getResourceableId()), businessPath);
contextualSubscriptionCtr = new ContextualSubscriptionController(ureq, getWindowControl(), subsContext,
publisherData);
listenTo(contextualSubscriptionCtr);
mainVC.put("contextualSubscription", contextualSubscriptionCtr.getInitialComponent());
backLink = LinkFactory.createLinkBack(mainVC, this);
FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
int i = 0;
for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) {
int colIndex = USER_PROPS_OFFSET + i++;
if (userPropertyHandler == null) continue;
String propName = userPropertyHandler.getName();
boolean visible = userManager.isMandatoryUserProperty(USER_PROPS_ID , userPropertyHandler);
FlexiColumnModel col;
if(UserConstants.FIRSTNAME.equals(propName)
|| UserConstants.LASTNAME.equals(propName)) {
col = new DefaultFlexiColumnModel(userPropertyHandler.i18nColumnDescriptorLabelKey(),
colIndex, userPropertyHandler.getName(), true, propName,
new StaticFlexiCellRenderer(userPropertyHandler.getName(), new TextFlexiCellRenderer()));
} else {
col = new DefaultFlexiColumnModel(visible, userPropertyHandler.i18nColumnDescriptorLabelKey(), colIndex, true, propName);
}
columnsModel.addFlexiColumnModel(col);
}
if (pfNode.hasParticipantBoxConfigured()){
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DropBoxCols.numberFiles,"drop.box"));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DropBoxCols.lastUpdate));
}
if (pfNode.hasCoachBoxConfigured()) {
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DropBoxCols.numberFilesReturn,"return.box"));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DropBoxCols.lastUpdateReturn));
}
StaticFlexiCellRenderer openCellRenderer = new StaticFlexiCellRenderer(translate("open.box"), "open.box");
openCellRenderer.setIconRightCSS("o_icon_start o_icon-fw");
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DropBoxCols.openbox,
"open.box", openCellRenderer));
tableModel = new DropBoxTableModel(columnsModel, getTranslator());
dropboxTable = uifactory.addTableElement(getWindowControl(), "table", tableModel, getTranslator(), formLayout);
dropboxTable.setMultiSelect(true);
dropboxTable.setSelectAllEnable(true);
dropboxTable.setExportEnabled(true);
dropboxTable.setAndLoadPersistedPreferences(ureq, this.getClass().getName() + "_" + pfView.name());
dropboxTable.setEmtpyTableMessageKey("table.empty");
tableModel.setObjects(pfManager.getParticipants(identity, pfNode, userPropertyHandlers, getLocale(), courseEnv, userCourseEnv.isAdmin()));
mainVC.contextPut("hasParticipants", tableModel.getRowCount() > 0);
FormLayoutContainer buttonGroupLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
buttonGroupLayout.setElementCssClass("o_button_group");
formLayout.add(buttonGroupLayout);
downloadLink = uifactory.addFormLink("download.link", buttonGroupLayout, Link.BUTTON);
uploadAllLink = uifactory.addFormLink("upload.link", buttonGroupLayout, Link.BUTTON);
}
private void uploadToSelection (File uploadFile, String fileName) {
List<Long> identitykeys = new ArrayList<>();
for (int i : dropboxTable.getMultiSelectedIndex()) {
identitykeys.add(tableModel.getObject(i).getIdentity().getIdentityKey());
}
List<Identity> identities = securityManager.loadIdentityByKeys(identitykeys);
pfManager.uploadFileToAllReturnBoxes(uploadFile, fileName, courseEnv, pfNode, identities);
}
private void downloadFromSelection (UserRequest ureq) {
List<Long> identitykeys = new ArrayList<>();
for (int i : dropboxTable.getMultiSelectedIndex()) {
identitykeys.add(tableModel.getObject(i).getIdentity().getIdentityKey());
}
List<Identity> identities = securityManager.loadIdentityByKeys(identitykeys);
pfManager.exportMediaResource(ureq, identities, pfNode, courseEnv);
}
@Override
protected void formOK(UserRequest ureq) {
}
private void doOpenUploadController (UserRequest ureq, boolean uploadToAll) {
pfFileUploadCtr = new PFFileUploadController(ureq, getWindowControl(), uploadToAll);
listenTo(pfFileUploadCtr);
cmc = new CloseableModalController(getWindowControl(), translate("close"),
pfFileUploadCtr.getInitialComponent(), true, translate("upload.link"));
listenTo(cmc);
cmc.activate();
}
private void doOpenHomePage (UserRequest ureq, UserPropertiesRow row) {
Identity identity = securityManager.loadIdentityByKey(row.getIdentityKey());
homePageDisplayController = new HomePageDisplayController(ureq, getWindowControl(), identity, new HomePageConfig());
listenTo(homePageDisplayController);
cmc = new CloseableModalController(getWindowControl(), translate("close"),
homePageDisplayController.getInitialComponent(), true, translate("upload.link"));
listenTo(cmc);
cmc.activate();
}
private void cleanUpCMC(){
removeAsListenerAndDispose(cmc);
removeAsListenerAndDispose(pfFileUploadCtr);
cmc = null;
pfFileUploadCtr = null;
}
private void back() {
if(pfParticipantController != null) {
mainVC.remove(pfParticipantController.getInitialComponent());
removeAsListenerAndDispose(pfParticipantController);
pfParticipantController = null;
}
}
}