branch develop updated (5620de37 -> fae8b566)
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 5620de37 refs #118 modification de l'ordre de choix dans un sondage new fae8b566 refs #172 : Envoie des mails d'invitations différé 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 fae8b56690bcac9f128343152e408822fb53bcf5 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed May 23 15:15:07 2018 +0200 refs #172 : Envoie des mails d'invitations différé Summary of changes: .../pollen/persistence/entity/PollTopiaDao.java | 7 +- .../entity/VoterListMemberTopiaDao.java | 20 ++++++ .../migration/h2/V3_2_0_1__add_invivation_sent.sql | 3 + .../postgresql/V3_2_0_1__add_invivation_sent.sql | 3 + pollen-persistence/src/main/xmi/pollen.properties | 2 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 30672 -> 30846 bytes .../chorem/pollen/rest/api/v1/VoterListApi.java | 21 +++++- .../org/chorem/pollen/services/bean/PollBean.java | 10 +++ .../pollen/services/bean/VoterListMemberBean.java | 10 +++ .../services/service/NotificationService.java | 20 +----- .../pollen/services/service/PollService.java | 2 + .../pollen/services/service/VoterListService.java | 71 +++++++++++++------ pollen-ui-riot-js/src/main/web/i18n/en.json | 9 ++- pollen-ui-riot-js/src/main/web/i18n/fr.json | 9 ++- pollen-ui-riot-js/src/main/web/js/PollForm.js | 20 +++++- .../src/main/web/js/VoterListService.js | 20 +++++- .../src/main/web/tag/poll/Summary.tag.html | 76 ++++++++++++++++++--- 17 files changed, 244 insertions(+), 59 deletions(-) create mode 100644 pollen-persistence/src/main/resources/db/migration/h2/V3_2_0_1__add_invivation_sent.sql create mode 100644 pollen-persistence/src/main/resources/db/migration/postgresql/V3_2_0_1__add_invivation_sent.sql -- 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 fae8b56690bcac9f128343152e408822fb53bcf5 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Wed May 23 15:15:07 2018 +0200 refs #172 : Envoie des mails d'invitations différé --- .../pollen/persistence/entity/PollTopiaDao.java | 7 +- .../entity/VoterListMemberTopiaDao.java | 20 ++++++ .../migration/h2/V3_2_0_1__add_invivation_sent.sql | 3 + .../postgresql/V3_2_0_1__add_invivation_sent.sql | 3 + pollen-persistence/src/main/xmi/pollen.properties | 2 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 30672 -> 30846 bytes .../chorem/pollen/rest/api/v1/VoterListApi.java | 21 +++++- .../org/chorem/pollen/services/bean/PollBean.java | 10 +++ .../pollen/services/bean/VoterListMemberBean.java | 10 +++ .../services/service/NotificationService.java | 20 +----- .../pollen/services/service/PollService.java | 2 + .../pollen/services/service/VoterListService.java | 71 +++++++++++++------ pollen-ui-riot-js/src/main/web/i18n/en.json | 9 ++- pollen-ui-riot-js/src/main/web/i18n/fr.json | 9 ++- pollen-ui-riot-js/src/main/web/js/PollForm.js | 20 +++++- .../src/main/web/js/VoterListService.js | 20 +++++- .../src/main/web/tag/poll/Summary.tag.html | 76 ++++++++++++++++++--- 17 files changed, 244 insertions(+), 59 deletions(-) diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java index 900d140d..38cd4aee 100644 --- a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollTopiaDao.java @@ -180,8 +180,11 @@ public class PollTopiaDao extends AbstractPollTopiaDao<Poll> { VoterListTopiaDao dao = topiaDaoSupplier .getDao(VoterList.class, VoterListTopiaDao.class); - List<VoterList> list = dao.forPollEquals(entity).findAll(); - dao.deleteAll(list); + dao.forPollEquals(entity) + .addNull(VoterList.PROPERTY_PARENT) + .tryFindUnique() + .toJavaUtil() + .ifPresent(dao::delete); } diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/VoterListMemberTopiaDao.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/VoterListMemberTopiaDao.java index 0c638412..004f3f48 100644 --- a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/VoterListMemberTopiaDao.java +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/VoterListMemberTopiaDao.java @@ -22,6 +22,10 @@ package org.chorem.pollen.persistence.entity; */ +import com.google.common.collect.Maps; + +import java.util.Map; + public class VoterListMemberTopiaDao extends AbstractVoterListMemberTopiaDao<VoterListMember> { @Override @@ -42,4 +46,20 @@ public class VoterListMemberTopiaDao extends AbstractVoterListMemberTopiaDao<Vot } + public long countDistinctMembers(Poll poll, boolean invitationSent) { + String alias = "m"; + String hql = "select count(" + alias + "." + VoterListMember.PROPERTY_MEMBER + "." + PollenPrincipal.PROPERTY_EMAIL + ")" + + " from " + VoterListMember.class.getCanonicalName() + " " + alias + + " where " + alias + "." + VoterListMember.PROPERTY_VOTER_LIST + "." + VoterList.PROPERTY_POLL + " = :" + VoterList.PROPERTY_POLL; + Map<String, Object> params = Maps.newHashMap(); + params.put(VoterList.PROPERTY_POLL, poll); + + if (invitationSent) { + hql += " and " + alias + "." + VoterListMember.PROPERTY_INVITATION_SENT + " = :" + VoterListMember.PROPERTY_INVITATION_SENT; + params.put(VoterListMember.PROPERTY_INVITATION_SENT, true); + } + + return count(hql, params); + } + } diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_2_0_1__add_invivation_sent.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_2_0_1__add_invivation_sent.sql new file mode 100644 index 00000000..c020f704 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/h2/V3_2_0_1__add_invivation_sent.sql @@ -0,0 +1,3 @@ +-- add invitation sent in VoterListMember +alter table voterlistmember add invitationsent boolean; +update voterlistmember set invitationsent = true; \ No newline at end of file diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_2_0_1__add_invivation_sent.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_2_0_1__add_invivation_sent.sql new file mode 100644 index 00000000..c020f704 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_2_0_1__add_invivation_sent.sql @@ -0,0 +1,3 @@ +-- add invitation sent in VoterListMember +alter table voterlistmember add invitationsent boolean; +update voterlistmember set invitationsent = true; \ No newline at end of file diff --git a/pollen-persistence/src/main/xmi/pollen.properties b/pollen-persistence/src/main/xmi/pollen.properties index b8f11682..4c4c9289 100644 --- a/pollen-persistence/src/main/xmi/pollen.properties +++ b/pollen-persistence/src/main/xmi/pollen.properties @@ -18,7 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # #L% ###m -model.tagvalue.version=3.1.0.9 +model.tagvalue.version=3.2.0.1 #model.tagValue.notGenerateToString=true #model.tagValue.constantPrefix=PROPERTY_ #model.tagValue.useEnumerationName=true diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index 3031d4e4..18196270 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ 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 082ca982..2b132b12 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 @@ -192,12 +192,29 @@ public class VoterListApi { } + @Path("/polls/{pollId}/voterLists/{voterListId}/send") + @GET + public int sendInvitationVoterList(@Context VoterListService voterListService, + @PathParam("pollId") PollenEntityId<Poll> pollId, + @PathParam("voterListId") PollenEntityId<VoterList> voterListId) { + return voterListService.sendInvitationVoterList(pollId.getEntityId(), voterListId.getEntityId(), false); + } + + @Path("/polls/{pollId}/voterLists/{voterListId}/members/{memberId}/send") + @GET + public boolean sendInvitationMember(@Context VoterListService voterListService, + @PathParam("pollId") PollenEntityId<Poll> pollId, + @PathParam("voterListId") PollenEntityId<VoterList> voterListId, + @PathParam("memberId") PollenEntityId<VoterListMember> memberId) { + return voterListService.sendInvitationMember(pollId.getEntityId(), voterListId.getEntityId(), memberId.getEntityId(), false); + } + @Path("/polls/{pollId}/voterLists/{voterListId}/resend") @GET public int resendInvitationVoterList(@Context VoterListService voterListService, @PathParam("pollId") PollenEntityId<Poll> pollId, @PathParam("voterListId") PollenEntityId<VoterList> voterListId) { - return voterListService.resendInvitationVoterList(pollId.getEntityId(), voterListId.getEntityId()); + return voterListService.sendInvitationVoterList(pollId.getEntityId(), voterListId.getEntityId(), true); } @Path("/polls/{pollId}/voterLists/{voterListId}/members/{memberId}/resend") @@ -206,7 +223,7 @@ public class VoterListApi { @PathParam("pollId") PollenEntityId<Poll> pollId, @PathParam("voterListId") PollenEntityId<VoterList> voterListId, @PathParam("memberId") PollenEntityId<VoterListMember> memberId) { - return voterListService.resendInvitationMember(pollId.getEntityId(), voterListId.getEntityId(), memberId.getEntityId()); + return voterListService.sendInvitationMember(pollId.getEntityId(), voterListId.getEntityId(), memberId.getEntityId(), true); } } 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 4fda8c9d..e117cac2 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 @@ -117,6 +117,8 @@ public class PollBean extends PollenBean<Poll> { protected long participantCount; + protected long participantInvitedCount; + protected long choiceCount; protected PollStatus status; @@ -436,6 +438,14 @@ public class PollBean extends PollenBean<Poll> { this.participantCount = participantCount; } + public long getParticipantInvitedCount() { + return participantInvitedCount; + } + + public void setParticipantInvitedCount(long participantInvitedCount) { + this.participantInvitedCount = participantInvitedCount; + } + public ReportResumeBean getReport() { return report; } 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 c354436d..2a0d21f2 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 @@ -40,6 +40,8 @@ public class VoterListMemberBean extends PollenBean<VoterListMember> { protected PollenEntityId<VoterList> voterListId; + protected boolean invitationSent; + protected boolean voting; protected boolean invalidEmail; @@ -83,6 +85,14 @@ public class VoterListMemberBean extends PollenBean<VoterListMember> { this.voterListId = voterListId; } + public boolean isInvitationSent() { + return invitationSent; + } + + public void setInvitationSent(boolean invitationSent) { + this.invitationSent = invitationSent; + } + public boolean isVoting() { return voting; } 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 34976bf9..8b576a06 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 @@ -32,7 +32,6 @@ import org.chorem.pollen.persistence.entity.PollenUserEmailAddress; import org.chorem.pollen.persistence.entity.Report; import org.chorem.pollen.persistence.entity.UserCredential; 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.service.mail.ChoiceAddedEmail; import org.chorem.pollen.services.service.mail.ChoiceReportEmail; @@ -202,23 +201,6 @@ public class NotificationService extends PollenServiceSupport { } } - if (PollType.RESTRICTED.equals(poll.getPollType())) { - - VoterList mainVoterList = getVoterListDao() - .forPollEquals(poll) - .addNull(VoterList.PROPERTY_PARENT) - .findUniqueOrNull(); - - List<VoterListMember> allMembers = getVoterListDao().getAllMembers(mainVoterList); - allMembers.stream() - .map(VoterListMember::getMember) - .distinct() - .forEach(pollenPrincipal -> { - RestrictedPollInvitationEmail mail = emailService.newRestrictedPollInvitationEmail(poll, pollenPrincipal); - mail.addTo(pollenPrincipal.getEmail()); - emailService.send(mail); - }); - } commit(); } @@ -332,7 +314,7 @@ public class NotificationService extends PollenServiceSupport { } } - public void onAddVoterList(Poll poll, List<VoterListMember> voterListMembers) { + public void sendInvitation(Poll poll, List<VoterListMember> voterListMembers) { EmailService emailService = getEmailService(); voterListMembers.stream() 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 1e48cad2..57c8c4f8 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 @@ -175,6 +175,8 @@ public class PollService extends PollenServiceSupport { if (Polls.isPollRestricted(entity)) { long participantCount = getVoterListService().getVoterListMemberCount(entity); bean.setParticipantCount(participantCount); + long participantInvitedCount = getVoterListService().getVoterListMemberInvitedCount(entity); + bean.setParticipantInvitedCount(participantInvitedCount); } long choiceCount = getChoiceService().getChoiceCount(entity); bean.setChoiceCount(choiceCount); 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 01f118ac..cb870f25 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 @@ -67,6 +67,7 @@ public class VoterListService extends PollenServiceSupport { } bean.setWeight(entity.getWeight()); bean.getVoterListId().setEntityId(entity.getVoterList().getTopiaId()); + bean.setInvitationSent(entity.isInvitationSent()); boolean voting = getVoteDao().forVoterListMemberContains(entity).exists(); bean.setVoting(voting); @@ -549,7 +550,7 @@ public class VoterListService extends PollenServiceSupport { } - List<VoterListMember> newVoters = createVoters(poll, listsToSave, membersToSave); + createVoters(poll, listsToSave, membersToSave); for (VoterList voterList : voterListToDelete) { @@ -565,8 +566,6 @@ public class VoterListService extends PollenServiceSupport { commit(); - getNotificationService().onAddVoterList(poll, newVoters); - } protected void checkVoters(Poll poll, List<VoterListBean> listsToSave, List<VoterListMemberBean> membersToSave) throws InvalidFormException { @@ -677,6 +676,15 @@ public class VoterListService extends PollenServiceSupport { List<VoterListMember> newVoters = Lists.newLinkedList(); + List<PollenPrincipal> principalSentInvitation = getVoterListMemberDao() + .forProperties(VoterListMember.PROPERTY_VOTER_LIST + "." + VoterList.PROPERTY_POLL, poll) + .addEquals(VoterListMember.PROPERTY_INVITATION_SENT, true) + .findAll() + .stream() + .map(VoterListMember::getMember) + .collect(Collectors.toList()); + + for (VoterListBean voterList : listsToSave) { if (voterList.getEntityId() == null || voterList.isTemporaryId()) { @@ -708,6 +716,9 @@ public class VoterListService extends PollenServiceSupport { voterListMember.setEntityId(null); VoterListMember voterListMemberSaved = saveVoterListMember(poll, voterListMember); voterListMember.setEntityId(voterListMemberSaved.getTopiaId()); + if (principalSentInvitation.contains(voterListMemberSaved.getMember())) { + voterListMemberSaved.setInvitationSent(true); + } newVoters.add(voterListMemberSaved); } else { @@ -718,7 +729,7 @@ public class VoterListService extends PollenServiceSupport { return newVoters; } - public int resendInvitationVoterList(String pollId, String voterListId) { + public int sendInvitationVoterList(String pollId, String voterListId, boolean allMemberNoVoting) { checkIsConnectedRequired(); checkNotNull(pollId); @@ -730,10 +741,10 @@ public class VoterListService extends PollenServiceSupport { List<VoterListMember> members = getVoterListDao().getAllMembers(voterList); - return resendInvitation(poll, members); + return sendInvitation(poll, members, allMemberNoVoting); } - public boolean resendInvitationMember(String pollId, String voterListId, String memberId) { + public boolean sendInvitationMember(String pollId, String voterListId, String memberId, boolean allMemberNoVoting) { checkIsConnectedRequired(); checkNotNull(pollId); @@ -744,30 +755,52 @@ public class VoterListService extends PollenServiceSupport { VoterListMember member = getVoterListMember0(voterList, memberId); - return resendInvitation(poll, Collections.singletonList(member)) == 1; + return sendInvitation(poll, Collections.singletonList(member), allMemberNoVoting) == 1; } - protected int resendInvitation(Poll poll, List<VoterListMember> members) { + protected int sendInvitation(Poll poll, List<VoterListMember> members, boolean allMemberNoVoting) { List<Vote> votes = getVoteDao().forPollEquals(poll).findAll(); - final Set<VoterListMember> memberVoting = votes.stream() - .map(Vote::getVoterListMember) - .flatMap(Collection::stream) - .collect(Collectors.toSet()); + List<VoterListMember> memberToSend; - List<VoterListMember> memberToSend = members.stream() - .filter(member -> !memberVoting.contains(member)) - .collect(Collectors.toList()); + if (allMemberNoVoting) { - getNotificationService().onAddVoterList(poll, memberToSend); + final Set<VoterListMember> memberVoting = votes.stream() + .map(Vote::getVoterListMember) + .flatMap(Collection::stream) + .collect(Collectors.toSet()); + + memberToSend = members.stream() + .filter(member -> !memberVoting.contains(member)) + .collect(Collectors.toList()); + } else { + memberToSend = members.stream() + .filter(member -> ! member.isInvitationSent()) + .collect(Collectors.toList()); + } + + getNotificationService().sendInvitation(poll, memberToSend); + + // plusieurs membre dans des liste différent peuvent avoir le même email + List<PollenPrincipal> pollenPrincipals = memberToSend.stream().map(VoterListMember::getMember).collect(Collectors.toList()); + + getVoterListMemberDao() + .forProperties(VoterListMember.PROPERTY_VOTER_LIST + "." + VoterList.PROPERTY_POLL, poll) + .addIn(VoterListMember.PROPERTY_MEMBER, pollenPrincipals) + .findAll() + .forEach(m -> m.setInvitationSent(true)); + + commit(); return memberToSend.size(); } public long getVoterListMemberCount(Poll poll) { - return getVoterListMemberDao() - .forProperties(VoterListMember.PROPERTY_VOTER_LIST + "." + VoterList.PROPERTY_POLL, poll) - .count(); + return getVoterListMemberDao().countDistinctMembers(poll, false); + } + + public long getVoterListMemberInvitedCount(Poll poll) { + return getVoterListMemberDao().countDistinctMembers(poll, true); } public Set<String> getVoterListMemberMails(VoterList voterList) { 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 c37ddfe1..15f8c500 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -31,7 +31,14 @@ "summary_invitations": "Number of invitations to vote sent by email:", "summary_vote": "Vote", "summary_members": "Participants", - "summary_membersNb": "participants received an email with a link to vote.", + "summary_membersInvited": "participants received an email with a link to vote.", + "summary_membersNoInvited_all": "Invitation emails have not been sent yet", + "summary_membersNoInvited_many": "{0} invitation emails have not been sent yet", + "summary_membersNoInvited_one": "1 Invitation email has not been sent yet", + "summary_sendInvitation": "Send invitation", + "summary_sendInvitations": "Send {0} invitations", + "summary_sendInvitations_success": "The {0} invitations are sent", + "summary_sendInvitation_success": "The invitation is sent", "summary_closePoll": "Close poll", "summary_reopenPoll": "Reopen poll", "summary_clonePoll": "Clone 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 3ac0d4a0..6208ddb0 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -31,7 +31,14 @@ "summary_invitations": "Nombre d'invitations à voter envoyées par email:", "summary_vote": "Voter", "summary_members": "Participants", - "summary_membersNb": "participants ont reçu un email avec un lien pour voter.", + "summary_membersInvited": "participants ont reçu un email avec un lien pour voter.", + "summary_membersNoInvited_all": "Les mails d'invitations n'ont pas encore été envoyés", + "summary_membersNoInvited_many": "{0} mails d'invitation n'ont pas encore été envoyés", + "summary_membersNoInvited_one": "1 mails d'invitation n'a pas encore été envoyé", + "summary_sendInvitation": "Envoyer l'invitation", + "summary_sendInvitations": "Envoyer les {0} invitations", + "summary_sendInvitations_success": "Les {0} invitations sont envoyées", + "summary_sendInvitation_success": "L'invitation est envoyée", "summary_closePoll": "Clôturer le sondage", "summary_reopenPoll": "Réouvrir le sondage", "summary_clonePoll": "Cloner le sondage", 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 1e87823d..52c38fb4 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollForm.js +++ b/pollen-ui-riot-js/src/main/web/js/PollForm.js @@ -214,7 +214,8 @@ class PollForm { if (this.model.pollType !== "FREE") { promises.push(voterListService.save()); } - return Promise.all(promises); + return Promise.all(promises) + .then(() => this.loadPoll(this.model.id, this.model.permissions)); } previousStep() { @@ -334,6 +335,23 @@ class PollForm { return Promise.reject("Init poll after get invalid emails"); } + sendInvitations() { + if (this.model.id) { + if (this.model.pollType === "RESTRICTED" && this.mainVoterList) { + return voterListService.sendInvitationList(this.mainVoterList) + .then(nbInvitation => { + return pollService.getPoll(this.model.id, this.model.permission) + .then(poll => { + Object.assign(this.model, poll); + return nbInvitation; + }); + }); + } + return Promise.reject("send invitation only for restricted poll"); + } + return Promise.reject("Init poll after get invalid emails"); + } + } export default singleton(PollForm); diff --git a/pollen-ui-riot-js/src/main/web/js/VoterListService.js b/pollen-ui-riot-js/src/main/web/js/VoterListService.js index 452bd878..3c9ce377 100644 --- a/pollen-ui-riot-js/src/main/web/js/VoterListService.js +++ b/pollen-ui-riot-js/src/main/web/js/VoterListService.js @@ -167,11 +167,11 @@ class VoterListService extends FetchService { let index = parent.subLists.indexOf(voterList); parent.subLists.splice(index, 1); - voterList.subLists.forEach(subList => { + voterList.subLists && voterList.subLists.forEach(subList => { this._deleteVoterList2(subList); }); - voterList.members.forEach(member => { + voterList.members && voterList.members.forEach(member => { delete this.voterListMembersById[member.id]; }); @@ -337,6 +337,22 @@ class VoterListService extends FetchService { return Promise.all(importPromises); } + sendInvitationList(voterList) { + if (!voterList.temp) { + let url = this._getUrlPrefix(this.pollForm.model.id, voterList.id) + "/send"; + return this.get(url, {permission: this.pollForm.model.permission}); + } + return Promise.reject(); + } + + sendInvitationMember(member) { + if (!member.temp) { + let url = this._getUrlPrefix(this.pollForm.model.id, member.voterListId) + "/members/" + member.id + "/send"; + return this.get(url, {permission: this.pollForm.model.permission}); + } + return Promise.reject(); + } + resendInvitationList(voterList) { if (!voterList.temp) { let url = this._getUrlPrefix(this.pollForm.model.id, voterList.id) + "/resend"; diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Summary.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Summary.tag.html index f26c5f90..01ae48a3 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Summary.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Summary.tag.html @@ -18,11 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #L% --> -import "./Choices.tag.html"; -import "./Settings.tag.html"; -import "../popup/QrCodeButton.tag.html"; -import "../components/MultiLineLabel.tag.html"; - <Summary> <div if={successMessage} class="c-alert c-alert--success">{successMessage}</div> @@ -74,7 +69,7 @@ import "../components/MultiLineLabel.tag.html"; <label class="c-label" for="voteUrl"> {_t.shareLink} </label> - <div class="share-actions"> + <div class="summary-part-actions"> <div class="c-input-group"> <div class="o-field"> <input id="voteUrl" @@ -103,8 +98,22 @@ import "../components/MultiLineLabel.tag.html"; <div if={opts.form.model.pollType === "RESTRICTED"} class="summary-part"> <h3>{_t.members}</h3> - <div> - <strong>{opts.form.model.participantCount}</strong> {_t.membersNb} + <div if={opts.form.model.participantInvitedCount == opts.form.model.participantCount}> + <strong>{opts.form.model.participantCount}</strong> {_t.membersInvited} + </div> + <div if={opts.form.model.participantInvitedCount < opts.form.model.participantCount}> + <strong>{opts.form.model.participantCount}</strong> {_t.members} + <span class="invitations-warning c-badge c-badge--warning"> + {getMembersWarningLabel()} + </span> + <div class="summary-part-actions"> + <button type="button" + class="c-button c-button--info" + onclick={sendInvitations}> + <i class="fa fa-paper-plane" aria-hidden="true"></i> + {getSendInvitationsLabel()} + </button> + </div> </div> </div> @@ -138,6 +147,11 @@ import "../components/MultiLineLabel.tag.html"; </div> <script type="es6"> + import "./Choices.tag.html"; + import "./Settings.tag.html"; + import "../popup/QrCodeButton.tag.html"; + import "../components/MultiLineLabel.tag.html"; + import session from "../../js/Session"; this.session = session; @@ -148,6 +162,32 @@ import "../components/MultiLineLabel.tag.html"; this.voteUrl = window.location.origin + window.location.pathname + "#poll/" + this.opts.form.model.id + "/vote"; }); + this.getMembersWarningLabel = () => { + let label; + if (this.opts.form.model.participantInvitedCount === 0) { + label = this._t.membersNoInvited_all; + } else { + let noInvited = this.opts.form.model.participantCount - this.opts.form.model.participantInvitedCount; + if (noInvited > 1) { + label = this._l("membersNoInvited_many", noInvited); + } else { + label = this._t.membersNoInvited_one; + } + } + return label; + }; + + this.getSendInvitationsLabel = () => { + let label; + let noInvited = this.opts.form.model.participantCount - this.opts.form.model.participantInvitedCount; + if (noInvited > 1) { + label = this._l("sendInvitations", noInvited); + } else { + label = this._t.sendInvitation; + } + return label; + }; + this.copyUrl = (refInputUrl) => () => { this.refs[refInputUrl].select(); document.execCommand("copy"); @@ -179,6 +219,15 @@ import "../components/MultiLineLabel.tag.html"; document.execCommand("copy"); }; + this.sendInvitations = () => { + this.opts.form.sendInvitations() + .then(nbInvitation => { + let message = nbInvitation > 1 ? this._l("sendInvitations_success", nbInvitation) : this._t.sendInvitation_success; + this.bus.trigger("message", message, "info"); + this.update(); + }); + }; + </script> <style> @@ -192,17 +241,22 @@ import "../components/MultiLineLabel.tag.html"; background-color: #eee; } - .share-actions { + .summary-part-actions { + margin-top: 5px; display: flex; } - .share-actions > .c-input-group { + .summary-part-actions > .c-input-group { flex-grow: 0.5; } - .share-actions > * { + .summary-part-actions > * { margin-right: 5px; } + .invitations-warning { + font-size: 1em; + } + </style> </Summary> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm