branch develop updated (2318dc2 -> d059538)
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 2318dc2 fixes #64 par défaut, on ne met pas la date de début de vote à la fin de la période d'ajout de choix new d059538 gestion des participant d'un sondage 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 d059538c853bc6310979e0d4695408a6a885ff60 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Tue May 16 11:48:30 2017 +0200 gestion des participant d'un sondage Summary of changes: .../org/chorem/pollen/rest/api/v1/PollApi.java | 8 +- .../chorem/pollen/rest/api/v1/VoterListApi.java | 37 ++-- pollen-rest-api/src/main/resources/mapping | 4 +- .../chorem/pollen/services/bean/PollenBean.java | 10 +- .../pollen/services/bean/PollenEntityId.java | 10 ++ .../chorem/pollen/services/bean/VoterListBean.java | 5 +- .../pollen/services/service/VoterListService.java | 39 +++-- pollen-ui-riot-js/src/main/web/i18n.json | 24 ++- pollen-ui-riot-js/src/main/web/js/PollForm.js | 22 ++- pollen-ui-riot-js/src/main/web/js/PollService.js | 4 +- .../src/main/web/js/VoterListService.js | 150 ++++++++++++++++ .../src/main/web/tag/poll/Voters.tag.html | 78 ++++++--- .../src/main/web/tag/voterList/VoterList.tag.html | 190 +++++++++++++++++++++ .../web/tag/voterList/VoterListMember.tag.html | 92 ++++++++++ 14 files changed, 607 insertions(+), 66 deletions(-) create mode 100644 pollen-ui-riot-js/src/main/web/js/VoterListService.js create mode 100644 pollen-ui-riot-js/src/main/web/tag/voterList/VoterList.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMember.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 d059538c853bc6310979e0d4695408a6a885ff60 Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Tue May 16 11:48:30 2017 +0200 gestion des participant d'un sondage --- .../org/chorem/pollen/rest/api/v1/PollApi.java | 8 +- .../chorem/pollen/rest/api/v1/VoterListApi.java | 37 ++-- pollen-rest-api/src/main/resources/mapping | 4 +- .../chorem/pollen/services/bean/PollenBean.java | 10 +- .../pollen/services/bean/PollenEntityId.java | 10 ++ .../chorem/pollen/services/bean/VoterListBean.java | 5 +- .../pollen/services/service/VoterListService.java | 39 +++-- pollen-ui-riot-js/src/main/web/i18n.json | 24 ++- pollen-ui-riot-js/src/main/web/js/PollForm.js | 22 ++- pollen-ui-riot-js/src/main/web/js/PollService.js | 4 +- .../src/main/web/js/VoterListService.js | 150 ++++++++++++++++ .../src/main/web/tag/poll/Voters.tag.html | 78 ++++++--- .../src/main/web/tag/voterList/VoterList.tag.html | 190 +++++++++++++++++++++ .../web/tag/voterList/VoterListMember.tag.html | 92 ++++++++++ 14 files changed, 607 insertions(+), 66 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 732839b..988304f 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 @@ -86,12 +86,14 @@ public class PollApi extends WebMotionController { public PollenEntityRef<Poll> createPoll(PollService pollService, PollBean poll, ChoiceBean[] choices, - List<VoterListBean> voterLists, - List<VoterListMemberBean> voterListMembers) throws InvalidFormException { + VoterListBean[] voterLists, + VoterListMemberBean[] voterListMembers) throws InvalidFormException { List<ChoiceBean> choiceList = Lists.newArrayList(choices); + List<VoterListBean> voterListList = Lists.newArrayList(voterLists); + List<VoterListMemberBean> voterListMemberList = Lists.newArrayList(voterListMembers); - return pollService.createPoll(poll, choiceList, voterLists, voterListMembers); + return pollService.createPoll(poll, choiceList, voterListList, voterListMemberList); } 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 cb2ef7c..a8e7181 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 @@ -35,7 +35,6 @@ import org.debux.webmotion.server.WebMotionController; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; /** * TODO @@ -57,9 +56,15 @@ public class VoterListApi extends WebMotionController { // // } - public List<VoterListBean> getVoterLists(VoterListService voterListService, PollenEntityId<Poll> pollId, PollenEntityId<VoterList> parentId) { + public VoterListBean getMainVoterList(VoterListService voterListService, PollenEntityId<Poll> pollId) { - return voterListService.getVoterLists(pollId.getEntityId(), parentId.getEntityId()); + return voterListService.getMainVoterList(pollId.getEntityId()); + + } + + public List<VoterListBean> getVoterLists(VoterListService voterListService, PollenEntityId<Poll> pollId, PollenEntityId<VoterList> voterListId) { + + return voterListService.getVoterLists(pollId.getEntityId(), voterListId.getEntityId()); } @@ -120,15 +125,25 @@ public class VoterListApi extends WebMotionController { } public void saveVoters(VoterListService voterListService, PollenEntityId<Poll> pollId, - List<VoterListBean> listsToSave, - List<VoterListMemberBean> membersToSave, - List<PollenEntityId<VoterList>> listIdsToDelete, - List<PollenEntityId<VoterListMember>> memberIdsToDelete) throws InvalidFormException { + VoterListBean[] listsToSave, + VoterListMemberBean[] membersToSave, + VoterListBean[] listsToDelete, + VoterListMemberBean[] membersToDelete) throws InvalidFormException { + List<String> listIds = Lists.newLinkedList(); + for (VoterListBean list : listsToDelete) { + listIds.add(list.getEntityId()); + } + + List<String> memberIds = Lists.newLinkedList(); + for (VoterListMemberBean member : membersToDelete) { + memberIds.add(member.getEntityId()); + } + voterListService.saveVoters(pollId.getEntityId(), - listsToSave, - membersToSave, - listIdsToDelete.stream().map(PollenEntityId::getEntityId).collect(Collectors.toList()), - memberIdsToDelete.stream().map(PollenEntityId::getEntityId).collect(Collectors.toList())); + Lists.newArrayList(listsToSave), + Lists.newArrayList(membersToSave), + listIds, + memberIds); } } diff --git a/pollen-rest-api/src/main/resources/mapping b/pollen-rest-api/src/main/resources/mapping index c1a63e2..6fee0d6 100644 --- a/pollen-rest-api/src/main/resources/mapping +++ b/pollen-rest-api/src/main/resources/mapping @@ -166,13 +166,15 @@ GET /v1/voteCountingTypes/{id} VoteCountingTypeApi.getVoteCounti # PUT /v1/polls/{pollId}/favoriteLists/{favoriteListId} VoterListApi.importFavoriteListNewGroup # PUT /v1/polls/{pollId}/voterLists/{voterListId}/favoriteLists/{favoriteListId} VoterListApi.importFavoriteList -GET /v1/polls/{pollId}/voterLists VoterListApi.getVoterLists +GET /v1/polls/{pollId}/mainVoterList VoterListApi.getMainVoterList GET /v1/polls/{pollId}/voterLists/{voterListId} VoterListApi.getVoterList POST /v1/polls/{pollId}/voterLists VoterListApi.createVoterList POST /v1/polls/{pollId}/voterLists/save VoterListApi.saveVoters PUT,POST /v1/polls/{pollId}/voterLists/{voterListId} VoterListApi.editVoterList DELETE /v1/polls/{pollId}/voterLists/{voterListId} VoterListApi.deleteVoterList +GET /v1/polls/{pollId}/voterLists/{voterListId}/lists VoterListApi.getVoterLists + GET /v1/polls/{pollId}/voterLists/{voterListId}/members VoterListApi.getMembers GET /v1/polls/{pollId}/voterLists/{voterListId}/members/{memberId} VoterListApi.getMember POST /v1/polls/{pollId}/voterLists/{voterListId}/members VoterListApi.addMember diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenBean.java index 2f94f20..24779cf 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenBean.java @@ -49,13 +49,21 @@ public abstract class PollenBean<E extends TopiaEntity> { } public boolean isPersisted() { - return id != null && id.isNotEmpty(); + return id != null && id.isNotEmpty() && !id.isTemporaryId(); } public String getEntityId() { return id.getEntityId(); } + public PollenEntityId<E> getId() { + return id; + } + + public boolean isTemporaryId() { + return id.isTemporaryId(); + } + public void setEntityId(String id) { this.id.setEntityId(id); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenEntityId.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenEntityId.java index 6a7dfaa..7cad78e 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenEntityId.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenEntityId.java @@ -37,6 +37,8 @@ import java.lang.reflect.Type; */ public class PollenEntityId<E extends TopiaEntity> { + public static final String TEMPORARY_ID_PREFIX = "TEMP"; + protected final Class<E> entityType; protected String entityId; @@ -67,6 +69,10 @@ public class PollenEntityId<E extends TopiaEntity> { this.entityType = entityType; } + public boolean isEmpty() { + return !isNotEmpty(); + } + public boolean isNotEmpty() { return StringUtils.isNotEmpty(reducedId) || StringUtils.isNotEmpty(entityId); } @@ -87,6 +93,10 @@ public class PollenEntityId<E extends TopiaEntity> { this.entityId = entityId; } + public boolean isTemporaryId() { + return reducedId != null && reducedId.startsWith(TEMPORARY_ID_PREFIX); + } + public void encode(TopiaIdFactory topiaIdFactory) { if (entityId != null) { diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListBean.java index 906c931..dc55075 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoterListBean.java @@ -48,8 +48,9 @@ public class VoterListBean extends PollenBean<VoterList> { setEntityId(entity.getTopiaId()); setName(entity.getName()); setWeight(entity.getWeight()); - setParentId(entity.getParent().getTopiaId()); - + if (entity.getParent() != null) { + setParentId(entity.getParent().getTopiaId()); + } } @Override 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 d09647b..2ced80e 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 @@ -31,6 +31,7 @@ import org.chorem.pollen.persistence.entity.PollenPrincipal; 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.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; @@ -53,8 +54,6 @@ import static org.nuiton.i18n.I18n.l; */ public class VoterListService extends PollenServiceSupport { - public static final String TEMP_ID_PREFIX = "TEMP-"; - // protected VoterListMemberBean emailToMember(String email) { // VoterListMemberBean member = new VoterListMemberBean(); // member.setEmail(email); @@ -573,16 +572,16 @@ public class VoterListService extends PollenServiceSupport { checkNotNull(listsToSave); checkNotNull(membersToSave); // verification des listes de voteurs - Map<String, Set<String>> listNameByParentId = Maps.newHashMap(); + Map<PollenEntityId<VoterList>, Set<String>> listNameByParentId = Maps.newHashMap(); for (VoterListBean voterList : listsToSave) { - Set<String> sisterNames = listNameByParentId.computeIfAbsent(voterList.getParentId().getEntityId(), parentId -> { - if (poll == null || parentId == null || parentId.startsWith(TEMP_ID_PREFIX)) { + Set<String> sisterNames = listNameByParentId.computeIfAbsent(voterList.getParentId(), parentId -> { + if (poll == null || parentId.isNotEmpty() || parentId.isTemporaryId()) { return Sets.newHashSet(); } else { - List<VoterList> existingVoterLists = getVoterLists0(poll, parentId); - return existingVoterLists.stream() + List<VoterList> existingVoterLists = getVoterLists0(poll, parentId.getEntityId()); + return existingVoterLists.stream() .map(VoterList::getName) .collect(Collectors.toSet()); } @@ -592,7 +591,7 @@ public class VoterListService extends PollenServiceSupport { if (voterList.getEntityId() != null) { - if (voterList.getEntityId().startsWith(TEMP_ID_PREFIX)) { + if (voterList.isTemporaryId()) { members = membersToSave.stream() .filter(member -> member.getVoterListId().getEntityId().equals(voterList.getEntityId())) @@ -625,7 +624,7 @@ public class VoterListService extends PollenServiceSupport { for (VoterListMemberBean voterListMember : membersToSave) { - if (voterListMember.getVoterListId().getEntityId() != null && !voterListMember.getVoterListId().getEntityId().startsWith(TEMP_ID_PREFIX)) { + if (voterListMember.getVoterListId().getEntityId() != null && !voterListMember.getVoterListId().isTemporaryId()) { Pair<Set<String>, Set<String>> brotherNamesEmails = listNamesEmailsByListId.computeIfAbsent(voterListMember.getVoterListId().getEntityId(), voterListId -> { List<VoterListMember> existingVoterListMembers = getVoterListMembers0(voterListId); @@ -665,21 +664,21 @@ public class VoterListService extends PollenServiceSupport { protected List<VoterListMember> createVoters(Poll poll, List<VoterListBean> listsToSave, List<VoterListMemberBean> membersToSave) { Map<String, VoterListBean> voterListBeanByTempId = listsToSave.stream() - .filter(list -> list.getEntityId() == null || list.getEntityId().startsWith(TEMP_ID_PREFIX)) + .filter(list -> list.getId().isEmpty() || list.isTemporaryId()) .collect(Collectors.toMap( - VoterListBean::getEntityId, + v -> v.getId().getReducedId(), Function.identity())); List<VoterListMember> newVoters = Lists.newLinkedList(); for (VoterListBean voterList : listsToSave) { - if (voterList.getEntityId() == null || voterList.getEntityId().startsWith(TEMP_ID_PREFIX)) { + if (voterList.getEntityId() == null || voterList.isTemporaryId()) { - String parentId = voterList.getParentId().getEntityId(); - if (parentId != null && parentId.startsWith(TEMP_ID_PREFIX)) { - parentId = voterListBeanByTempId.get(parentId).getEntityId(); - voterList.setParentId(parentId); + PollenEntityId<VoterList> parentId = voterList.getParentId(); + if (parentId.isNotEmpty() && parentId.isTemporaryId()) { + String parentIdString = voterListBeanByTempId.get(parentId.getReducedId()).getEntityId(); + voterList.setParentId(parentIdString); } voterList.setEntityId(null); @@ -694,10 +693,10 @@ public class VoterListService extends PollenServiceSupport { for (VoterListMemberBean voterListMember : membersToSave) { if (!voterListMember.isPersisted()) { - String voterListId = voterListMember.getVoterListId().getEntityId(); - if (voterListId == null || voterListId.startsWith(TEMP_ID_PREFIX)) { - voterListId = voterListBeanByTempId.get(voterListId).getEntityId(); - voterListMember.setVoterListId(voterListId); + PollenEntityId<VoterList> voterListId = voterListMember.getVoterListId(); + if (voterListId.isEmpty() || voterListId.isTemporaryId()) { + String voterListIdString = voterListBeanByTempId.get(voterListId.getReducedId()).getEntityId(); + voterListMember.setVoterListId(voterListIdString); } voterListMember.setEntityId(null); diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 7685492..c1499fb 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -285,6 +285,7 @@ "poll_voters_freePoll": "Tout le monde peut voter (Sondage public)", "poll_voters_restrictedPoll": "Seul les invités peuvent voter (Sondage privé)", "poll_voters_restrictedPoll_withMe": "Je participe au sondage", + "poll_voters_restrictedPoll_participants": "Participants au sondage", "poll_voters_restrictedPoll_withGroup": "Organiser les invités dans des groupes", "poll_voters_invite": "Inviter des participants", "poll_voters_already_invite_label": "Participants déjà invités", @@ -396,7 +397,16 @@ "favoriteList_childList_delete": "Retirer la sous-liste", "favoriteList_childList_deleteMessage": "Retirer la sou-liste ?", "error_manager_403": "Erreur : Accès refusé", - "error_manager_500": "Erreur : Service indisponible" + "error_manager_500": "Erreur : Service indisponile", + "voterList_name": "Nom", + "voterList_weight": "Poids", + "voterList_addMember": "Ajouter un participant", + "voterList_addVoterList": "Ajouter une sous-liste", + "voterList_delete": "Supprimer la liste", + "voterList_member_name": "Nom", + "voterList_member_email": "Courriel", + "voterList_member_weight": "Poids", + "voterList_member_delete": "Supprimer le participant" }, "en": { "main_pollen_title": "Pollen - ", @@ -674,6 +684,7 @@ "poll_voters_freePoll": "Everybody can vote (Public poll)", "poll_voters_restrictedPoll": "Only invited people can vote (Private poll)", "poll_voters_restrictedPoll_withMe": "I also want to participate", + "poll_voters_restrictedPoll_participants": "Poll participants", "poll_voters_restrictedPoll_withGroup": "Organize participants in groups", "poll_voters_invite": "Invite people to vote", "poll_voters_already_invite_label": "Participants already invited", @@ -783,6 +794,15 @@ "favoriteList_childList_delete": "Remove sub-list", "favoriteList_childList_deleteMessage": "Remove sub-list ?", "error_manager_403": "Error: Forbidden access", - "error_manager_500": "Error: Service unavailable" + "error_manager_500": "Error: Service unavailable", + "voterList_name": "Name", + "voterList_weight": "Weight", + "voterList_addMember": "Add member", + "voterList_addVoterList": "Add sub-list", + "voterList_delete": "delete list", + "voterList_member_name": "Name", + "voterList_member_email": "Email", + "voterList_member_weight": "Weight", + "voterList_member_delete": "delete member" } } 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 d71d181..72d2201 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollForm.js +++ b/pollen-ui-riot-js/src/main/web/js/PollForm.js @@ -25,6 +25,7 @@ let voteCountingTypeService = require("./VoteCountingTypeService"); let choiceService = require("./ChoiceService"); let resourceService = require("./ResourceService"); let pollService = require("./PollService"); +let voterListService = require("./VoterListService"); let bus = require("./PollenBus"); class PollForm { @@ -62,6 +63,7 @@ class PollForm { return Promise.all([ pollService.getPoll(pollId, permission), choiceService.getChoices(pollId, permission), + voterListService.init(pollId, permission), this._loadVoteCountingTypes() ]).then(results => { Object.assign(this.model, results[0]); @@ -94,7 +96,12 @@ class PollForm { } } + voterListService.init(this).then(voterList => { + this.mainVoterList = voterList; + }); + this.step = 0; + return Promise.resolve(this); }); } @@ -118,6 +125,10 @@ class PollForm { this.model.participant = []; this.choices = [new Choice("TEXT")]; + voterListService.init(this).then(voterList => { + this.mainVoterList = voterList; + }); + this.isInit = true; this.step = 0; }); @@ -141,7 +152,7 @@ class PollForm { } }); return Promise.all(fileUploadPromises).then(() => { - return pollService.create(this.model, this.choices).then((result) => { + return pollService.create(this.model, this.choices, voterListService.getVoterLists(), voterListService.getVoterListMembers()).then((result) => { console.info("Poll created"); console.info(result); this.model.id = result.id; @@ -184,10 +195,15 @@ class PollForm { save() { - return Promise.all([ + let promises = [ pollService.save(this.model), this._saveChoices() - ]); + ]; + + if (this.model.pollType !== "FREE") { + promises.push(voterListService.save()); + } + return Promise.all(promises); } previousStep() { 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 90e836d..12bd3f9 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollService.js +++ b/pollen-ui-riot-js/src/main/web/js/PollService.js @@ -27,8 +27,8 @@ class PollService extends FetchService { return this.getWithParams("/v1/polls/new", {choiceType: choiceType}); } - create(poll, choices) { - return this.form("/v1/polls/create", {poll: poll, choices: choices}); + create(poll, choices, voterLists, voterListMembers) { + return this.form("/v1/polls/create", {poll: poll, choices: choices, voterLists: voterLists, voterListMembers: voterListMembers}); } save(poll) { diff --git a/pollen-ui-riot-js/src/main/web/js/VoterListService.js b/pollen-ui-riot-js/src/main/web/js/VoterListService.js new file mode 100644 index 0000000..6ee5738 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/js/VoterListService.js @@ -0,0 +1,150 @@ +let singleton = require("./Singleton"); +let FetchService = require("./FetchService"); + +class VoterListService extends FetchService { + + constructor() { + super(); + this.tempPrefix = "TEMP"; + this.tempId = 1; + this.voterListsById = {}; + this.voterListMembersById = {}; + this.voterListsToDelete = []; + this.voterListMembersToDelete = []; + } + + _newVoterList(parent) { + return { + id: this.tempPrefix + this.tempId++, + parentId: parent && parent.id, + subLists: [], + members: [], + weight: 1, + loadded: true + }; + } + + _newMember(voterList) { + return { + id: this.tempPrefix + this.tempId++, + voterListId: voterList.id, + weight: 1 + }; + } + + init(pollForm) { + this.tempId = 1; + this.voterListsById = {}; + this.voterListMembersById = {}; + this.voterListsToDelete = []; + this.voterListMembersToDelete = []; + this.pollForm = pollForm; + let mainVoterListPromise = Promise.resolve(); + if (this.pollForm.model && this.pollForm.model.id) { + mainVoterListPromise = this.getWithParams("/v1/polls/" + pollForm.model.id + "/mainVoterList", {permission: pollForm.model.permission}); + } + mainVoterListPromise = mainVoterListPromise.then(list => { + let mainList = list || this._newVoterList(); + this.voterListsById[mainList.id] = mainList; + return mainList; + }); + return mainVoterListPromise; + } + + loadList(voterList) { + let voterListPromise; + if (!voterList.loadded) { + voterListPromise = Promise.resolve([[], []]); + if (this.pollForm.model && this.pollForm.model.id && !voterList.subLists && !voterList.id.startsWith(this.tempPrefix)) { + voterListPromise = Promise.all([ + this.getWithParams("/v1/polls/" + this.pollForm.model.id + "/voterLists/" + voterList.id + "/lists", {permission: this.pollForm.model.permission}), + this.getWithParams("/v1/polls/" + this.pollForm.model.id + "/voterLists/" + voterList.id + "/members", {permission: this.pollForm.model.permission})]); + } + voterListPromise.then(result => { + voterList.subLists = result[0]; + voterList.members = result[1]; + voterList.subLists.forEach(list => {this.voterListsById[list.id] = list;}); + voterList.members.forEach(member => {this.voterListMembersById[member.id] = member;}); + voterList.loadded = true; + return voterList; + }); + } else { + voterListPromise = Promise.resolve(voterList); + } + return voterListPromise; + } + + addVoterList(parent) { + let voterList = this._newVoterList(parent); + parent.subLists.push(voterList); + this.voterListsById[voterList.id] = voterList; + } + + deleteVoterList(voterList) { + let parent = this.voterListsById[voterList.parentId]; + let index = parent.subLists.indexOf(voterList); + parent.subLists.splice(index, 1); + + if (!voterList.id.startsWith(this.tempPrefix)) { + this.voterListsToDelete.push(voterList); + } + } + + addMember(parent) { + let member = this._newMember(parent); + parent.members.push(member); + this.voterListMembersById[member.id] = member; + } + + deleteMember(member) { + let voterList = this.voterListsById[member.voterListId]; + let index = voterList.members.indexOf(member); + voterList.members.splice(index, 1); + + if (!member.id.startsWith(this.tempPrefix)) { + this.voterListMembersToDelete.push(member); + } + } + + getVoterLists() { + return Object.values(this.voterListsById).map(voterlist => { + return { + id: voterlist.id, + parentId: voterlist.parentId, + name: voterlist.name, + weight: voterlist.weight + }; + }); + } + + getVoterListMembers() { + return Object.values(this.voterListMembersById).map(voterlistmember => { + return { + id: voterlistmember.id, + voterListId: voterlistmember.voterListId, + name: voterlistmember.name, + email: voterlistmember.email, + weight: voterlistmember.weight}; + }); + } + + getVoterListIdsToDelete() { + return this.voterListsToDelete.map(voterList => voterList.id); + } + + getVoterListMemberIdsToDelete() { + return this.voterListMembersToDelete.map(member => member.id); + } + + save() { + return this.form("/v1/polls/" + this.pollForm.model.id + "/voterLists/save?permission=" + this.pollForm.model.permission, + { + listsToSave: this.getVoterLists(), + membersToSave: this.getVoterListMembers(), + listsToDelete: this.voterListsToDelete, + membersToDelete: this.voterListMembersToDelete + }); + } +} + +module.exports = singleton(VoterListService); 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 e926411..56666c4 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 @@ -18,6 +18,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ + require("../voterList/VoterList.tag.html"); + <Voters> <div class="o-form-element"> <label class="c-label"> @@ -47,28 +49,38 @@ </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 show={!votePrivate}> + <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> - <div class="o-form-element"> - <label class="c-label"> - {__.new_invite_label} + <div class="o-form-element"> + <label class="c-label"> + {__.new_invite_label} + </label> + <textarea class="c-field" + rows="5" + ref="participants" + name="participants" + value="{participants}"/> + </div> + </div> + <div class="form-section" show={votePrivate}> + <label class="section-title"> + {__.restrictedPoll_participants} </label> - <textarea class="c-field" - rows="5" - ref="participants" - name="participants" - value="{participants}"/> + <div class="section-content"> + <VoterList voter-list={this.form.mainVoterList} ref="mainVoterList"/> + </div> </div> <script type="es6"> @@ -83,10 +95,10 @@ this.submit = () => { this.form.model.pollType = this.refs.pollType.value; - this.form.model.withMe = this.refs.withMe.checked; if (this.refs.participants.value) { this.form.model.participants = (this.form.model.participants || []).concat(this.refs.participants.value.split(/\s+/)); } + this.refs.mainVoterList.submit(); }; </script> @@ -96,7 +108,30 @@ padding: .5em; } + .form-section { + display: flex; + flex-wrap: wrap; + } + + .form-section .section-title { + width : 100%; + } + .form-section .section-content { + width : 100%; + } + @media (min-width: 640px) { + + .form-section .section-title { + width : 25%; + text-align: right; + padding: 1.5em 5px 0 0; + } + .form-section .section-content { + width : 75%; + } + + .o-form-element .c-label:first-child { width: 25%; display: inline-block; @@ -106,7 +141,8 @@ padding-right: 5px; } - .o-form-element .c-field { + .o-form-element .c-field, + .o-form-element .participants { width: 75%; display: inline-block; } diff --git a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterList.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterList.tag.html new file mode 100644 index 0000000..2f986cd --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterList.tag.html @@ -0,0 +1,190 @@ +require("./VoterListMember.tag.html"); + +<VoterList> + <div class="voter-list-header"> + <div class="voter-list-icone" onclick={toggleExpand}> + <i class="fa fa-caret-{expand ? 'down' : 'right'}" aria-hidden="true"></i> + <i class="fa fa-users" aria-hidden="true"></i> + </div> + <div class="voter-list-form"> + <div class="voter-list-fields" + if={opts.voterList.parentId}> + <div class="c-input-group"> + <div class="o-field"> + <input class="c-field" + type="text" + name="name" + ref="name" + value={opts.voterList.name} + placeholder={__.name}> + </div> + <div class="o-field field-weight"> + <input class="c-field" + type="number" + name="weight" + ref="weight" + value={opts.voterList.weight} + placeholder={__.weight}> + </div> + </div> + </div> + <div class="voter-list-actions"> + <button class="c-button c-button--success" + type="button" + onclick={addMember} + title={__.addMember}> + <i class="fa fa-plus" aria-hidden="true"></i> + <i class="fa fa-user" aria-hidden="true"></i> + </button> + <button class="c-button c-button--success" + type="button" + onclick={addVoterList} + title={__.addVoterList}> + <i class="fa fa-plus" aria-hidden="true"></i> + <i class="fa fa-users" aria-hidden="true"></i> + </button> + + <button class="c-button c-button--error" + type="button" + show={opts.voterList.parentId} + onclick={delete} + title={__.delete}> + <i class="fa fa-times" aria-hidden="true"></i> + </button> + </div> + </div> + + </div> + <div class="voter-list-content" + show={expand}> + + <VoterList each={voterlist in opts.voterList.subLists} voter-list={voterlist} ref="voterLists"/> + <voterListmember each={member in opts.voterList.members} member={member} ref="voterListMembers"/> + + </div> + + <script type="es6"> + let session = require("../../js/Session"); + this.installBundle(session, "voterList"); + let voterListService = require("../../js/VoterListService"); + + this.expand = false; + + this.toggleExpand = () => { + if (this.expand) { + this.expand = false; + } else { + this.expandWithAdd(false, false); + } + }; + + this.expandWithAdd = (addMember, addVoterList) => { + voterListService.loadList(this.opts.voterList).then(() => { + if (addMember) { + voterListService.addMember(this.opts.voterList); + } + if (addVoterList) { + voterListService.addVoterList(this.opts.voterList); + } + this.expand = true; + this.update(); + }); + }; + + this.addMember = () => { + this.expandWithAdd(true, false); + }; + + this.addVoterList = () => { + this.expandWithAdd(false, true); + }; + + this.delete = () => { + if (this.opts.voterList.parentId) { + voterListService.deleteVoterList(this.opts.voterList); + this.parent.update(); + } + }; + + this.submit = () => { + if (this.opts.voterList.parentId) { + this.opts.voterList.name = this.refs.name.value; + this.opts.voterList.weight = this.refs.weight.value; + } else { + this.opts.voterList.name = "main voters list"; + this.opts.voterList.weight = 1; + } + if (Array.isArray(this.refs.voterLists)) { + this.refs.voterLists.forEach(voterList => { + voterList.submit(); + }); + } else if (this.refs.voterLists) { + this.refs.voterLists.submit(); + } + + if (Array.isArray(this.refs.voterListMembers)) { + this.refs.voterListMembers.forEach(voterListMember => { + voterListMember.submit(); + }); + } else if (this.refs.voterListMembers) { + this.refs.voterListMembers.submit(); + } + }; + + </script> + + <style> + + voterlist { + display: block; + margin: 5px auto; + border-radius: 4px; + border: 1px solid #13a2ff; + box-shadow: 0 0 1px hsla(0,0%,7%,.6); + padding: 0 0.5em 0.5em 0.5em; + color: #13a2ff; + } + + .voter-list-header { + display: flex; + } + + .voter-list-icone { + display: flex; + margin: 0.8em 0 auto 0; + font-size: 1.2em; + } + + .voter-list-icone .fa { + margin-right: 5px; + } + + .voter-list-form { + flex-grow: 1; + display: flex; + justify-content: flex-end;; + flex-wrap: wrap; + } + + .voter-list-fields { + margin-top: 0.5em; + flex-grow: 1; + } + + .o-field.field-weight { + min-width: 90px; + flex-grow: 0; + } + + .voter-list-actions { + margin-top: 0.5em; + display: flex; + justify-content: flex-end; + } + + .voter-list-actions .c-button { + margin-left: 5px; + } + + </style> +</voterList> diff --git a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMember.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMember.tag.html new file mode 100644 index 0000000..ba772c4 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMember.tag.html @@ -0,0 +1,92 @@ +<VoterlistMember> + <div class="voter-list-member-icone"> + <i class="fa fa-user" aria-hidden="true"></i> + </div> + <div class="voter-list-member-fields"> + <div class="c-input-group"> + <div class="o-field"> + <input class="c-field" + type="text" + name="name" + ref="name" + value={opts.member.name} + placeholder={__.name}> + </div> + <div class="o-field"> + <input class="c-field" + type="email" + name="email" + ref="email" + value={opts.member.email} + placeholder={__.email}> + </div> + <div class="o-field field-weight"> + <input class="c-field" + type="number" + name="weight" + ref="weight" + value={opts.member.weight} + placeholder={__.weight}> + </div> + </div> + </div> + <div class="voter-list-member-actions"> + <button class="c-button c-button--error" + type="button" + onclick={delete} + title={__.delete}> + <i class="fa fa-times" aria-hidden="true"></i> + </button> + </div> + + <script type="es6"> + let session = require("../../js/Session"); + this.installBundle(session, "voterList_member"); + let voterListService = require("../../js/VoterListService"); + + + this.delete = () => { + voterListService.deleteMember(this.opts.member); + this.parent.update(); + }; + + this.submit = () => { + this.opts.member.name = this.refs.name.value; + this.opts.member.email = this.refs.email.value; + this.opts.member.weight = this.refs.weight.value; + }; + + </script> + + <style> + + voterlistmember { + display: flex; + margin: 5px auto; + border-radius: 4px; + border: 1px solid #13a2ff; + box-shadow: 0 0 1px hsla(0,0%,7%,.6); + padding: 0.5em; + color: #13a2ff; + } + + .voter-list-member-icone { + margin: auto 5px auto 0; + font-size: 1.2em; + } + + .voter-list-member-fields { + flex-grow: 1; + } + + .o-field.field-weight { + min-width: 90px; + flex-grow: 0; + } + + .voter-list-member-actions { + margin-left: 5px; + } + + </style> +</VoterlistMember> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm