FIX: poll when config is on_close only show results when poll is closed (#28299)
See: https://meta.discourse.org/t/cant-edit-topic-with-poll-bug-occurs/320845?u=merefield When the Poll is set to "results ON_CLOSE", vote numbers for each option are only streamed to the browser when the vote is Closed. It is therefore not possible to render the Results. The current issue is that when you refresh the page, for those that have voted the default view is results. For this type of poll this should NOT happen. The Results view in this mode should not be possible to see until closure, even for the Author. Because the votes are not yet serialised when this kind of poll remains open, an attempt to display results causes a JavaScript exception and in any case does not make logical sense. So the fix here is making sure the default view, for Polls that have results on close, is the voting view until the Poll is Closed. I've added a test to cover this scenario. Additionally, this requires a refresh of the page when the poll admin actions a Close to ensure the results are serialized in.
This commit is contained in:
parent
60d62f1b7e
commit
47f749744f
|
@ -26,7 +26,12 @@ export default class PollOptionsComponent extends Component {
|
|||
this.args.sendOptionSelect(option, rank);
|
||||
}
|
||||
<template>
|
||||
<ul class={{concatClass (if @isRankedChoice "ranked-choice-poll-options")}}>
|
||||
<ul
|
||||
class={{concatClass
|
||||
(if @isRankedChoice "ranked-choice-poll-options")
|
||||
"options"
|
||||
}}
|
||||
>
|
||||
{{#each @options key="rank" as |option|}}
|
||||
{{#if @isRankedChoice}}
|
||||
<PollOptionRankedChoice
|
||||
|
|
|
@ -7,6 +7,9 @@ import PollVoters from "./poll-voters";
|
|||
|
||||
export default class PollResultsStandardComponent extends Component {
|
||||
orderOptions = (options) => {
|
||||
options.forEach((option) => {
|
||||
option.votes = option.votes ?? 0;
|
||||
});
|
||||
return options.sort((a, b) => {
|
||||
if (a.votes < b.votes) {
|
||||
return 1;
|
||||
|
@ -41,11 +44,11 @@ export default class PollResultsStandardComponent extends Component {
|
|||
option.percentage = per;
|
||||
option.chosen = chosen;
|
||||
let voters = this.args.isPublic
|
||||
? this.args.voters[option.id]?.voters || []
|
||||
? this.args.voters?.[option.id]?.voters ?? []
|
||||
: [];
|
||||
option.voters = [...voters];
|
||||
option.loading = this.args.isPublic
|
||||
? this.args.voters[option.id]?.loading || false
|
||||
? this.args.voters?.[option.id]?.loading ?? false
|
||||
: false;
|
||||
});
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ const OPEN_STATUS = "open";
|
|||
export default class PollComponent extends Component {
|
||||
@service currentUser;
|
||||
@service siteSettings;
|
||||
@service router;
|
||||
@service appEvents;
|
||||
@service dialog;
|
||||
@service modal;
|
||||
|
@ -48,9 +49,10 @@ export default class PollComponent extends Component {
|
|||
|
||||
@tracked
|
||||
showResults =
|
||||
this.hasSavedVote ||
|
||||
(this.topicArchived && !this.staffOnly) ||
|
||||
(this.closed && !this.staffOnly);
|
||||
!(this.poll.results === ON_CLOSE && !this.closed) &&
|
||||
(this.hasSavedVote ||
|
||||
(this.topicArchived && !this.staffOnly) ||
|
||||
(this.closed && !this.staffOnly));
|
||||
|
||||
@tracked showTally = false;
|
||||
|
||||
|
@ -595,6 +597,15 @@ export default class PollComponent extends Component {
|
|||
) {
|
||||
this.showResults = this.status === CLOSED_STATUS;
|
||||
}
|
||||
|
||||
// Votes are only included in serialized results for results=ON_CLOSE when
|
||||
// the poll is closed, so we must refresh the page to pick these up.
|
||||
if (
|
||||
this.poll.results === ON_CLOSE &&
|
||||
this.status === CLOSED_STATUS
|
||||
) {
|
||||
this.router.refresh();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error) {
|
||||
|
|
|
@ -86,6 +86,43 @@ module("Poll | Component | poll", function (hooks) {
|
|||
);
|
||||
});
|
||||
|
||||
test("does not show results after voting when results are to be shown only on closed", async function (assert) {
|
||||
this.setProperties({
|
||||
attributes: EmberObject.create({
|
||||
post: EmberObject.create({
|
||||
id: 42,
|
||||
topic: {
|
||||
archived: false,
|
||||
},
|
||||
user_id: 29,
|
||||
}),
|
||||
hasSavedVote: true,
|
||||
poll: EmberObject.create({
|
||||
name: "poll",
|
||||
type: "regular",
|
||||
status: "open",
|
||||
results: "on_close",
|
||||
options: [
|
||||
{ id: "1f972d1df351de3ce35a787c89faad29", html: "yes" },
|
||||
{ id: "d7ebc3a9beea2e680815a1e4f57d6db6", html: "no" },
|
||||
],
|
||||
voters: 1,
|
||||
chart_type: "bar",
|
||||
}),
|
||||
vote: ["1f972d1df351de3ce35a787c89faad29"],
|
||||
groupableUserFields: [],
|
||||
}),
|
||||
preloadedVoters: [],
|
||||
});
|
||||
|
||||
await render(
|
||||
hbs`<Poll @attrs={{this.attributes}} @preloadedVoters={{this.preloadedVoters}} />`
|
||||
);
|
||||
|
||||
assert.ok(exists("ul.options"), "options are shown");
|
||||
assert.ok(!exists("ul.results"), "results are not shown");
|
||||
});
|
||||
|
||||
test("can vote", async function (assert) {
|
||||
this.setProperties({
|
||||
attributes: EmberObject.create({
|
||||
|
|
Loading…
Reference in New Issue