From 40a4d55c77aabcace5539bfaa6f95b5ecf847d8e Mon Sep 17 00:00:00 2001 From: Robert <35533304+merefield@users.noreply.github.com> Date: Tue, 5 Nov 2024 01:28:32 +0000 Subject: [PATCH] FIX: poll ranked choice voter expansion should append additional voters (#28432) Currently, for Ranked Choice results and voter list expansion, the code is replacing the voter list with the newly fetched page of voters instead of appending to the existing voter list. This is resolved in this PR and brings it in line with regular polls. See: https://meta.discourse.org/t/ranked-choice-poll-does-not-reflect-change-of-votes-in-outcome/321227/18 --- .../javascripts/discourse/components/poll.gjs | 50 ++++++++++--------- .../acceptance/poll-results-test.js | 18 ------- 2 files changed, 27 insertions(+), 41 deletions(-) diff --git a/plugins/poll/assets/javascripts/discourse/components/poll.gjs b/plugins/poll/assets/javascripts/discourse/components/poll.gjs index a5134f3f6cc..ca39f93fd60 100644 --- a/plugins/poll/assets/javascripts/discourse/components/poll.gjs +++ b/plugins/poll/assets/javascripts/discourse/components/poll.gjs @@ -468,19 +468,18 @@ export default class PollComponent extends Component { @action fetchVoters(optionId) { - let votersCount; + let voters; let preloadedVoters = this.preloadedVoters; - Object.keys(preloadedVoters).forEach((key) => { - if (key === optionId) { - preloadedVoters[key].loading = true; - } - }); + if (optionId) { + preloadedVoters[optionId].loading = true; + voters = preloadedVoters[optionId]?.voters; + } else { + voters = preloadedVoters; + } - this.preloadedVoters = Object.assign(preloadedVoters); - - votersCount = this.options.find((option) => option.id === optionId).voters - .length; + this.preloadedVoters = Object.assign({}, preloadedVoters); + const votersCount = voters?.length; return ajax("/polls/voters.json", { data: { @@ -493,14 +492,19 @@ export default class PollComponent extends Component { }) .then((result) => { this.voterListExpanded = true; - const voters = optionId - ? this.preloadedVoters[optionId].voters - : this.preloadedVoters; const newVoters = optionId ? result.voters[optionId] : result.voters; + let votersSet = new Set([]); + if (this.isRankedChoice) { - this.preloadedVoters[optionId].voters = [...new Set([...newVoters])]; + votersSet = new Set(voters.map((voter) => voter.user.username)); + newVoters.forEach((voter) => { + if (!votersSet.has(voter.user.username)) { + votersSet.add(voter.user.username); + voters.push(voter); + } + }); } else { - const votersSet = new Set(voters.map((voter) => voter.username)); + votersSet = new Set(voters.map((voter) => voter.username)); newVoters.forEach((voter) => { if (!votersSet.has(voter.username)) { votersSet.add(voter.username); @@ -509,12 +513,11 @@ export default class PollComponent extends Component { }); // remove users who changed their vote if (this.poll.type === REGULAR) { - Object.keys(this.preloadedVoters).forEach((otherOptionId) => { + Object.keys(preloadedVoters).forEach((otherOptionId) => { if (optionId !== otherOptionId) { - this.preloadedVoters[otherOptionId].voters = - this.preloadedVoters[otherOptionId].voters.filter( - (voter) => !votersSet.has(voter.username) - ); + preloadedVoters[otherOptionId].voters = preloadedVoters[ + otherOptionId + ].voters.filter((voter) => !votersSet.has(voter.username)); } }); } @@ -528,9 +531,10 @@ export default class PollComponent extends Component { } }) .finally(() => { - preloadedVoters = this.preloadedVoters; - preloadedVoters[optionId].loading = false; - this.preloadedVoters = Object.assign(preloadedVoters); + if (optionId) { + preloadedVoters[optionId].loading = false; + } + this.preloadedVoters = Object.assign({}, preloadedVoters); }); } diff --git a/plugins/poll/test/javascripts/acceptance/poll-results-test.js b/plugins/poll/test/javascripts/acceptance/poll-results-test.js index e238c2936c0..29fcc596b70 100644 --- a/plugins/poll/test/javascripts/acceptance/poll-results-test.js +++ b/plugins/poll/test/javascripts/acceptance/poll-results-test.js @@ -979,14 +979,6 @@ acceptance("Poll results", function (needs) { return helper.response({ voters: { db753fe0bc4e72869ac1ad8765341764: [ - { - id: 1, - username: "bianca", - name: null, - avatar_template: - "/letter_avatar_proxy/v4/letter/b/3be4f8/{size}.png", - title: null, - }, { id: 7, username: "foo", @@ -1004,16 +996,6 @@ acceptance("Poll results", function (needs) { return helper.response({ voters: { def034c6770c6fd3754c054ef9ec4721: [ - { - rank: 1, - user: { - id: 1, - username: "bianca", - name: null, - avatar_template: - "/letter_avatar_proxy/v4/letter/b/3be4f8/{size}.png", - }, - }, { rank: 1, user: {