branch develop updated (0b2a29da -> 8bba608d)
This is an automated email from the git hooks/post-receive script. New change to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git from 0b2a29da refs #173 : correction des tests new 8bba608d refs #209 : Ajout de la liste d'emargement pour les sondage restreints The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 8bba608d74628b1bc8687c25da19b931a7441739 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Fri Jun 15 11:41:59 2018 +0200 refs #209 : Ajout de la liste d'emargement pour les sondage restreints Summary of changes: .../chorem/pollen/rest/api/v1/VoterListApi.java | 26 ++++ pollen-services/pom.xml | 5 + .../org/chorem/pollen/services/bean/PollBean.java | 10 ++ .../pollen/services/bean/VoterListMemberBean.java | 10 ++ .../pollen/services/service/CommentService.java | 16 -- .../pollen/services/service/PollService.java | 3 + .../services/service/PollenServiceSupport.java | 18 +++ .../pollen/services/service/VoteService.java | 17 -- .../pollen/services/service/VoterListService.java | 77 +++++++++- .../service/security/PollenPermissions.java | 4 + .../services/service/security/SecurityService.java | 7 + .../i18n/pollen-services_en_GB.properties | 1 + .../i18n/pollen-services_fr_FR.properties | 1 + pollen-ui-riot-js/src/main/web/i18n/en.json | 4 + pollen-ui-riot-js/src/main/web/i18n/fr.json | 4 + pollen-ui-riot-js/src/main/web/js/Poll.js | 9 ++ pollen-ui-riot-js/src/main/web/js/PollService.js | 18 +++ pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 14 ++ .../src/main/web/tag/poll/Participants.tag.html | 171 +++++++++++++++++++++ .../src/main/web/tag/poll/Poll.tag.html | 31 ++-- pom.xml | 6 +- 21 files changed, 401 insertions(+), 51 deletions(-) create mode 100644 pollen-ui-riot-js/src/main/web/tag/poll/Participants.tag.html -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 8bba608d74628b1bc8687c25da19b931a7441739 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Fri Jun 15 11:41:59 2018 +0200 refs #209 : Ajout de la liste d'emargement pour les sondage restreints --- .../chorem/pollen/rest/api/v1/VoterListApi.java | 26 ++++ pollen-services/pom.xml | 5 + .../org/chorem/pollen/services/bean/PollBean.java | 10 ++ .../pollen/services/bean/VoterListMemberBean.java | 10 ++ .../pollen/services/service/CommentService.java | 16 -- .../pollen/services/service/PollService.java | 3 + .../services/service/PollenServiceSupport.java | 18 +++ .../pollen/services/service/VoteService.java | 17 -- .../pollen/services/service/VoterListService.java | 77 +++++++++- .../service/security/PollenPermissions.java | 4 + .../services/service/security/SecurityService.java | 7 + .../i18n/pollen-services_en_GB.properties | 1 + .../i18n/pollen-services_fr_FR.properties | 1 + pollen-ui-riot-js/src/main/web/i18n/en.json | 4 + pollen-ui-riot-js/src/main/web/i18n/fr.json | 4 + pollen-ui-riot-js/src/main/web/js/Poll.js | 9 ++ pollen-ui-riot-js/src/main/web/js/PollService.js | 18 +++ pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 14 ++ .../src/main/web/tag/poll/Participants.tag.html | 171 +++++++++++++++++++++ .../src/main/web/tag/poll/Poll.tag.html | 31 ++-- pom.xml | 6 +- 21 files changed, 401 insertions(+), 51 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/VoterListApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/VoterListApi.java index 2b132b12..50dd0a2a 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/VoterListApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/VoterListApi.java @@ -26,13 +26,17 @@ import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.VoterList; import org.chorem.pollen.persistence.entity.VoterListMember; import org.chorem.pollen.rest.api.beans.VoterListSaveBean; +import org.chorem.pollen.services.bean.PaginationParameterBean; +import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; +import org.chorem.pollen.services.bean.export.ExportBean; import org.chorem.pollen.services.service.InvalidFormException; import org.chorem.pollen.services.service.VoterListService; +import javax.ws.rs.BeanParam; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -43,6 +47,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.util.List; import java.util.Set; @@ -150,6 +155,27 @@ public class VoterListApi { } + @Path("/polls/{pollId}/participants") + @GET + public PaginationResultBean<VoterListMemberBean> getMembers(@Context VoterListService voterListService, + @PathParam("pollId") PollenEntityId<Poll> pollId, + @BeanParam PaginationParameterBean paginationParameter) { + + return voterListService.getAllVoterListMembers(pollId.getEntityId(), paginationParameter); + + } + + @Path("/polls/{pollId}/participants/exports") + @GET + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response exportFavoriteLists(@Context VoterListService voterListService, + @PathParam("pollId") PollenEntityId<Poll> pollId) { + + ExportBean exportBean = voterListService.exportAllVoterListMembers(pollId.getEntityId()); + + return ApiUtils.exportBeanToResponse(exportBean); + } + @Path("/polls/{pollId}/voterLists/{voterListId}/members") @POST public VoterListMemberBean addMember(@Context VoterListService voterListService, diff --git a/pollen-services/pom.xml b/pollen-services/pom.xml index 30c9ff2d..374d9bd0 100644 --- a/pollen-services/pom.xml +++ b/pollen-services/pom.xml @@ -181,6 +181,11 @@ <artifactId>nuiton-config</artifactId> </dependency> + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-csv</artifactId> + </dependency> + <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java index 5cd77515..6b8960d1 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java @@ -106,6 +106,8 @@ public class PollBean extends PollenBean<Poll> { protected boolean voteIsVisible; + protected boolean participantsIsVisible; + protected boolean canVote; protected long commentCount; @@ -318,6 +320,14 @@ public class PollBean extends PollenBean<Poll> { this.voteIsVisible = voteIsVisible; } + public boolean isParticipantsIsVisible() { + return participantsIsVisible; + } + + public void setParticipantsIsVisible(boolean participantsIsVisible) { + this.participantsIsVisible = participantsIsVisible; + } + public boolean isCanVote() { return canVote; } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListMemberBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListMemberBean.java index 2a0d21f2..4d881f75 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListMemberBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListMemberBean.java @@ -34,6 +34,8 @@ public class VoterListMemberBean extends PollenBean<VoterListMember> { protected String name; + protected String avatar; + protected String email; protected double weight; @@ -58,6 +60,14 @@ public class VoterListMemberBean extends PollenBean<VoterListMember> { this.name = name; } + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + public String getEmail() { return email; } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java index 11cad0ab..1a38cdb6 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/CommentService.java @@ -292,20 +292,4 @@ public class CommentService extends PollenServiceSupport { } - protected PaginationParameter getPaginationParameter(PaginationParameterBean paginationParameter) { - - if (paginationParameter == null) { - - paginationParameter = PaginationParameterBean.of( - 0, - PAGE_SIZE_DEFAULT, - Comment.PROPERTY_TOPIA_CREATE_DATE, - true); - - } - - return paginationParameter.toPaginationParameter(); - - } - } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java index 6f20b476..aea55ec6 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java @@ -170,6 +170,9 @@ public class PollService extends PollenServiceSupport { bean.setResultIsVisible(resultIsVisible); + boolean canReadParticipants = isPermitted(PollenPermissions.readParticipants(entity)); + bean.setParticipantsIsVisible(canReadParticipants); + boolean canVote = isPermitted(PollenPermissions.addVote(entity)); bean.setCanVote(canVote); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java index 7862bf41..6eac8118 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java @@ -53,6 +53,7 @@ import org.chorem.pollen.persistence.entity.VoterListTopiaDao; import org.chorem.pollen.services.PollenService; import org.chorem.pollen.services.PollenServiceContext; import org.chorem.pollen.services.PollenUIContext; +import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenBean; import org.chorem.pollen.services.bean.PollenBeans; @@ -67,6 +68,7 @@ import org.nuiton.topia.persistence.TopiaDao; import org.nuiton.topia.persistence.TopiaEntity; import org.nuiton.topia.persistence.TopiaIdFactory; import org.nuiton.util.StringUtil; +import org.nuiton.util.pagination.PaginationParameter; import org.nuiton.util.pagination.PaginationResult; import java.util.Collection; @@ -529,4 +531,20 @@ public abstract class PollenServiceSupport implements PollenService { token); } + protected PaginationParameter getPaginationParameter(PaginationParameterBean paginationParameter) { + + if (paginationParameter == null) { + + paginationParameter = PaginationParameterBean.of( + 0, + PAGE_SIZE_DEFAULT, + TopiaEntity.PROPERTY_TOPIA_CREATE_DATE, + true); + + } + + return paginationParameter.toPaginationParameter(); + + } + } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java index 5cac2fb8..852fe3ad 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java @@ -44,7 +44,6 @@ import org.chorem.pollen.services.bean.VoteToChoiceBean; import org.chorem.pollen.services.service.security.PollenPermissions; import org.chorem.pollen.votecounting.VoteCounting; import org.chorem.pollen.votecounting.model.VoteCountingConfig; -import org.nuiton.util.pagination.PaginationParameter; import org.nuiton.util.pagination.PaginationResult; import java.util.Collection; @@ -538,20 +537,4 @@ public class VoteService extends PollenServiceSupport { return getVoteDao().forPollEquals(poll).count(); } - - protected PaginationParameter getPaginationParameter(PaginationParameterBean paginationParameter) { - - if (paginationParameter == null) { - - paginationParameter = PaginationParameterBean.of( - 0, - PAGE_SIZE_DEFAULT, - Vote.PROPERTY_TOPIA_CREATE_DATE, - true); - - } - - return paginationParameter.toPaginationParameter(); - - } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoterListService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoterListService.java index cb870f25..17b1bdfa 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoterListService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoterListService.java @@ -21,6 +21,7 @@ package org.chorem.pollen.services.service; * #L% */ +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -32,12 +33,21 @@ import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.Vote; import org.chorem.pollen.persistence.entity.VoterList; import org.chorem.pollen.persistence.entity.VoterListMember; +import org.chorem.pollen.services.PollenTechnicalException; +import org.chorem.pollen.services.bean.PaginationParameterBean; +import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; +import org.chorem.pollen.services.bean.export.ExportBean; import org.chorem.pollen.services.service.security.PollenPermissions; +import org.nuiton.csv.Exporter; +import org.nuiton.csv.ExporterBuilder; +import org.nuiton.util.pagination.PaginationParameter; +import org.nuiton.util.pagination.PaginationResult; +import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -61,9 +71,13 @@ public class VoterListService extends PollenServiceSupport { VoterListMemberBean bean = new VoterListMemberBean(); bean.setEntityId(entity.getTopiaId()); - if (entity.getMember() != null) { - bean.setName(entity.getMember().getName()); - bean.setEmail(entity.getMember().getEmail()); + PollenPrincipal pollenPrincipal = entity.getMember(); + if (pollenPrincipal != null) { + bean.setName(pollenPrincipal.getName()); + bean.setEmail(pollenPrincipal.getEmail()); + if (pollenPrincipal.getPollenUser() != null && pollenPrincipal.getPollenUser().getAvatar() != null) { + bean.setAvatar(getPollenResourceService().getReduceIdByTopiaId(pollenPrincipal.getPollenUser().getAvatar().getTopiaId())); + } } bean.setWeight(entity.getWeight()); bean.getVoterListId().setEntityId(entity.getVoterList().getTopiaId()); @@ -71,7 +85,7 @@ public class VoterListService extends PollenServiceSupport { boolean voting = getVoteDao().forVoterListMemberContains(entity).exists(); bean.setVoting(voting); - bean.setInvalidEmail(entity.getMember().isInvalid()); + bean.setInvalidEmail(pollenPrincipal.isInvalid()); return bean; } @@ -216,6 +230,61 @@ public class VoterListService extends PollenServiceSupport { } + public PaginationResultBean<VoterListMemberBean> getAllVoterListMembers(String pollId, PaginationParameterBean paginationParameter) { + checkIsConnectedRequired(); + + checkNotNull(pollId); + Poll poll = getPollService().getPoll0(pollId); + checkPermission(PollenPermissions.readParticipants(poll)); + + PaginationParameter paginationParameter1 = + PaginationParameter.of(paginationParameter.getPageNumber(), + paginationParameter.getPageSize(), + "topiaEntity_." + VoterListMember.PROPERTY_MEMBER + "." + PollenPrincipal.PROPERTY_NAME, // FIXME pourquoi l'alias doit être ajouté ? + false); + PaginationResult<VoterListMember> result = getVoterListMemberDao() + .forProperties(VoterListMember.PROPERTY_VOTER_LIST + "." + VoterList.PROPERTY_POLL, poll) + .findPage(paginationParameter1); + + return toPaginationListBean(result, this::toVoterListMemberBean); + } + + public ExportBean exportAllVoterListMembers(String pollId) { + checkIsConnectedRequired(); + + checkNotNull(pollId); + Poll poll = getPollService().getPoll0(pollId); + checkPermission(PollenPermissions.readParticipants(poll)); + + List<VoterListMember> members = getVoterListMemberDao() + .forProperties(VoterListMember.PROPERTY_VOTER_LIST + "." + VoterList.PROPERTY_POLL, poll) + .setOrderByArguments(VoterListMember.PROPERTY_MEMBER + "." + PollenPrincipal.PROPERTY_NAME) + .findAll(); + + ImmutableList<VoterListMemberBean> memberBeans = toBeanList(members, this::toVoterListMemberBean); + + Exporter<VoterListMemberBean> beanExporter = new ExporterBuilder<VoterListMemberBean>() + .addColumn(PollenPrincipal.PROPERTY_NAME, VoterListMemberBean::getName) + .addColumn(PollenPrincipal.PROPERTY_EMAIL, VoterListMemberBean::getEmail) + .addColumn("voting", VoterListMemberBean::isVoting, b -> Boolean.toString(b)) + .build(); + + + ExportBean exportBean = new ExportBean(); + + try { + exportBean.setContent(beanExporter.toString(memberBeans)); + } catch (IOException e) { + throw new PollenTechnicalException("erron on export participants", e); + } + exportBean.setName(l(getLocale(), "pollen.export.voterListMember", poll.getTitle(), getNow())); + exportBean.setContentType("text/csv"); + + return exportBean; + } + + + public VoterListMemberBean getVoterListMember(String pollId, String voterListId, String memberId) { checkIsConnectedRequired(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenPermissions.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenPermissions.java index 1fd62788..15f11a58 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenPermissions.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenPermissions.java @@ -47,6 +47,10 @@ public class PollenPermissions { return securityService -> securityService.canReadVotes(poll); } + public static PollenPermission readParticipants(Poll poll) { + return securityService -> securityService.canReadParticipants(poll); + } + public static PollenPermission read(Vote vote) { return securityService -> securityService.canRead(vote); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java index 58dc2de3..38f0e953 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java @@ -456,6 +456,13 @@ public class SecurityService extends PollenServiceSupport { || VoteVisibility.CREATOR.equals(poll.getVoteVisibility()) && isCreator(poll)); } + public boolean canReadParticipants(Poll poll) { + return Polls.isPollRestricted(poll) && canRead(poll) + && (VoteVisibility.ANONYMOUS.equals(poll.getVoteVisibility()) + || Polls.isFinished(poll, getNow()) + || !poll.isContinuousResults()); + } + public boolean canRead(Vote vote) { return matchPrincipal(vote.getVoter()) || canReadVotes(vote.getPoll()); diff --git a/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties b/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties index dc059689..26ab4fbd 100644 --- a/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties +++ b/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties @@ -114,6 +114,7 @@ pollen.error.voterList.name.alreadyUsed=voterList name already used pollen.error.voterList.name.mandatory=voterList name cannot be empty pollen.error.voterList.weight.greaterThan0=voterList weight must be greater than 0 pollen.export.favoriteLists=favorite lists %s %tF.json +pollen.export.voterListMember=Voting List %1$s %2$TF %2$TH-%2$TM.csv pollen.service.feed.anonymous=Someone pollen.service.feed.choiceAdded.title=A choice has been added to the poll pollen.service.feed.commentAdded.title=A new comment has been published diff --git a/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties b/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties index 95a8f648..e988b33b 100644 --- a/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties +++ b/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties @@ -114,6 +114,7 @@ pollen.error.voterList.name.alreadyUsed=Le nom de la liste de votant existe déj pollen.error.voterList.name.mandatory=Nom de la liste de votant est obligatoire pollen.error.voterList.weight.greaterThan0=Poid de la liste de votant doit être supérieur à 0 pollen.export.favoriteLists=Listes de votants %s %tF.json +pollen.export.voterListMember=Liste d'émargement %1$s %2$TF %2$TH-%2$TM.csv pollen.service.feed.anonymous=Quelqu'un pollen.service.feed.choiceAdded.title=Un choix a été ajouté au sondage pollen.service.feed.commentAdded.title=Un nouveau commentaire a été publié diff --git a/pollen-ui-riot-js/src/main/web/i18n/en.json b/pollen-ui-riot-js/src/main/web/i18n/en.json index f940cf6a..7b220644 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -54,6 +54,7 @@ "poll_summaryTab": "Summary", "poll_settings": "Settings", "poll_tab_results": "Results", + "poll_tab_participant" : "Voting List", "poll_CLOSED": "Closed", "poll_ADDING_CHOICES": "Adding choices", "poll_VOTING": "Voting", @@ -183,6 +184,9 @@ "poll_votes_tooManyPoint": "There is {0} point distributed too much", "poll_votes_voteByClickAndDrop": "Vote by click and drop", "poll_votes_voteByInput": "Vote by entry", + "poll_participants_noParticipant": "Voting list is not available", + "poll_participants_download": "Download", + "poll_participants_download_title": "Download voting list", "polls_createdPolls": "My polls", "polls_assignPollToMe": "Link a poll to my account", "polls_assignPollToMe_title": "Link the poll", diff --git a/pollen-ui-riot-js/src/main/web/i18n/fr.json b/pollen-ui-riot-js/src/main/web/i18n/fr.json index 86449fd5..0c3a0a3f 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -54,6 +54,7 @@ "poll_summaryTab": "Résumé", "poll_settings": "Configuration", "poll_tab_results": "Résultats", + "poll_tab_participant" : "Liste d'émargement", "poll_CLOSED": "Fermé", "poll_ADDING_CHOICES": "Ajout de choix", "poll_VOTING": "Ouvert", @@ -183,6 +184,9 @@ "poll_votes_tooManyPoint": "Il y a {0} point distribué en trop", "poll_votes_voteByClickAndDrop": "Vote par cliquer/glisser", "poll_votes_voteByInput": "Vote par saisie", + "poll_participants_noParticipant": "Le liste d'émagement n'est pas diponible", + "poll_participants_download": "Télécharger", + "poll_participants_download_title": "Télécharger la liste d'émargement", "polls_createdPolls": "Mes sondages", "polls_assignPollToMe": "Attacher le sondage", "polls_assignPollToMe_title": "Attacher un sondage à mon compte", diff --git a/pollen-ui-riot-js/src/main/web/js/Poll.js b/pollen-ui-riot-js/src/main/web/js/Poll.js index a926373a..ca1e6bfb 100644 --- a/pollen-ui-riot-js/src/main/web/js/Poll.js +++ b/pollen-ui-riot-js/src/main/web/js/Poll.js @@ -149,6 +149,15 @@ class Poll { return Promise.reject("Init poll after load votes"); } + loadLazyParticipants(pagination) { + if (this._initPromise) { + return this._initPromise.then(() => { + return pollService.getParticipants(this.id, pagination, this.getPermission()); + }); + } + return Promise.reject("Init poll after load participants"); + } + loadForVotes() { if (this._initPromise) { return this._initPromise.then(() => { diff --git a/pollen-ui-riot-js/src/main/web/js/PollService.js b/pollen-ui-riot-js/src/main/web/js/PollService.js index 472edb1f..16cf67f1 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollService.js +++ b/pollen-ui-riot-js/src/main/web/js/PollService.js @@ -128,6 +128,24 @@ class PollService extends FetchService { let url = this._getUrlPrefix(pollId) + "/invalidEmails"; return this.get(url, {permission: permission}); } + + getParticipants(pollId, pagination, permission) { + let params = Object.assign({}, pagination); + if (permission) { + params.permission = permission; + } + let url = this._getUrlPrefix(pollId) + "/participants"; + return this.get(url, params); + } + + getVotes(pollId, pagination, permission) { + let params = Object.assign({}, pagination); + if (permission) { + params.permission = permission; + } + let url = this._getUrlPrefix(pollId); + return this.get(url, params); + } } export default singleton(PollService); diff --git a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html index 9cfd4e59..a83a98cd 100644 --- a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html @@ -131,6 +131,20 @@ import "./popup/ShowReportsModal.tag.html"; </Authorization> </route> + <route path="poll/*/participants"> + <Authorization connected-if-required="true"> + <Poll poll-id={routeArguments[0]} + tab-name="participants" /> + </Authorization> + </route> + <route path="poll/*/participants/*"> + <Authorization connected-if-required="true"> + <Poll poll-id={routeArguments[0]} + tab-name="participants" + permission={routeArguments[1]}/> + </Authorization> + </route> + <route path="poll/new/*"> <Authorization connected-if-required="true" promise={parent.parent.session.getCanCreatePollPromise()}> <PageChanged page="newPoll"/> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Participants.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Participants.tag.html new file mode 100644 index 00000000..25b550e5 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Participants.tag.html @@ -0,0 +1,171 @@ +<!-- + #%L + Pollen :: UI RiotJs + %% + Copyright (C) 2009 - 2017 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --> +<Participants> + <div class="container" show="{loaded}"> + <div if="{!poll.participantsIsVisible}" + class="c-alert c-alert--warning"> + {_t.noParticipant} + </div> + <div if="{poll.participantsIsVisible}" class="participants-body" > + <div class="actions-right"> + <a class="c-button c-button--info" + href="{parent.session.configuration.endPoint}/v1/polls/{poll.id}/participants/exports" + target="_blank" + title={_t.download_title}> + <i class="fa fa-download"></i> + {_t.download} + </a> + </div> + <LazyLoad pagination={pagination} onload={lazyLoad} load-size="20" ref="lazyLoad" class="elements"> + <yield to="element"> + <div class="participant"> + <div class="voting"> + <span class="fa-stack fa-lg"> + <i class="fa fa-square-o fa-stack-1x"></i> + <i show={element.voting} class="fa fa-check fa-stack-1x success"></i> + </span> + </div> + <div class="avatar"> + <Avatar avatar={element.avatar} name={element.name} rounded="true"/> + </div> + <div class="name-email"> + <div class="name"> + {element.name} + </div> + <div class="email"> + {element.email} + </div> + </div> + </div> + </yield> + <yield to="loading"> + <div class="participant"> + <div class="voting"></div> + <div class="avatar"> + <i class="fa fa-user-circle c-icon"></i> + </div> + <div class="name-email"> + <div class="name"> + <i class="fa fa-spinner fa-pulse"></i> + </div> + <div class="email"> + <i class="fa fa-spinner fa-pulse"></i> + </div> + </div> + </div> + </yield> + </LazyLoad> + </div> + </div> + + <script type="es6"> + import session from "../../js/Session"; + import poll from "../../js/Poll.js"; + + this.loaded = false; + this.installBundle(session, "poll_participants"); + + this.poll = poll; + + this.pagination = { + order: "member.name", + desc: true + }; + + this.lazyLoad = pagination => { + return this.poll.loadLazyParticipants(pagination).then((result) => { + this.loaded = true; + this.update(); + return result; + }); + }; + + this.onPollChange = poll2 => { + this.poll = poll2; + this.update(); + }; + + this.listen("poll", this.onPollChange); + + this.listen("user", (user, oldUser) => { + if (user !== oldUser && this.refs.lazyLoad) { + this.refs.lazyLoad.reload().then(() => { + this.update(); + }); + } + }); + + </script> + <style> + + .container { + display: flex; + justify-content: center; + } + + .participants-body { + /* width: 100% */ + } + + .participant { + display: flex; + align-items: center; + } + + .participant .voting { + width: 3em; + + } + + .participant .voting .fa-check { + left: 0.1em; + top: -0.1em; + font-size: 1.3em; + } + + .name-email { + display: flex; + justify-content: space-between; + flex-grow: 1; + } + + .participant .name, + .participant .email { + padding: 0 0.7em; + } + + .participant .avatar { + display: flex; + width: 2em; + height: 2em; + } + + .loading .participant .avatar { + font-size: 2em; + } + + .participant .avatar avatar { + width: 2em; + height: 2em; + } + + </style> +</Participants> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html index 7e046150..2f2e733f 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html @@ -18,16 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #L% --> -import "./Votes.tag.html"; -import "./Comments.tag.html"; -import "./Results.tag.html"; -import "./Choices.tag.html"; -import "./Settings.tag.html"; -import "./CheckEmails.tag.html"; -import "../popup/QrCodeButton.tag.html"; -import "../components/MultiLineLabel.tag.html"; -import "../components/InnerHtml.tag.html"; -import "./Report.tag.html"; <Poll> <div class="main-container" ref="mainContainer"> @@ -60,6 +50,12 @@ import "./Report.tag.html"; <i class="fa fa-trophy fa-15x"></i> {_t.tab_results} </a> </div> + <div if="{poll.participantsIsVisible}" + class="tab {selected : selectedTab === 'participants'}"> + <a href="#poll/{poll.id}/participants{poll.getPermission()?'/' + poll.getPermission() : ''}"> + <i class="fa fa-list fa-15x"></i> {_t.tab_participant} + </a> + </div> </div> <div if="{poll.permission}" @@ -145,8 +141,8 @@ import "./Report.tag.html"; </div> <Votes if={selectedTab === "votes"}/> - <Results if={selectedTab === "results"}/> + <Participants if={selectedTab === "participants"}/> </div> @@ -154,6 +150,19 @@ import "./Report.tag.html"; </div> <script type="es6"> + import "./Votes.tag.html"; + import "./Comments.tag.html"; + import "./Results.tag.html"; + import "./Choices.tag.html"; + import "./Settings.tag.html"; + import "./CheckEmails.tag.html"; + import "../popup/QrCodeButton.tag.html"; + import "../components/MultiLineLabel.tag.html"; + import "../components/InnerHtml.tag.html"; + import "./Report.tag.html"; + import "./Participants.tag.html"; + + import session from "../../js/Session"; import Message from "../../js/Message"; import route from "riot-route/lib/tag"; diff --git a/pom.xml b/pom.xml index f2cec315..6ee64536 100644 --- a/pom.xml +++ b/pom.xml @@ -185,7 +185,7 @@ <nuitonWebVersion>1.20</nuitonWebVersion> <nuitonUtilsVersion>3.0</nuitonUtilsVersion> <nuitonConfigVersion>3.4</nuitonConfigVersion> - <nuitonCsvVersion>3.0-alpha-3</nuitonCsvVersion> + <nuitonCsvVersion>3.0-rc-6</nuitonCsvVersion> <nuitonValidatorVersion>3.2</nuitonValidatorVersion> <h2Version>1.4.197</h2Version> <postgresqlVersion>42.2.2.jre7</postgresqlVersion> @@ -430,11 +430,11 @@ <version>1.0-rc-2</version> </dependency> - <!--dependency> + <dependency> <groupId>org.nuiton</groupId> <artifactId>nuiton-csv</artifactId> <version>${nuitonCsvVersion}</version> - </dependency--> + </dependency> <!--dependency> <groupId>org.nuiton</groupId> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm