This is an automated email from the git hooks/post-receive script. New commit to branch feature/multi-ui in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 8891b7f74ecedd2cad9df3ddaaa70d4012fc6988 Author: jcouteau <couteau@codelutin.com> Date: Mon Aug 26 17:26:27 2019 +0200 Multi-questions : Can vote on multi question ! Todo : Results with same UX --- pollen-ui-riot-js/src/main/web/i18n/en.json | 2 + pollen-ui-riot-js/src/main/web/i18n/fr.json | 2 + pollen-ui-riot-js/src/main/web/js/Poll.js | 15 +- .../src/main/web/tag/poll/EditVote.tag.html | 158 +++++++++++++-------- .../src/main/web/tag/poll/EditVoteOrder.tag.html | 30 ++-- .../web/tag/poll/{Votes.tag.html => Vote.tag.html} | 81 ++++++----- .../src/main/web/tag/poll/Votes.tag.html | 153 +++++--------------- .../src/main/web/tag/poll/VotesTable.tag.html | 23 ++- 8 files changed, 237 insertions(+), 227 deletions(-) diff --git a/pollen-ui-riot-js/src/main/web/i18n/en.json b/pollen-ui-riot-js/src/main/web/i18n/en.json index d8244173..97f2d0d6 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -187,6 +187,8 @@ "poll_votes_validation_before" : "I read and accept the", "poll_votes_validation_link" : "general terms of use.", "poll_votes_validation_after" : "For the consultation needs, my vote will be stored for 2 years, then anonymized.", + "poll_votes_previousQuestion": "Question précédente", + "poll_votes_nextQuestion": "Question suivante", "poll_participants_noParticipant": "Voting list is not available", "poll_participants_download": "Download", "poll_participants_download_title": "Download voting list", diff --git a/pollen-ui-riot-js/src/main/web/i18n/fr.json b/pollen-ui-riot-js/src/main/web/i18n/fr.json index 8a41615b..2b1a1976 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -187,6 +187,8 @@ "poll_votes_validation_before" : "J'ai lu et j'accepte les", "poll_votes_validation_link" : "conditions générales d'utilisation", "poll_votes_validation_after" : ". Pour les besoins de la consultation, mon vote sera conservé au maximum 2 ans puis anonymisé.", + "poll_votes_previousQuestion": "Question précédente", + "poll_votes_nextQuestion": "Question suivante", "poll_participants_noParticipant": "Le liste d'émagement n'est pas diponible", "poll_participants_download": "Télécharger", "poll_participants_download_title": "Télécharger la liste d'émargement", diff --git a/pollen-ui-riot-js/src/main/web/js/Poll.js b/pollen-ui-riot-js/src/main/web/js/Poll.js index e8bc808f..035d77b0 100644 --- a/pollen-ui-riot-js/src/main/web/js/Poll.js +++ b/pollen-ui-riot-js/src/main/web/js/Poll.js @@ -222,14 +222,21 @@ class Poll { .then(resultsArray => { this.choices = resultsArray[0]; this.choiceCount = this.choices.length; - this.questions[0].results = resultsArray[1]; - this.questions[0].choices.forEach(choice => { - choice.score = this.questions[0].results.scores.find(score => score.choiceId === choice.id); + var _this = this; + this.questions.forEach(function(question) { + if (questionId === question.id) { + question.results = resultsArray[1]; + question.choices.forEach(choice => { + choice.score = question.results.scores.find(score => score.choiceId === choice.id); + }); + + _this.question = question; + } }); pageTracker.trackResults(); - bus.trigger("poll", this); + bus.trigger("question", this.question); return Promise.resolve(this); }); } diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/EditVote.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/EditVote.tag.html index 1021b593..35cb12a1 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/EditVote.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/EditVote.tag.html @@ -23,23 +23,23 @@ <div class="form-wrapper"> <h3 class="c-heading" - if={(poll.questions[0] && poll.questions[0].voteCountingType === 2)}> - {_l("pointsDistribution", poll.questions[0].voteCountingConfig.points)} + if={(question && question.voteCountingType === 2)}> + {_l("pointsDistribution", question.voteCountingConfig.points)} </h3> <h3 class="c-heading" - if={poll.questions[0] && ([3, 5, 6, 7].indexOf(poll.questions[0].voteCountingType) >= 0) && !poll.questions[0].voteCountingConfig.maxChoiceNumber}> + if={question && ([3, 5, 6, 7].indexOf(question.voteCountingType) >= 0) && !question.voteCountingConfig.maxChoiceNumber}> {_t.voteByOrder} </h3> <h3 class="c-heading" - if={poll.questions[0] && (poll.questions[0].voteCountingType === 5) && poll.questions[0].voteCountingConfig.maxChoiceNumber}> - {_l("voteByOrderWithMax", poll.questions[0].voteCountingConfig.maxChoiceNumber)} + if={question && (question.voteCountingType === 5) && question.voteCountingConfig.maxChoiceNumber}> + {_l("voteByOrderWithMax", question.voteCountingConfig.maxChoiceNumber)} </h3> <form id="voteForm" class="voter separator" ref="formAddVote"> <HumanInput onsubmit="{saveVote}"></HumanInput> <div class="header"> <div class="current-voter separator-right"> <div class="o-field o-field--icon-left o-field--icon-right" - if={poll.questions[0] && (poll.questions[0].canVote || voteInEdition)} > + if={question && (question.canVote || voteInEdition)} > <i class="fa fa-fw fa-user c-icon" aria-hidden="true"></i> <input class="c-field {c-field--error: !voteInEdition && error && error['voter.name']}" type="text" @@ -51,24 +51,24 @@ placeholder={_t.authorPlaceHolder} value={poll.voterName}> </div> - <div if={poll.questions[0] && !poll.questions[0].canVote && !voteInEdition} + <div if={question && !question.canVote && !voteInEdition} class="choices-label"> {_t.choices} </div> </div> - <div if={poll.questions[0] && poll.questions[0].resultIsVisible} class="result-label"> - <strong if={poll.questions[0] && (poll.questions[0].voteCountingType !== 5) && (poll.questions[0].voteCountingType !== 2) && (poll.questions[0].voteCountingType !== 4)}>{_t.results}</strong> - <strong if={poll.questions[0] && ((poll.questions[0].voteCountingType === 5) || (poll.questions[0].voteCountingType === 2))}>{_t.scores}</strong> - <strong if={poll.questions[0] && (poll.questions[0].voteCountingType === 4)}>{_t.totals}</strong> + <div if={question && question.resultIsVisible} class="result-label"> + <strong if={question && (question.voteCountingType !== 5) && (question.voteCountingType !== 2) && (question.voteCountingType !== 4)}>{_t.results}</strong> + <strong if={question && ((question.voteCountingType === 5) || (question.voteCountingType === 2))}>{_t.scores}</strong> + <strong if={question && (question.voteCountingType === 4)}>{_t.totals}</strong> </div> </div> - <div each={choice, index in poll.questions[0] && poll.questions[0].choices} class="choice separator-top"> + <div each={choice, index in question && question.choices} class="choice separator-top"> <div class="choice-vote separator-right"> <div class="choice-value"> <ChoiceView choice={choice} center="true" tooltip-placement="left"></ChoiceView> </div> <div class="current-choice" - if={poll.questions[0] && (poll.questions[0].canVote || voteInEdition)}> + if={question && (question.canVote || voteInEdition)}> <input if={pollTypeCheckbox} class="check" type="checkbox" @@ -78,9 +78,9 @@ <input if={!pollTypeCheckbox && !pollTypeSelect} class="text c-field {c-field--error: !voteInEdition && error && (error['vote.voteValue#' + choice.id] || error['vote.totalVoteValue'])}" type="number" - required={!poll.questions[0].voteCountingConfig.maxChoiceNumber} - min="{poll.questions[0].voteCountingTypeValue && poll.questions[0].voteCountingTypeValue.minimumValue}" - max={this.poll.questions[0].voteCountingConfig.points} + required={!question.voteCountingConfig.maxChoiceNumber} + min="{question.voteCountingTypeValue && question.voteCountingTypeValue.minimumValue}" + max={this.question.voteCountingConfig.points} onchange="{onVoteChanged}" ref="{choice.id}_voteValue" tabindex="{10 * (index + 1)}"> @@ -90,7 +90,7 @@ onchange={onVoteChanged} tabindex="{10 * (index + 1)}"> <option value=""></option> - <option each={grad, index in poll.questions[0].voteCountingConfig.grades} + <option each={grad, index in question.voteCountingConfig.grades} value={index} ref="{choice.id}_voteValue"> {grad} @@ -98,26 +98,26 @@ </select> </div> </div> - <div if={poll.questions[0].resultIsVisible} class="score-choice"> + <div if={question.resultIsVisible} class="score-choice"> <span if={!choice.score}>{parent._t.noVote}</span> <span if={choice.score}> <i if="{choice.score.scoreOrder === 0}" class="fa fa-trophy fa-15x winner" aria-hidden="true"></i> <span if={!pollTypeSelect}> {choice.score.scoreValue} <span if={choice.score.scoreValue || !pollTypeCoombs}> - {parent._t["results_unit_" + poll.questions[0].voteCountingType + "_" + (choice.score.scoreValue > 1 ? "many" : "one")]} + {parent._t["results_unit_" + question.voteCountingType + "_" + (choice.score.scoreValue > 1 ? "many" : "one")]} </span> <span if={!choice.score.scoreValue && pollTypeCoombs}> {parent._t.eliminated} </span> </span> <span if={pollTypeSelect}> - {poll.questions[0].voteCountingConfig.grades[choice.score.scoreValue]} + {question.voteCountingConfig.grades[choice.score.scoreValue]} </span> </span> </div> </div> - <div class="footer separator-top" if="{poll.questions[0] && poll.questions[0].choices && (poll.questions[0].canVote || voteInEdition)}"> + <div class="footer separator-top" if="{question && question.choices && (question.canVote || voteInEdition)}"> <div class="current-voter-actions separator-right"> <div class="o-form-element" if={!session.isConnected()}> <label class="c-field c-field--choice gtu-validation"> @@ -138,7 +138,7 @@ class="c-button c-button--brand pull-right" type="submit" name="newVote" - tabindex="{(poll.questions[0].choices.length + 1) * 10}" + tabindex="{(question.choices.length + 1) * 10}" disabled={tooManyChoicesSelected || remainPoints || voting}> <i class="fa fa-envelope" aria-hidden="true"></i> {_t.toVote} @@ -146,7 +146,7 @@ <button if="{voteInEdition}" class="c-button c-button--error" type="button" - tabindex="{(poll.questions[0].choices.length + 2) * 10}" + tabindex="{(question.choices.length + 2) * 10}" onclick="{cancelEditVote}" disabled={voting}> <i class="fa fa-remove" aria-hidden="true"></i> @@ -154,7 +154,7 @@ </button> <button if="{voteInEdition}" class="c-button c-button--success" - tabindex="{(poll.questions[0].choices.length + 1) * 10}" + tabindex="{(question.choices.length + 1) * 10}" disabled={tooManyChoicesSelected || remainPoints || voting} type="submit"> <i class="fa fa-check" aria-hidden="true"></i> @@ -168,7 +168,7 @@ {_l(remainPoints === -1 ? "tooManyPoint" : "tooManyPoints", -remainPoints)} </div> <div class="c-hint--static c-hint--error" if="{tooManyChoicesSelected}"> - {_t.tooManyChoicesSelected} {poll.questions[0].voteCountingConfig.maxChoiceNumber} + {_t.tooManyChoicesSelected} {question.voteCountingConfig.maxChoiceNumber} </div> <div class="c-hint--static c-hint--error" if="{error}"> <div each={fields in error}> @@ -191,38 +191,77 @@ this.voting = false; + this.question = opts.question; + this.poll = poll; - if (this.poll.questions[0]) { - this.poll.loadForVotes(this.poll.questions[0].id).then(() => { + if (this.question) { + this.poll.loadForVotes(this.question.id).then(() => { this.update(); }); } this.onPollChange = poll2 => { + //reload question + var _this = this; + if (_this.question) { + poll2.questions.forEach(function(question) { + if (_this.question.id === question.id) { + _this.question = question; + } + }); + } else { + _this.question = poll2.questions[0]; + } + this.poll = poll2; - if (!poll2.questions[0].voteCountingTypeValue) { - this.poll.reloadVoteCountingTypeValue(this.poll.questions[0]).then(() => { - this.pollTypeCheckbox = poll2.questions[0].voteCountingTypeValue && poll2.questions[0].voteCountingTypeValue.renderType === "checkbox"; - this.pollTypeSelect = poll2.questions[0].voteCountingTypeValue && poll2.questions[0].voteCountingTypeValue.renderType === "select"; - this.pollTypeCoombs = poll2.questions[0].voteCountingType && poll2.questions[0].voteCountingType === 7; + if (this.question) { + if (!this.question.voteCountingTypeValue) { + this.poll.reloadVoteCountingTypeValue(this.question).then(() => { + this.pollTypeCheckbox = this.question.voteCountingTypeValue && this.question.voteCountingTypeValue.renderType === "checkbox"; + this.pollTypeSelect = this.question.voteCountingTypeValue && this.question.voteCountingTypeValue.renderType === "select"; + this.pollTypeCoombs = this.question.voteCountingType && this.question.voteCountingType === 7; + }); + } else { + this.pollTypeCheckbox = this.question.voteCountingTypeValue && this.question.voteCountingTypeValue.renderType === "checkbox"; + this.pollTypeSelect = this.question.voteCountingTypeValue && this.question.voteCountingTypeValue.renderType === "select"; + this.pollTypeCoombs = this.question.voteCountingType && this.question.voteCountingType === 7; + } + this.resultsLoaded = this.question.results !== undefined; + if (!this.resultsLoaded) { + this.poll.loadResults(this.question.id).then(() => { + }); + } + this.onVoteChanged(); + } + this.update(); + }; + + this.onQuestionChange = question2 => { + this.question = question2; + if (!this.question.voteCountingTypeValue) { + this.poll.reloadVoteCountingTypeValue(this.question).then(() => { + this.pollTypeCheckbox = this.question.voteCountingTypeValue && this.question.voteCountingTypeValue.renderType === "checkbox"; + this.pollTypeSelect = this.question.voteCountingTypeValue && this.question.voteCountingTypeValue.renderType === "select"; + this.pollTypeCoombs = this.question.voteCountingType && this.question.voteCountingType === 7; }); } else { - this.pollTypeCheckbox = poll2.questions[0].voteCountingTypeValue && poll2.questions[0].voteCountingTypeValue.renderType === "checkbox"; - this.pollTypeSelect = poll2.questions[0].voteCountingTypeValue && poll2.questions[0].voteCountingTypeValue.renderType === "select"; - this.pollTypeCoombs = poll2.questions[0].voteCountingType && poll2.questions[0].voteCountingType === 7; + this.pollTypeCheckbox = this.question.voteCountingTypeValue && this.question.voteCountingTypeValue.renderType === "checkbox"; + this.pollTypeSelect = this.question.voteCountingTypeValue && this.question.voteCountingTypeValue.renderType === "select"; + this.pollTypeCoombs = this.question.voteCountingType && this.question.voteCountingType === 7; } - this.resultsLoaded = poll2.questions[0].results !== undefined; + this.resultsLoaded = this.question.results !== undefined; if (!this.resultsLoaded) { - this.poll.loadResults(poll2.questions[0].id).then(() => { + this.poll.loadResults(this.question.id).then(() => { }); } - this.onVoteChanged(); + this.onVoteChanged(); this.update(); + }; - }; - this.listen("poll", this.onPollChange); + //this.listen("poll", this.onPollChange); + this.listen("question", this.onQuestionChange); this.listen("user", (user, oldUser) => { if (user !== oldUser) { if (user && this.refs.voterName && this.refs.voterName.value !== "") { @@ -250,19 +289,19 @@ vote.choice.forEach(choice => { let input = this.refs[choice.choiceId + "_voteValue"]; if (input) { - if (this.poll.questions[0].voteCountingTypeValue.renderType === "text") { + if (this.question.voteCountingTypeValue.renderType === "text") { input.value = choice.voteValue; - } else if (this.poll.questions[0].voteCountingTypeValue.renderType === "select") { + } else if (this.question.voteCountingTypeValue.renderType === "select") { input.forEach(option => {option.selected = option.value === choice.voteValue + "";}); } else { input.checked = choice.voteValue === 1; } } }); - if (this.poll.questions[0].voteCountingTypeValue.renderType === "select") { - this.refs[this.poll.questions[0].choices[0].id + "_voteValue"][0].parentNode.focus(); + if (this.question.voteCountingTypeValue.renderType === "select") { + this.refs[this.question.choices[0].id + "_voteValue"][0].parentNode.focus(); } else { - this.refs[this.poll.questions[0].choices[0].id + "_voteValue"].focus(); + this.refs[this.question.choices[0].id + "_voteValue"].focus(); } this.onVoteChanged(); }; @@ -272,37 +311,37 @@ if (!input) { return 0; } - if (this.poll.questions[0].voteCountingTypeValue.renderType === "text") { + if (this.question.voteCountingTypeValue.renderType === "text") { return input.value; } - if (this.poll.questions[0].voteCountingTypeValue.renderType === "select") { + if (this.question.voteCountingTypeValue.renderType === "select") { return input.find(option => option.selected).value; } return input.checked ? 1 : 0; }; this.onVoteChanged = () => { - if (this.poll.questions[0].voteCountingConfig.maxChoiceNumber) { + if (this.question.voteCountingConfig.maxChoiceNumber) { var selectedChoiceNb = 0; - this.poll.questions[0].choices && this.poll.questions[0].choices.forEach(c => { + this.question.choices && this.question.choices.forEach(c => { var choiceValue = this.getChoiceVoteValue(c.id + "_voteValue"); if (choiceValue && choiceValue !== "0") { selectedChoiceNb++; } }); - this.tooManyChoicesSelected = selectedChoiceNb > this.poll.questions[0].voteCountingConfig.maxChoiceNumber; + this.tooManyChoicesSelected = selectedChoiceNb > this.question.voteCountingConfig.maxChoiceNumber; } else { this.tooManyChoicesSelected = false; } - if (this.poll.questions[0].voteCountingConfig.points) { + if (this.question.voteCountingConfig.points) { let nbPoints = 0; - this.poll.questions[0].choices && this.poll.questions[0].choices.forEach(c => { + this.question.choices && this.question.choices.forEach(c => { var choiceValue = this.getChoiceVoteValue(c.id + "_voteValue"); if (choiceValue && choiceValue !== "0") { nbPoints += parseInt(choiceValue, 10); } }); - this.remainPoints = this.poll.questions[0].voteCountingConfig.points - nbPoints; + this.remainPoints = this.question.voteCountingConfig.points - nbPoints; } else { this.remainPoints = 0; } @@ -310,13 +349,14 @@ }; this.resetVoteForm = () => { - if (this.poll.questions[0].canVote) { + this.voteInEdition = null; + if (this.question.canVote) { this.refs.voterName.value = null; - this.poll.questions[0].choices.forEach(choice => { + this.question.choices.forEach(choice => { let input = this.refs[choice.id + "_voteValue"]; - if (this.poll.questions[0].voteCountingTypeValue.renderType === "text") { + if (this.question.voteCountingTypeValue.renderType === "text") { input.value = ""; - } else if (this.poll.questions[0].voteCountingTypeValue.renderType === "select") { + } else if (this.question.voteCountingTypeValue.renderType === "select") { input.forEach(option => {option.selected = false;}); } else { input.checked = ""; @@ -335,7 +375,7 @@ vote = Object.assign({}, this.voteInEdition); // don't modify original vote vote.voterName = this.refs.voterName.value; - this.poll.questions[0].choices.forEach(choice => { + this.question.choices.forEach(choice => { let voteChoice = this.poll.getVoteChoice(vote, choice); if (!voteChoice) { voteChoice = { @@ -354,7 +394,7 @@ choice: [] }; - this.poll.questions[0].choices.forEach(c => { + this.question.choices.forEach(c => { vote.choice.push({ choiceId: c.id, voteValue: this.getChoiceVoteValue(c.id + "_voteValue") diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/EditVoteOrder.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/EditVoteOrder.tag.html index 8250d370..371b9fb7 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/EditVoteOrder.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/EditVoteOrder.tag.html @@ -83,23 +83,23 @@ <i class="fa fa-trash"></i> {_t.choicesStashHelper} </div> - <Draggable each={choice in poll.questions[0] && poll.questions[0].choices && poll.questions[0].choices.slice().reverse() || []} + <Draggable each={choice in question && question.choices && question.choices.slice().reverse() || []} ref="choices" on-drop={dropChoice} class="choice-draggable"> <div class={choice-tile: true, noFirst: !isFirstGroup, noLast: !isLastGroup}> <div class="choice-order">{voteOrder !== undefined ? voteOrder + 1 : ""}</div> <ChoiceView choice={choice} center="true" tooltip-placement="left"></ChoiceView> - <div if={parent.poll.questions[0].resultIsVisible} class="score-choice"> + <div if={parent.question.resultIsVisible} class="score-choice"> <span if={!choice.score}>{parent.parent._t.noVote}</span> <span if={choice.score}> <i if="{choice.score.scoreOrder === 0}" class="fa fa-trophy fa-15x winner"></i> <span if={choice.score.scoreValue >= 0 || !parent.pollTypeRound}> {choice.score.scoreValue} - {parent.parent._t["results_unit_" + parent.poll.questions[0].voteCountingType + "_" + (choice.score.scoreValue > 1 ? "many" : "one")]} + {parent.parent._t["results_unit_" + parent.question.voteCountingType + "_" + (choice.score.scoreValue > 1 ? "many" : "one")]} </span> <span if={choice.score.scoreValue < 0 && parent.pollTypeRound}> - {parent.parent._l("eliminated", parent.poll.questions[0].choiceCount + choice.score.scoreValue + 1)} + {parent.parent._l("eliminated", parent.question.choiceCount + choice.score.scoreValue + 1)} </span> </span> </div> @@ -138,14 +138,24 @@ this.orderedAllChoices = false; this.poll = poll; - this.poll.loadForVotes().then(() => { - this.update(); - }); + this.question = opts.question + if (this.question) { + this.poll.loadForVotes(this.question.id).then(() => { + this.update(); + }); + } this.onPollChange = poll2 => { + //reload question + var _this = this; + poll2.questions.forEach(function(question) { + if (_this.question.id === question.id) { + _this.question = question; + } + }); this.poll = poll2; - this.pollTypeRound = poll2.questions[0].voteCountingType && (poll2.questions[0].voteCountingType === 7 || poll2.questions[0].voteCountingType === 6); - this.maxChoiceNumber = this.poll.questions[0].voteCountingConfig.maxChoiceNumber; + this.pollTypeRound = this.question.voteCountingType && (this.question.voteCountingType === 7 || this.question.voteCountingType === 6); + this.maxChoiceNumber = this.question.voteCountingConfig.maxChoiceNumber; this.update(); this.placeChoices(true); }; @@ -153,7 +163,7 @@ this.listen("resize", () => this.placeChoices(true)); this.listen("orientationchange", () => this.placeChoices(true)); - this.listen("poll", this.onPollChange); + //this.listen("poll", this.onPollChange); this.listen("user", (user, oldUser) => { if (user !== oldUser) { if (user && this.refs.voterName && this.refs.voterName.value !== "") { diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Vote.tag.html similarity index 70% copy from pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html copy to pollen-ui-riot-js/src/main/web/tag/poll/Vote.tag.html index 39dc6e12..671162b5 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Vote.tag.html @@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #L% --> -<Votes> +<Vote> <div class="container" show="{loaded}"> <span class="c-input-group actions-right" @@ -35,10 +35,12 @@ <EditVote ref="editVote" show={!isVoteByOrder || !voteClickAndDrop} - on-save-vote={saveVote}/> + on-save-vote={saveVote} + question="{question}"/> <EditVoteOrder ref="editVoteOrder" - show={isVoteByOrder && voteClickAndDrop} - on-save-vote={saveVote}/> + show={isVoteByOrder && voteClickAndDrop} + on-save-vote={saveVote} + question="{question}"/> <!-- Form to vote --> <p class="warning-label warning" if="{loaded && !poll.canVote}"> @@ -48,28 +50,28 @@ <!-- Form to add a choice --> <form ref="formAddChoice" class="formAddChoice" if={poll.status === "ADDING_CHOICES"}> - <HumanInput onsubmit="{addChoice}"></HumanInput> - <div class="o-form-element"> - <label class="c-label" for="choice">{_t.addChoice}</label> - <div class="c-input-group"> - <div class="o-field"> - <Choice ref="choice" - class="choice c-field" - name="choice" - choice="{choiceToAdd}"></Choice> - </div> - <button type="submit" - class="c-button c-button--success" - tooltips="{_t.addChoice}" - disabled="{addingChoice}"> - <i class="fa fa-plus" aria-hidden="true"></i> - </button> + <HumanInput onsubmit="{addChoice}"></HumanInput> + <div class="o-form-element"> + <label class="c-label" for="choice">{_t.addChoice}</label> + <div class="c-input-group"> + <div class="o-field"> + <Choice ref="choice" + class="choice c-field" + name="choice" + choice="{choiceToAdd}"></Choice> </div> + <button type="submit" + class="c-button c-button--success" + tooltips="{_t.addChoice}" + disabled="{addingChoice}"> + <i class="fa fa-plus" aria-hidden="true"></i> + </button> </div> + </div> </form> <!-- Show votes --> - <VotesTable if="{poll.questions[0] && poll.questions[0].voteCount > 0}" on-edit-vote={editVote}/> + <VotesTable if="{question && question.voteCount > 0}" on-edit-vote={editVote} question="{question}"/> </div> @@ -97,18 +99,38 @@ this.poll = poll; + this.question = opts.question; + this.choiceToAdd = this.poll.initChoice(); this.onPollChange = poll2 => { - this.loaded = poll2.questions[0].choices !== undefined; + //reload question + var _this = this; + if (_this.question) { + poll2.questions.forEach(function(question) { + if (_this.question.id === question.id) { + _this.question = question; + } + }); + } else { + _this.question = poll2.questions[0]; + } + this.loaded = this.question.choices !== undefined; this.poll = poll2; - this.isVoteByOrder = [3, 5, 6, 7].indexOf(poll2.voteCountingType) >= 0; + this.isVoteByOrder = [3, 5, 6, 7].indexOf(this.question.voteCountingType) >= 0; this.voteClickAndDrop = this.isVoteByOrder && session.getUserSetting("voteClickAndDrop", "true") === "true"; this.update(); }; + this.onQuestionChange = question2 => { + this.question=question2; + this.update(); + }; + this.listen("poll", this.onPollChange); + this.listen("question", this.onQuestionChange); + this.editVote = (vote) => { let editor = this.voteClickAndDrop ? this.refs.editVoteOrder : this.refs.editVote; editor.editVote(vote); @@ -116,17 +138,11 @@ this.saveVote = (vote) => { let oldPermission = this.poll.getPermission(); - let promise = vote.id ? this.poll.updateVote(this.poll.questions[0].id, vote) : this.poll.addVote(this.poll.questions[0].id, vote); + let promise = vote.id ? this.poll.updateVote(this.question.id, vote) : this.poll.addVote(this.question.id, vote); return promise.then(result => { - if (this.poll.getPermission() && oldPermission !== this.poll.getPermission()) { - setTimeout( - () => route("poll/" + this.poll.id + "/vote/" + this.poll.getPermission()), - 10 - ); - } if (this.poll.resultIsVisible) { - return this.poll.loadResults(this.poll.questions[0].id).then(() => result); + return this.poll.loadResults(this.question.id).then(() => result); } return result; }); @@ -151,6 +167,7 @@ this.update(); this.refs.choice.submit(); + //TODO add choice to question (not needed for April ! ) this.poll.addChoice(this.choiceToAdd).then(() => { this.addingChoice = false; this.choiceToAdd = this.poll.initChoice(this.choiceToAdd); @@ -180,4 +197,4 @@ } </style> -</Votes> +</Vote> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html index 39dc6e12..681176e4 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Votes.tag.html @@ -19,69 +19,29 @@ #L% --> <Votes> - <div class="container" show="{loaded}"> - - <span class="c-input-group actions-right" - if={isVoteByOrder}> - <button class="c-button c-button--info {c-button--ghost-info: !voteClickAndDrop, c-button--info: voteClickAndDrop}" - onclick={voteClickAndDropChange(true)} - title={_t.voteByClickAndDrop} - type="button"><i class="fa fa-list-ol" aria-hidden="true"></i></button> - <button class="c-button c-button--info {c-button--ghost-info: voteClickAndDrop, c-button--info: !voteClickAndDrop}" - onclick={voteClickAndDropChange(false)} - title={_t.voteByInput} - type="button"><i class="fa fa-i-cursor" aria-hidden="true"></i></button> - </span> - - <EditVote ref="editVote" - show={!isVoteByOrder || !voteClickAndDrop} - on-save-vote={saveVote}/> - <EditVoteOrder ref="editVoteOrder" - show={isVoteByOrder && voteClickAndDrop} - on-save-vote={saveVote}/> - - <!-- Form to vote --> - <p class="warning-label warning" if="{loaded && !poll.canVote}"> - <span if="{moment().isBefore(poll.beginDate)}">{_t.voteNotOpen}</span> - <span if="{moment().isAfter(poll.endDate)}">{_t.voteClosed}</span> - </p> - - <!-- Form to add a choice --> - <form ref="formAddChoice" class="formAddChoice" if={poll.status === "ADDING_CHOICES"}> - <HumanInput onsubmit="{addChoice}"></HumanInput> - <div class="o-form-element"> - <label class="c-label" for="choice">{_t.addChoice}</label> - <div class="c-input-group"> - <div class="o-field"> - <Choice ref="choice" - class="choice c-field" - name="choice" - choice="{choiceToAdd}"></Choice> - </div> - <button type="submit" - class="c-button c-button--success" - tooltips="{_t.addChoice}" - disabled="{addingChoice}"> - <i class="fa fa-plus" aria-hidden="true"></i> - </button> - </div> - </div> - </form> - - <!-- Show votes --> - <VotesTable if="{poll.questions[0] && poll.questions[0].voteCount > 0}" on-edit-vote={editVote}/> - - </div> + + <button if={questionToVote > 0} + type="button" + class="c-button c-button--info" + tabindex="1" + onclick={previousQuestion}> + <i class="fa fa-chevron-left " aria-hidden="true"></i> + {_t.previousQuestion} + </button> + + <button if={questionToVote < poll.questions.length - 1} + type="button" + class="c-button c-button--info" + tabindex="1" + onclick={nextQuestion}> + {_t.nextQuestion} + <i class="fa fa-chevron-right " aria-hidden="true"></i> + </button> + + <Vote question={question}/> <script type="es6"> - import "./Choice.tag.html"; - import "./ChoiceView.tag.html"; - import "./EditVote.tag.html"; - import "./EditVoteOrder.tag.html"; - import "./VotesTable.tag.html"; - import "../components/HumanInput.tag.html"; - import "../components/LazyLoad.tag.html"; - import "../components/Avatar.tag.html"; + import "./Vote.tag.html"; import session from "../../js/Session"; import moment from "moment"; @@ -91,76 +51,37 @@ this.loaded = false; this.moment = moment; this.installBundle(session, "poll_votes"); - this.addingChoice = false; - this.isVoteByOrder = false; - this.voteClickAndDrop = false; this.poll = poll; - this.choiceToAdd = this.poll.initChoice(); + this.questionToVote = 0; + + this.question = this.poll.questions[this.questionToVote]; this.onPollChange = poll2 => { this.loaded = poll2.questions[0].choices !== undefined; this.poll = poll2; - this.isVoteByOrder = [3, 5, 6, 7].indexOf(poll2.voteCountingType) >= 0; - this.voteClickAndDrop = this.isVoteByOrder && session.getUserSetting("voteClickAndDrop", "true") === "true"; + this.question = this.poll.questions[this.questionToVote]; + if (this.question) { + this.bus.trigger("question", this.question); + } this.update(); }; this.listen("poll", this.onPollChange); - this.editVote = (vote) => { - let editor = this.voteClickAndDrop ? this.refs.editVoteOrder : this.refs.editVote; - editor.editVote(vote); - }; - - this.saveVote = (vote) => { - let oldPermission = this.poll.getPermission(); - let promise = vote.id ? this.poll.updateVote(this.poll.questions[0].id, vote) : this.poll.addVote(this.poll.questions[0].id, vote); - - return promise.then(result => { - if (this.poll.getPermission() && oldPermission !== this.poll.getPermission()) { - setTimeout( - () => route("poll/" + this.poll.id + "/vote/" + this.poll.getPermission()), - 10 - ); - } - if (this.poll.resultIsVisible) { - return this.poll.loadResults(this.poll.questions[0].id).then(() => result); - } - return result; - }); - }; - - this.voteClickAndDropChange = value => () => { - if (this.isVoteByOrder && this.voteClickAndDrop !== value) { - session.setUserSetting("voteClickAndDrop", value); - let oldEditor = this.voteClickAndDrop ? this.refs.editVoteOrder : this.refs.editVote; - this.voteClickAndDrop = value; - let newEditor = this.voteClickAndDrop ? this.refs.editVoteOrder : this.refs.editVote; - let vote = oldEditor.getVote(); - newEditor.editVote(vote, true); - } + this.nextQuestion = () => { + this.questionToVote = this.questionToVote + 1; + this.question = this.poll.questions[this.questionToVote]; + this.bus.trigger("question", this.question); + this.update(); }; - this.addChoice = (e) => { - e.preventDefault(); - e.stopPropagation(); - - this.addingChoice = true; + this.previousQuestion = (e) => { + this.questionToVote = this.questionToVote - 1; + this.question = this.poll.questions[this.questionToVote]; + this.bus.trigger("question", this.question); this.update(); - - this.refs.choice.submit(); - this.poll.addChoice(this.choiceToAdd).then(() => { - this.addingChoice = false; - this.choiceToAdd = this.poll.initChoice(this.choiceToAdd); - this.refs.choice.updateChoice(); - this.update(); - }, errors => { - this.addingChoice = false; - this.bus.trigger("message", errors); - this.update(); - }); }; </script> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/VotesTable.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/VotesTable.tag.html index 216a2a90..173810d4 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/VotesTable.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/VotesTable.tag.html @@ -24,7 +24,7 @@ <div class="row header separator-bottom"> <div></div> <div class="choices separator-left" if="{showChoiceHeader}"> - <div each="{choice in poll.choices}" class="choice separator-top separator-right" + <div each="{choice in question.choices}" class="choice separator-top separator-right" onmouseenter="{parent.showTooltip(null, choice)}" onclick="{parent.showTooltip(null, choice)}" onmouseleave="{parent.hideTooltip}"> <ChoiceView choice={choice} center="true" hideReport="true"></ChoiceView> </div> @@ -55,7 +55,7 @@ </button> </div> <div class="results separator-left {'ignored': element.ignored}" ref="results{index}"> - <div each="{choice in parent.parent.poll.choices}" + <div each="{choice in parent.parent.question.choices}" class="result separator-right {'checkbox' : parent.parent.parent.pollTypeCheckbox} {'selected' : parent.parent.parent.pollTypeCheckbox && parent.parent.parent.poll.getVoteValue(element, choice) == 1}" onmouseenter="{parent.parent.parent.showTooltip(element, choice)}" onclick="{parent.parent.parent.showTooltip(element, choice)}" onmouseleave="{parent.parent.parent.hideTooltip}"> <span if="{!parent.parent.parent.pollTypeCheckbox}">{parent.parent.parent.poll.getVoteValue(element, choice)}</span> @@ -72,7 +72,7 @@ </div> </div> <div class="results separator-left" ref="results{index}"> - <div each="{choice in parent.poll.choices}" + <div each="{choice in parent.question.choices}" class="result separator-right"> <i class="fa fa-spinner fa-pulse" aria-hidden="true"></i> </div> @@ -108,13 +108,15 @@ this.poll = poll; + this.question = opts.question; + this.pagination = { order: "topiaCreateDate", desc: true }; this.lazyLoad = pagination => { - return this.poll.loadLazyVotes(this.poll.questions[0].id, pagination).then((result) => { + return this.poll.loadLazyVotes(this.question.id, pagination).then((result) => { this.loaded = result.pagination.count > 0; this.update(); return result; @@ -133,14 +135,23 @@ this.showChoiceHeader = results0 && this.poll.choices && results0.offsetWidth / this.poll.choices.length >= MIN_CHOICE_COLUMN_WIDTH; }; + this.onQuestionChange = question2 => { + this.question = question2; + this.pollTypeCheckbox = question2.voteCountingTypeValue && question2.voteCountingTypeValue.renderType === "checkbox"; + this.refresh(); + this.update(); + }; + + this.listen("question", this.onQuestionChange); + this.onPollChange = poll2 => { this.poll = poll2; - this.pollTypeCheckbox = poll2.voteCountingTypeValue && poll2.voteCountingTypeValue.renderType === "checkbox"; this.refresh(); this.update(); }; this.listen("poll", this.onPollChange); + this.listen("user", (user, oldUser) => { if (user !== oldUser) { this.refresh(); @@ -161,7 +172,7 @@ this.voting = true; this.update(); - this.poll.deleteVote(this.poll.questions[0].id, vote).then(() => { + this.poll.deleteVote(this.question.id, vote).then(() => { this.selectedChoiceNb = 0; this.updateShowChoiceContainer(); this.voting = false; -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.