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 7c9834e02419f4cba07e5428f79dec5faccb0802 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Mon Apr 10 15:02:21 2017 +0200 invitation des participants pour des sondage restreint ou ouvert à tous --- .../org/chorem/pollen/rest/api/v1/PollApi.java | 4 +- .../chorem/pollen/rest/api/v1/VoterListApi.java | 9 +-- .../services/service/NotificationService.java | 56 ++++++++++++++- .../pollen/services/service/PollService.java | 51 +++++++------- .../services/service/PollenUIUrlRenderService.java | 24 +++---- .../pollen/services/service/VoteService.java | 45 +++++------- .../pollen/services/service/VoterListService.java | 80 ++++++++++++++++++++-- .../pollen/services/service/mail/EmailService.java | 30 +++++++- ...vitationEmail.java => PollInvitationEmail.java} | 16 ++--- .../mail/RestrictedPollInvitationEmail.java | 18 +++++ .../security/DefaultPollenSecurityContext.java | 1 + .../service/security/PollenSecurityContext.java | 1 + .../services/service/security/SecurityService.java | 23 +++---- .../resources/email/PollInvitationEmail.mustache | 14 ++++ .../email/PollInvitationEmail_fr.mustache | 14 ++++ .../resources/email/ResendValidationEmail.mustache | 2 +- .../email/ResendValidationEmail_fr.mustache | 2 +- .../email/RestrictedPollInvitationEmail.mustache | 14 ++++ .../RestrictedPollInvitationEmail_fr.mustache | 14 ++++ .../email/UserAccountCreatedEmail.mustache | 2 +- .../email/UserAccountCreatedEmail_fr.mustache | 2 +- .../service/PollenUIUrlRenderServiceTest.java | 12 ++-- .../services/service/VoterListServiceTest.java | 8 +-- pollen-ui-riot-js/src/main/web/css/main.css | 4 ++ pollen-ui-riot-js/src/main/web/i18n.json | 6 +- pollen-ui-riot-js/src/main/web/js/Poll.js | 22 +++--- pollen-ui-riot-js/src/main/web/js/PollForm.js | 1 + pollen-ui-riot-js/src/main/web/js/Session.js | 6 +- pollen-ui-riot-js/src/main/web/js/VoteService.js | 8 ++- .../src/main/web/tag/poll/Poll.tag.html | 2 +- .../src/main/web/tag/poll/Voters.tag.html | 30 +++++++- .../src/main/web/tag/poll/Votes.tag.html | 22 +++--- 32 files changed, 398 insertions(+), 145 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java index 94302e9..39a567f 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java @@ -93,9 +93,9 @@ public class PollApi extends WebMotionController { } - public PollBean editPoll(PollService pollService, PollBean poll) throws InvalidFormException { + public PollBean editPoll(PollService pollService, PollBean poll, PollenUIContext pollenUIContext) throws InvalidFormException { - return pollService.editPoll(poll); + return pollService.editPoll(poll, pollenUIContext); } 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 c695f8a..7d37ff9 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,6 +26,7 @@ import org.chorem.pollen.persistence.entity.FavoriteList; 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.services.PollenUIContext; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.VoterListBean; @@ -69,11 +70,11 @@ public class VoterListApi extends WebMotionController { } - public PollenEntityRef<VoterList> createVoterList(VoterListService voterListService, PollenEntityId<Poll> pollId, VoterListBean voterList, VoterListMemberBean... members) throws InvalidFormException { + public PollenEntityRef<VoterList> createVoterList(VoterListService voterListService, PollenEntityId<Poll> pollId, VoterListBean voterList, PollenUIContext pollenUIContext, VoterListMemberBean... members) throws InvalidFormException { List<VoterListMemberBean> memberList = Lists.newArrayList(members); - return voterListService.addVoterList(pollId.getEntityId(), voterList, memberList); + return voterListService.addVoterList(pollId.getEntityId(), voterList, memberList, pollenUIContext); } @@ -101,9 +102,9 @@ public class VoterListApi extends WebMotionController { } - public VoterListMemberBean addMember(VoterListService voterListService, PollenEntityId<Poll> pollId, PollenEntityId<VoterList> voterListId, VoterListMemberBean member) throws InvalidFormException { + public VoterListMemberBean addMember(VoterListService voterListService, PollenEntityId<Poll> pollId, PollenEntityId<VoterList> voterListId, VoterListMemberBean member, PollenUIContext uiContext) throws InvalidFormException { - return voterListService.addVoterListMember(pollId.getEntityId(), voterListId.getEntityId(), member); + return voterListService.addVoterListMember(pollId.getEntityId(), voterListId.getEntityId(), member, uiContext); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java index 0e78416..b2a8b47 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/NotificationService.java @@ -26,16 +26,25 @@ import org.chorem.pollen.persistence.entity.Choice; import org.chorem.pollen.persistence.entity.Comment; import org.chorem.pollen.persistence.entity.FavoriteList; import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.PollType; +import org.chorem.pollen.persistence.entity.PollenPrincipal; 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.PollenUIContext; import org.chorem.pollen.services.service.mail.EmailService; import org.chorem.pollen.services.service.mail.LostPasswordEmail; import org.chorem.pollen.services.service.mail.PollClosedEmail; import org.chorem.pollen.services.service.mail.PollCreatedEmail; +import org.chorem.pollen.services.service.mail.PollInvitationEmail; import org.chorem.pollen.services.service.mail.ResendValidationEmail; +import org.chorem.pollen.services.service.mail.RestrictedPollInvitationEmail; import org.chorem.pollen.services.service.mail.UserAccountCreatedEmail; +import java.util.List; +import java.util.Set; + /** * Created on 4/30/14. * @@ -106,8 +115,9 @@ public class NotificationService extends PollenServiceSupport { public void onPollCreated(Poll poll, PollenUIContext pollenUIContext) { + EmailService emailService = getEmailService(); + if (StringUtils.isNotBlank(poll.getCreator().getEmail())) { - EmailService emailService = getEmailService(); PollCreatedEmail email = emailService.newPollCreatedEmail(poll, pollenUIContext); email.addTo(poll.getCreator().getEmail()); @@ -115,9 +125,31 @@ public class NotificationService extends PollenServiceSupport { emailService.send(email); } + if (PollType.FREE.equals(poll.getPollType()) && poll.getParticipants() != null) { + for (String email : poll.getParticipants().split("\\s+")) { + PollInvitationEmail mail = emailService.newPollInvitationEmail(poll, pollenUIContext); + + mail.addTo(email); + + emailService.send(mail); + } + } + + } - public void onPollEdited(Poll poll) { + public void onPollEdited(Poll poll, Set<String> newParticipants, PollenUIContext pollenUIContext) { + EmailService emailService = getEmailService(); + + if (PollType.FREE.equals(poll.getPollType()) ) { + for (String email : newParticipants) { + PollInvitationEmail mail = emailService.newPollInvitationEmail(poll, pollenUIContext); + + mail.addTo(email); + + emailService.send(mail); + } + } } @@ -176,5 +208,25 @@ public class NotificationService extends PollenServiceSupport { } + public void onAddVoterList(Poll poll, List<VoterListMember> voterListMembers, PollenUIContext pollenUIContext) { + EmailService emailService = getEmailService(); + + voterListMembers.stream() + .map(VoterListMember::getMember) + .forEach(pollenPrincipal -> { + RestrictedPollInvitationEmail email = emailService.newRestrictedPollInvitationEmail(poll, pollenPrincipal, pollenUIContext); + email.addTo(pollenPrincipal.getEmail()); + emailService.send(email); + }); + + } + + public void onAddVoterListMember(VoterList voterList, VoterListMember member, PollenUIContext uiContext) { + EmailService emailService = getEmailService(); + PollenPrincipal principal = member.getMember(); + RestrictedPollInvitationEmail email = emailService.newRestrictedPollInvitationEmail(voterList.getPoll(), principal, uiContext); + email.addTo(principal.getEmail()); + emailService.send(email); + } } 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 34df302..b2723e1 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 @@ -49,8 +49,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; -import java.util.LinkedHashSet; -import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.function.Function; @@ -201,30 +199,15 @@ public class PollService extends PollenServiceSupport { Poll savedPoll = savePoll(poll, choices); if (poll.getPollType() == PollType.RESTRICTED) { - Set<String> emails; - if (CollectionUtils.isNotEmpty(poll.getParticipants())) { - emails = new LinkedHashSet<>(poll.getParticipants()); - } else { - emails = new LinkedHashSet<>(); - } + + Set<String> participants = poll.getParticipants(); if (poll.isWithMe()) { - emails.add(poll.getCreatorEmail()); - } - VoterListBean voterList = getVoterListService().newRestrictedVoterList(); - List<VoterListMemberBean> members = new LinkedList<>(); - for (String email : emails) { - VoterListMemberBean member = new VoterListMemberBean(); - member.setEmail(email); - //FIXME Try to get name from email - member.setName(email); - member.setWeight(1.0); - members.add(member); - } - if (CollectionUtils.isNotEmpty(members)) { - getVoterListService().addVoterList(savedPoll.getTopiaId(), voterList, members); + participants.add(poll.getCreatorEmail()); } + getVoterListService().updatePollParticipants(savedPoll.getTopiaId(), participants, pollenUIContext); } + commit(); getNotificationService().onPollCreated(savedPoll, pollenUIContext); @@ -233,7 +216,7 @@ public class PollService extends PollenServiceSupport { } - public PollBean editPoll(PollBean poll) throws InvalidFormException { + public PollBean editPoll(PollBean poll, PollenUIContext pollenUIContext) throws InvalidFormException { checkNotNull(poll); checkIsPersisted(poll); @@ -241,11 +224,27 @@ public class PollService extends PollenServiceSupport { ErrorMap errorMap = checkPoll(poll); errorMap.failIfNotEmpty(); + Set<String> newParticipants = Sets.newHashSet(); + if (PollType.FREE.equals(poll.getPollType())) { + Poll pollDb = getPoll0(poll.getEntityId()); + newParticipants.addAll(Sets.newHashSet(poll.getParticipants())); + newParticipants.removeAll(Sets.newHashSet(pollDb.getParticipants().split("\\s+"))); + } Poll savedPoll = savePoll(poll, null); + if (poll.getPollType() == PollType.RESTRICTED) { + + Set<String> participants = poll.getParticipants(); + if (poll.isWithMe()) { + participants.add(poll.getCreatorEmail()); + } + + getVoterListService().updatePollParticipants(savedPoll.getTopiaId(), participants, pollenUIContext); + } + commit(); - getNotificationService().onPollEdited(savedPoll); + getNotificationService().onPollEdited(savedPoll, newParticipants, pollenUIContext); return toBean(PollBean.class, savedPoll, pollBeanFunction); @@ -403,6 +402,10 @@ public class PollService extends PollenServiceSupport { // link to connected user toSave.getCreator().setPollenUser(connectedUser); + } else if (getSecurityContext().getMainPrincipal() == null){ + + getSecurityContext().setMainPrincipal(toSave.getCreator()); + } toSave.getCreator().setName(poll.getCreatorName()); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUIUrlRenderService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUIUrlRenderService.java index 517f50f..31c11ee 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUIUrlRenderService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUIUrlRenderService.java @@ -37,9 +37,9 @@ public class PollenUIUrlRenderService extends PollenServiceSupport { url = pollEditUrl.replace("{pollId}", pollId); if (token == null) { - url = url.replace("/{pollToken}", ""); + url = url.replace("/{token}", ""); } else { - url = url.replace("{pollToken}", token); + url = url.replace("{token}", token); } } return url; @@ -54,31 +54,31 @@ public class PollenUIUrlRenderService extends PollenServiceSupport { url = pollVoteUrl.replace("{pollId}", pollId); if (token == null) { - url = url.replace("/{pollToken}", ""); + url = url.replace("/{token}", ""); } else { - url = url.replace("{pollToken}", token); + url = url.replace("{token}", token); } } return url; } - public String getPollVoteEditUrl(String pollVoteEditUrl, String pollId, String pollToken, String voteToken) { + public String getPollVoteEditUrl(String pollVoteEditUrl, String pollId, String voteId, String token) { String url = null; if (pollVoteEditUrl != null) { checkNotNull(pollId); - checkNotNull(voteToken); + checkNotNull(voteId); - url = pollVoteEditUrl.replace("{pollId}", pollId); + url = pollVoteEditUrl + .replace("{pollId}", pollId) + .replace("{voteId}", voteId); - if (pollToken == null) { - url = url.replace("/{pollToken}", ""); + if (token == null) { + url = url.replace("/{token}", ""); } else { - url = url.replace("{pollToken}", pollToken); + url = url.replace("{token}", token); } - - url = url.replace("{voteToken}", voteToken); } return url; 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 571ded5..7c2890c 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 @@ -22,7 +22,6 @@ package org.chorem.pollen.services.service; */ import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; import org.chorem.pollen.persistence.entity.Choice; import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollenPrincipal; @@ -256,10 +255,25 @@ public class VoteService extends PollenServiceSupport { toSave = getVoteDao().create(); // toSave.setPostDate(serviceContext.getNow()); + PollenPrincipal principal = getSecurityContext().getMainPrincipal(); + if (principal != null) { + VoterListMember voterListMember = getVoterListMemberDao().forEquals(VoterListMember.PROPERTY_MEMBER + "." + PollenPrincipal.PROPERTY_TOPIA_ID, principal.getTopiaId()) + .addEquals(VoterListMember.PROPERTY_VOTER_LIST + "." + VoterList.PROPERTY_POLL + "." + Poll.PROPERTY_TOPIA_ID, poll.getTopiaId()) + .findUniqueOrNull(); + if (voterListMember != null) { + toSave.setVoterListMember(voterListMember); + toSave.setWeight(voterListMember.getWeight()); + toSave.setVoter(principal); + } + } + // -- author -- // + if (toSave.getVoter() == null) { + toSave.setWeight(1); + PollenPrincipal author = getSecurityService().generatePollenPrincipal(); + toSave.setVoter(author); + } - PollenPrincipal author = getSecurityService().generatePollenPrincipal(); - toSave.setVoter(author); toSave.setPoll(poll); } @@ -267,31 +281,6 @@ public class VoteService extends PollenServiceSupport { // toSave.setText(vote.getText()); // - // -- weight -- // - - if (!voteExist) { - - double weight; - - if (StringUtils.isBlank(vote.getVoterListMemberId().getEntityId())) { - - // not link to a member, use default value - - weight = 1d; - - } else { - - //FIXME Get member and his weight - VoterListMember voterListMember = getVoterListMemberDao().forEquals(VoterListMember.PROPERTY_TOPIA_ID, vote.getVoterListMemberId().getEntityId()).findUnique(); - toSave.setVoterListMember(voterListMember); - weight = voterListMember.getWeight(); - - } - - toSave.setWeight(weight); - - } - // -- author -- // toSave.getVoter().setName(vote.getVoterName()); 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 f30e556..228084b 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,8 +21,10 @@ package org.chorem.pollen.services.service; * #L% */ +import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.chorem.pollen.persistence.entity.FavoriteList; import org.chorem.pollen.persistence.entity.FavoriteListMember; import org.chorem.pollen.persistence.entity.Poll; @@ -32,6 +34,7 @@ import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.VoterList; import org.chorem.pollen.persistence.entity.VoterListMember; import org.chorem.pollen.persistence.entity.VoterListTopiaDao; +import org.chorem.pollen.services.PollenUIContext; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; @@ -40,6 +43,7 @@ import org.chorem.pollen.services.service.security.PermissionVerb; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import static org.nuiton.i18n.I18n.l; @@ -51,10 +55,25 @@ import static org.nuiton.i18n.I18n.l; */ public class VoterListService extends PollenServiceSupport { + public static final String RESTRICTED_VOTER_LIST_NAME = "restrictedVoterList"; + + protected VoterListMemberBean emailToMember(String email) { + VoterListMemberBean member = new VoterListMemberBean(); + member.setEmail(email); + member.setWeight(1.0); + PollenUser user = getPollenUserDao().forEmailEquals(email).findAnyOrNull(); + if (user != null) { + member.setName(user.getName()); + } else { + member.setName(email); + } + return member; + } + public VoterListBean newRestrictedVoterList() { VoterListBean list = new VoterListBean(); - list.setName("restrictedVoterList"); + list.setName(RESTRICTED_VOTER_LIST_NAME); list.setWeight(1.0f); return list; @@ -146,6 +165,22 @@ public class VoterListService extends PollenServiceSupport { } + public VoterListBean getRestrictedVoterList(String pollId) { + + checkNotNull(pollId); + checkPermission(PermissionVerb.readPoll, pollId); + + VoterList voterList = getVoterListDao().forProperties(VoterList.PROPERTY_POLL + "." + Poll.PROPERTY_TOPIA_ID, pollId) + .addEquals(VoterList.PROPERTY_NAME, RESTRICTED_VOTER_LIST_NAME).findUniqueOrNull(); + + VoterListBean result = null; + if (voterList != null) { + result = toBean(VoterListBean.class, voterList); + } + + return result; + } + public VoterListBean getVoterList(String pollId, String voterListId) { checkNotNull(pollId); @@ -157,9 +192,40 @@ public class VoterListService extends PollenServiceSupport { } + protected void updatePollParticipants(String pollId, Set<String> emails, PollenUIContext pollenUIContext) throws InvalidFormException { + + VoterListBean voterList = getRestrictedVoterList(pollId); + if (voterList == null) { + List<VoterListMemberBean> members = emails.stream() + .filter(StringUtils::isNotBlank) + .map(this::emailToMember) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(members)) { + voterList = newRestrictedVoterList(); + addVoterList(pollId, voterList, members, pollenUIContext); + } + } else { + String voterListId = voterList.getEntityId(); + Set<String> emailMembers = getVoterListMembers(pollId, voterListId).stream() + .map(VoterListMemberBean::getEmail) + .collect(Collectors.toSet()); + + List<VoterListMemberBean> newMember = emails.stream() + .filter(StringUtils::isNotBlank) + .filter(email -> !emailMembers.contains(email)) + .map(this::emailToMember) + .collect(Collectors.toList()); + + for (VoterListMemberBean member : newMember) { + addVoterListMember(pollId, voterListId, member, pollenUIContext); + } + } + } + public PollenEntityRef<VoterList> addVoterList(String pollId, VoterListBean voterList, - List<VoterListMemberBean> members) throws InvalidFormException { + List<VoterListMemberBean> members, + PollenUIContext pollenUIContext) throws InvalidFormException { checkNotNull(pollId); checkNotNull(voterList); @@ -174,12 +240,14 @@ public class VoterListService extends PollenServiceSupport { errorMap.failIfNotEmpty(); VoterList result = saveVoterList(poll, voterList); + List<VoterListMember> voterListMembers = Lists.newLinkedList(); if (CollectionUtils.isNotEmpty(members)) { for (VoterListMemberBean member : members) { - saveVoterListMember(result, member); + VoterListMember voterListMember = saveVoterListMember(result, member); + voterListMembers.add(voterListMember); } @@ -187,7 +255,7 @@ public class VoterListService extends PollenServiceSupport { commit(); - //TODO Notify + getNotificationService().onAddVoterList(poll, voterListMembers, pollenUIContext); return PollenEntityRef.of(result); @@ -257,7 +325,7 @@ public class VoterListService extends PollenServiceSupport { } - public VoterListMemberBean addVoterListMember(String pollId, String voterListId, VoterListMemberBean member) throws InvalidFormException { + public VoterListMemberBean addVoterListMember(String pollId, String voterListId, VoterListMemberBean member, PollenUIContext uiContext) throws InvalidFormException { checkNotNull(pollId); checkNotNull(voterListId); @@ -275,6 +343,8 @@ public class VoterListService extends PollenServiceSupport { VoterListMember result = saveVoterListMember(voterList, member); commit(); + getNotificationService().onAddVoterListMember(voterList, result, uiContext); + return toBean(VoterListMemberBean.class, result); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java index 7edc5d2..9b01808 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java @@ -173,10 +173,38 @@ public class EmailService extends PollenServiceSupport { return email; } - public RestrictedPollInvitationEmail newRestrictedPollInvitationEmail(Poll poll, PollenPrincipal principal) { + public PollInvitationEmail newPollInvitationEmail(Poll poll, PollenUIContext pollenUIContext) { + PollInvitationEmail email = new PollInvitationEmail(getLocale()); + email.setPoll(poll); + + PollenEntityId<Poll> pollId = PollenEntityId.newId(Poll.class); + pollId.setEntityId(poll.getTopiaId()); + pollId.encode(serviceContext.getTopiaApplicationContext().getTopiaIdFactory()); + + email.setVoteUrl(getPollenUIUrlRenderService().getPollVoteUrl + (pollenUIContext.getPollVoteUrl(), + pollId.getReducedId(), + null)); + + return email; + } + + public RestrictedPollInvitationEmail newRestrictedPollInvitationEmail(Poll poll, PollenPrincipal principal, PollenUIContext pollenUIContext) { RestrictedPollInvitationEmail email = new RestrictedPollInvitationEmail(getLocale()); email.setPoll(poll); email.setPrincipal(principal); + + PollenEntityId<Poll> pollId = PollenEntityId.newId(Poll.class); + pollId.setEntityId(poll.getTopiaId()); + pollId.encode(serviceContext.getTopiaApplicationContext().getTopiaIdFactory()); + + email.setVoteUrl(getPollenUIUrlRenderService().getPollVoteUrl + (pollenUIContext.getPollVoteUrl(), + pollId.getReducedId(), + principal.getPermission().getToken())); + + email.setToken(principal.getPermission().getToken()); + return email; } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/RestrictedPollInvitationEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollInvitationEmail.java similarity index 77% copy from pollen-services/src/main/java/org/chorem/pollen/services/service/mail/RestrictedPollInvitationEmail.java copy to pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollInvitationEmail.java index 978e0b8..71928ec 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/RestrictedPollInvitationEmail.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/PollInvitationEmail.java @@ -22,7 +22,6 @@ package org.chorem.pollen.services.service.mail; */ import org.chorem.pollen.persistence.entity.Poll; -import org.chorem.pollen.persistence.entity.PollenPrincipal; import org.nuiton.i18n.I18n; import java.util.Locale; @@ -33,13 +32,12 @@ import java.util.Locale; * @author Tony Chemit - dev@tchemit.fr * @since 2.0 */ -public class RestrictedPollInvitationEmail extends PollenMail { +public class PollInvitationEmail extends PollenMail { protected Poll poll; + private String voteUrl; - protected PollenPrincipal principal; - - protected RestrictedPollInvitationEmail(Locale locale) { + protected PollInvitationEmail(Locale locale) { super(locale); } @@ -56,11 +54,11 @@ public class RestrictedPollInvitationEmail extends PollenMail { this.poll = poll; } - public PollenPrincipal getPrincipal() { - return principal; + public void setVoteUrl(String voteUrl) { + this.voteUrl = voteUrl; } - public void setPrincipal(PollenPrincipal principal) { - this.principal = principal; + public String getVoteUrl() { + return voteUrl; } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/RestrictedPollInvitationEmail.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/RestrictedPollInvitationEmail.java index 978e0b8..ac4ca08 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/RestrictedPollInvitationEmail.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/RestrictedPollInvitationEmail.java @@ -38,6 +38,8 @@ public class RestrictedPollInvitationEmail extends PollenMail { protected Poll poll; protected PollenPrincipal principal; + private String voteUrl; + private String token; protected RestrictedPollInvitationEmail(Locale locale) { super(locale); @@ -63,4 +65,20 @@ public class RestrictedPollInvitationEmail extends PollenMail { public void setPrincipal(PollenPrincipal principal) { this.principal = principal; } + + public void setVoteUrl(String voteUrl) { + this.voteUrl = voteUrl; + } + + public String getVoteUrl() { + return voteUrl; + } + + public void setToken(String token) { + this.token = token; + } + + public String getToken() { + return token; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/DefaultPollenSecurityContext.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/DefaultPollenSecurityContext.java index c2f80cf..c0f7612 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/DefaultPollenSecurityContext.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/DefaultPollenSecurityContext.java @@ -101,6 +101,7 @@ public class DefaultPollenSecurityContext implements Serializable, PollenSecurit } + @Override public void setMainPrincipal(PollenPrincipal mainPrincipal) { this.mainPrincipal = mainPrincipal; diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenSecurityContext.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenSecurityContext.java index c3744a1..e7739ac 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenSecurityContext.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/PollenSecurityContext.java @@ -55,4 +55,5 @@ public interface PollenSecurityContext { void setSubject(Subject subject); + void setMainPrincipal(PollenPrincipal creator); } 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 39ad2e3..6bee564 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 @@ -585,17 +585,6 @@ public class SecurityService extends PollenServiceSupport { } - for (Vote vote : principalByType.votes) { - permissions.add(createWildcardSubjectPermission(vote)); - if (vote.getPoll().getPollType() != PollType.FREE) { - permissions.remove(createSubjectPermission(PermissionVerb.addVote, vote.getPoll())); - } - - if (vote.getPoll().getVoteVisibility() == VoteVisibility.VOTER) { - generatePollVoterPermission(permissions, vote.getPoll()); - } - } - for (Poll poll : principalByType.polls) { // creator has all rights on the poll, choices and comments, but can only read votes @@ -610,7 +599,6 @@ public class SecurityService extends PollenServiceSupport { permissions.add(createSubjectPermission(PermissionVerb.readPollResult, poll)); permissions.add(createSubjectPermission(PermissionVerb.addChoice, poll)); permissions.add(createSubjectPermission(PermissionVerb.addComment, poll)); - permissions.add(createSubjectPermission(PermissionVerb.addVote, poll)); // add comment permissions @@ -649,6 +637,17 @@ public class SecurityService extends PollenServiceSupport { } } + for (Vote vote : principalByType.votes) { + permissions.add(createWildcardSubjectPermission(vote)); + if (vote.getPoll().getPollType() != PollType.FREE) { + permissions.remove(createSubjectPermission(PermissionVerb.addVote, vote.getPoll())); + } + + if (vote.getPoll().getVoteVisibility() == VoteVisibility.VOTER) { + generatePollVoterPermission(permissions, vote.getPoll()); + } + } + return permissions; } diff --git a/pollen-services/src/main/resources/email/PollInvitationEmail.mustache b/pollen-services/src/main/resources/email/PollInvitationEmail.mustache new file mode 100644 index 0000000..baf964d --- /dev/null +++ b/pollen-services/src/main/resources/email/PollInvitationEmail.mustache @@ -0,0 +1,14 @@ +Welcome, + +New poll has been created : {{poll.title}} + +{{#poll.description}} + + ------------------------------------- + + {{{poll.description}}} + + ------------------------------------- + +{{/poll.description}} +You must participate on this url <a href="{{voteUrl}}">{{voteUrl}}</a> diff --git a/pollen-services/src/main/resources/email/PollInvitationEmail_fr.mustache b/pollen-services/src/main/resources/email/PollInvitationEmail_fr.mustache new file mode 100644 index 0000000..a1a7c35 --- /dev/null +++ b/pollen-services/src/main/resources/email/PollInvitationEmail_fr.mustache @@ -0,0 +1,14 @@ +Bonjour, + +Un nouveau sondage a été créé : {{poll.title}} + +{{#poll.description}} + + ------------------------------------- + + {{{poll.description}}} + + ------------------------------------- + +{{/poll.description}} +Vous pouvez y participer avec l'adresse <a href="{{voteUrl}}">{{voteUrl}}</a> diff --git a/pollen-services/src/main/resources/email/ResendValidationEmail.mustache b/pollen-services/src/main/resources/email/ResendValidationEmail.mustache index 4e4df8c..5571f39 100644 --- a/pollen-services/src/main/resources/email/ResendValidationEmail.mustache +++ b/pollen-services/src/main/resources/email/ResendValidationEmail.mustache @@ -3,6 +3,6 @@ Welcome {{user.name}}, You had just created an account on the web application Pollen. -You must validate your email on this url: <a href="{{validateUrl}}">{{vaidateUrl}}</a> +You must validate your email on this url: <a href="{{validateUrl}}">{{validateUrl}}</a> You can now manage your polls by logging on the <a href="{{pollenUrl}}">Pollen</a> website. \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/ResendValidationEmail_fr.mustache b/pollen-services/src/main/resources/email/ResendValidationEmail_fr.mustache index f8762cc..5d4719c 100644 --- a/pollen-services/src/main/resources/email/ResendValidationEmail_fr.mustache +++ b/pollen-services/src/main/resources/email/ResendValidationEmail_fr.mustache @@ -2,6 +2,6 @@ Bonjour {{user.name}}, Vous venez de créer un compte sur l'application en ligne Pollen -Vous devez valider votre courriel en allant sur cette adresse : <a href="{{validateUrl}}">{{vaidateUrl}}</a> +Vous devez valider votre courriel en allant sur cette adresse : <a href="{{validateUrl}}">{{validateUrl}}</a> Vous pouvez gérer vos sondages en vous connectant sur <a href="{{pollenUrl}}">Pollen</a>. \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/RestrictedPollInvitationEmail.mustache b/pollen-services/src/main/resources/email/RestrictedPollInvitationEmail.mustache index e69de29..66b9d53 100644 --- a/pollen-services/src/main/resources/email/RestrictedPollInvitationEmail.mustache +++ b/pollen-services/src/main/resources/email/RestrictedPollInvitationEmail.mustache @@ -0,0 +1,14 @@ +Welcom {{principal.name}}, + +New poll has been created : {{poll.title}} + +{{#poll.description}} + + ------------------------------------- + + {{{poll.description}}} + + ------------------------------------- + +{{/poll.description}} +You must participate on this url <a href="{{voteUrl}}">{{voteUrl}}</a> diff --git a/pollen-services/src/main/resources/email/RestrictedPollInvitationEmail_fr.mustache b/pollen-services/src/main/resources/email/RestrictedPollInvitationEmail_fr.mustache index e69de29..8f88021 100644 --- a/pollen-services/src/main/resources/email/RestrictedPollInvitationEmail_fr.mustache +++ b/pollen-services/src/main/resources/email/RestrictedPollInvitationEmail_fr.mustache @@ -0,0 +1,14 @@ +Bonjour {{principal.name}}, + +Un nouveau sondage a été créé : {{poll.title}} + +{{#poll.description}} + + ------------------------------------- + + {{{poll.description}}} + + ------------------------------------- + +{{/poll.description}} +Vous pouvez y participer avec l'adresse <a href="{{voteUrl}}">{{voteUrl}}</a> diff --git a/pollen-services/src/main/resources/email/UserAccountCreatedEmail.mustache b/pollen-services/src/main/resources/email/UserAccountCreatedEmail.mustache index c74c09b..58da571 100644 --- a/pollen-services/src/main/resources/email/UserAccountCreatedEmail.mustache +++ b/pollen-services/src/main/resources/email/UserAccountCreatedEmail.mustache @@ -4,6 +4,6 @@ You had just created an account on the web application Pollen. Email: {{user.email}} -You must validate your email on this url: <a href="{{validateUrl}}">{{vaidateUrl}}</a> +You must validate your email on this url: <a href="{{validateUrl}}">{{validateUrl}}</a> You can now manage your polls by logging on the <a href="{{pollenUrl}}">Pollen</a> website. \ No newline at end of file diff --git a/pollen-services/src/main/resources/email/UserAccountCreatedEmail_fr.mustache b/pollen-services/src/main/resources/email/UserAccountCreatedEmail_fr.mustache index eeb0c7d..85250fb 100644 --- a/pollen-services/src/main/resources/email/UserAccountCreatedEmail_fr.mustache +++ b/pollen-services/src/main/resources/email/UserAccountCreatedEmail_fr.mustache @@ -4,6 +4,6 @@ Vous venez de créer un compte sur l'application en ligne Pollen Courriel: {{user.email}} -Vous devez valider votre courriel en allant sur cette adresse : <a href="{{validateUrl}}">{{vaidateUrl}}</a> +Vous devez valider votre courriel en allant sur cette adresse : <a href="{{validateUrl}}">{{validateUrl}}</a> Vous pouvez gérer vos sondages en vous connectant sur <a href="{{pollenUrl}}">Pollen</a>. \ No newline at end of file diff --git a/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUIUrlRenderServiceTest.java b/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUIUrlRenderServiceTest.java index a5035bd..2081fc1 100644 --- a/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUIUrlRenderServiceTest.java +++ b/pollen-services/src/test/java/org/chorem/pollen/services/service/PollenUIUrlRenderServiceTest.java @@ -44,9 +44,9 @@ public class PollenUIUrlRenderServiceTest extends AbstractPollenServiceTest { pollenUIContext = new PollenUIContext(); pollenUIContext.setUiEndPoint(UI_END_POINT); pollenUIContext.setUserValidateUrl(UI_END_POINT + "/#signcheck/{userId}/{token}"); - pollenUIContext.setPollEditUrl(UI_END_POINT + "/#poll/edit/{pollId}/{pollToken}"); - pollenUIContext.setPollVoteUrl(UI_END_POINT + "/#poll/vote/{pollId}/{pollToken}"); - pollenUIContext.setPollVoteEditUrl(UI_END_POINT + "/#poll/vote/{pollId}/{pollToken}/vote/{voteToken}"); + pollenUIContext.setPollEditUrl(UI_END_POINT + "/#poll/edit/{pollId}/{token}"); + pollenUIContext.setPollVoteUrl(UI_END_POINT + "/#poll/vote/{pollId}/{token}"); + pollenUIContext.setPollVoteEditUrl(UI_END_POINT + "/#poll/vote/{pollId}/{voteId}/{token}"); } @Test @@ -79,13 +79,9 @@ public class PollenUIUrlRenderServiceTest extends AbstractPollenServiceTest { public void pollVoteEditUrlTest() { String url; - url = service.getPollVoteEditUrl(pollenUIContext.getPollVoteEditUrl(),"PollId", null, "VoteToken"); - Assert.assertNotNull(url); - Assert.assertEquals(UI_END_POINT+ "/#poll/vote/PollId/vote/VoteToken", url); - url = service.getPollVoteEditUrl(pollenUIContext.getPollVoteEditUrl(),"PollId", "Token", "VoteToken"); Assert.assertNotNull(url); - Assert.assertEquals(UI_END_POINT + "/#poll/vote/PollId/Token/vote/VoteToken", url); + Assert.assertEquals(UI_END_POINT + "/#poll/vote/PollId/Token/VoteToken", url); } @Test diff --git a/pollen-services/src/test/java/org/chorem/pollen/services/service/VoterListServiceTest.java b/pollen-services/src/test/java/org/chorem/pollen/services/service/VoterListServiceTest.java index 9ddffcb..b2f1cd2 100644 --- a/pollen-services/src/test/java/org/chorem/pollen/services/service/VoterListServiceTest.java +++ b/pollen-services/src/test/java/org/chorem/pollen/services/service/VoterListServiceTest.java @@ -177,7 +177,7 @@ public class VoterListServiceTest extends AbstractPollenServiceTest { VoterListBean voterList = new VoterListBean(); try { - voterListService.addVoterList(pollId, voterList, null); + voterListService.addVoterList(pollId, voterList, null, new PollenUIContext()); Assert.fail(); } catch (InvalidFormException e) { // missing name @@ -187,7 +187,7 @@ public class VoterListServiceTest extends AbstractPollenServiceTest { } voterList.setWeight(1); try { - voterListService.addVoterList(pollId, voterList, null); + voterListService.addVoterList(pollId, voterList, null, new PollenUIContext()); Assert.fail(); } catch (InvalidFormException e) { // missing name @@ -197,7 +197,7 @@ public class VoterListServiceTest extends AbstractPollenServiceTest { voterList.setName("voterList1"); List<VoterListMemberBean> listMember = new ArrayList<>(); try { - voterListService.addVoterList(pollId, voterList, listMember); + voterListService.addVoterList(pollId, voterList, listMember, new PollenUIContext()); Assert.fail(); } catch (InvalidFormException e) { // missing member @@ -209,7 +209,7 @@ public class VoterListServiceTest extends AbstractPollenServiceTest { member.setWeight(1); listMember.add(member); - PollenEntityRef<VoterList> voterListPersisted = voterListService.addVoterList(pollId, voterList, listMember); + PollenEntityRef<VoterList> voterListPersisted = voterListService.addVoterList(pollId, voterList, listMember, new PollenUIContext()); Assert.assertNotNull(voterListPersisted); } diff --git a/pollen-ui-riot-js/src/main/web/css/main.css b/pollen-ui-riot-js/src/main/web/css/main.css index 78185ba..37405bb 100644 --- a/pollen-ui-riot-js/src/main/web/css/main.css +++ b/pollen-ui-riot-js/src/main/web/css/main.css @@ -133,3 +133,7 @@ input.c-button, button.c-button { display: inline-block; } + +ul { + margin-left: .5em; +} diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 7812c33..7a5427b 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -232,7 +232,8 @@ "poll_voters_restrictedPoll_withMe": "Je participe au sondage", "poll_voters_restrictedPoll_withGroup": "Organiser les invités dans des groupes", "poll_voters_invite": "Inviter des participants", - "poll_voters_invite_label": "Renseignez le courriel des participants (séparé par un espace)", + "poll_voters_already_invite_label": "Participants déjà invités", + "poll_voters_new_invite_label": "Renseignez le courriel des participants (séparé par un espace)", "poll_created_title": "Sondage créé", "poll_created_message": "Le sondage vient d'être créé. Un courriel vous a été adressé ainsi qu'aux éventuels participants.", "poll_created_edit": "Pour gérer le sondage, veuillez utiliser le lien suivant", @@ -510,7 +511,8 @@ "poll_voters_restrictedPoll_withMe": "I also want to participate", "poll_voters_restrictedPoll_withGroup": "Organize participants in groups", "poll_voters_invite": "Invite people to vote", - "poll_voters_invite_label": "Type participants emails separated by space", + "poll_voters_already_invite_label": "Participants already invited", + "poll_voters_new_invite_label": "Type participants emails separated by space", "poll_created_title": "Poll created", "poll_created_message": "The poll was created. An email was sent to you and declared voters.", "poll_created_edit": "To manage the poll, please use following link", 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 200d9e6..8c22af8 100644 --- a/pollen-ui-riot-js/src/main/web/js/Poll.js +++ b/pollen-ui-riot-js/src/main/web/js/Poll.js @@ -19,14 +19,16 @@ class Poll { } init(pollId, voteId, permission) { - this._initPromise = pollService.getPoll(pollId, !voteId && permission).then(result => { + this._initPromise = pollService.getPoll(pollId, permission).then(result => { delete this.id; delete this.permission; delete this.voteId; delete this.votePermission; Object.assign(this, result); this.voteId = voteId; - this.votePermission = voteId && permission; + if (!this.permission) { + this.votePermission = permission; + } this.choices = undefined; this.votes = undefined; this.comments = undefined; @@ -39,7 +41,7 @@ class Poll { } reloadPoll() { - return pollService.getPoll(this.id, this.permission).then(result => { + return pollService.getPoll(this.id, this.permission || this.votePermission).then(result => { Object.assign(this, result); bus.trigger("poll", this); return Promise.resolve(this); @@ -63,7 +65,7 @@ class Poll { loadChoices() { if (this.id) { - return choiceService.getChoices(this.id, this.permission) + return choiceService.getChoices(this.id, this.permission || this.votePermission) .then(result => { this.choices = result; bus.trigger("poll", this); @@ -118,12 +120,12 @@ class Poll { if (this._initPromise) { return this._initPromise.then(() => { var promises = [ - choiceService.getChoices(this.id, this.permission), + choiceService.getChoices(this.id, this.permission || this.votePermission), voteService.getVotes(this.id, this.votePermission || this.permission), voteCountingTypeService.getVoteCountingType(this.voteCountingType) ]; if (this.resultIsVisible) { - promises.push(resultService.getResults(this.id, this.permission)); + promises.push(resultService.getResults(this.id, this.permission || this.votePermission)); } return Promise.all(promises).then(resultsArray => { this.choices = resultsArray[0]; @@ -164,8 +166,8 @@ class Poll { return this._initPromise.then(() => { if (this.resultIsVisible) { return Promise.all([ - choiceService.getChoices(this.id, this.permission), - resultService.getResults(this.id, this.permission)]).then(resultsArray => { + choiceService.getChoices(this.id, this.permission || this.votePermission), + resultService.getResults(this.id, this.permission || this.votePermission)]).then(resultsArray => { this.choices = resultsArray[0]; this.choiceCount = this.choices.length; this.results = resultsArray[1]; @@ -209,7 +211,7 @@ class Poll { let paginationParameter = new Pagination(); paginationParameter.pageSize = -1; paginationParameter.order = "postDate"; - return commentService.getComments(this.id, paginationParameter, this.permission) + return commentService.getComments(this.id, paginationParameter, this.permission || this.votePermission) .then((result) => { this.comments = result.elements; this.commentCount = result.elements.length; @@ -248,7 +250,7 @@ class Poll { addVote(vote) { if (this.id) { - return voteService.addVote(this.id, vote).then((result) => { + return voteService.addVote(this.id, vote, this.votePermission || this.permission).then((result) => { this.voteId = result.id; this.votePermission = result.permission; return Promise.all([this.reloadPoll(), this.loadVotes()]); diff --git a/pollen-ui-riot-js/src/main/web/js/PollForm.js b/pollen-ui-riot-js/src/main/web/js/PollForm.js index 313057a..2d6332e 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollForm.js +++ b/pollen-ui-riot-js/src/main/web/js/PollForm.js @@ -68,6 +68,7 @@ class PollForm { this.choices = results[1]; this.showOptions = true; this.hasVotes = this.model.voteCount > 0; + this.model.alreadyParticipants = this.model.participants; this.creation = false; this.choicesToRemove = []; this.step = 0; diff --git a/pollen-ui-riot-js/src/main/web/js/Session.js b/pollen-ui-riot-js/src/main/web/js/Session.js index 8420a0b..851e415 100644 --- a/pollen-ui-riot-js/src/main/web/js/Session.js +++ b/pollen-ui-riot-js/src/main/web/js/Session.js @@ -37,9 +37,9 @@ class Session { this.pollenUIContext = { uiEndPoint: window.location.origin, userValidateUrl: window.location.origin + "/#signcheck/{userId}/{token}", - pollVoteUrl: window.location.origin + "/#poll/{pollId}/vote/{pollToken}", - pollVoteEditUrl: window.location.origin + "/#poll/{pollId}/vote/{pollToken}/vote/{voteToken}", - pollEditUrl: window.location.origin + "/#poll/{pollId}/edit/{pollToken}" + pollVoteUrl: window.location.origin + "/#poll/{pollId}/vote/{token}", + pollVoteEditUrl: window.location.origin + "/#poll/{pollId}/vote/{voteId}/{token}", + pollEditUrl: window.location.origin + "/#poll/{pollId}/edit/{token}" }; // pour contenir les traductions this.i18n = require("../i18n.json"); diff --git a/pollen-ui-riot-js/src/main/web/js/VoteService.js b/pollen-ui-riot-js/src/main/web/js/VoteService.js index b4029bb..ef729c6 100644 --- a/pollen-ui-riot-js/src/main/web/js/VoteService.js +++ b/pollen-ui-riot-js/src/main/web/js/VoteService.js @@ -31,8 +31,12 @@ class VoteService extends FetchService { return this.getWithParams("/v1/polls/" + pollId + "/votes", args); } - addVote(pollId, form) { - return this.form("/v1/polls/" + pollId + "/votes", {vote: form}); + addVote(pollId, form, permission) { + let url = "/v1/polls/" + pollId + "/votes"; + if (permission) { + url += "?permission=" + permission; + } + return this.form(url, {vote: form}); } updateVote(pollId, form, permission) { 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 2bc5ea6..9933a44 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 @@ -67,7 +67,7 @@ require("./Settings.tag.html"); </div> </div> <div class="o-form-element" - if={poll.permission || poll.voteId}> + if={poll.pollType === "FREE"}> <label class="c-label" for="urlForVote">{__.urlForVote}</label> <div class="c-input-group u-small"> <div class="o-field"> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Voters.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Voters.tag.html index bdce5c8..e926411 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Voters.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Voters.tag.html @@ -46,9 +46,23 @@ </div> </label> </div> + + <div class="o-form-element" if={form.model.alreadyParticipants && form.model.alreadyParticipants.length}> + <label class="c-label"> + {__.already_invite_label} + </label> + <div class="participants"> + <ul class="c-list"> + <li each={participant in form.model.alreadyParticipants} class="c-list__item"> + {participant} + </li> + </ul> + </div> + </div> + <div class="o-form-element"> <label class="c-label"> - {__.invite_label} + {__.new_invite_label} </label> <textarea class="c-field" rows="5" @@ -70,11 +84,18 @@ this.submit = () => { this.form.model.pollType = this.refs.pollType.value; this.form.model.withMe = this.refs.withMe.checked; - this.form.model.participants = this.refs.participants.value ? this.refs.participants.value.split(/\s+/) : []; + if (this.refs.participants.value) { + this.form.model.participants = (this.form.model.participants || []).concat(this.refs.participants.value.split(/\s+/)); + } }; </script> <style> + + .o-form-element .participants { + padding: .5em; + } + @media (min-width: 640px) { .o-form-element .c-label:first-child { width: 25%; @@ -90,6 +111,11 @@ display: inline-block; } + + .o-form-element .participants { + display: inline-block; + } + .o-form-element .c-toggle { margin-left: 25%; } diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html index 2402b97..188a91c 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html @@ -136,7 +136,7 @@ require("./Podium.tag.html"); </div> <div class="vote-actions"> <span class="c-input-group" - if="{poll.canVote && vote.permission && (!voteId || voteId != vote.id)}"> + if="{!poll.isClosed && vote.permission && (!voteId || voteId != vote.id)}"> <button type="button" class="c-button c-button--error" onclick="{parent.deleteVote(vote)}"> @@ -258,15 +258,17 @@ require("./Podium.tag.html"); }); this.poll.addVote(vote).then(() => { - this.refs.voterName.value = null; - this.poll.choices.forEach(choice => { - let input = this.refs[choice.id + "_voteValue"]; - if (this.poll.voteCountingTypeValue.renderType === "text") { - input.value = ""; - } else { - input.checked = ""; - } - }); + if (this.poll.canVote) { + this.refs.voterName.value = null; + this.poll.choices.forEach(choice => { + let input = this.refs[choice.id + "_voteValue"]; + if (this.poll.voteCountingTypeValue.renderType === "text") { + input.value = ""; + } else { + input.checked = ""; + } + }); + } this.error = {}; if (this.poll.resultIsVisible) { this.poll.loadResults().then(() => { -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.