Author: fdesbois Date: 2010-06-21 10:42:04 +0000 (Mon, 21 Jun 2010) New Revision: 555 Log: - Evo #2247 : Add option style for inactive users. Need javascript to manage manually the select input. - Remove zoneUpdater mixin (already exists in nuiton-web) Added: trunk/wao-ui/src/main/webapp/js/AdminUserSelect.js Removed: trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/mixins/ZoneUpdater.java trunk/wao-ui/src/main/webapp/js/ZoneUpdater.js Modified: trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/pages/Administration.java trunk/wao-ui/src/main/webapp/Administration.tml Deleted: trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/mixins/ZoneUpdater.java =================================================================== --- trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/mixins/ZoneUpdater.java 2010-06-21 09:23:28 UTC (rev 554) +++ trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/mixins/ZoneUpdater.java 2010-06-21 10:42:04 UTC (rev 555) @@ -1,102 +0,0 @@ -/* - * #%L - * Wao :: Web Interface - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2010 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ -package fr.ifremer.wao.ui.mixins; - -import org.apache.commons.lang.ArrayUtils; -import org.apache.tapestry5.BindingConstants; -import org.apache.tapestry5.ClientElement; -import org.apache.tapestry5.ComponentResources; -import org.apache.tapestry5.Link; -import org.apache.tapestry5.RenderSupport; -import org.apache.tapestry5.annotations.Environmental; -import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary; -import org.apache.tapestry5.annotations.InjectContainer; -import org.apache.tapestry5.annotations.Parameter; -import org.apache.tapestry5.ioc.annotations.Inject; - -/** - * ZoneUpdater.java - * - * From <http://tinybits.blogspot.com/2009/05/update-zone-on-any-client-side-event.html> - * by Inge Solvoll - * - * @author ingesol - */ - at IncludeJavaScriptLibrary("context:js/ZoneUpdater.js") -public class ZoneUpdater { - - public static final String PLACEHOLDER = "XXX"; - - @Inject - private ComponentResources resources; - - @Environmental - private RenderSupport renderSupport; - - @Parameter(defaultPrefix = BindingConstants.LITERAL) - private String clientEvent; - - @Parameter(defaultPrefix = BindingConstants.LITERAL, required = true) - private String event; - - @InjectContainer - private ClientElement element; - - @Parameter - private Object[] context; - - @Parameter(defaultPrefix = BindingConstants.LITERAL) - // To enable popups to fire events on this document, enter "document" here. - private String listeningElement; - - @Parameter(defaultPrefix = BindingConstants.LITERAL, required = true) - private String zone; - - protected Link createLink(Object[] context) { - - if (context == null) { - context = new Object[]{PLACEHOLDER}; - } else { - context = ArrayUtils.add(context, PLACEHOLDER); // To be replaced by javascript - } - - return resources.createEventLink(event, context); - - } - - void afterRender() { - String link = createLink(context).toAbsoluteURI(); - String elementId = element.getClientId(); - if (clientEvent == null) { - clientEvent = event; - } - - if (listeningElement == null) { - listeningElement = "$('" + elementId + "')"; - } - renderSupport.addScript("new ZoneUpdater('%s', %s, '%s', '%s', '%s', '%s')", elementId, listeningElement, clientEvent, link, zone, PLACEHOLDER); - - } -} Modified: trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/pages/Administration.java =================================================================== --- trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/pages/Administration.java 2010-06-21 09:23:28 UTC (rev 554) +++ trunk/wao-ui/src/main/java/fr/ifremer/wao/ui/pages/Administration.java 2010-06-21 10:42:04 UTC (rev 555) @@ -57,8 +57,11 @@ import org.apache.commons.lang.StringUtils; import org.apache.tapestry5.EventContext; import org.apache.tapestry5.OptionModel; +import org.apache.tapestry5.RenderSupport; import org.apache.tapestry5.SelectModel; import org.apache.tapestry5.StreamResponse; +import org.apache.tapestry5.annotations.Environmental; +import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary; import org.apache.tapestry5.annotations.IncludeStylesheet; import org.apache.tapestry5.annotations.InjectComponent; import org.apache.tapestry5.annotations.Log; @@ -88,6 +91,7 @@ */ @RequiresAuthentication(value = {UserRole.ADMIN, UserRole.COORDINATOR}, readOnlyAllowed = false) @IncludeStylesheet("context:css/administration.css") + at IncludeJavaScriptLibrary("context:js/AdminUserSelect.js") public class Administration { @InjectComponent @@ -115,6 +119,9 @@ @Inject private Messages messages; + @Environmental + private RenderSupport renderSupport; + @Property private String companyId; @@ -143,7 +150,7 @@ void setupRender() throws WaoException { companies = null; getCompanies(); - user = null; + userEdited = null; userModel = null; } @@ -162,6 +169,11 @@ return new String[] {companyId, userId}; } + void afterRender() { + // Prototype class for UserSelect (manual usage because of specific style on options) + renderSupport.addScript("new AdminUserSelect();"); + } + /**************************** IMPORTS (ADMIN) *******************************/ @Inject @@ -306,7 +318,7 @@ companyId = null; } userId = null; - user = null; + userEdited = null; } void onSuccessFromCompany() throws WaoException { @@ -314,45 +326,52 @@ companyId = company.getId(); } + /******************** USER ACTIONS FORM ***********************************/ + + private List<WaoUser> users; + + @Property + private WaoUser user; + @Log - public GenericSelectModel<WaoUser> getUsersSelectModel() throws WaoException { - if (usersSelectModel == null) { - List<WaoUser> users = serviceUser.getUsersByCompany(getCompany()); - if (logger.isDebugEnabled()) { - logger.debug("Nb users : " + users.size()); - } - usersSelectModel = new GenericSelectModel<WaoUser>(users, WaoUser.class, - "fullName", "id", propertyAccess); + public List<WaoUser> getUsers() { + if (users == null) { + users = serviceUser.getUsersByCompany(getCompany()); } - return usersSelectModel; + return users; } - /******************** USER ACTIONS FORM ***********************************/ +// @Log +// public GenericSelectModel<WaoUser> getUsersSelectModel() throws WaoException { +// if (usersSelectModel == null) { +// List<WaoUser> users = serviceUser.getUsersByCompany(getCompany()); +// if (logger.isDebugEnabled()) { +// logger.debug("Nb users : " + users.size()); +// } +// usersSelectModel = new GenericSelectModel<WaoUser>(users, WaoUser.class, +// "fullName", "id", propertyAccess); +// } +// return usersSelectModel; +// } - @Inject - private BeanModelSource beanModelSource; - - /** - * User is persistant cause of autobuild problem ?!? - */ - @Persist - private WaoUser user; - - public WaoUser getUser() throws WaoException { - if (user == null) { - if (userId != null) { - if (logger.isDebugEnabled()) { - logger.debug("User exist in selectModel : " + userId); - } - user = getUsersSelectModel().findObject(userId); - } else { - user = serviceUser.getNewUser(getCompany()); - generatePassword = true; + private WaoUser findUser(String id) { + for (WaoUser user : getUsers()) { + if (user.getId().equals(id)) { + return user; } } - return user; + return null; } + public String getUserOptionStyle() { + String result = ""; + // Inactive user + if (!user.getActive()) { + result = "line-through"; + } + return result; + } + @Log void onSelectedFromAddNewUser() { addNewUserSelected = true; @@ -368,10 +387,10 @@ if (addNewUserSelected) { userId = null; } else if (deleteUserSelected && userId != null) { - user = getUsersSelectModel().findObject(userId); + userEdited = findUser(userId); try { - serviceUser.deleteUser(user); - user = null; + serviceUser.deleteUser(userEdited); + userEdited = null; userId = null; layout.addInfo("Utilisateur supprimé avec succès !"); } catch (WaoBusinessException eee) { @@ -383,35 +402,21 @@ } } -// @Log -// void onChangeFromUsers(String userId) { -// this.userId = userId; -// } -// -// @Log -// void onActionFromDeleteUser() { -// user = getUsersSelectModel().findObject(userId); -// try { -// serviceUser.deleteUser(user); -// user = null; -// userId = null; -// layout.addInfo("Utilisateur supprimé avec succès !"); -// } catch (WaoBusinessException eee) { -// layout.addError(eee.getMessage()); -// } -// } -// -// @Log -// void onActionFromAddNewUser() { -// userId = null; -// } - /******************** USER FORM ******************************************/ @InjectComponent private Zone userFormZone; + @Inject + private BeanModelSource beanModelSource; + + /** + * User is persistant cause of autobuild problem ?!? + */ @Persist + private WaoUser userEdited; + + @Persist private BeanModel<WaoUser> userModel; @Property @@ -420,6 +425,21 @@ @Property private String password; + public WaoUser getUserEdited() throws WaoException { + if (userEdited == null) { + if (userId != null) { + if (logger.isDebugEnabled()) { + logger.debug("User exist in selectModel : " + userId); + } + userEdited = findUser(userId); + } else { + userEdited = serviceUser.getNewUser(getCompany()); + generatePassword = true; + } + } + return userEdited; + } + public BeanModel<WaoUser> getUserModel() { if (userModel == null) { userModel = beanModelSource.createEditModel(WaoUser.class, messages); @@ -445,7 +465,7 @@ @Log void onValidateFormFromUserForm() { userForm.clearErrors(); - if (user.getUserRoles().isEmpty()) { + if (userEdited.getUserRoles().isEmpty()) { userForm.recordError("L'utilisateur doit au minimum avoir un rôle."); } } @@ -453,20 +473,20 @@ @Log Object onSuccessFromUserForm() throws WaoException { if (logger.isDebugEnabled()) { - logger.debug("User : " + user); + logger.debug("User : " + userEdited); } if (!StringUtils.isEmpty(password)) { - user.setPassword(password); - user.setPasswordChanged(true); + userEdited.setPassword(password); + userEdited.setPasswordChanged(true); } try { - serviceUser.createUpdateUser(user, generatePassword); - userId = user.getId(); + serviceUser.createUpdateUser(userEdited, generatePassword); + userId = userEdited.getId(); } catch (WaoBusinessException eee) { if (eee.getType().equals(Type.SMTP_NOT_FOUND)) { layout.addInfo(eee.getMessage()); - userId = user.getId(); + userId = userEdited.getId(); } else { layout.addError(eee.getMessage()); } @@ -524,7 +544,7 @@ public String getRoleReadOnly() { String text = ""; - if (user.isReadOnly(role)) { + if (userEdited.isReadOnly(role)) { text = "lecture seule"; } return text; @@ -551,7 +571,7 @@ " (readOnly=" + readOnly + ")"); } if (userRole != null) { - user.addUserRole(userRole, readOnly); + userEdited.addUserRole(userRole, readOnly); } // Reset fields userRole = null; @@ -563,8 +583,8 @@ @Log Object onActionFromRemoveRole(int roleIndex) { - UserRole roleToRemove = user.getUserRoles().get(roleIndex); - user.removeUserRole(roleToRemove); + UserRole roleToRemove = userEdited.getUserRoles().get(roleIndex); + userEdited.removeUserRole(roleToRemove); // Refresh the zone refreshUserRoleZone = true; return userRoleZone; Modified: trunk/wao-ui/src/main/webapp/Administration.tml =================================================================== --- trunk/wao-ui/src/main/webapp/Administration.tml 2010-06-21 09:23:28 UTC (rev 554) +++ trunk/wao-ui/src/main/webapp/Administration.tml 2010-06-21 10:42:04 UTC (rev 555) @@ -91,19 +91,19 @@ <t:if t:test="usersAvailable"> <form class="actions clearfix" t:type="form" t:id="userActionsForm"> + <input t:type="hidden" t:id="hiddenUserId" t:value="userId" /> <div class="fields fleft"> - <t:label t:for="users" /> : - <input t:type="select" t:id="users" t:model="usersSelectModel" t:value="userId" /> + <label for="users">Liste des utilisateurs</label> : + <!--<input t:type="select" t:id="users" t:model="usersSelectModel" t:value="userId" />--> + <!--<select t:type="any" t:id="users" name="users" type="text" t:mixins="nuiton/zoneUpdater" t:event="change" t:zone="userFormZone">--> + <select id="users" name="users" type="text"> + <option value=""/> + <t:loop t:source="users" t:value="user" t:volatile="true"> + <option class="${userOptionStyle}" value="${user.id}">${user.fullName}</option> + </t:loop> + </select> </div> <div class="icons fleft"> - <!--<input t:type="submit" class="ico search" value="Show Details" t:title="Afficher détails" />--> - <!--<a t:type="actionlink" t:id="deleteUser" t:title="Supprimer cet utilisateur"--> - <!--t:mixins="Confirm" t:message="Etes-vous sûr de vouloir supprimer définitivement cet utilisateur ?">--> - <!--<img src="${asset:context:img/delete2.png}" alt="Supprimer cet utilisateur" />--> - <!--</a>--> - <!--<a t:type="actionlink" t:id="addNewUser" t:title="Ajouter un nouvel utilisateur">--> - <!--<img src="${asset:context:img/add.png}" alt="Ajouter un nouvel utilisateur" />--> - <!--</a>--> <input t:type="submit" t:id="showUser" class="ico search" value="Show Details" t:title="Afficher détails" /> <input t:type="submit" t:id="deleteUser" class="ico22px delete" value="Delete user" t:title="Supprimer cet utilisateur" t:mixins="nuiton/confirm" t:message="literal:Etes-vous sûr de vouloir supprimer définitivement cet utilisateur ?" /> @@ -113,19 +113,19 @@ <fieldset class="user-form clearfix"> <t:zone t:id="userFormZone" t:update="show"> - <form t:type="beaneditform" class="clearfix" t:id="userForm" t:object="user" t:model="userModel" t:zone="userFormZone"> + <form t:type="beaneditform" class="clearfix" t:id="userForm" t:object="userEdited" t:model="userModel" t:zone="userFormZone"> <t:errors /> <p:firstName> <label t:type="label" for="firstName" /> - <input t:type="textfield" t:id="firstName" value="user.firstName" t:validate="required" /> + <input t:type="textfield" t:id="firstName" value="userEdited.firstName" t:validate="required" /> </p:firstName> <p:lastName> <label t:type="label" for="lastName" /> - <input t:type="textfield" t:id="lastName" value="user.lastName" t:validate="required" /> + <input t:type="textfield" t:id="lastName" value="userEdited.lastName" t:validate="required" /> </p:lastName> <p:login> <label t:type="label" for="login" /> - <input t:type="textfield" t:id="login" value="user.login" t:validate="required" /> + <input t:type="textfield" t:id="login" value="userEdited.login" t:validate="required" /> </p:login> <p:password> <label t:type="label" for="generatePassword" /> @@ -148,7 +148,7 @@ <img src="${asset:context:img/add-16px.png}" /> </a> <ul> - <li t:type="loop" t:source="user.userRoles" t:value="role" t:index="roleIndex"> + <li t:type="loop" t:source="userEdited.userRoles" t:value="role" t:index="roleIndex"> ${role.label} ${roleReadOnly} <a t:type="actionlink" t:id="removeRole" t:context="roleIndex" title="Supprimer ce rôle" t:zone="so-admin-userRoleZone"> <img src="${asset:context:img/remove-22px.png}" /> Added: trunk/wao-ui/src/main/webapp/js/AdminUserSelect.js =================================================================== --- trunk/wao-ui/src/main/webapp/js/AdminUserSelect.js (rev 0) +++ trunk/wao-ui/src/main/webapp/js/AdminUserSelect.js 2010-06-21 10:42:04 UTC (rev 555) @@ -0,0 +1,33 @@ +/** + * This class is used to manage manually user select on Administration page. + * Options need style depends on inactivity of users. So we use javascript to + * manage dynamic states of the select. Initialization if needed (the correct + * option to select) then use a hidden field 'hiddenUserId' to keep userId + * context (ids are values of options). + * This hidden field will be interpreted by Tapestry when form will be submit. + */ +AdminUserSelect = Class.create({ + initialize: function() { + this.hiddenUserId = $('userActionsForm').hiddenUserId; + this.userSelect = $('userActionsForm').users; + this.userSelect.observe('change', this.updateUserId.bind(this)); + + var userId = $F(this.hiddenUserId); + + // Initialize selected option + if (userId) { + var options = this.userSelect.select('option'); + for (i = 0; i < options.length; i++) { + if (options[i].value == userId) { + options[i].selected = true; + break; + } + } + } + //Tapestry.debug('Initialized !'); + }, + updateUserId: function(event) { + //Tapestry.debug('select value : ' + $F(this.userSelect)); + this.hiddenUserId.setValue($F(this.userSelect)); + } +}); \ No newline at end of file Deleted: trunk/wao-ui/src/main/webapp/js/ZoneUpdater.js =================================================================== --- trunk/wao-ui/src/main/webapp/js/ZoneUpdater.js 2010-06-21 09:23:28 UTC (rev 554) +++ trunk/wao-ui/src/main/webapp/js/ZoneUpdater.js 2010-06-21 10:42:04 UTC (rev 555) @@ -1,133 +0,0 @@ -/* - * #%L - * Wao :: Web Interface - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2010 Ifremer - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ -/** - * ZoneUpdater.js - * - * From <http://tinybits.blogspot.com/2009/05/update-zone-on-any-client-side-event.html> - * by Inge Solvoll - */ -var ZoneUpdater = Class.create(); - -ZoneUpdater.prototype = { - - initialize: function(zoneElementId, listeningElement, event, link, zone, placeholder) { - - this.zoneElement = $(zoneElementId); - - this.event = event; - - this.link = link; - - this.placeholder = placeholder; - - $T(this.zoneElement).zoneId = zone; - - listeningElement.observe(this.event, this.updateZone.bindAsEventListener(this)); - - }, - - updateZone: function(event) { - - var zoneObject = Tapestry.findZoneManager(this.zoneElement); - - if ( !zoneObject ) return; - - var param; - - if (this.zoneElement.value) { - - param = this.zoneElement.value; - - } - - if (!param) param = ' '; - - param = this.encodeForUrl(param); - - var updatedLink = this.link.gsub(this.placeholder, param); - - zoneObject.updateFromURL(updatedLink); - - }, - - encodeForUrl: function(string) { - - /** - - * See equanda.js for updated version of this - - */ - - string = string.replace(/\r\n/g,"\n"); - - var res = ""; - - for (var n = 0; n < string.length; n++) - - { - - var c = string.charCodeAt( n ); - - if ( '$' == string.charAt( n ) ) - - { - - res += '$$'; - - } - - else if ( this.inRange( c, "AZ" ) || this.inRange( c, "az" ) || this.inRange( c, "09" ) || this.inRange( c, ".." ) ) - - { - - res += string.charAt( n ) - - } - - else - - { - - var tmp = c.toString(16); - - while ( tmp.length < 4 ) tmp = "0" + tmp; - - res += '$' + tmp; - - } - - } - - return res; - - }, - - inRange: function(code, range) { - - return code >= range.charCodeAt( 0 ) && code <= range.charCodeAt( 1 ); - - } - -}