From c8c859762b04c5175aa60ca3333a0f17698a779b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=94=A6=E5=BF=83?= <41134017+Lhcfl@users.noreply.github.com> Date: Wed, 7 Aug 2024 17:46:29 +0800 Subject: [PATCH] FEATURE: Absolute Numbers in Poll (#28240) What does this add? =================== This PR adds an extra button to the poll to show the absolute number of people who voted for each option. This button will only be added for the single/multi-select bar chart. Related meta topic: https://meta.discourse.org/t/absolute-numbers-in-polls/32771 --- .../components/poll-buttons-dropdown.gjs | 21 ++++++++++ .../components/poll-results-standard.gjs | 15 +++++-- .../components/poll-results-tabs.gjs | 1 + .../javascripts/discourse/components/poll.gjs | 27 ++++++++++++- .../poll/assets/stylesheets/common/poll.scss | 7 +++- plugins/poll/config/locales/client.en.yml | 11 ++++++ .../component/poll-buttons-dropdown-test.js | 39 ++++++++++++++++++- .../component/poll-results-standard-test.js | 37 ++++++++++++++++++ 8 files changed, 150 insertions(+), 8 deletions(-) diff --git a/plugins/poll/assets/javascripts/discourse/components/poll-buttons-dropdown.gjs b/plugins/poll/assets/javascripts/discourse/components/poll-buttons-dropdown.gjs index 06871de3e67..457c4209a7e 100644 --- a/plugins/poll/assets/javascripts/discourse/components/poll-buttons-dropdown.gjs +++ b/plugins/poll/assets/javascripts/discourse/components/poll-buttons-dropdown.gjs @@ -35,6 +35,20 @@ const buttonOptionsMap = { icon: "lock", action: "toggleStatus", }, + showTally: { + className: "btn-default show-tally", + label: "poll.show-tally.label", + title: "poll.show-tally.title", + icon: "info", + action: "toggleDisplayMode", + }, + showPercentage: { + className: "btn-default show-percentage", + label: "poll.show-percentage.label", + title: "poll.show-percentage.title", + icon: "info", + action: "toggleDisplayMode", + }, }; export default class PollButtonsDropdownComponent extends Component { @@ -68,8 +82,15 @@ export default class PollButtonsDropdownComponent extends Component { topicArchived, groupableUserFields, isAutomaticallyClosed, + availableDisplayMode, } = this.args; + if (availableDisplayMode) { + const option = { ...buttonOptionsMap[availableDisplayMode] }; + option.id = option.action; + contents.push(option); + } + if (groupableUserFields.length && voters > 0) { const option = { ...buttonOptionsMap.showBreakdown }; option.id = option.action; diff --git a/plugins/poll/assets/javascripts/discourse/components/poll-results-standard.gjs b/plugins/poll/assets/javascripts/discourse/components/poll-results-standard.gjs index b244563e122..1b0eec3b631 100644 --- a/plugins/poll/assets/javascripts/discourse/components/poll-results-standard.gjs +++ b/plugins/poll/assets/javascripts/discourse/components/poll-results-standard.gjs @@ -76,10 +76,17 @@ export default class PollResultsStandardComponent extends Component {
{{#unless @isRankedChoice}} - {{i18n - "number.percent" - count=option.percentage - }} + {{#if @showTally}} + {{i18n + "poll.votes" + count=option.votes + }} + {{else}} + {{i18n + "number.percent" + count=option.percentage + }} + {{/if}} {{/unless}} {{htmlSafe option.html}}
diff --git a/plugins/poll/assets/javascripts/discourse/components/poll-results-tabs.gjs b/plugins/poll/assets/javascripts/discourse/components/poll-results-tabs.gjs index 67187829b19..c210a4fe9d5 100644 --- a/plugins/poll/assets/javascripts/discourse/components/poll-results-tabs.gjs +++ b/plugins/poll/assets/javascripts/discourse/components/poll-results-tabs.gjs @@ -65,6 +65,7 @@ export default class TabsComponent extends Component { @voters={{@voters}} @votersCount={{@votersCount}} @fetchVoters={{@fetchVoters}} + @showTally={{@showTally}} /> {{/if}} diff --git a/plugins/poll/assets/javascripts/discourse/components/poll.gjs b/plugins/poll/assets/javascripts/discourse/components/poll.gjs index c555c5b7510..6baf80ab27b 100644 --- a/plugins/poll/assets/javascripts/discourse/components/poll.gjs +++ b/plugins/poll/assets/javascripts/discourse/components/poll.gjs @@ -12,7 +12,11 @@ import icon from "discourse-common/helpers/d-icon"; import i18n from "discourse-common/helpers/i18n"; import I18n from "discourse-i18n"; import PollBreakdownModal from "../components/modal/poll-breakdown"; -import { PIE_CHART_TYPE } from "../components/modal/poll-ui-builder"; +import { + MULTIPLE_POLL_TYPE, + PIE_CHART_TYPE, + REGULAR_POLL_TYPE, +} from "../components/modal/poll-ui-builder"; import PollButtonsDropdown from "../components/poll-buttons-dropdown"; import PollInfo from "../components/poll-info"; import PollOptions from "../components/poll-options"; @@ -48,6 +52,8 @@ export default class PollComponent extends Component { (this.topicArchived && !this.staffOnly) || (this.closed && !this.staffOnly); + @tracked showTally = false; + checkUserGroups = (user, poll) => { const pollGroups = poll && poll.groups && poll.groups.split(",").map((g) => g.toLowerCase()); @@ -452,6 +458,17 @@ export default class PollComponent extends Component { return htmlSafe(I18n.t("poll.average_rating", { average })); } + get availableDisplayMode() { + if ( + !this.showResults || + this.poll.chart_type === PIE_CHART_TYPE || + ![REGULAR_POLL_TYPE, MULTIPLE_POLL_TYPE].includes(this.poll.type) + ) { + return null; + } + return this.showTally ? "showPercentage" : "showTally"; + } + @action updatedVoters() { this.preloadedVoters = this.defaultPreloadedVoters(); @@ -640,6 +657,12 @@ export default class PollComponent extends Component { } }); } + + @action + toggleDisplayMode() { + this.showTally = !this.showTally; + } + {{/if}} {{/if}} @@ -754,6 +778,7 @@ export default class PollComponent extends Component { @groupableUserFields={{this.groupableUserFields}} @isAutomaticallyClosed={{this.isAutomaticallyClosed}} @dropDownClick={{this.dropDownClick}} + @availableDisplayMode={{this.availableDisplayMode}} />