branch feature/pollen-riot-js updated (29ccbc0 -> c802d85)
This is an automated email from the git hooks/post-receive script. New change to branch feature/pollen-riot-js in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git from 29ccbc0 Mise en place des commentaires sur sondage + continue page de vote new 050bfbc improve PollenBean new c802d85 Ajout des votes The 2 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 c802d85ebf3afe48f4337ee3a70e437c9e33574a Author: Tony CHEMIT <dev@tchemit.fr> Date: Tue Jan 24 17:01:50 2017 +0100 Ajout des votes commit 050bfbc1c4de0c46c11fe51515c7dc3cf4d22bbf Author: Tony CHEMIT <dev@tchemit.fr> Date: Tue Jan 24 17:01:37 2017 +0100 improve PollenBean Summary of changes: .../chorem/pollen/services/bean/PollenBean.java | 14 +- pollen-ui-riot-js/src/main/web/i18n.json | 24 +- .../web/js/{CommentService.js => ChoiceService.js} | 24 +- .../web/js/{CommentService.js => VoteService.js} | 24 +- pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag | 6 +- .../src/main/web/tag/poll/PollComments.tag | 21 +- .../src/main/web/tag/poll/PollCreated.tag | 2 +- .../src/main/web/tag/poll/PollVotes.tag | 395 ++++++++++++++++++++- 8 files changed, 460 insertions(+), 50 deletions(-) copy pollen-ui-riot-js/src/main/web/js/{CommentService.js => ChoiceService.js} (63%) copy pollen-ui-riot-js/src/main/web/js/{CommentService.js => VoteService.js} (63%) -- 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 feature/pollen-riot-js in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 050bfbc1c4de0c46c11fe51515c7dc3cf4d22bbf Author: Tony CHEMIT <dev@tchemit.fr> Date: Tue Jan 24 17:01:37 2017 +0100 improve PollenBean --- .../java/org/chorem/pollen/services/bean/PollenBean.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) 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 6fdf6e4..2f94f20 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 @@ -24,6 +24,8 @@ package org.chorem.pollen.services.bean; import com.google.common.base.Preconditions; import org.nuiton.topia.persistence.TopiaEntity; +import java.util.Objects; + /** * Created on 5/15/14. * @@ -47,7 +49,7 @@ public abstract class PollenBean<E extends TopiaEntity> { } public boolean isPersisted() { - return id.isNotEmpty(); + return id != null && id.isNotEmpty(); } public String getEntityId() { @@ -64,17 +66,11 @@ public abstract class PollenBean<E extends TopiaEntity> { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof PollenBean)) return false; - - PollenBean that = (PollenBean) o; - - return id.equals(that.id); - + return this == o || o instanceof PollenBean && Objects.equals(id, ((PollenBean) o).id); } @Override public int hashCode() { - return id.hashCode(); + return Objects.hashCode(id); } } -- 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 feature/pollen-riot-js in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit c802d85ebf3afe48f4337ee3a70e437c9e33574a Author: Tony CHEMIT <dev@tchemit.fr> Date: Tue Jan 24 17:01:50 2017 +0100 Ajout des votes --- pollen-ui-riot-js/src/main/web/i18n.json | 24 +- pollen-ui-riot-js/src/main/web/js/ChoiceService.js | 55 +++ pollen-ui-riot-js/src/main/web/js/VoteService.js | 55 +++ pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag | 6 +- .../src/main/web/tag/poll/PollComments.tag | 21 +- .../src/main/web/tag/poll/PollCreated.tag | 2 +- .../src/main/web/tag/poll/PollVotes.tag | 395 ++++++++++++++++++++- 7 files changed, 541 insertions(+), 17 deletions(-) diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 68fae6a..7cfb62e 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -1,6 +1,15 @@ { "fr": { - "comment_popup_create":"Créer un commentaire", + "poll_comments_noComment":"Pas de commentaire.", + "poll_comments_title":"Commentaires", + "poll_comments_addComment":"Ajouter un commentaire", + "poll_comments_deleteComment":"Supprimer le commentaire ?", + "poll_votes_title":"Votes", + "poll_votes_deleteVote":"Supprimer le vote ?", + "poll_votes_authorPlaceHolder":"Renseigner votre nom", + "poll_votes_vote":"Voter", + "poll_votes_delete":"Supprimer le vote ?", + "comment_popup_create":"Ajouter un commentaire", "comment_popup_edit":"Éditer un commentaire", "comment_popup_action":"Enregistrer", "comment_popup_authorPlaceholder":"Saisir votre nom", @@ -141,8 +150,17 @@ "": "" }, "en": { - "comment_popup_create":"Create a comment", - "comment_popup_edit":"edit a comment", + "poll_comments_noComment":"No comment.", + "poll_comments_title":"Comments", + "poll_comments_addComment":"Add a comment", + "poll_comments_deleteComment":"Delete comment?", + "poll_votes_title":"Votes", + "poll_votes_deleteVote":"Delete vote?", + "poll_votes_authorPlaceHolder":"Fill your name", + "poll_votes_vote":"Vote", + "poll_votes_delete":"Delete vote?", + "comment_popup_create":"Add a comment", + "comment_popup_edit":"Edit a comment", "comment_popup_action":"Save", "comment_popup_authorPlaceholder":"Fill your name", "comment_popup_textPlaceholder":"Fill your comment", diff --git a/pollen-ui-riot-js/src/main/web/js/ChoiceService.js b/pollen-ui-riot-js/src/main/web/js/ChoiceService.js new file mode 100644 index 0000000..210bad4 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/js/ChoiceService.js @@ -0,0 +1,55 @@ +/*- + * #%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% + */ +let singleton = require("./Singleton"); +let FetchService = require("./FetchService"); + +class ChoiceService extends FetchService { + + getChoices(pollId, permission) { + let args = {}; + if (permission) { + args.permission = permission; + } + return this.getWithParams("/v1/polls/" + pollId + "/choices", args); + } + + addChoice(pollId, form) { + return this.form("/v1/polls/" + pollId + "/choices", {choice: form}); + } + + updateChoice(pollId, form, permission) { + let url = "/v1/polls/" + pollId + "/choices/" + form.id; + if (permission) { + url += "?permission=" + permission; + } + return this.form(url, {choice: form}); + } + + deleteChoice(pollId, choiceId, permission) { + let url = "/v1/polls/" + pollId + "/choices/" + choiceId; + if (permission) { + url += "?permission=" + permission; + } + return this.doDelete(url); + } +} + +module.exports = singleton(ChoiceService); diff --git a/pollen-ui-riot-js/src/main/web/js/VoteService.js b/pollen-ui-riot-js/src/main/web/js/VoteService.js new file mode 100644 index 0000000..b4029bb --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/js/VoteService.js @@ -0,0 +1,55 @@ +/*- + * #%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% + */ +let singleton = require("./Singleton"); +let FetchService = require("./FetchService"); + +class VoteService extends FetchService { + + getVotes(pollId, permission) { + let args = {}; + if (permission) { + args.permission = permission; + } + return this.getWithParams("/v1/polls/" + pollId + "/votes", args); + } + + addVote(pollId, form) { + return this.form("/v1/polls/" + pollId + "/votes", {vote: form}); + } + + updateVote(pollId, form, permission) { + let url = "/v1/polls/" + pollId + "/votes/" + form.id; + if (permission) { + url += "?permission=" + permission; + } + return this.form(url, {vote: form}); + } + + deleteVote(pollId, voteId, permission) { + let url = "/v1/polls/" + pollId + "/votes/" + voteId; + if (permission) { + url += "?permission=" + permission; + } + return this.doDelete(url); + } +} + +module.exports = singleton(VoteService); diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag index 9ef8b61..690326d 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag @@ -10,12 +10,12 @@ require('./PollComments.tag'); <div class="tab-header"> <div class="{selectedTab=='votes'?'tab-selected':'tab-not-selected'}"> - <a href="#poll/{pollId}/vote"> + <a href="#poll/{pollId}/vote{permission?'/' + permission : ''}"> <i class="fa fa-thumbs-o-up fa-flip-horizontal"></i>Votes </a> </div> <div class="{selectedTab=='comments'?'tab-selected':'tab-not-selected'}"> - <a href="#poll/{pollId}/comment"> + <a href="#poll/{pollId}/comment{permission?'/' + permission : ''}"> <i class="fa fa-comments-o"></i>Comments </a> </div> @@ -43,6 +43,7 @@ require('./PollComments.tag'); if (this.selectedTab == 'votes') { riot.mount(this.refs.content, "pollvotes", { pollId: this.pollId, + poll:this.poll, session: session, permission: this.permission }); @@ -73,6 +74,7 @@ require('./PollComments.tag'); padding: 15px 15px; width: 90%; margin-left: 20px; + margin-bottom: 10px; } .tab-content { diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/PollComments.tag b/pollen-ui-riot-js/src/main/web/tag/poll/PollComments.tag index b863063..978d237 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/PollComments.tag +++ b/pollen-ui-riot-js/src/main/web/tag/poll/PollComments.tag @@ -1,14 +1,15 @@ require('../Pagination.tag'); require('./CommentPopup.tag'); + <PollComments> <div class="comment-container"> <div class="legend"> - Comments <a if="{comments.length > -1}" onclick="{toggleSort}"><i ref="sortOwner" - class="fa fa-sort-amount-desc"></i></a> + {__.title} <a if="{comments.length > -1}" onclick="{toggleSort}"><i ref="sortOwner" + class="fa fa-sort-amount-desc"></i></a> </div> - <div class="body"> + <div show="{loaded}" class="body"> - <div if="{comments.length == 0}">Pas de commentaire</div> + <div show="{comments.length == 0}">{__.noComment}</div> <table show="{comments.length > 0}"> <tbody> <tr each="{comment in comments}"> @@ -48,7 +49,7 @@ require('./CommentPopup.tag'); </table> <div class="actions"> - <a class="button mainColorBackground" onclick="{openAddComment}">Ajouter un commentaire</a> + <a class="button mainColorBackground" onclick="{openAddComment}">{__.addComment}</a> </div> </div> </div> @@ -56,7 +57,7 @@ require('./CommentPopup.tag'); <CommentPopup ref="commentPopup"/> <script> - + this.loaded = false; let session = require("../../js/Session"); this.installBundle(session, "poll_comments"); let commentService = require("../../js/CommentService"); @@ -72,14 +73,14 @@ require('./CommentPopup.tag'); this.sortValue = true; // means desc this.comments = []; - this.toggleSort = (e) => { + this.toggleSort = () => { this.refs.sortOwner.classList.toggle('fa-sort-amount-desc'); this.refs.sortOwner.classList.toggle('fa-sort-amount-asc'); this.sortValue = !this.sortValue; this.pagination.onSortChange('postDate', this.sortValue); }; - this.openAddComment = (e) => { + this.openAddComment = () => { let comment = { text: '', authorName: '' @@ -123,7 +124,7 @@ require('./CommentPopup.tag'); let commentId = e.target.parentNode.parentNode.id; this.comments.forEach(comment => { if (comment.id == commentId) { - let response = confirm('Delete comment ?'); + let response = confirm(this.__deleteComment); if (response) { return commentService.deleteComment(this.pollId, commentId, this.permission || comment.permission || '') .then((result) => { @@ -149,6 +150,7 @@ require('./CommentPopup.tag'); return commentService.getComments(this.pollId, pagination, this.permission).then((result) => { this.comments = result.elements; console.info(this.comments); + this.loaded = true; this.update(); return result; }); @@ -156,6 +158,7 @@ require('./CommentPopup.tag'); </script> <style> + .danger { color: red; } diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/PollCreated.tag b/pollen-ui-riot-js/src/main/web/tag/poll/PollCreated.tag index 67fea23..7cdfaf4 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/PollCreated.tag +++ b/pollen-ui-riot-js/src/main/web/tag/poll/PollCreated.tag @@ -29,7 +29,7 @@ Le sondage «{form.model.title}» vient d'être créé. Un courriel vous a été adressé ainsi qu'aux éventuels participants. <br/> - <a href="#poll/{form.model.id}/edit">Accéder au sondage</a>. + <a href="#poll/{form.model.id}/vote">Accéder au sondage</a>. </div> </div> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/PollVotes.tag b/pollen-ui-riot-js/src/main/web/tag/poll/PollVotes.tag index 69efb7c..42abedf 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/PollVotes.tag +++ b/pollen-ui-riot-js/src/main/web/tag/poll/PollVotes.tag @@ -1,5 +1,396 @@ <PollVotes> - <div> - Votes + <div class="vote-container"> + <div class="legend"> + {__.title} + </div> + <div show="{loaded}" class="body"> + <form ref="form" onsubmit="{addOrEditVote}"> + + <table> + <thead> + <tr> + <th></th> + <th each="{choice in choices}"> + {choice.choiceValue} + </th> + </tr> + </thead> + <tbody> + <tr ref="newVote" class="{voteId?'':'selected'}" if="{poll.canVote}"> + <td class="vote-header"> + <input ref="voterName" name="voterName" class="voter" type="text" + required="{voteId?'':'required'}" disabled="{voteId?'disabled':''}" + placeholder="{__.authorPlaceHolder}"> + <input name="newVote" disabled="{voteId?'disabled':''}" type="submit" + class="button mainColorBackground {voteId?'disabled':''}" + value="{__.vote}" onclick="{prepareNewVote}"> + </td> + <td class="vote-choice" each="{choice in choices}"> + <div> + <input class="check" type="checkbox" name="{choice.id}.voteValue" + disabled="{voteId?'disabled':''}"> + </div> + </td> + </tr> + <tr each="{vote in votes}" ref="vote_{vote.id}"> + <td class="vote-header"> + <div class="voter"> + <div show="{vote.id != voteId}"> + <i class="fa fa-user"/> + {vote.voterName} + </div> + <input ref="vote_{vote.id}_voter" class="voter" type="text" value="{vote.voterName}" + required="{vote.id == voteId?'required':''}" show="{voteId == vote.id}" + disabled="{vote.id == voteId?'':'disabled'}" + placeholder="{__.authorPlaceHolder}"> + </div> + <div class="actions vote right" if="{vote.permission && (!voteId || voteId != vote.id)}" + id="{vote.id}"> + <a onclick="{parent.onEditVote}"><i class="fa fa-pencil-square-o fa-15x"/></a> + <a onclick="{parent.deleteVote}"><i class="fa fa-trash danger fa-15x"/></a> + </div> + + <div class="actions right vote-cancel" show="{voteId == vote.id}"> + <a onclick="{cancelEditVote}" class="small danger"> + <i class="fa fa-remove fa-15x"/> + </a> + <button class="icon" ref="vote_{vote.id}_vote" type="submit" + value="{__.vote}"> + <i class="fa fa-check fa-15x"/> + </button> + </div> + + </td> + <td class="vote-choice" each="{choice in vote.choice}"> + <div> + <input ref="vote_{vote.id}_{choice.choiceId}" class="check" type="checkbox" + checked="{choice.voteValue == 1?'checked':''}" + disabled="{voteId == vote.id?'':'disabled'}"> + </div> + </td> + </tr> + </tbody> + </table> + </form> + </div> </div> + + <script> + this.voteId = null; + this.loaded = false; + let session = require("../../js/Session"); + this.installBundle(session, "poll_votes"); + let voteService = require("../../js/VoteService"); + let choiceService = require("../../js/ChoiceService"); + + this.pollId = opts.pollId; + this.permission = opts.permission; + this.poll = opts.poll; + + this.votes = []; + this.choices = []; + + this.on('mount', () => { + if (session.isConnected() && this.poll.canVote && session.user) { + this.refs.voterName.value = session.user.name; + } + this.form = this.refs.form; + }); + + this.prepareNewVote = () => { + this.voteId = null; + }; + + this.cancelEditVote = () => { + let previousVoteId = this.voteId; + this.voteId = null; + let tr = this.refs['vote_' + previousVoteId]; + tr.classList.remove("selected"); + this.votes.forEach(v => { + if (previousVoteId == v.id) { + v.choice.forEach(c => { + this.refs['vote_' + previousVoteId + "_" + c.choiceId].checked = c.voteValue == 1 ? 'checked' : ''; + }) + } + }); + + }; + + this.onEditVote = (e) => { + if (this.voteId) { + let tr = this.refs['vote_' + this.voteId]; + tr.classList.remove("selected"); + } + this.voteId = e.target.parentNode.parentNode.id; + let tr = e.target.parentNode.parentNode.parentNode.parentNode; + tr.classList.add("selected"); + this.refs['vote_' + this.voteId + "_vote"].value = this.__.vote; + this.votes.forEach(v => { + if (this.voteId == v.id) { + this.refs['vote_' + this.voteId + "_voter"].value = v.voterName; + } + }); + }; + + this.submit = e => { + console.info("submit") + this.refs.form.onsubmit(); + }; + this.addOrEditVote = e => { + e.preventDefault(); + e.stopPropagation(); + + let newVote = !this.voteId; + + let vote = {choice: []}; + + if (newVote) { + + vote.id = null; + vote.voterName = this.refs.voterName.value; + + let form = this.refs.form; + this.choices.forEach(c => { + + vote.choice.push({ + choiceId: c.id, + voteValue: form[c.id + '.voteValue'].checked ? 1 : 0 + }); + + }); + + } else { + + vote.id = this.voteId; + vote.voterName = this.refs['vote_' + this.voteId + '_voter'].value; + + this.votes.forEach(v => { + if (this.voteId == v.id) { + v.choice.forEach(c => { + vote.choice.push({ + id: c.id, + choiceId: c.choiceId, + voteValue: this.refs['vote_' + this.voteId + "_" + c.choiceId].checked ? 1 : 0 + }); + }) + } + }); + + } + + console.info("Vote to send:"); + console.info(vote); + if (newVote) { + voteService.addVote(this.pollId, vote) + .then((result) => { + console.info("created vote"); + console.info(result); + this.refresh(); + + this.refs.voterName.value = null; + let form = this.refs.form; + this.choices.forEach(c => { + form[c.id + '.voteValue'].checked = ''; + + }); + + }); + } else { + voteService.updateVote(this.pollId, vote, this.permission || vote.permission || '') + .then((result) => { + console.info("updated vote"); + console.info(result); + this.refresh(); + + this.cancelEditVote(); + }); + } + }; + + this.deleteVote = (e) => { + let voteId = e.target.parentNode.parentNode.id; + this.votes.forEach(vote => { + if (vote.id == voteId) { + let response = confirm(this.__delete); + if (response) { + return voteService.deleteVote(this.pollId, voteId, this.permission || vote.permission || '') + .then((result) => { + console.info("delete vote"); + console.info(result); + this.refresh(); + }); + } + } + }); + }; + + this.refresh = () => { + if (!this.pollId) { + return Promise.resolve([]); + } + return voteService.getVotes(this.pollId, this.permission).then((result) => { + this.votes = result; + console.info("Reload votes"); + console.info(this.votes); + this.loaded = true; + this.update(); + return result; + }); + }; + + choiceService.getChoices(this.pollId, this.permission) + .then((result) => { + console.info("get choices"); + console.info(result); + this.choices = result; + this.refresh(); + }); + + </script> + <style> + + .actions { + width: 70px; + } + + .icon:hover { + cursor: pointer; + } + + .icon { + border-style: none; + background-color: white; + } + + .fa-15x { + font-size: 1.5em; + } + + .danger { + color: red; + } + + div.voter { + width: 100%; + } + + input.voter { + width: 100%; + } + + .vote-container { + width: 800px; + } + + .right { + display: flex; + justify-content: flex-end; + flex-grow: 1; + } + + .vote > a, .vote-cancel > a, .vote-cancel > button { + padding-left: 7px; + } + + .vote-cancel > button { + color: #13a2ff; + } + + .vote-header { + display: flex; + flex-direction: row; + align-items: center; + justify-items: center; + height: 50px; + } + + .vote-choice > div { + display: flex; + flex-flow: column; + align-items: center; + } + + .vote-cancel { + display: flex; + flex-flow: row; + align-items: center; + } + + .legend { + width: 800px; + } + + input.button { + width: 60px; + margin: 0 0 0 5px; + } + + a.button { + margin: 0 0 0 5px; + } + + input.voter { + margin: 0; + } + + input.disabled { + background: #ddd; + cursor: not-allowed; + } + + th:first-child { + border-right: 1px solid #ddd; + border-top: none; + width: 400px; + } + + td:first-child { + border-left: 1px solid #ddd; + } + + tr.selected > td:first-child { + border-left: 2px solid #13a2ff; + } + + tr.selected > td:last-child { + border-right: 2px solid #13a2ff; + } + + tr.selected > td { + border-bottom: 2px solid #13a2ff; + border-right: 1px solid #ddd; + border-top: 2px solid #13a2ff; + } + + td { + border-bottom: 1px solid #ddd; + border-right: 1px solid #ddd; + vertical-align: middle; + padding-left: 5px; + padding-right: 5px; + } + + th { + border-bottom: 1px solid #ddd; + border-top: 1px solid #ddd; + border-right: 1px solid #ddd; + vertical-align: middle; + height: 50px; + } + + table { + width: 800px; + border-spacing: 0; + } + + .check { + width: 20px; + height: 30px; + margin: 0 0 0 5px; + } + + .body { + margin-top: 10px; + } + </style> </PollVotes> \ No newline at end of file -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm