branch develop updated (936da1ad -> 18949e2b)
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 936da1ad correction flux RSS pour des sondage déja créé, titre et créateur d'un sondage non blanc new 18949e2b UI des listes de votants pour les sondages restraints 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 18949e2b417e1a30d2522b243698dea0cb134a3d Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Fri Jul 21 12:23:24 2017 +0200 UI des listes de votants pour les sondages restraints Summary of changes: .../entity/VoterListMemberTopiaDao.java | 6 +- .../chorem/pollen/rest/api/v1/VoterListApi.java | 2 +- .../chorem/pollen/services/bean/VoterListBean.java | 20 ++ .../pollen/services/service/VoterListService.java | 24 ++- pollen-ui-riot-js/src/main/web/conf.js | 2 +- pollen-ui-riot-js/src/main/web/i18n.json | 10 +- pollen-ui-riot-js/src/main/web/js/I18nHelper.js | 8 + pollen-ui-riot-js/src/main/web/js/PollForm.js | 32 +++ .../src/main/web/js/VoterListService.js | 83 +++++++- .../src/main/web/tag/components/Card.tag.html | 4 +- .../web/tag/components/ContextualMenu.tag.html | 19 +- .../main/web/tag/favoriteList/MemberCard.tag.html | 33 --- .../web/tag/favoriteList/MemberEditModal.tag.html | 29 +-- .../src/main/web/tag/poll/EditPoll.tag.html | 8 +- .../src/main/web/tag/poll/Settings.tag.html | 19 ++ .../src/main/web/tag/poll/Voters.tag.html | 149 ------------- .../tag/voterList/ImportFavoritListModal.tag.html | 59 +++++ .../src/main/web/tag/voterList/VoterList.tag.html | 237 ++++++++++++--------- .../web/tag/voterList/VoterListActions.tag.html | 177 --------------- .../main/web/tag/voterList/VoterListCard.tag.html | 82 +++++++ .../web/tag/voterList/VoterListEditModal.tag.html | 77 +++++++ .../web/tag/voterList/VoterListMember.tag.html | 101 --------- .../web/tag/voterList/VoterListMemberCard.tag.html | 81 +++++++ .../VoterListMemberEditModal.tag.html} | 57 +++-- pollen-ui-riot-js/webpack.config.js | 5 +- 25 files changed, 679 insertions(+), 645 deletions(-) delete mode 100644 pollen-ui-riot-js/src/main/web/tag/poll/Voters.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/voterList/ImportFavoritListModal.tag.html delete mode 100644 pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/voterList/VoterListCard.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/voterList/VoterListEditModal.tag.html delete mode 100644 pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMember.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMemberCard.tag.html copy pollen-ui-riot-js/src/main/web/tag/{favoriteList/MemberEditModal.tag.html => voterList/VoterListMemberEditModal.tag.html} (56%) -- 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 18949e2b417e1a30d2522b243698dea0cb134a3d Author: Sylvain Bavencoff <bavencoff@codelutin.com> Date: Fri Jul 21 12:23:24 2017 +0200 UI des listes de votants pour les sondages restraints --- .../entity/VoterListMemberTopiaDao.java | 6 +- .../chorem/pollen/rest/api/v1/VoterListApi.java | 2 +- .../chorem/pollen/services/bean/VoterListBean.java | 20 ++ .../pollen/services/service/VoterListService.java | 24 ++- pollen-ui-riot-js/src/main/web/conf.js | 2 +- pollen-ui-riot-js/src/main/web/i18n.json | 10 +- pollen-ui-riot-js/src/main/web/js/I18nHelper.js | 8 + pollen-ui-riot-js/src/main/web/js/PollForm.js | 32 +++ .../src/main/web/js/VoterListService.js | 83 +++++++- .../src/main/web/tag/components/Card.tag.html | 4 +- .../web/tag/components/ContextualMenu.tag.html | 19 +- .../main/web/tag/favoriteList/MemberCard.tag.html | 33 --- .../web/tag/favoriteList/MemberEditModal.tag.html | 29 +-- .../src/main/web/tag/poll/EditPoll.tag.html | 8 +- .../src/main/web/tag/poll/Settings.tag.html | 19 ++ .../src/main/web/tag/poll/Voters.tag.html | 149 ------------- .../tag/voterList/ImportFavoritListModal.tag.html | 59 +++++ .../src/main/web/tag/voterList/VoterList.tag.html | 237 ++++++++++++--------- .../web/tag/voterList/VoterListActions.tag.html | 177 --------------- .../main/web/tag/voterList/VoterListCard.tag.html | 82 +++++++ .../web/tag/voterList/VoterListEditModal.tag.html | 77 +++++++ .../web/tag/voterList/VoterListMember.tag.html | 101 --------- .../web/tag/voterList/VoterListMemberCard.tag.html | 81 +++++++ .../VoterListMemberEditModal.tag.html} | 57 +++-- pollen-ui-riot-js/webpack.config.js | 5 +- 25 files changed, 679 insertions(+), 645 deletions(-) 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 19251904..5dcd1dfe 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 @@ -12,9 +12,9 @@ public class VoterListMemberTopiaDao extends AbstractVoterListMemberTopiaDao<Vot Vote vote = voteDao.forVoterListMemberContains(entity).findUniqueOrNull(); if (vote != null) { vote.removeVoterListMember(entity); - } - if (vote.isVoterListMemberEmpty()) { - voteDao.delete(vote); + if (vote.isVoterListMemberEmpty()) { + voteDao.delete(vote); + } } super.delete(entity); 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 b843445b..8ac33dd7 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 @@ -78,7 +78,7 @@ public class VoterListApi { } - @Path("/polls/{pollId}/voterLists/{voterListId}") + @Path("/polls/{pollId}/voterLists/{voterListId}/lists") @GET public List<VoterListBean> getVoterLists(@Context VoterListService voterListService, @PathParam("pollId") PollenEntityId<Poll> pollId, 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 1f8a34b0..2eec3235 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 @@ -38,6 +38,10 @@ public class VoterListBean extends PollenBean<VoterList> { protected PollenEntityId<VoterList> parentId; + protected long countSubLists; + + protected long countMembers; + public VoterListBean() { super(VoterList.class); } @@ -91,4 +95,20 @@ public class VoterListBean extends PollenBean<VoterList> { public void setParentId(PollenEntityId<VoterList> parentId) { this.parentId = parentId; } + + public long getCountSubLists() { + return countSubLists; + } + + public void setCountSubLists(long countSubLists) { + this.countSubLists = countSubLists; + } + + public long getCountMembers() { + return countMembers; + } + + public void setCountMembers(long countMembers) { + this.countMembers = countMembers; + } } 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 39312b3a..40bb172f 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 @@ -151,6 +151,22 @@ public class VoterListService extends PollenServiceSupport { }; } + protected VoterListBean voterListBeanFunction(VoterListBean bean) { + + String entityId = bean.getEntityId(); + long countSubLists = getVoterListDao() + .forProperties(VoterList.PROPERTY_PARENT + "." + VoterList.PROPERTY_TOPIA_ID, entityId) + .count(); + + long countMembers = getVoterListMemberDao() + .forProperties(VoterListMember.PROPERTY_VOTER_LIST + "." + VoterList.PROPERTY_TOPIA_ID, entityId) + .count(); + + bean.setCountSubLists(countSubLists); + bean.setCountMembers(countMembers); + return bean; + } + public List<VoterListBean> getVoterLists(String pollId, String parentId) { checkNotNull(pollId); @@ -158,7 +174,7 @@ public class VoterListService extends PollenServiceSupport { Poll poll = getPollService().getPoll0(pollId); List<VoterList> voterLists = getVoterLists0(poll, parentId); - return toBeanList(VoterListBean.class, voterLists); + return toBeanList(VoterListBean.class, voterLists, this::voterListBeanFunction); } @@ -174,7 +190,7 @@ public class VoterListService extends PollenServiceSupport { VoterListBean result = null; if (voterList != null) { - result = toBean(VoterListBean.class, voterList); + result = toBean(VoterListBean.class, voterList, this::voterListBeanFunction); } return result; @@ -187,7 +203,7 @@ public class VoterListService extends PollenServiceSupport { checkPermission(PermissionVerb.readPoll, pollId); VoterList voterList = getVoterList0(pollId, voterListId); - return toBean(VoterListBean.class, voterList); + return toBean(VoterListBean.class, voterList, this::voterListBeanFunction); } @@ -223,7 +239,7 @@ public class VoterListService extends PollenServiceSupport { VoterList result = getVoterListDao().forTopiaIdEquals(voterList.getEntityId()).findUnique(); //TODO Notify - return toBean(VoterListBean.class, result); + return toBean(VoterListBean.class, result, this::voterListBeanFunction); } diff --git a/pollen-ui-riot-js/src/main/web/conf.js b/pollen-ui-riot-js/src/main/web/conf.js index eeb2148f..5b5da95d 100644 --- a/pollen-ui-riot-js/src/main/web/conf.js +++ b/pollen-ui-riot-js/src/main/web/conf.js @@ -1,5 +1,5 @@ window.pollenConf = { - endPoint: "http://localhost:8888/pollen-rest-api", + endPoint: POLLEN_API_URL, piwikUrl: "", // add the piwik url, eg: http://localhost/piwik piwikSiteId: "", // add the site id, eg: 3 defaultMessageTimeout: 15, diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 2aee07af..8c56ba3d 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -238,6 +238,7 @@ "poll_description_nameNotBlank": "Vote nom ne doit pas être blanc", "poll_description_email": "Votre courriel", "poll_description_emailPlaceHolder": "Renseignez votre courriel", + "poll_settings_restricted": "Sondage restraint ?", "poll_settings_basic_usage": "Options par défaut", "poll_settings_use_basic_usage": "Utiliser les options par défaut", "poll_settings_basic_usage_detail": "Par défaut Pollen vous propose : ", @@ -332,7 +333,6 @@ "poll_step_choices": "Choix", "poll_step_options": "Options", "poll_step_voters": "Participants", - "poll_voters_description": "Qui peut voter ?", "poll_voters_previous": "Précédent", "poll_voters_save": "Enregistrer", "poll_voters_freePoll": "Tout le monde peut voter (Sondage public)", @@ -470,8 +470,12 @@ "favoriteList_import": "Importer", "error_manager_403": "Erreur : Accès refusé", "error_manager_500": "Erreur : Service indisponile", + "voterList_new": "Nouveelle liste", + "voterList_edit": "Modifier la liste", "voterList_name": "Nom", + "voterList_name_error_alreadyExist": "Le Nom existe dèjà dans cette liste", "voterList_weight": "Poids", + "voterList_main_list": "Liste principale", "voterList_addMember": "Ajouter un participant", "voterList_addVoterList": "Ajouter une sous-liste", "voterList_exportFavoriteList": "Exporter dans une nouvelle liste de votants", @@ -484,8 +488,12 @@ "voterList_resendInvitation_success": "invitations sont envoyées", "voterList_resendInvitation_one": "1 invitation est envoyée", "voterList_resendInvitation_none": "Tout les participants de cette liste ont votés", + "voterList_member_new": "Nouveau participant", + "voterList_member_edit": "Modifier le participant", "voterList_member_name": "Nom", + "voterList_member_name_error_alreadyExist": "Le Nom existe dèjà dans cette liste", "voterList_member_email": "Courriel", + "voterList_member_email_error_alreadyExist": "Le Courriel existe dèjà dans cette liste", "voterList_member_weight": "Poids", "voterList_member_delete": "Supprimer le participant", "voterList_member_deleteMessage": "Supprimer le participant ?", diff --git a/pollen-ui-riot-js/src/main/web/js/I18nHelper.js b/pollen-ui-riot-js/src/main/web/js/I18nHelper.js index 5f5e891a..44d05500 100644 --- a/pollen-ui-riot-js/src/main/web/js/I18nHelper.js +++ b/pollen-ui-riot-js/src/main/web/js/I18nHelper.js @@ -58,6 +58,14 @@ module.exports = { return this.i18nformat(this.__[key], params) || key; }, + translateErrors(errors) { + let errorsTranslate = {}; + Object.keys(errors).forEach((key) => { + errorsTranslate[key] = errors[key].map(this._l); + }); + return errorsTranslate; + }, + i18nformat(value, params) { if (!params) { return value; 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 9abd9b4d..e7135964 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollForm.js +++ b/pollen-ui-riot-js/src/main/web/js/PollForm.js @@ -50,6 +50,8 @@ class PollForm { this.model = {}; this.choices = []; this.choicesToRemove = []; + this.mainVoterList = {}; + this.currentVoterList = {}; } _loadVoteCountingTypes() { @@ -101,8 +103,10 @@ class PollForm { voterListService.init(this).then(voterList => { this.mainVoterList = voterList; + this.setCurrentVoterList(voterList); }); + this._updateSteps(); this.step = 0; return Promise.resolve(this); @@ -130,9 +134,11 @@ class PollForm { voterListService.init(this).then(voterList => { this.mainVoterList = voterList; + this.setCurrentVoterList(voterList); }); this.isInit = true; + this._updateSteps(); this.setStep(0); }); } @@ -265,6 +271,32 @@ class PollForm { this.model.commentVisibility = "EVERYBODY"; } + togglePollType() { + if (this.model.pollType === "RESTRICTED") { + this.model.pollType = "FREE"; + } else { + this.model.pollType = "RESTRICTED"; + } + this._updateSteps(); + bus.trigger("pollStepsChange", this.steps); + } + + _updateSteps() { + let steps = ["general", "choices", "options"]; + if (this.model.pollType === "RESTRICTED") { + steps.push("voters"); + } + this.steps = steps; + } + + setCurrentVoterList(list) { + return voterListService.loadList(list).then(() => { + this.currentVoterList = list; + return list; + }); + } + + } module.exports = 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 088347e5..7294960c 100644 --- a/pollen-ui-riot-js/src/main/web/js/VoterListService.js +++ b/pollen-ui-riot-js/src/main/web/js/VoterListService.js @@ -22,7 +22,9 @@ class VoterListService extends FetchService { return { id: this.tempPrefix + this.tempId++, parentId: parent && parent.id, + countSubLists: 0, subLists: [], + countMembers: 0, members: [], name: name, weight: weight || 1, @@ -94,11 +96,37 @@ class VoterListService extends FetchService { return voterListPromise; } + _checkVoterList(parent, name, weight, id) { + let errors = {}; + let sameName = parent.subLists.find(m => m.id !== id && m.name === name); + if (sameName) { + errors.name = ["name_error_alreadyExist"]; + } + return errors; + } + addVoterList(parent, name, weight) { + let errors = this._checkVoterList(parent, name, weight); + if (Object.keys(errors).length > 0) { + return Promise.reject(errors); + } let voterList = this._newVoterList(parent, name, weight); parent.subLists.push(voterList); this.voterListsById[voterList.id] = voterList; - return voterList; + parent.countSubLists = parent.subLists.length; + return Promise.resolve(voterList); + } + + saveVoterList(id, name, weight) { + let voterList = this.voterListsById[id]; + let parent = this.voterListsById[voterList.parentId]; + let errors = this._checkVoterList(parent, name, weight, id); + if (Object.keys(errors).length > 0) { + return Promise.reject(errors); + } + voterList.name = name; + voterList.weight = weight; + return Promise.resolve(voterList); } deleteVoterList(voterList) { @@ -119,6 +147,7 @@ class VoterListService extends FetchService { if (!voterList.id.startsWith(this.tempPrefix)) { this.voterListsToDelete.push(voterList); } + parent.countSubLists = parent.subLists.length; } _deleteVoterList2(voterList) { @@ -128,11 +157,43 @@ class VoterListService extends FetchService { delete this.voterListsById[voterList.id]; } + + _checkMember(parent, name, email, weight, id) { + let errors = {}; + let sameName = parent.members.find(m => m.id !== id && m.name === name); + if (sameName) { + errors.name = ["name_error_alreadyExist"]; + } + let sameEmail = parent.members.find(m => m.id !== id && m.email === email); + if (sameEmail) { + errors.email = ["email_error_alreadyExist"]; + } + return errors; + } + addMember(parent, name, email, weight) { + let errors = this._checkMember(parent, name, email, weight); + if (Object.keys(errors).length > 0) { + return Promise.reject(errors); + } let member = this._newMember(parent, name, email, weight); parent.members.push(member); this.voterListMembersById[member.id] = member; - return member; + parent.countMembers = parent.members.length; + return Promise.resolve(member); + } + + saveMember(id, name, email, weight) { + let member = this.voterListMembersById[id]; + let parent = this.voterListsById[member.voterListId]; + let errors = this._checkMember(parent, name, email, weight, id); + if (Object.keys(errors).length > 0) { + return Promise.reject(errors); + } + member.name = name; + member.email = email; + member.weight = weight; + return Promise.resolve(member); } deleteMember(member) { @@ -144,6 +205,7 @@ class VoterListService extends FetchService { if (!member.id.startsWith(this.tempPrefix)) { this.voterListMembersToDelete.push(member); } + voterList.countMembers = voterList.members.length; } getVoterLists() { @@ -185,7 +247,10 @@ class VoterListService extends FetchService { listsToDelete: this.voterListsToDelete, membersToDelete: this.voterListMembersToDelete }, - {permission: this.pollForm.model.permission}); + {permission: this.pollForm.model.permission}).then(() => { + this.voterListsToDelete = []; + this.voterListMembersToDelete = []; + }); } importFavoriteList(voterList, favoriteListId) { @@ -197,7 +262,9 @@ class VoterListService extends FetchService { }; let importPromises = []; importPromises.push(FavoriteListService.members(favoriteListId, "", pagination).then(result => { - result.elements.forEach(member => {this.addMember(voterList, member.name, member.email, member.weight);}); + result.elements.forEach(member => { + this.addMember(voterList, member.name, member.email, member.weight); + }); return Promise.resolve(); })); let paginationChild = { @@ -207,10 +274,10 @@ class VoterListService extends FetchService { pageNumber: 0 }; importPromises.push(FavoriteListService.childrenLists(favoriteListId, "", paginationChild).then(result => { - let subListImportPromises = []; - result.elements.forEach(childList => { - let subVoterList = this.addVoterList(voterList, childList.child.name, childList.weight); - subListImportPromises.push(this.importFavoriteList(subVoterList, childList.child.id)); + let subListImportPromises = result.elements.map(childList => { + return this.addVoterList(voterList, childList.child.name, childList.weight).then(subVoterList => { + return this.importFavoriteList(subVoterList, childList.child.id); + }); }); return Promise.all(subListImportPromises); })); diff --git a/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html index 59d80110..307c8aed 100644 --- a/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/components/Card.tag.html @@ -17,11 +17,11 @@ require("./LetterAvatar.tag.html"); <div class="card-content"> - <div if={!opts.href} class="card-avatar"> + <div if={!opts.href && !opts.onletterclick} class="card-avatar"> <LetterAvatar name={opts.name} rounded="true"/> </div> - <a if={opts.href} href={opts.href} class="card-avatar"> + <a if={opts.href || opts.onletterclick} href={opts.href} onclick={opts.onletterclick} class="card-avatar"> <LetterAvatar name={opts.name} rounded="true"/> </a> diff --git a/pollen-ui-riot-js/src/main/web/tag/components/ContextualMenu.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/ContextualMenu.tag.html index 63f27cab..1cffb8f0 100644 --- a/pollen-ui-riot-js/src/main/web/tag/components/ContextualMenu.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/components/ContextualMenu.tag.html @@ -1,5 +1,5 @@ -<ContextualMenu> - <i class="icon fa fa-plus"></i> +<ContextualMenu class={open : opts.openForce}> + <i class="icon fa {opts.icon || 'fa-plus'}"></i> <div class="links"> <yield/> @@ -15,11 +15,8 @@ overflow: hidden; background-color: var(--main); color:var(--background); - } - - contextualmenu:hover { - width: inherit; - height: inherit; + max-width: 90%; + z-index: 3; } .icon { @@ -33,11 +30,11 @@ .links { max-width: 0; max-height: 0; - transition: max-width 0.75s, max-height 0.75s; - + transition: max-width 1s, max-height 1s; } - contextualmenu:hover .links { + contextualmenu:hover .links, + contextualmenu.open .links { max-width: 500px; max-height: 500px; transition: max-width 1s, max-height 1s; @@ -57,7 +54,7 @@ } @media (max-width: 640px) { - contextualmenu { + contextualmenu { right: 1em; bottom: 1em; } diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberCard.tag.html index 2f29dc96..6d8f120a 100644 --- a/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberCard.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberCard.tag.html @@ -58,39 +58,6 @@ require("./MemberEditModal.tag.html"); text-overflow: ellipsis; } - .member-card-view { - display: flex; - justify-content: space-between; - } - - .member-actions { - display: flex; - align-items: flex-start; - } - - .member-actions button { - margin-left: 3px; - } - - .member-card-edit .o-form-element .c-label:first-child { - width: 25%; - display: inline-block; - text-align: right; - float: left; - padding-top: 0.5em; - padding-right: 5px; - } - - .member-card-edit .o-form-element .c-field { - width: 75%; - display: inline-block; - } - - .member-card-edit .o-form-element .c-toggle, - .member-card-edit .o-form-element .c-hint { - margin-left: 25%; - } - </style> </MemberCard> diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html index 2e915c2e..eb3291cf 100644 --- a/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html @@ -69,26 +69,19 @@ require("../popup/Modal.tag.html"); let promise; if (member.id) { - promise = favoriteListService.saveMember(this.opts.favoriteList.id, member).then(() => { - this.errors = {}; - }, errors => { - this.errors = errors; - this.bus.trigger("message", new Message(errors, "error")); - this.update(); - return Promise.reject(); - }); + promise = favoriteListService.saveMember(this.opts.favoriteList.id, member); } else { - promise = favoriteListService.addMember(this.opts.favoriteList.id, member).then(() => { - this.errors = {}; - this.update(); - }, errors => { - this.errors = errors; - this.bus.trigger("message", new Message(errors, "error")); - this.update(); - return Promise.reject(); - }); + promise = favoriteListService.addMember(this.opts.favoriteList.id, member); } - return promise; + return promise.then(() => { + this.errors = {}; + this.update(); + }, errors => { + this.errors = errors; + this.bus.trigger("message", errors, "error"); + this.update(); + return Promise.reject(); + }); }; </script> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/EditPoll.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/EditPoll.tag.html index c5774bf9..e16bd74c 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/EditPoll.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/EditPoll.tag.html @@ -21,7 +21,7 @@ require("./Description.tag.html"); require("./Choices.tag.html"); require("./Settings.tag.html"); -require("./Voters.tag.html"); +require("../voterList/VoterList.tag.html"); require("./Summary.tag.html"); require("../components/HumanInput.tag.html"); @@ -57,7 +57,7 @@ require("../components/HumanInput.tag.html"); <Description if={!showSummary && form.step === 0} form={form}/> <Choices if={!showSummary && form.step === 1} form={form}/> <Settings if={!showSummary && form.step === 2} form={form}/> - <Voters if={!showSummary && form.step === 3} form={form}/> + <VoterList if={!showSummary && form.step === 3 && form.model.pollType === "RESTRICTED"} form={form} ref="voters"/> <Summary if={showSummary} form={form}/> <div class="actions" if={!showSummary}> @@ -176,6 +176,10 @@ require("../components/HumanInput.tag.html"); } }; + this.listen("pollStepsChange", () => { + this.update(); + }); + </script> <style> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html index 70a521e7..9317a978 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html @@ -22,6 +22,21 @@ require("../components/date-time-picker.tag.html"); <Settings> <div class="form-section" show={form.creation}> + <div class="o-form-element"> + <label class="c-toggle c-toggle--info"> + {__.restricted} + <input type="checkbox" + name="pollType" + ref="pollType" + disabled={opts.form.hasVotes} + checked={opts.form.model.pollType === "RESTRICTED"} + onclick={togglePollType}> + <div class="c-toggle__track"> + <div class="c-toggle__handle"></div> + </div> + </label> + </div> + <h4><i class="fa fa-cogs"></i> {__.basic_usage}</h4> <div class="o-form-element"> <label class="c-toggle c-toggle--info"> @@ -422,6 +437,10 @@ require("../components/date-time-picker.tag.html"); this.notifyMeBeforePollEnds = !this.notifyMeBeforePollEnds; }; + this.togglePollType = () => { + this.opts.form.togglePollType(); + }; + this.submit = () => { if (!this.showOptions && this.form.creation) { 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 deleted file mode 100644 index 7ae9d685..00000000 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Voters.tag.html +++ /dev/null @@ -1,149 +0,0 @@ -/*- - * #%L - * Pollen :: UI (Riot Js) - * %% - * Copyright (C) 2009 - 2017 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ - require("../voterList/VoterList.tag.html"); - -<Voters> - <div class="o-form-element"> - <label class="c-label"> - {__.description} - </label> - <select class="c-field" - name="pollType" - ref="pollType" - disabled={form.hasVotes} - value={form.model.pollType} - onchange={pollTypeChange} > - <option value="FREE">{__.freePoll}</option> - <option value="RESTRICTED">{__.restrictedPoll}</option> - </select> - </div> - - <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 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> - <div class="section-content"> - <VoterList voter-list={form.mainVoterList} form={opts.form} ref="mainVoterList"/> - </div> - </div> - - <script type="es6"> - this.session = require("../../js/Session"); - this.installBundle(this.session, "poll_voters"); - this.form = this.opts.form; - this.votePrivate = this.form.model.pollType !== "FREE"; - this.participants = ""; - this.pollTypeChange = (e) => { - this.votePrivate = e.target.value !== "FREE"; - }; - - this.submit = () => { - this.form.model.pollType = this.refs.pollType.value; - 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> - <style> - - .o-form-element .participants { - 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; - text-align: right; - float: left; - padding-top: 0.5em; - padding-right: 5px; - } - - .o-form-element .c-field, - .o-form-element .participants { - width: 75%; - display: inline-block; - } - - - .o-form-element .participants { - display: inline-block; - } - - .o-form-element .c-toggle { - margin-left: 25%; - } - } - - - </style> -</Voters> diff --git a/pollen-ui-riot-js/src/main/web/tag/voterList/ImportFavoritListModal.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/ImportFavoritListModal.tag.html new file mode 100644 index 00000000..d3ed3cc0 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/voterList/ImportFavoritListModal.tag.html @@ -0,0 +1,59 @@ +require("../popup/Modal.tag.html"); + +<ImportFavoritListModal> + + <modal header={__.importFavoriteList} + onsubmit={import} + ref="importFavoriteListModal"> + <div show={favoriteLists.length === 0}> + {__.importFavoriteList_none} + </div> + <select class="c-field" + show={favoriteLists.length > 0} + ref="selectFavoriteListToImport"> + <option each={favoriteList in parent.favoriteLists} + value={favoriteList.id}> + {favoriteList.name} + </option> + </select> + </modal> + + <script type="es6"> + let session = require("../../js/Session"); + this.installBundle(session, "voterList"); + let favoriteListService = require("../../js/FavoriteListService"); + let voterListService = require("../../js/VoterListService"); + + this.favoriteLists = []; + + this.open = () => { + let pagination = { + order: "name", + desc: false, + pageSize: -1, + pageNumber: 0 + }; + return favoriteListService.favoriteLists(pagination).then((result) => { + this.favoriteLists = result.elements; + let promise = this.refs.importFavoriteListModal.open(); + this.parent.update(); + return promise; + }); + }; + + this.import = () => { + let favoriteListId = this.refs.importFavoriteListModal.refs.selectFavoriteListToImport.value; + return voterListService.importFavoriteList(this.opts.voterList, favoriteListId).then(() => { + this.errors = {}; + this.update(); + }, errors => { + this.errors = this.translateErrors(errors); + this.bus.trigger("message", this.errors, "error"); + this.update(); + return Promise.reject(); + }); + }; + + </script> + +</ImportFavoritListModal> 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 index 4485d767..eb2b8f4f 100644 --- 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 @@ -1,133 +1,168 @@ -require("./VoterListMember.tag.html"); -require("./VoterListActions.tag.html"); -require("../popup/Modal.tag.html"); - -<VoterList class="card"> - <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" - disabled={opts.form.model.isClosed} - value={opts.voterList.name} - required - placeholder={__.name}> - </div> - <div class="o-field o-field--icon-left field-weight"> - <i class="fa fa-fw fa-balance-scale c-icon" aria-hidden="true"></i> - <input class="c-field" - type="number" - name="weight" - ref="weight" - disabled={opts.form.model.isClosed} - value={opts.voterList.weight} - required - placeholder={__.weight}> - </div> - </div> - </div> - <VoterListActions voter-list={opts.voterList} form={parent.opts.form}/> - </div> +require("./VoterListCard.tag.html"); +require("./VoterListEditModal.tag.html"); +require("./VoterListMemberCard.tag.html"); +require("./VoterListMemberEditModal.tag.html"); +require("./ImportFavoritListModal.tag.html"); +require("../components/ContextualMenu.tag.html"); + +<VoterList> + <ol class="c-breadcrumbs"> + <li class="c-breadcrumbs__crumb" each={list, index in getVoterListsStack()}> + <a class="c-link" onclick={parent.setCurrent(list)}> + {index === 0 ? parent.__.main_list : list.name} + </a> + </li> + <li class="c-breadcrumbs__crumb c-text--loud"> + {opts.form.currentVoterList.parentId ? opts.form.currentVoterList.name : __.main_list} + </li> + </ol> + + <div class="elements"> + <VoterListCard each={subList in opts.form.currentVoterList.subLists} + voter-list={subList} + form={parent.opts.form} + on-voter-list-change={parent.update} + onletterClick={parent.setCurrent(subList)}/> + <VoterListMemberCard each={member in opts.form.currentVoterList.members} + member={member} + form={parent.opts.form} + on-member-change={parent.update}/> </div> - <div class="voter-list-content" - show={expand}> - <VoterList each={voterlist in opts.voterList.subLists} voter-list={voterlist} form={parent.opts.form} ref="voterLists"/> - <voterListmember each={member in opts.voterList.members} member={member} form={parent.opts.form} ref="voterListMembers"/> - <VoterListActions if={opts.voterList.subLists.length + opts.voterList.members.length > 5} voter-list={opts.voterList} form={parent.opts.form}/> - </div> + <ContextualMenu if={!opts.form.model.isClosed} + icon="fa-ellipsis-v" + open-force={opts.form.currentVoterList.countMembers === 0 && opts.form.currentVoterList.countSubLists === 0}> + <a onclick={parent.addMember} > + <i class="fa fa-plus" aria-hidden="true"></i> + <i class="fa fa-user" aria-hidden="true"></i> + {parent.__.addMember} + </a> + <a onclick={parent.addVoterList} > + <i class="fa fa-plus" aria-hidden="true"></i> + <i class="fa fa-users" aria-hidden="true"></i> + {parent.__.addVoterList} + </a> + <a if={parent.user} + onclick={parent.importFavoriteList} > + <i class="fa fa-arrow-down" aria-hidden="true"></i> + <i class="fa fa-users" aria-hidden="true"></i> + {parent.__.importFavoriteList} + </a> + <a if={parent.user && !parent.opts.form.currentVoterList.temp} + onclick={parent.exportToFavoriteList} > + <i class="fa fa-arrow-up" aria-hidden="true"></i> + <i class="fa fa-users" aria-hidden="true"></i> + {parent.__.exportFavoriteList} + </a> + + <a if={!parent.opts.form.creation && !parent.opts.form.model.isClosed && !parent.opts.form.currentVoterList.temp} + onclick={parent.resendInvitation} > + <i class="fa fa-paper-plane" aria-hidden="true"></i> + {parent.__.resendInvitation} + </a> + + </ContextualMenu> + + <VoterListEditModal ref="createListModal" + parent-list={opts.form.currentVoterList}/> + + <VoterListMemberEditModal ref="creatMemberModal" + voter-list={opts.form.currentVoterList}/> + + <ImportFavoritListModal ref="importFavoriteListModal" + voter-list={opts.form.currentVoterList}/> <script type="es6"> let session = require("../../js/Session"); this.installBundle(session, "voterList"); let voterListService = require("../../js/VoterListService"); let favoriteListsService = require("../../js/FavoriteListService"); + let route = require("riot-route"); - this.expand = false; + this.user = session.getUser(); + + this.onUserChange = user => { + this.user = user; + this.update(); + }; - this.toggleExpand = () => { - if (this.expand) { - this.expand = false; - } else { - this.expandable(); + this.listen("user", this.onUserChange); + + this.getVoterListsStack = () => { + let stack = []; + let current = this.opts.form.currentVoterList; + while (current.parentId) { + current = voterListService.voterListsById[current.parentId]; + stack.push(current); } + return stack.reverse(); }; - this.expandable = () => { - return voterListService.loadList(this.opts.voterList).then(() => { - this.expand = true; + this.setCurrent = list => () => { + this.opts.form.setCurrentVoterList(list).then(() => { this.update(); - return Promise.resolve(); }); }; - 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 = this.__.mainList + this.opts.form.model.title; - 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(); - } + this.addMember = () => { + this.refs.creatMemberModal.open().then(() => { + this.update(); + }, () => {}); + this.update(); + }; + + this.addVoterList = () => { + this.refs.createListModal.open().then(() => { + this.update(); + }, () => {}); + this.update(); + }; + + this.importFavoriteList = () => { + this.refs.importFavoriteListModal.open().then(() => { + this.update(); + }, () => {}); + this.update(); + }; - if (Array.isArray(this.refs.voterListMembers)) { - this.refs.voterListMembers.forEach(voterListMember => { - voterListMember.submit(); + this.exportToFavoriteList = () => { + if (session.getUser() && !this.opts.form.currentVoterList.temp) { + favoriteListsService.importFromVoterList(this.opts.form.currentVoterList.id).then((result) => { + route("/favoriteLists/" + result.id); + }, errors => { + this.bus.trigger("message", errors, "error"); + this.parent.update(); }); - } else if (this.refs.voterListMembers) { - this.refs.voterListMembers.submit(); } }; - </script> - - <style> + this.resendInvitation = () => { + voterListService.resendInvitationList(this.opts.form.currentVoterList).then((result) => { + let message; + if (result <= 0) { + message = this.__.resendInvitation_none; + } else if (result === 1) { + message = this.__.resendInvitation_one; + } else { + message = result + " " + this.__.resendInvitation_success; + } + this.bus.trigger("message", message, "info"); + }); + }; - .voter-list-header { - display: flex; - } + this.submit = () => { + this.opts.form.mainVoterList.name = this.__.mainList + this.opts.form.model.title; + }; - .voter-list-icone { - display: flex; - margin: 0.3em 0 auto 0; - font-size: 1.2em; - } + </script> - .voter-list-icone .fa { - margin-right: 5px; - } + <style> - .voter-list-form { - flex-grow: 1; + .elements { display: flex; - justify-content: flex-end;; flex-wrap: wrap; - } - - .voter-list-fields { - flex-grow: 1; - } - - .o-field.field-weight { - min-width: 90px; - flex-grow: 0; + justify-content: flex-start; } </style> diff --git a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html deleted file mode 100644 index 94559847..00000000 --- a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListActions.tag.html +++ /dev/null @@ -1,177 +0,0 @@ -<VoterListActions> - - <button class="c-button c-button--success" - type="button" - show={!opts.form.model.isClosed} - disabled={opts.form.model.isClosed} - 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" - show={!opts.form.model.isClosed} - disabled={opts.form.model.isClosed} - 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--success" - type="button" - onclick={importFavoriteList} - show={user && !opts.form.model.isClosed} - disabled={!user || opts.form.model.isClosed} - title={__.importFavoriteList}> - <i class="fa fa-arrow-down" aria-hidden="true"></i> - <i class="fa fa-users" aria-hidden="true"></i> - </button> - - <button class="c-button c-button--info" - type="button" - onclick={exportToFavoriteList} - show={user && !opts.voterList.temp} - disabled={!user || opts.voterList.temp} - title={__.exportFavoriteList}> - <i class="fa fa-arrow-up" aria-hidden="true"></i> - <i class="fa fa-users" aria-hidden="true"></i> - </button> - - <button class="c-button c-button--info" - type="button" - show={!opts.form.creation && !opts.form.model.isClosed} - disabled={opts.form.creation || opts.form.model.isClosed} - onclick={resendInvitation} - title={__.resendInvitation}> - <i class="fa fa-paper-plane" aria-hidden="true"></i> - </button> - - <button class="c-button c-button--error" - type="button" - show={opts.voterList.parentId && !opts.form.model.isClosed} - disabled={!opts.voterList.parentId || opts.form.model.isClosed} - onclick={delete} - title={__.delete}> - <i class="fa fa-times" aria-hidden="true"></i> - </button> - - <modal header={__.importFavoriteList} - ref="importFavoriteListModal"> - <div show={favoriteLists.length === 0}> - {__.importFavoriteList_none} - </div> - <select class="c-field" - show={favoriteLists.length > 0} - ref="selectFavoriteListToImport"> - <option each={favoriteList in parent.favoriteLists} - value={favoriteList.id}> - {favoriteList.name} - </option> - </select> - </modal> - - <script type="es6"> - let session = require("../../js/Session"); - this.installBundle(session, "voterList"); - let voterListService = require("../../js/VoterListService"); - let favoriteListsService = require("../../js/FavoriteListService"); - let route = require("riot-route"); - - this.favoriteLists = []; - this.user = session.getUser(); - - this.onUserChange = user => { - this.user = user; - this.update(); - }; - - this.listen("user", this.onUserChange); - - this.addMember = () => { - this.parent.expandable().then(() => { - voterListService.addMember(this.opts.voterList); - this.parent.update(); - }); - }; - - this.addVoterList = () => { - this.parent.expandable().then(() => { - voterListService.addVoterList(this.opts.voterList); - this.parent.update(); - }); - }; - - this.delete = () => { - if (this.opts.voterList.parentId) { - this.confirm(this.__.deleteMessage).then((confirm) => { - if (confirm) { - voterListService.deleteVoterList(this.opts.voterList); - this.parent.parent.update(); - } - }); - } - }; - - this.importFavoriteList = () => { - if (session.getUser()) { - let pagination = { - order: "name", - desc: false, - pageSize: -1, - pageNumber: 0 - }; - favoriteListsService.favoriteLists(pagination).then((result) => { - this.favoriteLists = result.elements; - this.refs.importFavoriteListModal.open().then(() => { - let favoriteListId = this.refs.importFavoriteListModal.refs.selectFavoriteListToImport.value; - this.parent.expandable().then(() => { - voterListService.importFavoriteList(this.opts.voterList, favoriteListId).then(() => { - return this.parent.expandable(); - }); - }); - }, () => {}); - this.parent.update(); - }); - } - }; - - this.exportToFavoriteList = () => { - if (session.getUser() && !this.opts.voterList.temp) { - favoriteListsService.importFromVoterList(this.opts.voterList.id).then((result) => { - route("/favoriteLists/" + result.id); - }, errors => { - this.bus.trigger("message", errors); - this.parent.update(); - }); - } - }; - - this.resendInvitation = () => { - voterListService.resendInvitationList(this.opts.voterList).then((result) => { - if (result <= 0) { - this.info(this.__.resendInvitation_none); - } else if (result === 1) { - this.info(this.__.resendInvitation_one); - } else { - this.info(result + " " + this.__.resendInvitation_success); - } - }); - }; - </script> - - <style> - - voterlistactions { - display: flex; - justify-content: flex-end; - } - - voterlistactions > .c-button { - margin-left: 5px; - } - - </style> - -</VoterListActions> diff --git a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListCard.tag.html new file mode 100644 index 00000000..f11fdbc5 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListCard.tag.html @@ -0,0 +1,82 @@ +require("../components/Card.tag.html"); +require("./VoterListEditModal.tag.html"); +<VoterListCard> + + <Card name={opts.voterList.name} + weight={opts.voterList.weight} + ondelete={delete} + onedit={edit} + onletterclick={opts.onletterclick} + class="list-card"> + <yield to="actions"> + <a class="info" + if={!parent.opts.form.creation && !parent.opts.form.model.isClosed && !parent.opts.voterList.temp} + title={parent.__.resendInvitation} + onclick={parent.resendInvitation}> + <i class="fa fa-paper-plane"></i> + </a> + </yield> + <yield to="detail"> + <div> + {parent.opts.voterList.countSubLists} <i class="fa fa-users"></i> + </div> + <div> + {parent.opts.voterList.countMembers} <i class="fa fa-user"></i> + </div> + </yield> + </Card> + + <VoterListEditModal ref="editModal" + voter-list={opts.voterList}/> + + <script type="es6"> + let session = require("../../js/Session"); + this.installBundle(session, "voterList"); + let voterListService = require("../../js/VoterListService"); + + this.edit = () => { + this.refs.editModal.open().then(() => { + if (this.opts.onVoterListChange) { + this.opts.onVoterListChange(); + } else { + this.update(); + } + }, () => {this.update();}); + this.update(); + }; + + this.delete = () => { + this.confirm(this.__.deleteMessage).then((confirm) => { + if (confirm) { + voterListService.deleteVoterList(this.opts.voterList); + if (this.opts.onVoterListChange) { + this.opts.onVoterListChange(); + } + } + }); + }; + + this.resendInvitation = () => { + voterListService.resendInvitationList(this.opts.voterList).then((result) => { + let message; + if (result <= 0) { + message = this.__.resendInvitation_none; + } else if (result === 1) { + message = this.__.resendInvitation_one; + } else { + message = result + " " + this.__.resendInvitation_success; + } + this.bus.trigger("message", message, "info"); + }); + }; + + </script> + + <style> + .card-detail { + display: flex; + justify-content: space-around; + } + </style> + +</VoterListCard> diff --git a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListEditModal.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListEditModal.tag.html new file mode 100644 index 00000000..b33c1357 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListEditModal.tag.html @@ -0,0 +1,77 @@ +require("../popup/Modal.tag.html"); + +<VoterListEditModal> + <Modal ref="modal" + header={opts.voterList.id ? __.edit : __.new} + label={__.save} + type="success" + onsubmit={save}> + <div class="o-form-element"> + <label class="c-label" for="name">{parent.__.name}</label> + <input type="text" + id="name" + ref="name" + class="c-field" + placeholder={parent.__.name_placeholder} + value={parent.opts.voterList.name} + class="c-field {c-field--error : parent.errors.name}"> + </div> + <div class="o-form-element"> + <label class="c-label" for="email">{parent.__.weight}</label> + <input type="number" + id="weight" + ref="weight" + required + value={parent.opts.voterList.weight || 1} + step="0.01" + class="c-field {c-field--error : parent.errors.weight}"> + </div> + </Modal> + + <script type="es6"> + let session = require("../../js/Session"); + let Message = require("../../js/Message"); + this.installBundle(session, "voterList"); + let voterListService = require("../../js/VoterListService"); + + if (!this.opts.voterList) { + this.opts.voterList = {}; + } + + this.errors = {}; + + this.open = () => { + if (!this.opts.voterList.id) { + this.refs.modal.refs.name.value = ""; + this.refs.modal.refs.weight.value = 1; + } + return this.refs.modal.open(); + }; + + this.save = () => { + let promise; + if (this.opts.voterList.id) { + promise = voterListService.saveVoterList( + this.opts.voterList.id, + this.refs.modal.refs.name.value, + this.refs.modal.refs.weight.value); + } else { + promise = voterListService.addVoterList( + this.opts.parentList, + this.refs.modal.refs.name.value, + this.refs.modal.refs.weight.value); + } + return promise.then(() => { + this.errors = {}; + this.update(); + }, errors => { + this.errors = this.translateErrors(errors); + this.bus.trigger("message", this.errors, "error"); + this.update(); + return Promise.reject(); + }); + }; + + </script> + +</VoterListEditModal> 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 deleted file mode 100644 index a0c71772..00000000 --- a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMember.tag.html +++ /dev/null @@ -1,101 +0,0 @@ -<VoterlistMember> - <div class="c-input-group"> - <div class="o-field o-field--icon-left o-field--icon-right"> - <i class="fa fa-user c-icon" aria-hidden="true"></i> - <input class="c-field" - type="text" - name="name" - ref="name" - disabled={opts.form.model.isClosed} - value={opts.member.name} - required - placeholder={__.name}> - <i if={!opts.form.creation} - class="fa fa-{opts.member.voting ? 'check-square-o' : 'square-o'} c-icon" aria-hidden="true"></i> - </div> - <div class="o-field"> - <input class="c-field" - type="email" - name="email" - ref="email" - disabled={opts.form.model.isClosed} - value={opts.member.email} - required - placeholder={__.email}> - </div> - <div class="o-field o-field--icon-left field-weight"> - <i class="fa fa-fw fa-balance-scale c-icon" aria-hidden="true"></i> - <input class="c-field" - type="number" - name="weight" - ref="weight" - disabled={opts.form.model.isClosed} - value={opts.member.weight} - required - placeholder={__.weight}> - </div> - <button class="c-button c-button--info" - type="button" - show={!opts.form.creation && !opts.form.model.isClosed} - disabled={opts.form.creation || opts.member.voting || opts.form.model.isClosed} - onclick={resendInvitation} - title={__.resendInvitation}> - <i class="fa fa-paper-plane" aria-hidden="true"></i> - </button> - <button class="c-button c-button--error" - type="button" - show={!opts.form.model.isClosed} - disabled={opts.form.model.isClosed} - 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 = () => { - this.confirm(this.__.deleteMessage).then((result) => { - if (result) { - voterListService.deleteMember(this.opts.member); - this.parent.update(); - } - }); - }; - - this.resendInvitation = () => { - voterListService.resendInvitationMember(this.opts.member).then((result) => { - this.info(result ? this.__.resendInvitation_success : this.__.resendInvitation_none); - }); - }; - - 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: block; - margin: 5px auto; - } - - .voter-list-member-fields { - flex-grow: 1; - } - - .o-field.field-weight { - min-width: 90px; - flex-grow: 0; - } - - </style> -</VoterlistMember> diff --git a/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMemberCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMemberCard.tag.html new file mode 100644 index 00000000..ee7f14fc --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMemberCard.tag.html @@ -0,0 +1,81 @@ +require("../components/Card.tag.html"); +require("./VoterListMemberEditModal.tag.html"); +<VoterListMemberCard> + + <Card name={opts.member.name} + weight={opts.member.weight} + ondelete={delete} + onEdit={edit} + class="member-card"> + <yield to="actions"> + <a class="info" + if={!parent.opts.form.creation && !parent.opts.form.model.isClosed && parent.opts.member.id && !parent.opts.member.voting} + title={parent.__.resendInvitation} + onclick={parent.resendInvitation}> + <i class="fa fa-paper-plane"></i> + </a> + </yield> + <yield to="detail"> + <span title={parent.opts.member.email}> + {parent.opts.member.email} + </span> + <i if={parent.opts.member.voting} class="voting success fa fa-check" aria-hidden="true"></i> + </yield> + </Card> + + <VoterListMemberEditModal ref="editModal" + member={opts.member}/> + + <script type="es6"> + let session = require("../../js/Session"); + this.installBundle(session, "voterList_member"); + let voterListService = require("../../js/VoterListService"); + + this.edit = () => { + this.refs.editModal.open().then(() => { + if (this.opts.onMemberChange) { + this.opts.onMemberChange(); + } else { + this.update(); + } + }, () => {this.update();}); + this.update(); + }; + + this.delete = () => { + this.confirm(this.__.deleteMessage).then((confirm) => { + if (confirm) { + voterListService.deleteMember(this.opts.member); + this.opts.onMemberChange(); + } + }); + }; + + this.resendInvitation = () => { + voterListService.resendInvitationMember(this.opts.member).then((result) => { + this.bus.trigger("message", result ? this.__.resendInvitation_success : this.__.resendInvitation_none, "info"); + }); + }; + + </script> + + <style> + + .card-detail { + font-size: 0.8em; + white-space: nowrap; + overflow: hidden; + text-align: center; + text-overflow: ellipsis; + } + + .voting { + position: absolute; + top: 55px; + font-size: 5em; + left: 93px; + } + + </style> + +</VoterListMemberCard> diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMemberEditModal.tag.html similarity index 56% copy from pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html copy to pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMemberEditModal.tag.html index 2e915c2e..b98409c0 100644 --- a/pollen-ui-riot-js/src/main/web/tag/favoriteList/MemberEditModal.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/voterList/VoterListMemberEditModal.tag.html @@ -1,6 +1,6 @@ require("../popup/Modal.tag.html"); -<MemberEditModal> +<VoterListMemberEditModal> <Modal ref="modal" header={opts.member.id ? __.edit : __.new} label={__.save} @@ -12,7 +12,7 @@ require("../popup/Modal.tag.html"); id="name" ref="name" required - class="c-field" + class="c-field {c-field--error: parent.errors.email}" placeholder={parent.__.name_placeholder} value={parent.opts.member.name}> </div> @@ -25,7 +25,6 @@ require("../popup/Modal.tag.html"); class="c-field {c-field--error: parent.errors.email}" placeholder={parent.__.email_placeholder} value={parent.opts.member.email}> - <div class="c-hint c-hint--static c-hint--error" each={error in parent.errors.email}>{error}</div> </div> <div class="o-form-element"> <label class="c-label" for="email">{parent.__.weight}</label> @@ -41,9 +40,8 @@ require("../popup/Modal.tag.html"); <script type="es6"> let session = require("../../js/Session"); - let Message = require("../../js/Message"); - this.installBundle(session, "favoriteList_member"); - let favoriteListService = require("../../js/FavoriteListService"); + this.installBundle(session, "voterList_member"); + let voterListService = require("../../js/VoterListService"); if (!this.opts.member) { this.opts.member = {}; @@ -61,36 +59,31 @@ require("../popup/Modal.tag.html"); }; this.save = () => { - let member = {}; - Object.assign(member, this.opts.member); - member.name = this.refs.modal.refs.name.value; - member.email = this.refs.modal.refs.email.value; - member.weight = this.refs.modal.refs.weight.value; - let promise; - if (member.id) { - promise = favoriteListService.saveMember(this.opts.favoriteList.id, member).then(() => { - this.errors = {}; - }, errors => { - this.errors = errors; - this.bus.trigger("message", new Message(errors, "error")); - this.update(); - return Promise.reject(); - }); + if (this.opts.member.id) { + promise = voterListService.saveMember( + this.opts.member.id, + this.refs.modal.refs.name.value, + this.refs.modal.refs.email.value, + this.refs.modal.refs.weight.value); } else { - promise = favoriteListService.addMember(this.opts.favoriteList.id, member).then(() => { - this.errors = {}; - this.update(); - }, errors => { - this.errors = errors; - this.bus.trigger("message", new Message(errors, "error")); - this.update(); - return Promise.reject(); - }); + promise = voterListService.addMember( + this.opts.voterList, + this.refs.modal.refs.name.value, + this.refs.modal.refs.email.value, + this.refs.modal.refs.weight.value); } - return promise; + return promise.then(() => { + this.errors = {}; + this.update(); + }, errors => { + this.errors = this.translateErrors(errors); + this.bus.trigger("message", this.errors, "error"); + this.update(); + return Promise.reject(); + }); }; </script> -</MemberEditModal> +</VoterListMemberEditModal> diff --git a/pollen-ui-riot-js/webpack.config.js b/pollen-ui-riot-js/webpack.config.js index 7832044d..0a233ab7 100644 --- a/pollen-ui-riot-js/webpack.config.js +++ b/pollen-ui-riot-js/webpack.config.js @@ -32,7 +32,10 @@ module.exports = { new webpack.ProvidePlugin({riot: "riot"}), new CopyWebpackPlugin([ - {from: "src/main/web/conf.js"}, + {from: "src/main/web/conf.js", + transform: function(content) { + return content.toString().replace("POLLEN_API_URL", JSON.stringify(process.env.POLLEN_SERVER_CONTEXT || "http://localhost:8888/pollen-rest-api")); + }}, {from: "src/main/web/index.html"}, {from: "src/main/web/home", to: "home"}, {from: "src/main/web/robots.txt"}, -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm