/**
* <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.admin.landingpages.ui;
import static org.olat.admin.landingpages.model.Rule.ADMIN;
import static org.olat.admin.landingpages.model.Rule.AUTHOR;
import static org.olat.admin.landingpages.model.Rule.GROUP_MGR;
import static org.olat.admin.landingpages.model.Rule.POOL_MGR;
import static org.olat.admin.landingpages.model.Rule.RSRC_MGR;
import static org.olat.admin.landingpages.model.Rule.USER_MGR;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.olat.admin.landingpages.LandingPagesModule;
import org.olat.admin.landingpages.model.Rule;
import org.olat.admin.landingpages.model.Rules;
import org.olat.admin.landingpages.ui.RulesDataModel.RCols;
import org.olat.basesecurity.BaseSecurityModule;
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.elements.SingleSelection;
import org.olat.core.gui.components.form.flexible.elements.TextElement;
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.FormSubmit;
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.FlexiTableDataModelFactory;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableRendererType;
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.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.util.Util;
import org.olat.user.UserManager;
import org.olat.user.propertyhandlers.UserPropertyHandler;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 15.05.2014<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class LandingPagesAdminController extends FormBasicController {
private static final String USER_PROPS_ID = LandingPagesModule.class.getName();
private RulesDataModel model;
private FlexiTableElement tableEl;
private static final String[] roleKeys = new String[]{ "none",
AUTHOR, USER_MGR, GROUP_MGR, RSRC_MGR, POOL_MGR, ADMIN
};
private final String[] roleValues;
private final String[] attrKeys;
private final String[] attrValues;
private FormSubmit saveButton;
private ChooserController chooserCtrl;
private CloseableCalloutWindowController chooserCalloutCtrl;
@Autowired
private UserManager userManager;
@Autowired
private LandingPagesModule lpModule;
@Autowired
private BaseSecurityModule securityModule;
private AtomicInteger counter = new AtomicInteger();
public LandingPagesAdminController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl, "rules");
setTranslator(Util.createPackageTranslator(UserPropertyHandler.class, getLocale(), getTranslator()));
roleValues = new String[roleKeys.length];
for(int i=0; i<roleKeys.length; i++) {
roleValues[i] = translate(roleKeys[i]);
}
boolean isAdministrativeUser = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles());
List<UserPropertyHandler> userPropertyHandlers = userManager
.getUserPropertyHandlersFor(USER_PROPS_ID, isAdministrativeUser);
int numOfProperties = userPropertyHandlers.size();
attrKeys = new String[numOfProperties + 1];
attrValues = new String[numOfProperties + 1];
attrKeys[0] = "";
attrValues[0] = "-";
for(int i=0; i<numOfProperties; i++) {
UserPropertyHandler handler = userPropertyHandlers.get(i);
attrKeys[i+1] = handler.getName();
attrValues[i+1] = translate(handler.i18nFormElementLabelKey());
}
initForm(ureq);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
setFormTitle("landingpages.title");
//add the table
FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RCols.position.i18nKey(), RCols.position.ordinal()));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RCols.role.i18nKey(), RCols.role.ordinal()));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RCols.userAttributeKey.i18nKey(), RCols.userAttributeKey.ordinal()));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RCols.userAttributeValue.i18nKey(), RCols.userAttributeValue.ordinal()));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RCols.landingPage.i18nKey(), RCols.landingPage.ordinal()));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RCols.landingPageChooser.i18nKey(), RCols.landingPageChooser.ordinal()));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("up", -1, "up",
new StaticFlexiCellRenderer("", "up", "o_icon o_icon-lg o_icon_move_up",translate("up"))));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("down", -1, "down",
new StaticFlexiCellRenderer("", "down", "o_icon o_icon-lg o_icon_move_down", translate("down"))));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("add", translate("add"), "add"));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("delete", translate("delete"), "delete"));
//pack the rules
Rules rules = lpModule.getRules();
List<Rule> ruleList = new ArrayList<>(rules.getRules());
if(ruleList.isEmpty()) {
ruleList.add(new Rule());
}
List<RuleWrapper> wrappers = new ArrayList<>();
int i = 0;
for(Rule rule:ruleList) {
wrappers.add(initRuleWrapper(++i, rule, formLayout));
}
if(formLayout instanceof FormLayoutContainer) {
FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout;
layoutCont.contextPut("rules", wrappers);
}
model = new RulesDataModel(columnsModel, wrappers);
tableEl = uifactory.addTableElement(getWindowControl(), "rules", model, getTranslator(), formLayout);
tableEl.setCustomizeColumns(false);
tableEl.setRendererType(FlexiTableRendererType.classic);
FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
formLayout.add("buttons", buttonLayout);
saveButton = uifactory.addFormSubmitButton("save", buttonLayout);
}
@Override
protected void doDispose() {
//
}
private RuleWrapper initRuleWrapper(int pos, Rule rule, FormItemContainer formLayout) {
int i = counter.incrementAndGet();
RuleWrapper wrapper = new RuleWrapper(rule);
wrapper.setPosition(pos);
SingleSelection roleEl = uifactory.addDropdownSingleselect("role-" + i, null, formLayout, roleKeys, roleValues, null);
String role = rule.getRole();
for(int j=roleKeys.length; j-->0; ) {
if(roleKeys[j].equals(role)) {
roleEl.select(roleKeys[j], true);
}
}
wrapper.setRoleEl(roleEl);
SingleSelection attrNameEl = uifactory.addDropdownSingleselect("attr-key-" + i, null, formLayout, attrKeys, attrValues, null);
String userAttributeKey = rule.getUserAttributeKey();
for(int j=attrKeys.length; j-->0; ) {
if(attrKeys[j].equals(userAttributeKey)) {
attrNameEl.select(attrKeys[j], true);
}
}
wrapper.setAttrNameEl(attrNameEl);
TextElement valEl = uifactory.addTextElement("attr-val-" + i, null, 256, "", formLayout);
valEl.setValue(rule.getUserAttributeValue());
wrapper.setAttrValueEl(valEl);
TextElement landingPageEl = uifactory.addTextElement("l-page-" + i, null, 256, "", formLayout);
landingPageEl.setValue(rule.getLandingPath());
wrapper.setLandingPageEl(landingPageEl);
formLayout.add(landingPageEl);
FormLink chooser = uifactory.addFormLink("chooser-" + i, "chooser", RCols.landingPageChooser.i18nKey(), null, formLayout, Link.BUTTON);
chooser.setIconRightCSS("o_icon o_icon_caret");
chooser.setUserObject(wrapper);
wrapper.setLandingPageChooser(chooser);
return wrapper;
}
@Override
protected void formOK(UserRequest ureq) {
int rowCount = model.getRowCount();
List<Rule> ruleList = new ArrayList<Rule>(rowCount);
for(int i=0; i<rowCount; i++) {
ruleList.add(model.getObject(i).save());
}
Rules rules = new Rules();
rules.setRules(ruleList);
lpModule.setRules(rules);
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if(source == tableEl) {
if(event instanceof SelectionEvent) {
SelectionEvent se = (SelectionEvent)event;
RuleWrapper row = model.getObject(se.getIndex());
if("up".equals(se.getCommand())) {
moveUp(row);
} else if("down".equals(se.getCommand())) {
moveDown(row);
} else if("add".equals(se.getCommand())) {
addRow(row);
} else if("delete".equals(se.getCommand())) {
deleteRow(row);
}
tableEl.reset();
tableEl.getComponent().setDirty(true);
}
} else if(source instanceof FormLink && source.getUserObject() instanceof RuleWrapper) {
RuleWrapper rule = (RuleWrapper)source.getUserObject();
String cmd = ((FormLink)source).getCmd();
if("chooser".equals(cmd)) {
FormLink link = (FormLink)source;
openChooser(ureq, rule, link);
}
saveButton.getComponent().setDirty(false);
source.getComponent().setDirty(false);
tableEl.getComponent().setDirty(false);
flc.setDirty(false);
}
super.formInnerEvent(ureq, source, event);
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(chooserCtrl == source) {
if(event == Event.DONE_EVENT) {
LandingPages lp = chooserCtrl.getSelectedLandingPage();
RuleWrapper rule = chooserCtrl.getRow();
if(lp != null) {
rule.getLandingPageEl().setValue(lp.businessPath());
saveButton.getComponent().setDirty(true);
}
}
chooserCalloutCtrl.deactivate();
cleanUp();
}
super.event(ureq, source, event);
}
private void cleanUp() {
removeAsListenerAndDispose(chooserCtrl);
removeAsListenerAndDispose(chooserCalloutCtrl);
chooserCtrl = null;
chooserCalloutCtrl = null;
}
private void openChooser(UserRequest ureq, RuleWrapper row, FormLink link) {
removeAsListenerAndDispose(chooserCtrl);
removeAsListenerAndDispose(chooserCalloutCtrl);
chooserCtrl = new ChooserController(ureq, getWindowControl(), row);
listenTo(chooserCtrl);
chooserCalloutCtrl = new CloseableCalloutWindowController(ureq, getWindowControl(),
chooserCtrl.getInitialComponent(), link.getFormDispatchId(), "", true, "");
listenTo(chooserCalloutCtrl);
chooserCalloutCtrl.activate();
}
private void addRow(RuleWrapper row) {
List<RuleWrapper> rows = model.getObjects();
int currentIndex = rows.indexOf(row);
RuleWrapper newRule = initRuleWrapper(1, new Rule(), flc);
if(currentIndex >= 0 && currentIndex < rows.size() - 1) {
rows.add(currentIndex + 1, newRule);
} else {
rows.add(newRule);
}
model.setObjects(reOrder(rows));
}
private void deleteRow(RuleWrapper row) {
List<RuleWrapper> rows = model.getObjects();
rows.remove(row);
if(rows.isEmpty()) {
Rule rule = new Rule();
rows.add(initRuleWrapper(1, rule, flc));
}
model.setObjects(reOrder(rows));
}
private void moveUp(RuleWrapper row) {
List<RuleWrapper> rows = model.getObjects();
int currentIndex = rows.indexOf(row);
if(currentIndex > 0) {
rows.remove(currentIndex);
rows.add(currentIndex - 1, row);
}
model.setObjects(reOrder(rows));
}
private void moveDown(RuleWrapper row) {
List<RuleWrapper> rows = model.getObjects();
int currentIndex = rows.indexOf(row);
if(currentIndex >= 0 && currentIndex + 1 < rows.size()) {
rows.remove(currentIndex);
rows.add(currentIndex + 1, row);
}
model.setObjects(reOrder(rows));
}
private List<RuleWrapper> reOrder(List<RuleWrapper> rows) {
int i=0;
for(RuleWrapper row:rows) {
row.setPosition(++i);
}
return rows;
}
private class ChooserController extends BasicController {
private final RuleWrapper row;
private LandingPages selectedLandingPage;
public ChooserController(UserRequest ureq, WindowControl wControl, RuleWrapper row) {
super(ureq, wControl);
this.row = row;
VelocityContainer mainVC = createVelocityContainer("chooser");
int i = counter.incrementAndGet();
List<String> links = new ArrayList<>();
for(LandingPages lp:LandingPages.values()) {
String name = lp.name() + "-" + i;
Link link = LinkFactory.createLink(name, lp.name(), getTranslator(), mainVC, this, Link.LINK | Link.NONTRANSLATED);
link.setCustomDisplayText(translate(lp.i18nKey()));
link.setUserObject(lp);
mainVC.put(name, link);
links.add(name);
}
mainVC.contextPut("links", links);
putInitialPanel(mainVC);
}
public RuleWrapper getRow() {
return row;
}
public LandingPages getSelectedLandingPage() {
return selectedLandingPage;
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
if(source instanceof Link) {
Link link = (Link)source;
if(link.getUserObject() instanceof LandingPages) {
selectedLandingPage = (LandingPages)link.getUserObject();
}
}
fireEvent(ureq, Event.DONE_EVENT);
}
@Override
protected void doDispose() {
//
}
}
}