UX: explain choices priorities (#28574)

This commit will add `highest priority` to first choice and `lowest priority` to the last choice to make it more explicit to the user.
This commit is contained in:
Joffrey JAFFEUX 2024-08-27 13:03:48 +02:00 committed by GitHub
parent ac5964c402
commit 7335b44d4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 67 additions and 22 deletions

View File

@ -7,6 +7,7 @@ import { htmlSafe } from "@ember/template";
import concatClass from "discourse/helpers/concat-class"; import concatClass from "discourse/helpers/concat-class";
import routeAction from "discourse/helpers/route-action"; import routeAction from "discourse/helpers/route-action";
import icon from "discourse-common/helpers/d-icon"; import icon from "discourse-common/helpers/d-icon";
import I18n from "discourse-i18n";
import PollOptionRankedChoice from "./poll-option-ranked-choice"; import PollOptionRankedChoice from "./poll-option-ranked-choice";
export default class PollOptionsComponent extends Component { export default class PollOptionsComponent extends Component {
@ -25,6 +26,36 @@ export default class PollOptionsComponent extends Component {
sendRank(option, rank = 0) { sendRank(option, rank = 0) {
this.args.sendOptionSelect(option, rank); this.args.sendOptionSelect(option, rank);
} }
get rankedChoiceDropdownContent() {
let rankedChoiceDropdownContent = [];
rankedChoiceDropdownContent.push({
id: 0,
name: I18n.t("poll.options.ranked_choice.abstain"),
});
this.args.options.forEach((option, i) => {
option.rank = 0;
let priority = "";
if (i === 0) {
priority = ` ${I18n.t("poll.options.ranked_choice.highest_priority")}`;
}
if (i === this.args.options.length - 1) {
priority = ` ${I18n.t("poll.options.ranked_choice.lowest_priority")}`;
}
rankedChoiceDropdownContent.push({
id: i + 1,
name: (i + 1).toString() + priority,
});
});
return rankedChoiceDropdownContent;
}
<template> <template>
<ul <ul
class={{concatClass class={{concatClass
@ -36,7 +67,7 @@ export default class PollOptionsComponent extends Component {
{{#if @isRankedChoice}} {{#if @isRankedChoice}}
<PollOptionRankedChoice <PollOptionRankedChoice
@option={{option}} @option={{option}}
@rankedChoiceDropdownContent={{@rankedChoiceDropdownContent}} @rankedChoiceDropdownContent={{this.rankedChoiceDropdownContent}}
@sendRank={{this.sendRank}} @sendRank={{this.sendRank}}
/> />
{{else}} {{else}}

View File

@ -291,25 +291,6 @@ export default class PollComponent extends Component {
return this.status === CLOSED_STATUS || this.isAutomaticallyClosed; return this.status === CLOSED_STATUS || this.isAutomaticallyClosed;
} }
get rankedChoiceDropdownContent() {
let rankedChoiceDropdownContent = [];
rankedChoiceDropdownContent.push({
id: 0,
name: I18n.t("poll.options.ranked_choice.abstain"),
});
this.poll.options.forEach((option, i) => {
option.rank = 0;
rankedChoiceDropdownContent.push({
id: i + 1,
name: (i + 1).toString(),
});
});
return rankedChoiceDropdownContent;
}
get isAutomaticallyClosed() { get isAutomaticallyClosed() {
return ( return (
(this.poll.close ?? false) && (this.poll.close ?? false) &&
@ -716,7 +697,6 @@ export default class PollComponent extends Component {
<PollOptions <PollOptions
@isCheckbox={{this.isCheckbox}} @isCheckbox={{this.isCheckbox}}
@isRankedChoice={{this.isRankedChoice}} @isRankedChoice={{this.isRankedChoice}}
@rankedChoiceDropdownContent={{this.rankedChoiceDropdownContent}}
@options={{this.options}} @options={{this.options}}
@votes={{this.vote}} @votes={{this.vote}}
@sendOptionSelect={{this.toggleOption}} @sendOptionSelect={{this.toggleOption}}

View File

@ -113,6 +113,8 @@ en:
label: "Options" label: "Options"
ranked_choice: ranked_choice:
abstain: "Abstain" abstain: "Abstain"
highest_priority: "(highest priority)"
lowest_priority: "(lowest priority)"
login: "Login to vote!" login: "Login to vote!"
error_while_toggling_status: "Sorry, there was an error toggling the status of this poll." error_while_toggling_status: "Sorry, there was an error toggling the status of this poll."

View File

@ -1,8 +1,9 @@
import { render } from "@ember/test-helpers"; import { click, render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { module, test } from "qunit"; import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { count } from "discourse/tests/helpers/qunit-helpers"; import { count } from "discourse/tests/helpers/qunit-helpers";
import I18n from "discourse-i18n";
const OPTIONS = [ const OPTIONS = [
{ id: "1ddc47be0d2315b9711ee8526ca9d83f", html: "This", votes: 0, rank: 0 }, { id: "1ddc47be0d2315b9711ee8526ca9d83f", html: "This", votes: 0, rank: 0 },
@ -128,4 +129,35 @@ module("Poll | Component | poll-options", function (hooks) {
assert.strictEqual(count("li img"), 2); assert.strictEqual(count("li img"), 2);
}); });
test("ranked choice - priorities", async function (assert) {
this.setProperties({
isCheckbox: false,
isRankedChoice: true,
rankedChoiceDropdownContent: [],
options: OPTIONS,
votes: [],
});
await render(hbs`<PollOptions
@isCheckbox={{this.isCheckbox}}
@isRankedChoice={{this.isRankedChoice}}
@ranked_choice_dropdown_content={{this.ranked_choice_dropdown_content}}
@options={{this.options}}
@votes={{this.votes}}
@sendRadioClick={{this.toggleOption}}
/>`);
await click(
`.ranked-choice-poll-option[data-poll-option-id='${OPTIONS[0].id}'] button`
);
assert
.dom(".dropdown-menu__item:nth-child(2)")
.hasText(`1 ${I18n.t("poll.options.ranked_choice.highest_priority")}`);
assert
.dom(".dropdown-menu__item:nth-child(4)")
.hasText(`3 ${I18n.t("poll.options.ranked_choice.lowest_priority")}`);
});
}); });