Author: fdesbois Date: 2010-05-06 12:35:53 +0200 (Thu, 06 May 2010) New Revision: 2987 Url: http://chorem.org/repositories/revision/pollen/2987 Log: Evo #190 : Finish UserLists page with favoriteList and participant managment. (todo : i18n messages + javadoc) Added: trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceFavoriteImpl.java trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceFavoriteImplTest.java trunk/pollen-ui/src/main/webapp/css/users.css Removed: trunk/pollen-ui/src/main/webapp/css/lists.css Modified: trunk/pollen-business/src/main/java/org/chorem/pollen/PollenBusinessException.java trunk/pollen-business/src/main/java/org/chorem/pollen/TopiaQueryBuilder.java trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceUserImpl.java trunk/pollen-business/src/main/resources/i18n/pollen-business-en_GB.properties trunk/pollen-business/src/main/resources/i18n/pollen-business-fr_FR.properties trunk/pollen-business/src/main/xmi/pollen.properties trunk/pollen-business/src/main/xmi/pollen.zargo trunk/pollen-business/src/test/java/org/chorem/pollen/business/AbstractServiceTest.java trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceUserImplTest.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/UserListsCreate.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/UserListsUpdate.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/data/FavoriteParticipantDataSource.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserLists.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserProfile.java trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/AppModule.java trunk/pollen-ui/src/main/resources/i18n/pollen-ui-fr_FR.properties trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/Border.tml trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/UserListsCreate.tml trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/UserListsUpdate.tml trunk/pollen-ui/src/main/webapp/admin/AdminUsers.tml trunk/pollen-ui/src/main/webapp/css/common.css trunk/pollen-ui/src/main/webapp/css/main.css trunk/pollen-ui/src/main/webapp/user/UserLists.tml trunk/pollen-ui/src/main/webapp/user/UserProfile.tml Modified: trunk/pollen-business/src/main/java/org/chorem/pollen/PollenBusinessException.java =================================================================== --- trunk/pollen-business/src/main/java/org/chorem/pollen/PollenBusinessException.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-business/src/main/java/org/chorem/pollen/PollenBusinessException.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -49,7 +49,19 @@ SMTP_NOT_AVAILABLE(n_("pollen.exception.smtp_not_available")), /** Exception when favorite list name is already defined for user **/ FAVORITE_LIST_NAME_EXIST( - n_("pollen.exception.favorite_list_name_exist")); + n_("pollen.exception.favorite_list_name_exist")), + /** + * Exception when favorite participant name ($2) and email ($3) are + * already defined for the current list ($1). + **/ + FAVORITE_PARTICIPANT_EXIST( + n_("pollen.exception.favorite_participant_exist")), + /** + * Exception when favorite participant name ($2) with no email is + * already defined for the current list ($1). + **/ + FAVORITE_PARTICIPANT_EXIST_WITHOUT_EMAIL( + n_("pollen.exception.favorite_participant_exist_without_email")); private String message; Modified: trunk/pollen-business/src/main/java/org/chorem/pollen/TopiaQueryBuilder.java =================================================================== --- trunk/pollen-business/src/main/java/org/chorem/pollen/TopiaQueryBuilder.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-business/src/main/java/org/chorem/pollen/TopiaQueryBuilder.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.chorem.pollen.bean.Filter; import org.nuiton.topia.framework.TopiaQuery; import org.nuiton.topia.persistence.TopiaDAO; @@ -28,6 +30,8 @@ */ public class TopiaQueryBuilder { + private static final Log log = LogFactory.getLog(TopiaQueryBuilder.class); + protected TopiaQuery query; public TopiaQueryBuilder() { @@ -138,6 +142,14 @@ String orderBy = filter.getOrderBy(); String referenceId = filter.getReferenceId(); + if (log.isDebugEnabled()) { + log.debug("Filter added to the query : " + + "startIndex = " + startIndex + + " _ endIndex = " + endIndex + + " _ orderBy = " + orderBy + + " _ referenceId = " + referenceId); + } + // Add limits. Only startIndex do nothing. // startIndex + endIndex provides the limit if (filter.getStartIndex() != null && endIndex != null) { Added: trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceFavoriteImpl.java =================================================================== --- trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceFavoriteImpl.java (rev 0) +++ trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceFavoriteImpl.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -0,0 +1,280 @@ +package org.chorem.pollen.service; + +import java.util.List; +import java.util.Map; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.PollenBusinessException; +import org.chorem.pollen.PollenBusinessException.PollenExceptionType; +import org.chorem.pollen.PollenContext; +import org.chorem.pollen.PollenDAOHelper; +import org.chorem.pollen.PollenException; +import org.chorem.pollen.PollenQueryBuilder; +import org.chorem.pollen.bean.Filter; +import org.chorem.pollen.entity.FavoriteList; +import org.chorem.pollen.entity.FavoriteListDAO; +import org.chorem.pollen.entity.FavoriteListImpl; +import org.chorem.pollen.entity.FavoriteParticipant; +import org.chorem.pollen.entity.FavoriteParticipantDAO; +import org.chorem.pollen.entity.FavoriteParticipantImpl; +import org.chorem.pollen.entity.UserAccount; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.framework.TopiaQuery; +import org.nuiton.topia.framework.TopiaQuery.Op; +import org.nuiton.topia.persistence.TopiaEntity; + +/** + * ServiceFavorite + * + * Created: 5 mai 2010 + * + * @author fdesbois + * $Id$ + */ +public class ServiceFavoriteImpl extends ServiceFavoriteAbstract { + + private Log log = LogFactory.getLog(ServiceUserImpl.class); + private static final String BINDER_CONTEXT_FAVORITE_LIST = "favoriteList"; + private PollenContext context; + + public void setContext(PollenContext context) { + this.context = context; + } + + @Override + protected TopiaContext beginTransaction() throws TopiaException { + return context.beginTransaction(); + } + + @Override + protected void treateError(TopiaContext transaction, Exception eee, + String message, Object... args) throws PollenException { + context.treateError(transaction, eee, message, args); + } + + @Override + protected void closeTransaction(TopiaContext transaction) { + context.closeTransaction(transaction); + } + + @Override + protected FavoriteList executeGetNewFavoriteList(UserAccount user) { + FavoriteList result = new FavoriteListImpl(); + result.setUserAccount(user); + return result; + } + + @Override + protected void executeCreateFavoriteList(TopiaContext transaction, + FavoriteList list) throws TopiaException, PollenBusinessException { + + FavoriteListDAO dao = PollenDAOHelper.getFavoriteListDAO(transaction); + + // check favoriteList name exist for user + UserAccount user = list.getUserAccount(); + int count = dao.createQuery(). + add(FavoriteList.USER_ACCOUNT, user). + add(FavoriteList.NAME, list.getName()). + executeCount(); + // existing list found + if (count > 0) { + throw new PollenBusinessException( + PollenExceptionType.FAVORITE_LIST_NAME_EXIST, + list.getName(), user.getDisplayName()); + } + + FavoriteList newList = dao.create( + FavoriteList.USER_ACCOUNT, list.getUserAccount(), + FavoriteList.NAME, list.getName()); +// list.setTopiaId(newList.getTopiaId()); + + transaction.commitTransaction(); + } + + @Override + protected void executeDeleteFavoriteList(TopiaContext transaction, + FavoriteList list) throws TopiaException { + FavoriteListDAO dao = PollenDAOHelper.getFavoriteListDAO(transaction); + + FavoriteList listLoaded = dao.findByTopiaId(list.getTopiaId()); + dao.delete(listLoaded); + + transaction.commitTransaction(); + } + + @Override + protected List<FavoriteList> executeGetFavoriteLists( + TopiaContext transaction, UserAccount user) throws TopiaException { + + FavoriteListDAO dao = PollenDAOHelper.getFavoriteListDAO(transaction); + + List<FavoriteList> results = dao.findAllByUserAccount(user); + + return results; + } + + /** + * Check if the {@code participant} doesn't already exists with same + * email, name and favoriteList. + * + * @param dao used to verify the existing participant + * @param participant FavoriteParticipant to check + * @throws PollenBusinessException if FavoriteParticipant already exists + * @throws TopiaException for technical errors from ToPIA + */ + protected void checkFavoriteParticipant(FavoriteParticipantDAO dao, + FavoriteParticipant participant) + throws PollenBusinessException, TopiaException { + + FavoriteList list = participant.getFavoriteList(); + + TopiaQuery query = dao.createQuery(). + add(FavoriteParticipant.FAVORITE_LIST, list). + add(FavoriteParticipant.NAME, participant.getName()). + add(FavoriteParticipant.EMAIL, participant.getEmail()); + + // Check only on entities different from the one in argument + if (StringUtils.isNotEmpty(participant.getTopiaId())) { + query.add(TopiaEntity.TOPIA_ID, Op.NEQ, participant.getTopiaId()); + } + + int count = query.executeCount(); + // existing participant found + if (count > 0) { + // The error type (message) depends on email nullity + if (participant.getEmail() == null) { + throw new PollenBusinessException( + PollenExceptionType.FAVORITE_PARTICIPANT_EXIST_WITHOUT_EMAIL, + list.getName(), + participant.getName()); + } else { + throw new PollenBusinessException( + PollenExceptionType.FAVORITE_PARTICIPANT_EXIST, + list.getName(), + participant.getName(), + participant.getEmail()); + } + } + } + + @Override + protected FavoriteParticipant executeGetNewFavoriteParticipant( + FavoriteList list) { + FavoriteParticipant result = new FavoriteParticipantImpl(); + result.setFavoriteList(list); + result.setWeight(1.); + return result; + } + + @Override + protected void executeCreateFavoriteParticipant(TopiaContext transaction, + FavoriteParticipant participant) + throws PollenBusinessException, TopiaException { + + FavoriteParticipantDAO dao = + PollenDAOHelper.getFavoriteParticipantDAO(transaction); + + checkFavoriteParticipant(dao, participant); + + // Create newParticipant with naturalId + FavoriteParticipant newParticipant = + dao.create(participant.getName(), + participant.getEmail(), + participant.getFavoriteList()); + + // Set other field + newParticipant.setWeight(participant.getWeight()); + + transaction.commitTransaction(); + } + + @Override + protected void executeDeleteFavoriteParticipant(TopiaContext transaction, + String id) throws TopiaException { + + FavoriteParticipantDAO dao = + PollenDAOHelper.getFavoriteParticipantDAO(transaction); + + FavoriteParticipant participantLoaded = dao.findByTopiaId(id); + + dao.delete(participantLoaded); + + transaction.commitTransaction(); + } + + @Override + protected void executeUpdateFavoriteParticipant(TopiaContext transaction, + FavoriteParticipant participant) + throws TopiaException, PollenBusinessException { + + FavoriteParticipantDAO dao = + PollenDAOHelper.getFavoriteParticipantDAO(transaction); + + checkFavoriteParticipant(dao, participant); + + FavoriteParticipant participantLoaded = + dao.findByTopiaId(participant.getTopiaId()); + + // Set all fields except favoriteList that can't be changed + participantLoaded.setName(participant.getName()); + participantLoaded.setEmail(participant.getEmail()); + participantLoaded.setWeight(participant.getWeight()); + + dao.update(participantLoaded); + + transaction.commitTransaction(); + } + + @Override + protected FavoriteParticipant executeGetFavoriteParticipant( + TopiaContext transaction, String id) throws TopiaException { + + FavoriteParticipantDAO dao = + PollenDAOHelper.getFavoriteParticipantDAO(transaction); + + FavoriteParticipant result = dao.findByTopiaId(id); + // Load parent list + result.getFavoriteList(); + + return result; + } + + @Override + protected Map<String, FavoriteParticipant> executeGetFavoriteParticipants( + TopiaContext transaction, Filter filter) throws TopiaException { + + PollenQueryBuilder builder = new PollenQueryBuilder(); + + TopiaQuery query = + builder.createQueryFindFavoriteParticipantsByFavoriteList(filter); + + FavoriteParticipantDAO dao = + PollenDAOHelper.getFavoriteParticipantDAO(transaction); + + if (log.isDebugEnabled()) { + log.debug("Query : " + query); + } + + query.addLoad(FavoriteParticipant.FAVORITE_LIST); + + Map<String, FavoriteParticipant> results = + dao.findAllMappedByQuery(query); + + return results; + } + + @Override + protected int executeGetNbFavoriteParticipants(TopiaContext transaction, + Filter filter) throws TopiaException { + + PollenQueryBuilder builder = new PollenQueryBuilder(); + + TopiaQuery query = + builder.createQueryFindFavoriteParticipantsByFavoriteList(filter); + + int result = query.executeCount(transaction); + return result; + } +} Property changes on: trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceFavoriteImpl.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceUserImpl.java =================================================================== --- trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceUserImpl.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-business/src/main/java/org/chorem/pollen/service/ServiceUserImpl.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -19,22 +19,18 @@ import org.chorem.pollen.entity.FavoriteParticipant; import org.chorem.pollen.entity.FavoriteParticipantDAO; import org.chorem.pollen.entity.FavoriteParticipantImpl; -import org.chorem.pollen.entity.PollAccount; -import org.chorem.pollen.EntityQueryProperty; import org.chorem.pollen.PollenQueryBuilder; import org.chorem.pollen.TopiaQueryBuilder; -import org.chorem.pollen.entity.PollAccountDAO; import org.chorem.pollen.entity.UserAccount; import org.chorem.pollen.entity.UserAccountDAO; import org.chorem.pollen.entity.UserAccountImpl; +import org.nuiton.i18n.I18n; import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaException; import org.nuiton.topia.framework.TopiaQuery; import org.nuiton.topia.framework.TopiaQuery.Op; import org.nuiton.topia.persistence.util.TopiaEntityBinder; import org.nuiton.util.beans.Binder; -import org.nuiton.util.beans.BinderBuilder; -import org.nuiton.util.beans.BinderProvider; /** * ServiceUserImpl @@ -51,8 +47,6 @@ private Log log = LogFactory.getLog(ServiceUserImpl.class); - private static final String BINDER_CONTEXT_FAVORITE_LIST = "favoriteList"; - private PollenContext context; public void setContext(PollenContext context) { @@ -293,152 +287,5 @@ return result; } - @Override - protected FavoriteList executeGetNewFavoriteList(UserAccount user) { - FavoriteList result = new FavoriteListImpl(); - result.setUserAccount(user); - return result; - } - @Override - protected void executeCreateFavoriteList(TopiaContext transaction, - FavoriteList list) throws TopiaException, PollenBusinessException { - - FavoriteListDAO dao = PollenDAOHelper.getFavoriteListDAO(transaction); - - // check favoriteList name exist for user - UserAccount user = list.getUserAccount(); - int count = dao.createQuery(). - add(FavoriteList.USER_ACCOUNT, user). - add(FavoriteList.NAME, list.getName()). - executeCount(); - // existing list found - if (count > 0) { - throw new PollenBusinessException( - PollenExceptionType.FAVORITE_LIST_NAME_EXIST, - list.getName(), user.getDisplayName()); - } - - FavoriteList newList = dao.create( - FavoriteList.USER_ACCOUNT, list.getUserAccount(), - FavoriteList.NAME, list.getName()); -// list.setTopiaId(newList.getTopiaId()); - - transaction.commitTransaction(); - } - - @Override - protected void executeDeleteFavoriteList(TopiaContext transaction, - FavoriteList list) throws TopiaException { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - protected List<FavoriteList> executeGetFavoriteLists( - TopiaContext transaction, UserAccount user) throws TopiaException { - - FavoriteListDAO dao = PollenDAOHelper.getFavoriteListDAO(transaction); - - List<FavoriteList> results = dao.findAllByUserAccount(user); - - return results; - } - - @Override - protected FavoriteParticipant executeGetNewFavoriteParticipant( - TopiaContext transaction, FavoriteList list) - throws TopiaException { - FavoriteParticipant result = new FavoriteParticipantImpl(); - result.setFavoriteList(list); - result.setWeight(1.); - return result; - } - - @Override - protected void executeCreateFavoriteParticipant(TopiaContext transaction, - FavoriteParticipant participant) - throws PollenBusinessException, TopiaException { - - FavoriteParticipantDAO dao = - PollenDAOHelper.getFavoriteParticipantDAO(transaction); - - FavoriteList list = participant.getFavoriteList(); -// int count = dao.createQuery(). -// add(FavoriteParticipant.FAVORITE_LIST, list). -// add(FavoriteParticipant.NAME, participant.getName()). -// add(FavoriteParticipant.EMAIL, participant.getEmail()). -// executeCount(); -// // existing participant found -// if (count > 0) { -// throw new PollenBusinessException( -// PollenExceptionType.FAVORITE_PARTICIPANT_EXIST, -// list.getName(), list.getName()); -// } - - // Create newParticipant with naturalId - FavoriteParticipant newParticipant = - dao.create(FavoriteParticipant.FAVORITE_LIST, list, - FavoriteParticipant.NAME, participant.getName(), - FavoriteParticipant.EMAIL, participant.getEmail()); - - // Set other field - newParticipant.setWeight(participant.getWeight()); - - // Update input participant with new topiaId -// participant.setTopiaId(newParticipant.getTopiaId()); - - transaction.commitTransaction(); - } - - @Override - protected void executeDeleteFavoriteParticipant(TopiaContext transaction, - FavoriteParticipant participant) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - protected void executeUpdateFavoriteParticipant(TopiaContext transaction, - FavoriteParticipant participant) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - protected Map<String, FavoriteParticipant> executeGetFavoriteParticipants( - TopiaContext transaction, Filter filter) throws TopiaException { - - PollenQueryBuilder builder = new PollenQueryBuilder(); - - TopiaQuery query = - builder.createQueryFindFavoriteParticipantsByFavoriteList(filter); - - FavoriteParticipantDAO dao = - PollenDAOHelper.getFavoriteParticipantDAO(transaction); - - if (log.isDebugEnabled()) { - log.debug("Query : " + query); - } - - Map<String, FavoriteParticipant> results = - dao.findAllMappedByQuery(query); - - if (log.isDebugEnabled()) { - log.debug("Results : " + results); - } - - return results; - } - - @Override - protected int executeGetNbFavoriteParticipants(TopiaContext transaction, - Filter filter) throws TopiaException { - - PollenQueryBuilder builder = new PollenQueryBuilder(); - - TopiaQuery query = - builder.createQueryFindFavoriteParticipantsByFavoriteList(filter); - - int result = query.executeCount(transaction); - return result; - } - } Modified: trunk/pollen-business/src/main/resources/i18n/pollen-business-en_GB.properties =================================================================== --- trunk/pollen-business/src/main/resources/i18n/pollen-business-en_GB.properties 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-business/src/main/resources/i18n/pollen-business-en_GB.properties 2010-05-06 10:35:53 UTC (rev 2987) @@ -7,6 +7,17 @@ pollen.error.encodePassword= pollen.error.serviceEmail.getNewEmail= pollen.error.serviceEmail.sendEmail= +pollen.error.serviceFavorite.createFavoriteList= +pollen.error.serviceFavorite.createFavoriteParticipant= +pollen.error.serviceFavorite.deleteFavoriteList= +pollen.error.serviceFavorite.deleteFavoriteParticipant= +pollen.error.serviceFavorite.getFavoriteLists= +pollen.error.serviceFavorite.getFavoriteParticipant= +pollen.error.serviceFavorite.getFavoriteParticipants= +pollen.error.serviceFavorite.getNbFavoriteParticipants= +pollen.error.serviceFavorite.getNewFavoriteList= +pollen.error.serviceFavorite.getNewFavoriteParticipant= +pollen.error.serviceFavorite.updateFavoriteParticipant= pollen.error.serviceList.createAccountForPersonList= pollen.error.serviceList.deleteAccountFromPersonList= pollen.error.serviceMail.sendEmail= @@ -65,6 +76,8 @@ pollen.error.serviceVote.getVotesByPoll=Unable to load votes from poll with uid \= %1$s pollen.error.serviceVote.hasAlreadyVoted=Unable test vote existing for account with votingId \= %1$s and poll with uid \= %2$s pollen.exception.favorite_list_name_exist= +pollen.exception.favorite_participant_exist= +pollen.exception.favorite_participant_exist_without_email= pollen.exception.load_configuration= pollen.exception.poll_not_exist=No such poll exists. Please make sure that you are using the correct link and copy it completely into your browser's address field. pollen.exception.smtp_not_available= @@ -77,3 +90,4 @@ pollen.info.start=Start Pollen pollen.info.started=Pollen is started \! pollen.info.stop=Stop Pollen +pollen.text.empty= Modified: trunk/pollen-business/src/main/resources/i18n/pollen-business-fr_FR.properties =================================================================== --- trunk/pollen-business/src/main/resources/i18n/pollen-business-fr_FR.properties 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-business/src/main/resources/i18n/pollen-business-fr_FR.properties 2010-05-06 10:35:53 UTC (rev 2987) @@ -7,6 +7,17 @@ pollen.error.encodePassword= pollen.error.serviceEmail.getNewEmail= pollen.error.serviceEmail.sendEmail= +pollen.error.serviceFavorite.createFavoriteList= +pollen.error.serviceFavorite.createFavoriteParticipant= +pollen.error.serviceFavorite.deleteFavoriteList= +pollen.error.serviceFavorite.deleteFavoriteParticipant= +pollen.error.serviceFavorite.getFavoriteLists= +pollen.error.serviceFavorite.getFavoriteParticipant= +pollen.error.serviceFavorite.getFavoriteParticipants= +pollen.error.serviceFavorite.getNbFavoriteParticipants= +pollen.error.serviceFavorite.getNewFavoriteList= +pollen.error.serviceFavorite.getNewFavoriteParticipant= +pollen.error.serviceFavorite.updateFavoriteParticipant= pollen.error.serviceList.createAccountForPersonList= pollen.error.serviceList.deleteAccountFromPersonList= pollen.error.serviceMail.sendEmail=Erreur lors de l'envoi de l'email sur le serveur %1$s\:%2$d pour %3$s de la part de %4$s @@ -64,6 +75,8 @@ pollen.error.serviceVote.getVotesByPoll= pollen.error.serviceVote.hasAlreadyVoted= pollen.exception.favorite_list_name_exist=La liste %1$s existe d\u00E9j\u00E0 pour l'utilisateur %2$s +pollen.exception.favorite_participant_exist=La liste %1$s contient d\u00E9j\u00E0 un utilisateur nomm\u00E9 %2$s avec un email %3$s +pollen.exception.favorite_participant_exist_without_email=La liste %1$s contient d\u00E9j\u00E0 un utilisateur nomm\u00E9 %2$s avec aucun email pollen.exception.load_configuration=La configuration n'a pas \u00E9t\u00E9 charg\u00E9e correctement \! Veuillez v\u00E9rifier le d\u00E9marrage de l'application. pollen.exception.poll_not_exist=Il n'y a pas de sondage \u00E0 cette adresse. Veuillez verifier que vous utilisez le lien correcte et copiez-le compl\u00E8tement dans le champ d'adresse de votre navigateur. pollen.exception.smtp_not_available=Impossible d'envoyer un email \u00E0 %1$s. Serveur smtp indisponible pour l'envoi d'email, veuillez contacter un administrateur. Modified: trunk/pollen-business/src/main/xmi/pollen.properties =================================================================== --- trunk/pollen-business/src/main/xmi/pollen.properties 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-business/src/main/xmi/pollen.properties 2010-05-06 10:35:53 UTC (rev 2987) @@ -12,7 +12,8 @@ org.chorem.pollen.entity.FavoriteList.attribute.userAccount.tagvalue.naturalId=true org.chorem.pollen.entity.FavoriteList.attribute.name.tagvalue.naturalId=true +org.chorem.pollen.entity.FavoriteParticipant.class.tagvalue.naturalIdMutable=true org.chorem.pollen.entity.FavoriteParticipant.attribute.favoriteList.tagvalue.naturalId=true org.chorem.pollen.entity.FavoriteParticipant.attribute.name.tagvalue.naturalId=true org.chorem.pollen.entity.FavoriteParticipant.attribute.email.tagvalue.naturalId=true -org.chorem.pollen.entity.FavoriteParticipant.attribute.email.tagvalue.notNull=false \ No newline at end of file +org.chorem.pollen.entity.FavoriteParticipant.attribute.email.tagvalue.notNull=false Modified: trunk/pollen-business/src/main/xmi/pollen.zargo =================================================================== (Binary files differ) Modified: trunk/pollen-business/src/test/java/org/chorem/pollen/business/AbstractServiceTest.java =================================================================== --- trunk/pollen-business/src/test/java/org/chorem/pollen/business/AbstractServiceTest.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-business/src/test/java/org/chorem/pollen/business/AbstractServiceTest.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -12,8 +12,13 @@ import org.chorem.pollen.PollenContext; import org.chorem.pollen.PollenContextImpl; import org.chorem.pollen.PollenDAOHelper; +import org.chorem.pollen.entity.FavoriteList; +import org.chorem.pollen.entity.FavoriteListDAO; +import org.chorem.pollen.entity.FavoriteParticipant; +import org.chorem.pollen.entity.FavoriteParticipantDAO; import org.chorem.pollen.entity.UserAccount; import org.chorem.pollen.entity.UserAccountDAO; +import org.chorem.pollen.service.ServiceFavoriteImpl; import org.chorem.pollen.service.ServiceUserImpl; import org.junit.After; import org.junit.Ignore; @@ -41,6 +46,8 @@ protected ServiceUserImpl serviceUser; + protected ServiceFavoriteImpl serviceFavorite; + public void start(String dbname) throws IOException { log.info("## START ## : " + dbname); @@ -87,6 +94,14 @@ return serviceUser; } + public ServiceFavoriteImpl getServiceFavorite() { + if (serviceFavorite == null) { + serviceFavorite = new ServiceFavoriteImpl(); + serviceFavorite.setContext(getContext()); + } + return serviceFavorite; + } + public TopiaContext beginTransaction() throws TopiaException { return getContext().beginTransaction(); } @@ -140,4 +155,35 @@ } } + public FavoriteList createFavoriteList(String name, UserAccount user) + throws TopiaException { + + TopiaContext transaction = beginTransaction(); + try { + FavoriteListDAO dao = + PollenDAOHelper.getFavoriteListDAO(transaction); + + FavoriteList list = dao.create(name, user); + transaction.commitTransaction(); + return list; + } finally { + transaction.closeContext(); + } + } + + public FavoriteParticipant createFavoriteParticipant(String name, + String email, FavoriteList list) throws TopiaException { + TopiaContext transaction = beginTransaction(); + try { + FavoriteParticipantDAO dao = + PollenDAOHelper.getFavoriteParticipantDAO(transaction); + + FavoriteParticipant participant = dao.create(name, email, list); + transaction.commitTransaction(); + return participant; + } finally { + transaction.closeContext(); + } + } + } Added: trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceFavoriteImplTest.java =================================================================== --- trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceFavoriteImplTest.java (rev 0) +++ trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceFavoriteImplTest.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -0,0 +1,109 @@ + +package org.chorem.pollen.service; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.PollenBusinessException; +import org.chorem.pollen.PollenBusinessException.PollenExceptionType; +import org.chorem.pollen.PollenDAOHelper; +import org.chorem.pollen.business.AbstractServiceTest; +import org.chorem.pollen.entity.FavoriteList; +import org.chorem.pollen.entity.FavoriteParticipant; +import org.chorem.pollen.entity.FavoriteParticipantDAO; +import org.chorem.pollen.entity.UserAccount; +import org.junit.Assert; +import org.junit.Test; +import org.nuiton.topia.TopiaContext; + +/** + * ServiceFavoriteImplTest + * + * Created: 5 mai 2010 + * + * @author fdesbois + * $Id$ + */ +public class ServiceFavoriteImplTest extends AbstractServiceTest { + + private static final Log log = LogFactory.getLog(ServiceUserImplTest.class); + + @Test + public void testCreateFavoriteParticipant() throws Exception { + start("testCreateFavoriteParticipant"); + + UserAccount user = createUser(false); + + final FavoriteList list = createFavoriteList("LIST", user); + + log.info("test 1 : no problem on creation"); + FavoriteParticipant participant = + getServiceFavorite().getNewFavoriteParticipant(list); + + participant.setName("participant"); + participant.setEmail("email"); + + getServiceFavorite().createFavoriteParticipant(participant); + + log.info("test 2 : problem on naturalId : participant already" + + " set with same email"); + + participant = + getServiceFavorite().getNewFavoriteParticipant(list); + + participant.setName("participant"); + participant.setEmail("email"); + + try { + getServiceFavorite().createFavoriteParticipant(participant); + } catch (PollenBusinessException eee) { + Assert.assertEquals(PollenExceptionType.FAVORITE_PARTICIPANT_EXIST, + eee.getType()); + } + + log.info("test 3 : email in naturalId can be null"); + + participant = + getServiceFavorite().getNewFavoriteParticipant(list); + + participant.setName("participant2"); + participant.setEmail(null); + + getServiceFavorite().createFavoriteParticipant(participant); + + TopiaContext transaction = beginTransaction(); + try { + FavoriteParticipantDAO dao = + PollenDAOHelper.getFavoriteParticipantDAO(transaction); + String email = null; + + FavoriteParticipant result = dao.findByProperties( + FavoriteParticipant.NAME, "participant2", + FavoriteParticipant.EMAIL, email, + FavoriteParticipant.FAVORITE_LIST, list); + + Assert.assertNotNull(result); + } finally { + transaction.closeContext(); + } + } + + @Test + public void testUpdateFavoriteParticipant() throws Exception { + start("testUpdateFavoriteParticipant"); + + /** PREPARE DATA **/ + UserAccount user = createUser(false); + + FavoriteList list = createFavoriteList("LIST", user); + FavoriteParticipant participant = + createFavoriteParticipant("participant", null, list); + + /** EXEC METHOD **/ + log.info("test 1 : update ok : add email"); + participant.setEmail("email"); + participant.setWeight(1.); + + getServiceFavorite().updateFavoriteParticipant(participant); + } + +} Property changes on: trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceFavoriteImplTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceUserImplTest.java =================================================================== --- trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceUserImplTest.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-business/src/test/java/org/chorem/pollen/service/ServiceUserImplTest.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -8,12 +8,17 @@ import org.chorem.pollen.PollenDAOHelper; import org.chorem.pollen.PollenException; import org.chorem.pollen.business.AbstractServiceTest; +import org.chorem.pollen.business.TestData; +import org.chorem.pollen.entity.FavoriteList; +import org.chorem.pollen.entity.FavoriteParticipant; +import org.chorem.pollen.entity.FavoriteParticipantDAO; import org.chorem.pollen.entity.UserAccount; import org.chorem.pollen.entity.UserAccountDAO; import org.chorem.pollen.entity.UserAccountImpl; import org.junit.Assert; import org.junit.Test; import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.framework.TopiaQuery; /** * @@ -42,7 +47,7 @@ log.info("test 2 : Do not encode new password -> newPassword empty"); user.setPassword(expected); user.setNewPassword(null); - serviceUser.copyUserAccount(user, destination); + getServiceUser().copyUserAccount(user, destination); Assert.assertEquals(expected, destination.getPassword()); } @@ -62,11 +67,11 @@ UserAccountDAO dao = PollenDAOHelper.getUserAccountDAO(transaction); log.info("test 1 : Good password"); - serviceUser.checkPassword(dao, "homer", encodedPassword); + getServiceUser().checkPassword(dao, "homer", encodedPassword); log.info("test 2 : Wrong password"); try { - serviceUser.checkPassword(dao, "homer", "bad"); + getServiceUser().checkPassword(dao, "homer", "bad"); } catch (PollenBusinessException eee) { log.error("Error : " + eee.getMessage()); Assert.assertEquals(PollenExceptionType.USER_WRONG_PASSWORD, @@ -264,14 +269,4 @@ } } - @Test - public void testCreateFavoriteParticipant() throws Exception { - start("testCreateFavoriteParticipant"); - - UserAccount user = createUser(false); - - // TODO : test on naturalId and nullity - - } - } \ No newline at end of file Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/UserListsCreate.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/UserListsCreate.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/UserListsCreate.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -11,7 +11,7 @@ import org.chorem.pollen.PollenBusinessException; import org.chorem.pollen.PollenBusinessException.PollenExceptionType; import org.chorem.pollen.entity.FavoriteList; -import org.chorem.pollen.service.ServiceUser; +import org.chorem.pollen.service.ServiceFavorite; import org.chorem.pollen.ui.base.PollenPage; import org.chorem.pollen.ui.services.PollenManager; import org.slf4j.Logger; @@ -40,7 +40,7 @@ private PollenManager manager; @Inject - private ServiceUser serviceUser; + private ServiceFavorite serviceFavorite; /** Properties **/ @Property @@ -63,13 +63,13 @@ logger.debug("User connected : " + page.getUserConnected()); } newFavoriteList = - serviceUser.getNewFavoriteList(page.getUserConnected()); + serviceFavorite.getNewFavoriteList(page.getUserConnected()); } } void onValidateFormFromCreateList() { try { - serviceUser.createFavoriteList(newFavoriteList); + serviceFavorite.createFavoriteList(newFavoriteList); } catch (PollenBusinessException eee) { String message = manager.getErrorMessage(eee, messages, logger); Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/UserListsUpdate.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/UserListsUpdate.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/components/UserListsUpdate.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -1,21 +1,24 @@ package org.chorem.pollen.ui.components; -import java.util.List; -import org.apache.tapestry5.ComponentResources; +import org.apache.commons.lang.StringUtils; import org.apache.tapestry5.annotations.InjectComponent; +import org.apache.tapestry5.annotations.Log; import org.apache.tapestry5.annotations.Parameter; -import org.apache.tapestry5.annotations.Persist; import org.apache.tapestry5.annotations.Property; +import org.apache.tapestry5.corelib.components.Form; import org.apache.tapestry5.corelib.components.Zone; +import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.annotations.Inject; +import org.chorem.pollen.PollenBusinessException; import org.chorem.pollen.bean.Filter; import org.chorem.pollen.entity.FavoriteList; import org.chorem.pollen.entity.FavoriteParticipant; -import org.chorem.pollen.entity.PollAccount; -import org.chorem.pollen.service.ServiceUser; +import org.chorem.pollen.service.ServiceFavorite; import org.chorem.pollen.ui.data.EvenOdd; import org.chorem.pollen.ui.data.FavoriteParticipantDataSource; +import org.chorem.pollen.ui.services.PollenManager; +import org.nuiton.web.tapestry5.components.FeedBack; import org.slf4j.Logger; /** @@ -31,41 +34,34 @@ */ public class UserListsUpdate { + /** Parameters of the component **/ @Parameter(required = true) - @Property - private List<PollAccount> source; + private FavoriteList source; + /** Services injected **/ @Inject private Logger logger; @Inject - private ComponentResources resources; + private ServiceFavorite serviceFavorite; @Inject - private ServiceUser serviceUser; + private PollenManager manager; - @Persist - @Property - private FavoriteList favoriteListSelected; + @Inject + private Messages messages; + /** Main properties for Grid **/ private EvenOdd evenOdd; - @Persist private FavoriteParticipantDataSource participants; @Property private FavoriteParticipant participant; - @Property - private FavoriteParticipant newParticipant; - @InjectComponent private Zone updateZone; - void setupRender() { - resources.discardPersistentFieldChanges(); - } - public EvenOdd getEvenOdd() { if (evenOdd == null) { evenOdd = new EvenOdd(); @@ -74,35 +70,215 @@ } public boolean canDisplayAccounts() { - return favoriteListSelected != null; + return source != null; } + /** + * Load participants data from serviceFavorite in a + * {@link FavoriteParticipantDataSource} to manage pagination and order. + * The filter added contains data for serviceFavorite (startIndex, endIndex, + * orderBy and referenceId). The reference is set to the source FavoriteList + * of the component, i.e. all FavoriteParticipants need to be part of the + * FavoriteList source. + * + * @return + */ public FavoriteParticipantDataSource getParticipants() { if (participants == null) { if (logger.isDebugEnabled()) { logger.debug("Create DATASOURCE"); } Filter filter = new Filter(); - filter.setReference(favoriteListSelected); + filter.setReference(source); participants = - new FavoriteParticipantDataSource(serviceUser, filter); + new FavoriteParticipantDataSource(serviceFavorite, filter); } return participants; } - void onActionFromRemoveParticipant(String UId) { - // NEED DELETE ACCOUNT FOR LIST + /***************************** EDIT PARTICIPANT FORM **********************/ + + /** + * FORM EVENTS ORDER -> RENDER : + * load size of participants dataSource + * call prepareForRender + * load participants data + * + * FORM EVENTS ORDER -> SUBMIT : + * call prepareForSubmit + * load size of participants dataSource + * load participants data + * load participantEdited to push form data + * call selected on submit button + * call validateForm + * call success or failure + * call submit + */ + + @InjectComponent + private Form participantsForm; + + @InjectComponent + private FeedBack participantsFeedback; + + private FavoriteParticipant participantEdited; + + @Property + private String participantEditedId; + + /** + * Test if the edited participant is the current one in the Grid. + * + * @return true if the participantEdited is defined and correspond to the + * current participant in the Grid + */ + public boolean isEditionMode() { + // The current participant in the loop is equals to the edited one + return participantEditedId != null && + participant.getId().equals(participantEditedId); } + /** + * ON_ACTION :: Handler method for action on editParticipant actionLink. + * The participantEdited will be set to the participant selected in the Grid + * with {@code id}. + * + * @param id key of the participant from the Grid + * @return the updateZone content to refresh + */ + Object onActionFromEditParticipant(String id) { + if (logger.isDebugEnabled()) { + logger.debug("Participant in edition : " + id); + } + participantEditedId = id; + return updateZone.getBody(); + } + + /** + * ON_ACTION :: Handler method for action on cancelEdition actionLink. + * Simply refresh the zone will change edition mode. + * + * @return the updateZone content to refresh + */ + Object onActionFromCancelEdition() { + return updateZone.getBody(); + } + + /** + * ON_ACTION :: Handler method for action on deletedAccount actionLink. + * The selected login from the Grid will be used to delete the user. + * + * @param login used to delete the user + * @return the updateZone content to refresh + * @see ServiceUser#deleteUser(String) + */ + Object onActionFromRemoveParticipant(String id) { + serviceFavorite.deleteFavoriteParticipant(id); + participantsFeedback.addInfo("Suppression OK"); + return updateZone; + } + + /** + * Getter to retrieve participantEdited. + * <br \> + * The participantEditedId is needed and was provided for render by the + * {@link #onActionFromEditParticipant(String)} method and for submit by + * the hidden field in the form that keep the id after rendering the form. + * The participantEdited is loaded from the participants dataSource that + * contains all FavoriteParticipant displayed in the Grid. The submit will + * reload the participants dataSource before saving modification on the + * FavoriteParticipant edited. + * + * @return the FavoriteParticipant in edition + */ + public FavoriteParticipant getParticipantEdited() { + if (participantEdited == null && participantEditedId != null) { + if (logger.isDebugEnabled()) { + logger.debug("Load from dataSource participantEditedId : " + + participantEditedId); + } + participantEdited = participants.get(participantEditedId); + } + return participantEdited; + } + + /** + * ON_VALIDATE_FORM :: Handler method for validateForm event of the + * usersForm. The accountEdited will be updated using serviceUser. Errors + * from service will be recorded into the usersForm. + * + * @see ServiceUser#updateUser(UserAccount, boolean) + */ + @Log + void onValidateFormFromParticipantsForm() { + if (logger.isDebugEnabled()) { + logger.debug("participant saved : " + participantEdited); + } + try { + serviceFavorite.updateFavoriteParticipant(participantEdited); + } catch (PollenBusinessException eee) { + String message = manager.getErrorMessage(eee, messages, logger); + participantsForm.recordError(message); + } + } + + /** + * ON_SUCCESS :: Handler method for success event of the participantsForm. + * Refresh the page to display a success message. + * + * @return the page container. + */ + Object onSuccessFromParticipantsForm() { + participantsFeedback.addInfo("Modification OK"); + // Clean form data before refresh zone + cleanFormData(); + return updateZone; + } + + protected void cleanFormData() { + participantEditedId = null; + participantEdited = null; + } + + /** + * ON_FAILURE :: Handler method for failure event of the participantsForm. + * Will display errors and keep participantEdited in edition. + * + * @return the updateZone to refresh + */ + Object onFailureFromParticipantsForm() { + return updateZone; + } + + /***************************** NEW PARTICIPANT FORM ***********************/ + + @Property + private FavoriteParticipant newParticipant; + + @InjectComponent + private Form addParticipant; + void onPrepareFromAddParticipant() { if (newParticipant == null) { newParticipant = - serviceUser.getNewFavoriteParticipant(favoriteListSelected); + serviceFavorite.getNewFavoriteParticipant(source); } } - Object onSuccessFromAddParticipant() { - serviceUser.createFavoriteParticipant(newParticipant); - return updateZone.getBody(); + void onValidateFormFromAddParticipant() { + if (logger.isDebugEnabled()) { + logger.debug("FavoriteList selected : " + source); + } + try { + serviceFavorite.createFavoriteParticipant(newParticipant); + } catch (PollenBusinessException eee) { + String message = manager.getErrorMessage(eee, messages, logger); + addParticipant.recordError(message); + } } + + Object onSubmitFromAddParticipant() { + participantsFeedback.addInfo("Ajout OK"); + return updateZone; + } } Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/data/FavoriteParticipantDataSource.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/data/FavoriteParticipantDataSource.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/data/FavoriteParticipantDataSource.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -6,8 +6,7 @@ import org.chorem.pollen.PollenException; import org.chorem.pollen.bean.Filter; import org.chorem.pollen.entity.FavoriteParticipant; -import org.chorem.pollen.entity.PollAccount; -import org.chorem.pollen.service.ServiceUser; +import org.chorem.pollen.service.ServiceFavorite; import org.nuiton.web.tapestry5.data.AbstractMappedGridDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,11 +28,12 @@ private static final Logger logger = LoggerFactory.getLogger(FavoriteParticipantDataSource.class); - private ServiceUser service; + private ServiceFavorite service; private Filter filter; - public FavoriteParticipantDataSource(ServiceUser service, Filter filter) { + public FavoriteParticipantDataSource(ServiceFavorite service, + Filter filter) { this.service = service; this.filter = filter; } @@ -53,12 +53,16 @@ @Override protected int count() throws PollenException { - return service.getNbFavoriteParticipants(filter); + int count = service.getNbFavoriteParticipants(filter); + if (logger.isDebugEnabled()) { + logger.debug("Nb elements : " + count); + } + return count; } @Override public Class<?> getRowType() { - return PollAccount.class; + return FavoriteParticipant.class; } } Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserLists.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserLists.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserLists.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -22,13 +22,16 @@ import org.apache.tapestry5.annotations.IncludeStylesheet; import org.apache.tapestry5.annotations.InjectComponent; import org.apache.tapestry5.annotations.Parameter; +import org.apache.tapestry5.annotations.Persist; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.ioc.annotations.Inject; +import org.apache.tapestry5.ioc.services.PropertyAccess; import org.chorem.pollen.entity.FavoriteList; -import org.chorem.pollen.service.ServiceUser; +import org.chorem.pollen.service.ServiceFavorite; import org.chorem.pollen.ui.base.AbstractPollenPage; import org.chorem.pollen.ui.components.Border; import org.chorem.pollen.ui.data.AddressBar; +import org.chorem.pollen.ui.data.GenericSelectModel; import org.chorem.pollen.ui.data.PollenRequiresAuthentication; /** @@ -41,276 +44,67 @@ * @version $Id$ */ @PollenRequiresAuthentication -@IncludeStylesheet("context:css/lists.css") +@IncludeStylesheet("context:css/users.css") public class UserLists extends AbstractPollenPage { @InjectComponent private Border border; + @Override + public Border getBorder() { + return border; + } + /** Page title from Messages **/ @Parameter(defaultPrefix = BindingConstants.MESSAGE, value = "pollen.page.UserLists.title") @Property private String title; + public AddressBar getAddressBar() { + return AddressBar.newBar().appendCurrent(title); + } + @Inject - private ServiceUser serviceUser; + private ServiceFavorite serviceFavorite; + @Inject + private PropertyAccess propertyAccess; + private List<FavoriteList> favoriteLists; + private GenericSelectModel<FavoriteList> favoriteListModel; - @Override - public Border getBorder() { - return border; + @Persist + @Property + private FavoriteList favoriteListSelected; + + public GenericSelectModel<FavoriteList> getFavoriteListModel() { + if (favoriteListModel == null) { + favoriteListModel = + new GenericSelectModel<FavoriteList>(getFavoriteLists(), + FavoriteList.class, + FavoriteList.NAME, + FavoriteList.NAME, + propertyAccess); + } + return favoriteListModel; } - - public AddressBar getAddressBar() { - return AddressBar.newBar().appendCurrent(title); - } public List<FavoriteList> getFavoriteLists() { if (favoriteLists == null) { - favoriteLists = serviceUser.getFavoriteLists(getUserConnected()); + favoriteLists = serviceFavorite.getFavoriteLists(getUserConnected()); } return favoriteLists; } - -// -// /** -// * Liste de favoris sélectionnée. -// */ -// @Persist -// @Property -// private PersonListDTO selectedList; + public boolean canDeleteList() { + return favoriteListSelected != null; + } -// /** -// * Nouvelle liste de favoris. -// */ -// @Property -// private PersonListDTO newList; -// -// /** -// * Compte courant (pour l'itération des votants de la liste). -// */ -// @SuppressWarnings("unused") -// @Property -// private PollAccountDTO account; -// -// /** -// * Nouveau compte. -// */ -// @Property -// private PollAccountDTO newAccount; -// -// /** -// * Fichier CSV contenant une liste de votants. -// */ -// @Property -// private UploadedFile accountsFile; -// -// /** -// * URL de recherche LDAP pour une liste de votants. -// */ -// @Property -// private String accountsUrl; -// -// /** -// * Zone à rafraîchir. -// */ -// @InjectComponent -// private Zone listsZone; -// -// /** -// * Formulaire de création de liste. -// */ -// @Component -// private Form createListForm; -// -// /** -// * Formulaire de création de compte. -// */ -// @Component -// private Form createAccountForm; -// -// /** -// * Messages. -// */ -// @Inject -// private Messages messages; -// -// /** -// * Objet servant à changer la couleur à chaque ligne de la liste. -// */ -// @SuppressWarnings("unused") -// -// @Parameter(defaultPrefix = BindingConstants.MESSAGE, value = "title") -// @Property -// private String title; -// -// @SuppressWarnings("unused") -// @Property -// private AddressBarItem[] address; -// -// /** -// * Sert à créer listModel. -// */ -// @Inject -// private BeanModelSource beanModelSource; -// -// /** -// * Sert à passer les messages en paramètre de la création de listModel. -// */ -// @Inject -// private ComponentResources componentResources; -// -// /** -// * Modèle pour l'affichage de la liste des favoris. -// */ -// @SuppressWarnings("unchecked") -// @Property -// @Retain -// private BeanModel listModel; -// -// /** Injection des services */ -// @Inject -// private ServiceList serviceList; -// @Inject -// private ServicePollAccount servicePollAccount; -// -// /** -// * Méthode appelée à la création d'une liste. -// */ -// Object onSuccessFromCreateListForm() { -// -// // Contrôle du nom de la liste -// for (PersonListDTO list : lists) { -// if (list.getName().equals(newList.getName())) { -// createListForm.recordError(messages.format("listExists", -// newList.getName())); -// return this; -// } -// } -// -// // Import CVS des comptes -// if (accountsFile != null) { -// if (!accountsFile.getContentType().equals("text/csv")) { -// createListForm.recordError(messages.format("invalidCsv", -// accountsFile.getFileName())); -// return this; -// } -// List<PollAccountDTO> accounts = CSVAccountUtil -// .importList(accountsFile); -// if (accounts.size() == 0) { -// createListForm.recordError(messages.format("noAccountCsv", -// accountsFile.getFileName())); -// return this; -// } -// newList.getPollAccounts().addAll(accounts); -// } -// -// // Import LDAP des comptes -// if (accountsUrl != null) { -// List<PollAccountDTO> accounts = LDAPAccountUtil -// .importList(accountsUrl); -// if (accounts.size() == 0) { -// createListForm.recordError(messages.format("noAccountLdap", -// accountsUrl)); -// return this; -// } -// newList.getPollAccounts().addAll(accounts); -// } -// -// // Création de la nouvelle liste -// newList.setUserId(user.getId()); -// newList.setId(serviceList.createPersonList(newList)); -// -// // Sélection de la liste courante -// lists = serviceList.findPersonListByUser(user.getId()); -// for (PersonListDTO list : lists) { -// if (list.getId().equals(newList.getId())) { -// selectedList = list; -// } -// } -// -// return this; -// } -// -// /** -// * Méthode appelée à la suppression d'une liste. -// */ -// Object onActionFromDeleteList() { -// if (selectedList != null) { -// for (PersonListDTO dto : lists) { -// if (dto.getId().equals(selectedList.getId())) { -// if (serviceList.deletePersonList(selectedList.getId())) { -// feedback.addInfo(messages.format("listDeleted", -// selectedList.getName())); -// } else { -// feedback.addError(messages.format("listNotDeleted", -// selectedList.getName())); -// } -// } -// } -// } -// selectedList = null; -// return this; -// } -// -// /** -// * Méthode appelée à la création d'un compte. -// */ -// Object onSuccessFromCreateAccountForm() { -// // TODO : use onValidateForm method : test return block, may be -// // a problem between failure and success -// for (PollAccountDTO dto : selectedList.getPollAccounts()) { -// if (dto.getVotingId().equals(newAccount.getVotingId())) { -// createAccountForm.recordError(messages.format("accountExists", -// newAccount.getVotingId())); -// } -// } -// if (!createAccountForm.getHasErrors()) { -//// newAccount.setPersonListId(selectedList.getId()); -//// selectedList.getPollAccounts().add(newAccount); -//// serviceList.updatePersonList(selectedList); -//// selectedList = serviceList.findPersonListById(selectedList.getId()); -// serviceList.createAccountInPersonList(selectedList, account); -// } -// return listsZone.getBody(); -// } -// -// /** -// * Méthode appelée à la suppression d'un compte. -// */ -// Object onActionFromDeleteAccount(String accountId) { -//// Iterator<PollAccountDTO> it = selectedList.getPollAccounts() -//// .iterator(); -//// while (it.hasNext()) { -//// if (accountId.equals(it.next().getId())) { -//// it.remove(); -//// } -//// } -//// serviceList.updatePersonList(selectedList); -//// servicePollAccount.deletePollAccount(accountId); -//// selectedList = serviceList.findPersonListById(selectedList.getId()); -// serviceList.deleteAccountFromPersonList(selectedList, accountId); -// return listsZone.getBody(); -// } -// -// /** -// * Récupération des exceptions du champs d'upload de fichier. -// */ -// Object onUploadException(FileUploadException ex) { -// createListForm.recordError("Upload exception: " + ex.getMessage()); -// return this; -// } -// -// /** Retourne vrai s'il n'existe aucune liste */ -// public boolean isListsNull() { -// return CollectionUtils.isEmpty(lists); -// } -// -// /** Retourne vrai si la liste sélectionnée est vide */ -// public boolean isSelectedListNull() { -// return selectedList == null; -// } + void onActionFromDeleteList() { + if (canDeleteList()) { + serviceFavorite.deleteFavoriteList(favoriteListSelected); + addInfo("Suppression OK"); + } + } } \ No newline at end of file Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserProfile.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserProfile.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/pages/user/UserProfile.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -100,7 +100,7 @@ /** * UserAccount for form edition */ - private UserAccount userEditable; + private UserAccount user; @Inject private Locale currentLocale; @@ -123,11 +123,11 @@ @Property private String passwordVerify; - public UserAccount getUserEditable() { - if (userEditable == null) { - userEditable = getUserConnected(); + public UserAccount getUser() { + if (user == null) { + user = getUserConnected(); } - return userEditable; + return user; } /** @@ -141,7 +141,7 @@ @Log void onValidateFormFromAccountForm() { // Check newPassword that must be equals to passwordVerify - String newPassword = userEditable.getNewPassword(); + String newPassword = user.getNewPassword(); if (StringUtils.isNotEmpty(newPassword) && !newPassword.equals(passwordVerify)) { accountForm.recordError(newPasswordField, @@ -152,12 +152,12 @@ try { // Update the user if (logger.isDebugEnabled()) { - logger.debug("TopiaId : " + userEditable.getTopiaId()); - logger.debug("Login : " + userEditable.getLogin()); - logger.debug("Password : " + userEditable.getPassword()); - logger.debug("NewPassword : " + userEditable.getNewPassword()); + logger.debug("TopiaId : " + user.getTopiaId()); + logger.debug("Login : " + user.getLogin()); +// logger.debug("Password : " + user.getPassword()); +// logger.debug("NewPassword : " + user.getNewPassword()); } - serviceUser.updateUser(userEditable, false); + serviceUser.updateUser(user, false); } catch (PollenBusinessException eee) { String message = manager.getErrorMessage(eee, messages, logger); switch (eee.getType()) { @@ -181,7 +181,7 @@ // Stay in edited mode to show errors edited = true; // Reset new password - userEditable.setNewPassword(null); + user.setNewPassword(null); return accountForm; } } Modified: trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/AppModule.java =================================================================== --- trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/AppModule.java 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/java/org/chorem/pollen/ui/services/AppModule.java 2010-05-06 10:35:53 UTC (rev 2987) @@ -29,12 +29,13 @@ import org.apache.tapestry5.services.ApplicationStateCreator; import org.apache.tapestry5.services.ApplicationStateManager; import org.apache.tapestry5.services.ComponentRequestFilter; -import org.apache.tapestry5.services.LibraryMapping; import org.apache.tapestry5.upload.services.UploadSymbols; import org.chorem.pollen.PollenContextImpl; import org.chorem.pollen.entity.UserAccount; import org.chorem.pollen.service.ServiceEmail; import org.chorem.pollen.service.ServiceEmailImpl; +import org.chorem.pollen.service.ServiceFavorite; +import org.chorem.pollen.service.ServiceFavoriteImpl; import org.chorem.pollen.service.ServicePoll; import org.chorem.pollen.service.ServicePollImpl; import org.chorem.pollen.service.ServiceUser; @@ -74,6 +75,12 @@ return service; } + public static ServiceFavorite buildServiceFavorite(PollenManager manager) { + ServiceFavoriteImpl service = new ServiceFavoriteImpl(); + service.setContext(manager.getContext()); + return service; + } + public static ServicePoll buildServicePoll(PollenManager manager) { ServicePollImpl service = new ServicePollImpl(); service.setContext(manager.getContext()); Modified: trunk/pollen-ui/src/main/resources/i18n/pollen-ui-fr_FR.properties =================================================================== --- trunk/pollen-ui/src/main/resources/i18n/pollen-ui-fr_FR.properties 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/resources/i18n/pollen-ui-fr_FR.properties 2010-05-06 10:35:53 UTC (rev 2987) @@ -26,17 +26,26 @@ pollen.ui.user.create.sendEmail=Un email a \u00E9t\u00E9 envoy\u00E9 au nouvel utilisateur %1$s \u00E0 l'adresse %2$s. pollen.ui.user.create.emailFailedShowPassword=Le mot de passe g\u00E9n\u00E9r\u00E9 est le suivant : %1$s pollen.ui.user.create.success=L'utilisateur %1$s a \u00E9t\u00E9 cr\u00E9\u00E9 avec succ\u00E8s. -pollen.ui.user.nbUsers=%1$d utilisateurs existants. -pollen.ui.user.update.edit=Modifier cet utilisateur. -pollen.ui.user.update.save=Enregistrer les modifications. -pollen.ui.user.update.cancel=Annuler les changements. -pollen.ui.user.delete=Supprimer cet utilisateur. +pollen.ui.user.nbUsers=%1$d utilisateurs existants +pollen.ui.user.update.edit=Modifier cet utilisateur +pollen.ui.user.update.save=Enregistrer les modifications +pollen.ui.user.update.cancel=Annuler les changements +pollen.ui.user.delete=Supprimer cet utilisateur pollen.ui.user.delete.confirmMessage=Etes-vous s\u00FBr de vouloir d\u00E9finitivement supprimer cet utilisateur ? pollen.ui.list.create.title=Cr\u00E9er une nouvelle liste pollen.ui.list.create.success=La liste %1$s a \u00E9t\u00E9 cr\u00E9\u00E9e avec succ\u00E8s. -pollen.ui.list.update.notSelected=Aucune liste s\u00E9lectionn\u00E9e. -pollen.ui.list.update.emptyList=Liste vide. Ajoutez des votants en saisissant leur nom et email. -pollen.ui.list.update.addParticipant=Ajouter un nouvel utilisateur \u00E0 la liste +pollen.ui.list.create.weightHelp=Ce chiffre correspond au poids du vote de la personne, c'est \u00E0 dire le nombre de voix que poss\u00E8de la personne dans le sondage. +pollen.ui.list.update.addParticipant=Ajouter un nouveau votant \u00E0 la liste +pollen.ui.list.delete=Supprimer la liste %1$s +pollen.ui.list.delete.confirmMessage=Etes-vous s\u00FBr de vouloir d\u00E9finitivement supprimer cette liste et l'int\u00E9gralit\u00E9 de ses votants ? +pollen.ui.list.notSelected=Aucune liste s\u00E9lectionn\u00E9e +pollen.ui.list.emptyList=Liste vide. Ajoutez des votants en saisissant leur nom et email. +pollen.ui.list.nbParticipants=%1$d votants contenus dans cette liste +pollen.ui.list.update.cancelEdition=Annuler les changements +pollen.ui.list.update.saveParticipant=Enregistrer les modifications +pollen.ui.list.update.updateParticipant=Modifier ce votant +pollen.ui.list.update.removeParticipant=Supprimer ce votant +pollen.ui.list.update.removeParticipant.confirmMessage=Etes-vous s\u00FBr de vouloir supprimer %1$s de la liste ? # OLD LOGIN_COMPONENT connectionLegend=Connexion @@ -59,6 +68,9 @@ listSelect-label= Liste listName-label= Nom name-label= Nom +weight-label=Poids +editEmail-regexp=^([a-zA-Z0-9_.+-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$ +editEmail-regexp-message=Adresse email invalide. ############################ CHOICE ############################################ pollen.ui.choice.delete.confirm=Etes-vous s\u00FBr de vouloir d\u00E9finitivement supprimer ce choix ? Modified: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/Border.tml =================================================================== --- trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/Border.tml 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/Border.tml 2010-05-06 10:35:53 UTC (rev 2987) @@ -156,9 +156,9 @@ <!-- Contenu --> <div id="${pageBodyId}" class="content"> <noscript> - <t:feedback t:id="errorJs" /> + <div t:type="nuiton/feedback" t:id="errorJs" /> </noscript> - <t:feedback t:id="borderFeedback" t:autoClear="false"/> + <div t:type="nuiton/feedback" t:id="borderFeedback" t:autoClear="false"/> <t:body /> </div> </div> Modified: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/UserListsCreate.tml =================================================================== --- trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/UserListsCreate.tml 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/UserListsCreate.tml 2010-05-06 10:35:53 UTC (rev 2987) @@ -1,34 +1,32 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <body xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> <t:zone t:id="createZone" t:update="show"> - <form t:type="form" t:id="createList" action="tapestry" t:zone="createZone"> - <div id="createListFormDiv"> - <t:errors/> - <fieldset> - <legend>${message:pollen.ui.list.create.title}</legend> - <div> - <label t:type="label" for="listName" />* : - <input t:type="textfield" t:id="listName" value="newFavoriteList.name" t:validate="required"/> - </div> - <!-- <div> - <t:label for="accountsFile" /> - <input t:type="upload" t:id="accountsFile" /> - <span t:type="ck/Tooltip" title="${message:help}" value="${message:accountsFile-help}" effect="appear"> - <img src="${asset:context:img/help.png}" alt="${message:help}"/> - </span> - </div> - <div> - <t:label for="accountsUrl" /> - <t:textfield t:id="accountsUrl" t:value="accountsUrl" /> - <span t:type="ck/Tooltip" title="${message:help}" value="${message:accountsUrl-help}" effect="appear"> - <img src="${asset:context:img/help.png}" alt="${message:help}"/> - </span> - </div>--> - <div class="buttons"> - <input t:type="submit" value="${message:pollen.ui.button.create}"/> - </div> - </fieldset> - </div> + <form t:type="form" class="createList" t:id="createList" action="tapestry" t:zone="createZone"> + <t:errors/> + <fieldset class="create"> + <legend>${message:pollen.ui.list.create.title}</legend> + <div> + <label t:type="label" for="listName" />* : + <input t:type="textfield" t:id="listName" value="newFavoriteList.name" t:validate="required"/> + </div> + <!-- <div> + <t:label for="accountsFile" /> + <input t:type="upload" t:id="accountsFile" /> + <span t:type="ck/Tooltip" title="${message:help}" value="${message:accountsFile-help}" effect="appear"> + <img src="${asset:context:img/help.png}" alt="${message:help}"/> + </span> + </div> + <div> + <t:label for="accountsUrl" /> + <t:textfield t:id="accountsUrl" t:value="accountsUrl" /> + <span t:type="ck/Tooltip" title="${message:help}" value="${message:accountsUrl-help}" effect="appear"> + <img src="${asset:context:img/help.png}" alt="${message:help}"/> + </span> + </div>--> + <div class="buttons"> + <input t:type="submit" value="${message:pollen.ui.button.create}"/> + </div> + </fieldset> </form> </t:zone> </body> Modified: trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/UserListsUpdate.tml =================================================================== --- trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/UserListsUpdate.tml 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/resources/org/chorem/pollen/ui/components/UserListsUpdate.tml 2010-05-06 10:35:53 UTC (rev 2987) @@ -1,34 +1,86 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <body xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> - <form t:type="form" t:id="selectListForm" action="tapestry"> - <div> - ${message:listSelect-label}: - <select t:id="listSelect" t:type="ck/beanSelect" t:list="source" t:value="favoriteListSelected" - t:labelField="literal:name" t:valueField="literal:name" /> - <input t:type="submit" value="${message:pollen.ui.button.ok}"/> - </div> - </form> - <t:if test="canDisplayAccounts()"> - <t:zone t:id="updateZone" show="show" update="show"> - <!-- Display all Accounts child of favoriteListSelected --> - <div t:type="grid" t:source="participants" t:row="participant" - t:include="name, email, weight" t:add="actions" - t:rowsPerPage="20" t:rowClass="prop:evenodd.next" t:inPlace="true"> - <p:actionsCell> - <a t:type="actionlink" t:id="removeParticipant" t:context="participant.id"> - <img src="${asset:context:img/delete.png}" alt="${message:pollen.ui.list.remove}"/> - </a> - </p:actionsCell> - <p:empty> - ${message:pollen.ui.list.update.emptyList} - </p:empty> - </div> + <div t:type="zone" class="updateZone" t:id="updateZone" t:update="show"> + <p class="center"> + <t:if t:test="participants.availableRows"> + ${format:pollen.ui.list.nbParticipants=participants.availableRows} + <p:else> + ${message:pollen.ui.list.emptyList} + </p:else> + </t:if> + </p> + <form t:type="form" t:id="participantsForm" action="tapestry" t:zone="updateZone"> + <t:errors /> + <p><input t:type="hidden" value="participantEditedId" /></p> + <!-- Display all Accounts child of favoriteList --> + <div t:type="grid" t:source="participants" t:row="participant" + t:include="name, email, weight" t:add="actions" + t:rowsPerPage="10" t:rowClass="prop:evenodd.next" t:inPlace="true"> + <p:nameCell> + <t:if t:test="editionMode"> + <input t:type="textfield" t:id="editName" value="participantEdited.name" t:validate="required" size="10" /> + <p:else>${participant.name}</p:else> + </t:if> + </p:nameCell> + <p:emailCell> + <t:if t:test="editionMode"> + <input t:type="textfield" t:id="editEmail" value="participantEdited.email" t:validate="regexp" size="15" /> + <p:else>${participant.email}</p:else> + </t:if> + </p:emailCell> + <p:weightCell> + <t:if t:test="editionMode"> + <input t:type="textfield" t:id="editWeight" value="participantEdited.weight" t:validate="required" size="1" /> + <p:else>${participant.weight}</p:else> + </t:if> + </p:weightCell> + <p:actionsCell> + <t:if t:test="editionMode"> + <a t:type="actionlink" t:id="cancelEdition" title="${message:pollen.ui.list.update.cancelEdition}" t:zone="updateZone"> + <img src="${asset:context:img/undo.png}" alt="${message:pollen.ui.list.update.cancelEdition}" /> + </a> + <input t:type="submit" t:id="saveParticipant" t:image="context:img/save.png" value="Save" + title="${message:pollen.ui.list.update.saveParticipant}" /> + <p:else> + <a t:type="actionlink" t:id="editParticipant" t:context="participant.id" t:zone="updateZone" + title="${message:pollen.ui.list.update.updateParticipant}"> + <img src="${asset:context:img/editSmall.png}" alt="${message:pollen.ui.list.update.updateParticipant}" /> + </a> + <a t:type="actionlink" t:id="removeParticipant" t:context="participant.id" t:zone="updateZone" + title="${message:pollen.ui.list.update.removeParticipant}" + t:mixins="nuiton/confirm" t:message="format:pollen.ui.list.update.removeParticipant.confirmMessage=participant.name"> + <img src="${asset:context:img/delete.png}" alt="${message:pollen.ui.list.update.removeParticipant}" /> + </a> + </p:else> + </t:if> + </p:actionsCell> + <p:empty /> + </div> + </form> + + <div t:type="nuiton/feedback" t:id="participantsFeedback" /> - <!-- Add a new FavoriteParticipant to favoriteListSelected --> - <form t:type="form" t:id="addParticipant" t:zone="updateZone" action="tapestry"> - <table class="t-data-grid"> + <!-- Add a new FavoriteParticipant to favoriteList --> + <form t:type="form" class="addParticipant" t:id="addParticipant" t:zone="updateZone" action="tapestry"> + <fieldset class="create"> + <legend>${message:pollen.ui.list.update.addParticipant}</legend> + <t:errors/> + <div> + <label t:type="label" for="name" />* : + <input t:type="textfield" t:id="name" t:value="newParticipant.name" t:validate="required" size="10"/> + <label t:type="label" for="email" /> : + <input t:type="textfield" t:id="email" t:value="newParticipant.email" t:validate="regexp" size="15"/> + <label t:type="label" for="weight" /> : + <input t:type="textfield" t:id="weight" t:value="newParticipant.weight" t:validate="required" size="1"/> + <span t:type="ck/Tooltip" t:title="message:pollen.ui.tooltip.help" t:value="message:pollen.ui.list.create.weightHelp" t:effect="appear"> + <img src="${asset:context:img/help.png}" alt="${message:pollen.ui.tooltip.help}"/> + </span> + <input t:type="submit" value="${message:pollen.ui.button.add}" title="${message:pollen.ui.list.update.addParticipant}"/> + </div> + </fieldset> + <!--<table class="t-data-grid"> <tr> <td class="votingId"> <input t:type="textfield" t:id="name" t:value="newParticipant.name" t:validate="required" size="10"/> @@ -43,8 +95,7 @@ <input t:type="submit" value="${message:pollen.ui.button.add}" title="${message:pollen.ui.list.update.addParticipant}"/> </td> </tr> - </table> - <t:errors/> + </table>--> </form> <!-- Delete the favoriteListSelected --> @@ -54,10 +105,10 @@ </a> </p>--> - </t:zone> + </div> <p:else> - ${message:pollen.ui.list.update.notSelected} + <p class="center">${message:pollen.ui.list.notSelected}</p> </p:else> </t:if> </body> Modified: trunk/pollen-ui/src/main/webapp/admin/AdminUsers.tml =================================================================== --- trunk/pollen-ui/src/main/webapp/admin/AdminUsers.tml 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/webapp/admin/AdminUsers.tml 2010-05-06 10:35:53 UTC (rev 2987) @@ -71,8 +71,8 @@ <input t:type="textfield" t:id="newLogin" value="newUser.login" t:validate="required" /> <label t:type="label" for="newEmail">${message:email-label}</label> : <input t:type="textfield" t:id="newEmail" value="newUser.email" t:validate="regexp" /> - <span t:type="ck/Tooltip" title="message:pollen.ui.tooltip.help" t:value="message:pollen.ui.user.create.passwordHelp" t:effect="appear"> - <img src="${asset:context:img/help.png}" alt="message:help"/> + <span t:type="ck/Tooltip" t:title="message:pollen.ui.tooltip.help" t:value="message:pollen.ui.user.create.passwordHelp" t:effect="appear"> + <img src="${asset:context:img/help.png}" alt="${message:pollen.ui.tooltip.help}"/> </span> <input t:type="submit" value="${message:pollen.ui.button.add}" title="${message:pollen.ui.user.create.title}" /> </p> Modified: trunk/pollen-ui/src/main/webapp/css/common.css =================================================================== --- trunk/pollen-ui/src/main/webapp/css/common.css 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/webapp/css/common.css 2010-05-06 10:35:53 UTC (rev 2987) @@ -34,31 +34,6 @@ display: block; } -/** feedback.css not worked yet in nuiton-tapestry-extra **/ -.fb-error { - width: 400px; - margin: auto; - text-align: center; - color: #000; - font-weight: bold; - padding: 3px; - border: solid; - border-color: #f00; - border-width: 2px; - margin-bottom: 10px; -} - -.fb-info { - width: 400px; - margin: auto; - text-align: center; - color: #000; - padding: 3px; - border: solid; - border-color: #000; - border-width: 2px; -} - .center { text-align: center; } @@ -76,3 +51,7 @@ background: url(../img/save.png) no-repeat center center; } +.mbottom5 { + margin-bottom: 5px; +} + Deleted: trunk/pollen-ui/src/main/webapp/css/lists.css =================================================================== --- trunk/pollen-ui/src/main/webapp/css/lists.css 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/webapp/css/lists.css 2010-05-06 10:35:53 UTC (rev 2987) @@ -1,122 +0,0 @@ -#listsZone { - width: 970px; - margin: auto; - text-align: center; - margin-bottom: 40px; -} - -#createListFormDiv { - width: 450px; - margin: auto; -} - -#createListFormDiv legend { - color: #727a7e; - font-weight: bold; -} - -#createListFormDiv fieldset { - width: 380px; - border: 1px solid #aab; - padding: 15px; - padding-bottom: 10px; - margin: auto; - vertical-align: top; - text-align: left; -} - -/*#createListFormDiv label { - display: block; - width: 80px; - float: left; -}*/ - -#createListForm div { - margin-bottom: 10px; -} - -.buttons { - text-align: center; - margin-top: 20px; -} - -DIV.t-data-grid { - font-family: Arial, Helvetica, sans-serif; - margin-top:20px; - margin-bottom:20px; -} - -DIV.t-data-grid-pager { - margin: 8px 0px; -} - -DIV.t-data-grid-pager A, DIV.t-data-grid-pager SPAN.current { - text-decoration: none; - padding: 2px 5px; - font-size: 14px; - margin-right: 5px; -} - -DIV.t-data-grid-pager A { - background-color: #32b5c9; - border: 1px solid #aab; - color: #fff; -} - -DIV.t-data-grid-pager A:hover { - border: 1px solid #000; - color: #000; -} - -DIV.t-data-grid-pager SPAN.current { - color: #fff; - border: 1px solid #32b5c9; - background-color: #000; -} - -TABLE.t-data-grid { - border-collapse: collapse; - border-left: 1px solid #aab; - border-top: 1px solid #aab; - background-color: #fff; - font-size: 14px; - margin: auto; - width: 400px; -} - -TABLE.t-data-grid THEAD { - border-top: 1px solid #aab; /* For Firefox */ -} - -TABLE.t-data-grid THEAD TR { - color: #fff; - background-color: #32b5c9; -} - -TABLE.t-data-grid THEAD TR a { - color: #fff; - background-color: #32b5c9; -} - -TABLE.t-data-grid THEAD TR TH { - text-align: left; - padding: 2px 3px; - white-space: nowrap; - border-right: 1px solid #aab; - border-bottom: 1px solid #aab; - background-color:#32b5c9; -} - -TABLE.t-data-grid TBODY TR { - background-color: #fff; -} - -TABLE.t-data-grid TBODY TR.odd { - background-color: #bce7ed; -} - -TABLE.t-data-grid TBODY TR TD { - border-right: 1px solid #aab; - border-bottom: 1px solid #aab; - padding: 2px 5px; -} \ No newline at end of file Modified: trunk/pollen-ui/src/main/webapp/css/main.css =================================================================== --- trunk/pollen-ui/src/main/webapp/css/main.css 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/webapp/css/main.css 2010-05-06 10:35:53 UTC (rev 2987) @@ -1,13 +1,13 @@ body { - background-color: #FFF; - background-repeat: no-repeat; - background-position: bottom right; - background-attachment: fixed; - border: none; - font-family: "Trebuchet MS", Arial, sans-serif; - font-size: small; - width: 1000px; - margin: auto; + background-color: #FFF; + background-repeat: no-repeat; + background-position: bottom right; + background-attachment: fixed; + border: none; + font-family: "Trebuchet MS", Arial, sans-serif; + font-size: small; + width: 1000px; + margin: auto; } #CreationBody { @@ -23,17 +23,17 @@ } body a { - color: #727a7e; + color: #727a7e; } body a img { - border: none; + border: none; } body ul { - list-style-type: none; - margin: 0px; - padding: 0px; + list-style-type: none; + margin: 0px; + padding: 0px; } /*Haut de page*/ @@ -62,31 +62,31 @@ } #po-header-connection { - float: right; - vertical-align: top; - position: relative; - margin-right: 10px; - text-align: right; + float: right; + vertical-align: top; + position: relative; + margin-right: 10px; + text-align: right; } #po-header-connection form { - margin: 0px; - padding: 0px; - width: 200px; + margin: 0px; + padding: 0px; + width: 200px; } #po-header-connection a, #po-header-connection span { - padding: 1px; - padding-left: 5px; - padding-right: 5px; - text-decoration: none; - cursor: pointer; + padding: 1px; + padding-left: 5px; + padding-right: 5px; + text-decoration: none; + cursor: pointer; } #po-header-connection a:hover, #po-header-connection span:hover { - -moz-border-radius: 10px; + -moz-border-radius: 10px; background-color: #000; color: #fff; } @@ -112,80 +112,80 @@ } #top { - padding: 7px; - text-align: left; - vertical-align: middle; + padding: 7px; + text-align: left; + vertical-align: middle; } #top a { - color: #000; - text-decoration: none; + color: #000; + text-decoration: none; } #menu { - display: inline; + display: inline; } #menu li { - cursor: pointer; + cursor: pointer; } #menu li a { - padding: 1px; - padding-left: 5px; - padding-right: 5px; + padding: 1px; + padding-left: 5px; + padding-right: 5px; } #menu li a:hover { - -moz-border-radius: 10px; - background-color: #000; - color: #fff; + -moz-border-radius: 10px; + background-color: #000; + color: #fff; } .menu_elt { - display: inline; - margin-right: 40px; - position: relative; + display: inline; + margin-right: 40px; + position: relative; } /** DROPDOWN MENU **/ .dropdown_menu { - padding-top: 9px; - position: absolute; - z-index: 20; + padding-top: 9px; + position: absolute; + z-index: 20; } .dropdown_menu .top_leftIndex { - height: 16px; - width: 16px; - border: none; - background-image: url("../img/topleft_menuIndex.png"); - background-repeat: no-repeat; - background-position: left; - float: left; + height: 16px; + width: 16px; + border: none; + background-image: url("../img/topleft_menuIndex.png"); + background-repeat: no-repeat; + background-position: left; + float: left; } .dropdown_menu .top_rightIndex { - height: 16px; - width: 16px; - border: none; - background-image: url("../img/topright_menuIndex.png"); - background-repeat: no-repeat; - background-position: right; - float: right; + height: 16px; + width: 16px; + border: none; + background-image: url("../img/topright_menuIndex.png"); + background-repeat: no-repeat; + background-position: right; + float: right; } .dropdown_menu .top_middleIndex { - margin: 15px; - margin-bottom: 0px; - margin-top: 0px; - background-color: #ff0; - border-top: none; - -moz-border-radius-bottomright: 15px; - -moz-border-radius-bottomleft: 15px; - padding: 10px; - padding-top: 0px; - min-width: 140px; + margin: 15px; + margin-bottom: 0px; + margin-top: 0px; + background-color: #ff0; + border-top: none; + -moz-border-radius-bottomright: 15px; + -moz-border-radius-bottomleft: 15px; + padding: 10px; + padding-top: 0px; + min-width: 140px; } .dropdown_menu .top_leftCreation { @@ -288,10 +288,10 @@ } .dropdown_menu li { - z-index: 25; - padding: 3px; - display: block; - letter-spacing: 0px; + z-index: 25; + padding: 3px; + display: block; + letter-spacing: 0px; } #menu1 { @@ -305,29 +305,29 @@ } #login_menu { - top: 12px; - right: -10px; + top: 12px; + right: -10px; } #compte_menu { - top: 12px; - right: -25px; + top: 12px; + right: -25px; } HTML>BODY DIV.t-error LI { - margin-left: 0px; + margin-left: 10px; } /* Le corps de la page */ #corps { - text-align: justify; - color: #000; - border: none; - min-height: 300px; + text-align: justify; + color: #000; + border: none; + min-height: 300px; } #corps h1,h2,h3,h4 { - text-align: center; + text-align: center; } #corps .titleIndex { @@ -353,16 +353,16 @@ } #corps h2 { - color: #727a7e; + color: #727a7e; } #po-header-addressBar { - padding: 5px; - margin-left: 350px; + padding: 5px; + margin-left: 350px; } .IndexAddress { - background-color: #ffffaa; + background-color: #ffffaa; } .CreationAddress { @@ -370,7 +370,7 @@ } .VoteAddress { - background-color: #b0f580; + background-color: #b0f580; } .VoteCountingAddress { @@ -378,20 +378,20 @@ } .content { - padding: 15px; + padding: 15px; } /* Pied de page */ #po-footer { - padding: 5px; - font-size: small; - text-align: center; - margin-top: 20px; + padding: 5px; + font-size: small; + text-align: center; + margin-top: 20px; } #po-footer a, #po-footer span { - color:#727a7e; + color:#727a7e; } /** old LoginComponent > Connexion page **/ Added: trunk/pollen-ui/src/main/webapp/css/users.css =================================================================== --- trunk/pollen-ui/src/main/webapp/css/users.css (rev 0) +++ trunk/pollen-ui/src/main/webapp/css/users.css 2010-05-06 10:35:53 UTC (rev 2987) @@ -0,0 +1,176 @@ +/* + Document : users + Created on : 5 mai 2010, 11:15:04 + Author : fdesbois + Description: + Purpose of the stylesheet follows. +*/ + +/********************************************/ +/************** UserLists *****************/ +/********************************************/ +#p-userLists DIV.updateZone DIV.fb-info { + margin-bottom: 10px; +} + +#p-userLists FIELDSET.create { + border: 1px solid #aab; + padding: 15px; + padding-bottom: 10px; + margin: auto; + vertical-align: top; + text-align: left; +} + +#p-userLists FIELDSET.create LEGEND { + color: #727a7e; + font-weight: bold; +} + +#p-userLists FORM.participantsForm DIV.t-error { + width: 600px; + margin: auto; +} + +#p-userLists FORM.addParticipant FIELDSET { + width: 580px; + margin-bottom: 20px; +} + +#p-userLists FORM.createList FIELDSET { + width: 450px; +} + +/*#listsZone { + width: 970px; + margin: auto; + text-align: center; + margin-bottom: 40px; +}*/ + +.buttons { + text-align: center; + margin-top: 20px; +} + +/*#createListFormDiv { + width: 450px; + margin: auto; +} + +#createListFormDiv legend { + color: #727a7e; + font-weight: bold; +} + +#createListFormDiv fieldset { + width: 380px; + border: 1px solid #aab; + padding: 15px; + padding-bottom: 10px; + margin: auto; + vertical-align: top; + text-align: left; +} + +#createListForm div { + margin-bottom: 10px; +}*/ + +/*#createListFormDiv label { + display: block; + width: 80px; + float: left; +}*/ + +DIV.t-data-grid { + font-family: Arial, Helvetica, sans-serif; + margin-top:20px; + margin-bottom:20px; +} + +DIV.t-data-grid-pager { + text-align: center; +} + +DIV.t-data-grid-pager A, DIV.t-data-grid-pager SPAN.current { + text-decoration: none; + padding: 2px 5px; + font-size: 14px; + margin-right: 5px; +} + +DIV.t-data-grid-pager A { + background-color: #32b5c9; + border: 1px solid #aab; + color: #fff; +} + +DIV.t-data-grid-pager A:hover { + border: 1px solid #000; + color: #000; +} + +DIV.t-data-grid-pager SPAN.current { + color: #fff; + border: 1px solid #32b5c9; + background-color: #000; +} + +TABLE.t-data-grid { + border-collapse: collapse; + border-left: 1px solid #aab; + border-top: 1px solid #aab; + background-color: #fff; + font-size: 14px; + margin: auto; + width: 500px; +} + +TABLE.t-data-grid THEAD { + border-top: 1px solid #aab; /* For Firefox */ +} + +TABLE.t-data-grid THEAD TR { + color: #fff; + background-color: #32b5c9; +} + +TABLE.t-data-grid THEAD TR a { + color: #fff; + background-color: #32b5c9; +} + +TABLE.t-data-grid THEAD TR TH { + text-align: left; + padding: 2px 3px; + white-space: nowrap; + border-right: 1px solid #aab; + border-bottom: 1px solid #aab; + background-color:#32b5c9; +} + +TABLE.t-data-grid THEAD TR TH.weight { + width: 50px; +} + +TABLE.t-data-grid THEAD TR TH.actions { + width: 50px; +} + +TABLE.t-data-grid TBODY TR { + background-color: #fff; +} + +TABLE.t-data-grid TBODY TR.odd { + background-color: #bce7ed; +} + +TABLE.t-data-grid TBODY TR TD { + border-right: 1px solid #aab; + border-bottom: 1px solid #aab; + padding: 2px 5px; +} + + + Property changes on: trunk/pollen-ui/src/main/webapp/css/users.css ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/pollen-ui/src/main/webapp/user/UserLists.tml =================================================================== --- trunk/pollen-ui/src/main/webapp/user/UserLists.tml 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/webapp/user/UserLists.tml 2010-05-06 10:35:53 UTC (rev 2987) @@ -1,15 +1,25 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<t:border t:addressBar="addressBar" t:pageLogo="literal:Creation" t:pageTitle="prop:title" +<t:border t:addressBar="addressBar" t:pageLogo="literal:Creation" t:pageTitle="prop:title" t:pageBodyId="p-userLists" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> <h1 class="titleCreation">${title}</h1> - <div id="listsDiv"> + <t:if test="favoriteLists"> + <form t:type="form" t:id="selectFavoriteList" action="tapestry"> + <div class="center"> + <label t:type="label" for="listSelect" /> : + <select t:type="select" t:id="listSelect" t:model="favoriteListModel" t:encoder="favoriteListModel" + t:value="favoriteListSelected" onChange="this.form.submit()" /> + <t:if t:test="canDeleteList()"> + + <a t:type="actionlink" t:id="deleteList" title="${format:pollen.ui.list.delete=favoriteListSelected.name}" + t:mixins="nuiton/confirm" t:message="pollen.ui.list.delete.confirmMessage"> + <img src="${asset:context:img/delete.png}" alt="${format:pollen.ui.list.delete=favoriteListSelected.name}" /> + </a> + </t:if> + </div> + </form> + <t:userListsUpdate t:id="update" t:source="favoriteListSelected" /> + </t:if> - <t:if test="favoriteLists"> - <t:userListsUpdate t:source="favoriteLists" /> - </t:if> - - <t:userListsCreate /> - - </div> + <t:userListsCreate /> </t:border> \ No newline at end of file Modified: trunk/pollen-ui/src/main/webapp/user/UserProfile.tml =================================================================== --- trunk/pollen-ui/src/main/webapp/user/UserProfile.tml 2010-05-04 16:24:31 UTC (rev 2986) +++ trunk/pollen-ui/src/main/webapp/user/UserProfile.tml 2010-05-06 10:35:53 UTC (rev 2987) @@ -1,98 +1,91 @@ <t:border t:addressBar="addressBar" t:pageLogo="literal:Creation" - xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> + xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd" xmlns:p="tapestry:parameter"> <h1 class="titleCreation">${message:title}</h1> - <t:if test="userExists"> - - <t:zone t:id="accountZone" show="show" update="show"> - <t:form t:id="accountForm" zone="accountZone"> - <div id="myAccountFormDiv"> - <div id="myAccountError"> - <t:errors /> - </div> - <FieldSet> - <legend>${message:connectionInfoLegend}</legend> - <div> - <label>${message:login-label}</label> - ${user.login} - </div> - <t:if test="edited"> - <div> - <t:label for="password" /> - <t:PasswordField t:id="password" t:value="userEditable.password" t:validate="required,minlength=6" /> - </div> - <div> - <t:label for="newPassword1" /> - <t:PasswordField t:id="newPassword1" t:value="userEditable.newPassword" t:validate="minlength=6" /> - </div> - <div> - <t:label for="passwordVerify" /> - <t:PasswordField t:id="passwordVerify" t:value="passwordVerify" t:validate="minlength=6" /> - </div> - </t:if> - </FieldSet> + <t:zone t:id="accountZone" show="show" update="show"> + <t:form t:id="accountForm" zone="accountZone"> + <div id="myAccountFormDiv"> + <div id="myAccountError"> + <t:errors /> + </div> - <FieldSet> - <legend>${message:userInfoLegend}</legend> + <FieldSet> + <legend>${message:connectionInfoLegend}</legend> + <div> + <label>${message:login-label}</label> + ${user.login} + </div> + <t:if test="edited"> <div> - <t:label for="email" /> - <t:if test="edited"> - <t:TextField t:id="email" t:value="userEditable.email" t:validate="regexp" /> - <p:else> - <t:if test="user.email"> - ${user.email} - <p:else>-</p:else> - </t:if> - </p:else> - </t:if> + <t:label for="password" /> + <t:PasswordField t:id="password" t:value="user.password" t:validate="required,minlength=6" /> </div> <div> - <t:label for="firstName" /> - <t:if test="edited"> - <t:TextField t:id="firstName" t:value="userEditable.firstName" /> - <p:else> - <t:if test="user.firstName"> - ${user.firstName} - <p:else>-</p:else> - </t:if> - </p:else> - </t:if> + <t:label for="newPassword1" /> + <t:PasswordField t:id="newPassword1" t:value="user.newPassword" t:validate="minlength=6" /> </div> <div> - <t:label for="lastName" /> - <t:if test="edited"> - <t:TextField t:id="lastName" t:value="userEditable.lastName" /> - <p:else> - <t:if test="user.lastName"> - ${user.lastName} - <p:else>-</p:else> - </t:if> - </p:else> - </t:if> + <t:label for="passwordVerify" /> + <t:PasswordField t:id="passwordVerify" t:value="passwordVerify" t:validate="minlength=6" /> </div> - </FieldSet> + </t:if> + </FieldSet> - <div class="buttons"> + <FieldSet> + <legend>${message:userInfoLegend}</legend> + <div> + <t:label for="email" /> <t:if test="edited"> - <input type="submit" value="${message:submit-label}" /> - <a t:type="pagelink" t:page="user/profile" style="text-decoration: none;"> - <input type="button" value="${message:cancel-action}" /> - </a> + <t:TextField t:id="email" t:value="user.email" t:validate="regexp" /> <p:else> - <a t:type="actionlink" t:id="editAccount" style="text-decoration: none;"> - <input type="button" value="${message:edit-action}" /> - </a> + <t:if test="user.email"> + ${user.email} + <p:else>-</p:else> + </t:if> </p:else> </t:if> </div> + <div> + <t:label for="firstName" /> + <t:if test="edited"> + <t:TextField t:id="firstName" t:value="user.firstName" /> + <p:else> + <t:if test="user.firstName"> + ${user.firstName} + <p:else>-</p:else> + </t:if> + </p:else> + </t:if> + </div> + <div> + <t:label for="lastName" /> + <t:if test="edited"> + <t:TextField t:id="lastName" t:value="user.lastName" /> + <p:else> + <t:if test="user.lastName"> + ${user.lastName} + <p:else>-</p:else> + </t:if> + </p:else> + </t:if> + </div> + </FieldSet> + + <div class="buttons"> + <t:if test="edited"> + <input type="submit" value="${message:submit-label}" /> + <a t:type="pagelink" t:page="user/profile" style="text-decoration: none;"> + <input type="button" value="${message:cancel-action}" /> + </a> + <p:else> + <a t:type="actionlink" t:id="editAccount" style="text-decoration: none;"> + <input type="button" value="${message:edit-action}" /> + </a> + </p:else> + </t:if> </div> - </t:form> - </t:zone> - - <p:else> - <h4>${message:noUser}</h4> - <t:LoginComponent /> - </p:else> - </t:if> + </div> + </t:form> + </t:zone> </t:border> \ No newline at end of file