From 4cec091f1ad02dfda9ca4ab2598c61efbc05ff98 Mon Sep 17 00:00:00 2001 From: Kris Date: Wed, 5 Jul 2023 12:20:18 -0400 Subject: [PATCH] REFACTOR: improve poll info layout (#22353) --- .../common/components/widget-dropdown.scss | 5 +- .../stylesheets/common/foundation/mixins.scss | 8 +- .../discourse/widgets/discourse-poll.js | 348 ++++++++++++------ .../lib/discourse-markdown/poll.js | 15 +- .../poll/assets/stylesheets/common/poll.scss | 287 +++++++++++++-- .../poll/assets/stylesheets/desktop/poll.scss | 94 ----- .../poll/assets/stylesheets/mobile/poll.scss | 46 --- plugins/poll/config/locales/client.en.yml | 23 +- plugins/poll/plugin.rb | 2 - plugins/poll/spec/lib/pretty_text_spec.rb | 6 +- .../acceptance/poll-breakdown-test.js | 8 +- .../acceptance/poll-results-test.js | 7 +- 12 files changed, 529 insertions(+), 320 deletions(-) delete mode 100644 plugins/poll/assets/stylesheets/desktop/poll.scss delete mode 100644 plugins/poll/assets/stylesheets/mobile/poll.scss diff --git a/app/assets/stylesheets/common/components/widget-dropdown.scss b/app/assets/stylesheets/common/components/widget-dropdown.scss index 9530286a1f0..22a05e807c0 100644 --- a/app/assets/stylesheets/common/components/widget-dropdown.scss +++ b/app/assets/stylesheets/common/components/widget-dropdown.scss @@ -11,7 +11,6 @@ .widget-dropdown-body { display: flex; flex-direction: column; - padding: 0.25em; background: var(--secondary); z-index: z("dropdown"); border: 1px solid var(--primary-low); @@ -22,7 +21,7 @@ .widget-dropdown-item { cursor: pointer; - padding: 0.25em; + padding: 0.5em 1em; display: flex; flex: 1; align-items: center; @@ -43,7 +42,7 @@ } &:hover { - background: var(--tertiary-low); + background: var(--d-hover); } } diff --git a/app/assets/stylesheets/common/foundation/mixins.scss b/app/assets/stylesheets/common/foundation/mixins.scss index 11fceb31722..afb712eca77 100644 --- a/app/assets/stylesheets/common/foundation/mixins.scss +++ b/app/assets/stylesheets/common/foundation/mixins.scss @@ -19,7 +19,13 @@ $breakpoints: ( ); @mixin breakpoint($bp, $rule: max-width, $type: screen, $sidebar: false) { - @media #{$type} and (#{$rule}: map-get($breakpoints, $bp)) { + $bp-value: map-get($breakpoints, $bp); + + @if $rule == min-width { + $bp-value: calc(#{$bp-value} + 1px); + } + + @media #{$type} and (#{$rule}: #{$bp-value}) { @content; } diff --git a/plugins/poll/assets/javascripts/discourse/widgets/discourse-poll.js b/plugins/poll/assets/javascripts/discourse/widgets/discourse-poll.js index 012ec03fdbf..2fc41f9b937 100644 --- a/plugins/poll/assets/javascripts/discourse/widgets/discourse-poll.js +++ b/plugins/poll/assets/javascripts/discourse/widgets/discourse-poll.js @@ -7,17 +7,48 @@ import { createWidget } from "discourse/widgets/widget"; import evenRound from "discourse/plugins/poll/lib/even-round"; import { getColors } from "discourse/plugins/poll/lib/chart-colors"; import { h } from "virtual-dom"; -import { iconNode } from "discourse-common/lib/icon-library"; +import { iconHTML, iconNode } from "discourse-common/lib/icon-library"; import loadScript from "discourse/lib/load-script"; import { popupAjaxError } from "discourse/lib/ajax-error"; import { relativeAge } from "discourse/lib/formatter"; import round from "discourse/lib/round"; import { applyLocalDates } from "discourse/lib/local-dates"; +import hbs from "discourse/widgets/hbs-compiler"; import PollBreakdownModal from "../components/modal/poll-breakdown"; import { getOwner } from "@ember/application"; const FETCH_VOTERS_COUNT = 25; +const buttonOptionsMap = { + exportResults: { + className: "btn-default export-results", + label: "poll.export-results.label", + title: "poll.export-results.title", + icon: "download", + action: "exportResults", + }, + showBreakdown: { + className: "btn-default show-breakdown", + label: "poll.breakdown.breakdown", + icon: "chart-pie", + action: "showBreakdown", + }, + openPoll: { + className: "btn-default toggle-status", + label: "poll.open.label", + title: "poll.open.title", + icon: "unlock-alt", + action: "toggleStatus", + }, + closePoll: { + className: "btn-default toggle-status", + label: "poll.close.label", + title: "poll.close.title", + icon: "lock", + action: "toggleStatus", + }, +}; + function optionHtml(option, siteSettings = {}) { const el = document.createElement("span"); el.innerHTML = option.html; @@ -25,12 +56,6 @@ function optionHtml(option, siteSettings = {}) { return new RawHtml({ html: `${el.innerHTML}` }); } -function infoTextHtml(text) { - return new RawHtml({ - html: `${text}`, - }); -} - function checkUserGroups(user, poll) { const pollGroups = poll && poll.groups && poll.groups.split(",").map((g) => g.toLowerCase()); @@ -407,14 +432,18 @@ createWidget("discourse-poll-info", { }, html(attrs) { - const { poll } = attrs; + const { poll, post } = attrs; + const closed = attrs.isClosed; + const isStaff = this.currentUser && this.currentUser.staff; + const isMe = this.currentUser && post.user_id === this.currentUser.id; const count = poll.voters; const contents = [ - h("p", [ + h("div.poll-info_counts-count", [ h("span.info-number", count.toString()), h("span.info-label", I18n.t("poll.voters", { count })), ]), ]; + const instructions = []; if (attrs.isMultiple) { if (attrs.showResults || attrs.isClosed) { @@ -423,7 +452,7 @@ createWidget("discourse-poll-info", { }, 0); contents.push( - h("p", [ + h("div.poll-info_counts-count", [ h("span.info-number", totalVotes.toString()), h( "span.info-label", @@ -438,21 +467,94 @@ createWidget("discourse-poll-info", { poll.options.length ); if (help) { - contents.push(infoTextHtml(help)); + instructions.push( + new RawHtml({ + html: `
  • + ${iconHTML("list-ul")} + ${help} +
  • `, + }) + ); } } } + if (poll.close) { + const closeDate = moment.utc(poll.close, "YYYY-MM-DD HH:mm:ss Z"); + if (closeDate.isValid()) { + const title = closeDate.format("LLL"); + let label; + let icon; + + if (attrs.isAutomaticallyClosed) { + const age = relativeAge(closeDate.toDate(), { addAgo: true }); + label = I18n.t("poll.automatic_close.age", { age }); + icon = "lock"; + } else { + const timeLeft = moment().to(closeDate, true); + label = I18n.t("poll.automatic_close.closes_in", { timeLeft }); + icon = "far-clock"; + } + + instructions.push( + new RawHtml({ + html: `
  • + ${iconHTML(icon)} + ${label} +
  • `, + }) + ); + } + } + + let infoText; + if (poll.results === "on_vote" && !attrs.hasVoted && !isMe) { + infoText = new RawHtml({ + html: `
  • + ${iconHTML("check")} + ${I18n.t("poll.results.vote.title")} +
  • `, + }); + } else if (poll.results === "on_close" && !closed) { + infoText = new RawHtml({ + html: `
  • + ${iconHTML("lock")} + ${I18n.t("poll.results.closed.title")} +
  • `, + }); + } else if (poll.results === "staff_only" && !isStaff) { + infoText = new RawHtml({ + html: `
  • + ${iconHTML("shield-alt")} + ${I18n.t("poll.results.staff.title")} +
  • `, + }); + } + + if (infoText) { + instructions.push(infoText); + } + if ( !attrs.isClosed && !attrs.showResults && poll.public && poll.results !== "staff_only" ) { - contents.push(infoTextHtml(I18n.t("poll.public.title"))); + instructions.push( + new RawHtml({ + html: `
  • + ${iconHTML("far-eye")} + ${I18n.t("poll.public.title")} +
  • `, + }) + ); } - return contents; + return [ + h("div.poll-info_counts", contents), + h("ul.poll-info_instructions", instructions), + ]; }, }); @@ -595,6 +697,82 @@ function stripHtml(html) { return doc.body.textContent || ""; } +createWidget("discourse-poll-buttons-dropdown", { + tagName: "div.poll-buttons-dropdown", + + buildId(attrs) { + return `poll-buttons-dropdown-${attrs.id}`; + }, + + transform(attrs) { + return { + content: this._buildContent(attrs), + onChange: (item) => this.sendWidgetAction(item.id, item.param), + }; + }, + + template: hbs` + {{attach + widget="widget-dropdown" + attrs=(hash + id=this.attrs.id + icon="cog" + label="poll.options.label" + content=this.transformed.content + onChange=this.transformed.onChange + options=this.transformed.options + ) + }} +`, + + optionsCount(attrs) { + return this._buildContent(attrs).length; + }, + + _buildContent(attrs) { + const contents = []; + const isAdmin = this.currentUser && this.currentUser.admin; + const dataExplorerEnabled = this.siteSettings.data_explorer_enabled; + const exportQueryID = this.siteSettings.poll_export_data_explorer_query_id; + const { poll, post } = attrs; + const closed = attrs.isClosed; + const isStaff = this.currentUser && this.currentUser.staff; + const topicArchived = post.get("topic.archived"); + + if (attrs.groupableUserFields.length && poll.voters > 0) { + const option = { ...buttonOptionsMap.showBreakdown }; + option.id = option.action; + contents.push(option); + } + + if (isAdmin && dataExplorerEnabled && poll.voters > 0 && exportQueryID) { + const option = { ...buttonOptionsMap.exportResults }; + option.id = option.action; + contents.push(option); + } + + if ( + this.currentUser && + (this.currentUser.id === post.user_id || isStaff) && + !topicArchived + ) { + if (closed) { + if (!attrs.isAutomaticallyClosed) { + const option = { ...buttonOptionsMap.openPoll }; + option.id = option.action; + contents.push(option); + } + } else { + const option = { ...buttonOptionsMap.closePoll }; + option.id = option.action; + contents.push(option); + } + } + + return contents; + }, +}); + createWidget("discourse-poll-buttons", { tagName: "div.poll-buttons", @@ -605,13 +783,12 @@ createWidget("discourse-poll-buttons", { const closed = attrs.isClosed; const staffOnly = poll.results === "staff_only"; const isStaff = this.currentUser && this.currentUser.staff; - const isAdmin = this.currentUser && this.currentUser.admin; const isMe = this.currentUser && post.user_id === this.currentUser.id; - const dataExplorerEnabled = this.siteSettings.data_explorer_enabled; const hideResultsDisabled = !staffOnly && (closed || topicArchived); - const exportQueryID = this.siteSettings.poll_export_data_explorer_query_id; + const dropdown = this.attach("discourse-poll-buttons-dropdown", attrs); + const dropdownOptionsCount = dropdown.optionsCount(attrs); - if (attrs.isMultiple && !hideResultsDisabled) { + if (attrs.isMultiple && !hideResultsDisabled && !attrs.showResults) { const castVotesDisabled = !attrs.canCastVotes; contents.push( this.attach("button", { @@ -620,144 +797,75 @@ createWidget("discourse-poll-buttons", { }`, label: "poll.cast-votes.label", title: "poll.cast-votes.title", + icon: castVotesDisabled ? "far-square" : "check", disabled: castVotesDisabled, action: "castVotes", }) ); - contents.push(" "); } - if (attrs.showResults || hideResultsDisabled) { + if (attrs.showResults && !hideResultsDisabled) { contents.push( this.attach("button", { className: "btn-default toggle-results", label: "poll.hide-results.label", title: "poll.hide-results.title", - icon: "far-eye-slash", - disabled: hideResultsDisabled, + icon: "chevron-left", action: "toggleResults", }) ); - } else { - let showResultsButton; - let infoText; + } - if (poll.results === "on_vote" && !attrs.hasVoted && !isMe) { - infoText = infoTextHtml(I18n.t("poll.results.vote.title")); - } else if (poll.results === "on_close" && !closed) { - infoText = infoTextHtml(I18n.t("poll.results.closed.title")); - } else if (poll.results === "staff_only" && !isStaff) { - infoText = infoTextHtml(I18n.t("poll.results.staff.title")); - } else { + if (!attrs.showResults && !hideResultsDisabled) { + let showResultsButton; + + if ( + !(poll.results === "on_vote" && !attrs.hasVoted && !isMe) && + !(poll.results === "on_close" && !closed) && + !(poll.results === "staff_only" && !isStaff) && + poll.voters > 0 + ) { showResultsButton = this.attach("button", { className: "btn-default toggle-results", label: "poll.show-results.label", title: "poll.show-results.title", - icon: "far-eye", - disabled: poll.voters === 0, + icon: "chart-bar", action: "toggleResults", }); } - if (showResultsButton) { - contents.push(showResultsButton); - } - if (attrs.hasSavedVote) { contents.push( this.attach("button", { className: "btn-default remove-vote", label: "poll.remove-vote.label", title: "poll.remove-vote.title", - icon: "trash-alt", + icon: "undo", action: "removeVote", }) ); } - if (infoText) { - contents.push(infoText); + if (showResultsButton) { + contents.push(showResultsButton); } } - if (attrs.groupableUserFields.length && poll.voters > 0) { - const button = this.attach("button", { - className: "btn-default poll-show-breakdown", - label: "poll.group-results.label", - title: "poll.group-results.title", - icon: "far-eye", - action: "showBreakdown", - }); - - contents.push(button); - } - - if (isAdmin && dataExplorerEnabled && poll.voters > 0 && exportQueryID) { - contents.push( - this.attach("button", { - className: "btn btn-default export-results", - label: "poll.export-results.label", - title: "poll.export-results.title", - icon: "download", - disabled: poll.voters === 0, - action: "exportResults", - }) - ); - } - - if (poll.close) { - const closeDate = moment(poll.close); - if (closeDate.isValid()) { - const title = closeDate.format("LLL"); - let label; - - if (attrs.isAutomaticallyClosed) { - const age = relativeAge(closeDate.toDate(), { addAgo: true }); - label = I18n.t("poll.automatic_close.age", { age }); - } else { - const timeLeft = moment().to(closeDate, true); - label = I18n.t("poll.automatic_close.closes_in", { timeLeft }); - } - - contents.push( - new RawHtml({ - html: `${label}`, - }) - ); + // only show the dropdown if there's more than 1 button + // otherwise just show the button + if (dropdownOptionsCount > 1) { + contents.push(dropdown); + } else if (dropdownOptionsCount === 1) { + const singleOptionId = dropdown._buildContent(attrs)[0].id; + let singleOption = buttonOptionsMap[singleOptionId]; + if (singleOptionId === "toggleStatus") { + singleOption = closed + ? buttonOptionsMap.openPoll + : buttonOptionsMap.closePoll; } + contents.push(this.attach("button", singleOption)); } - - if ( - this.currentUser && - (this.currentUser.id === post.user_id || isStaff) && - !topicArchived - ) { - if (closed) { - if (!attrs.isAutomaticallyClosed) { - contents.push( - this.attach("button", { - className: "btn-default toggle-status", - label: "poll.open.label", - title: "poll.open.title", - icon: "unlock-alt", - action: "toggleStatus", - }) - ); - } - } else { - contents.push( - this.attach("button", { - className: "toggle-status btn-danger", - label: "poll.close.label", - title: "poll.close.title", - icon: "lock", - action: "toggleStatus", - }) - ); - } - } - - return contents; + return [contents]; }, }); @@ -806,11 +914,11 @@ export default createWidget("discourse-poll", { showResults, }); - return h("div", [ + return [ this.attach("discourse-poll-container", newAttrs), this.attach("discourse-poll-info", newAttrs), this.attach("discourse-poll-buttons", newAttrs), - ]); + ]; }, min() { @@ -833,7 +941,9 @@ export default createWidget("discourse-poll", { isAutomaticallyClosed() { const { poll } = this.attrs; - return poll.close && moment.utc(poll.close) <= moment(); + return ( + poll.close && moment.utc(poll.close, "YYYY-MM-DD HH:mm:ss Z") <= moment() + ); }, isClosed() { diff --git a/plugins/poll/assets/javascripts/lib/discourse-markdown/poll.js b/plugins/poll/assets/javascripts/lib/discourse-markdown/poll.js index 6238e32d574..972ac92f4bd 100644 --- a/plugins/poll/assets/javascripts/lib/discourse-markdown/poll.js +++ b/plugins/poll/assets/javascripts/lib/discourse-markdown/poll.js @@ -158,10 +158,6 @@ const rule = { token.attrs = attributes; header.push(token); - token = new state.Token("poll_open", "div", 1); - token.block = true; - header.push(token); - token = new state.Token("poll_open", "div", 1); token.attrs = [["class", "poll-container"]]; header.push(token); @@ -236,7 +232,11 @@ const rule = { token = state.push("poll_open", "div", 1); token.attrs = [["class", "poll-info"]]; - state.push("paragraph_open", "p", 1); + token = state.push("poll_open", "div", 1); + token.attrs = [["class", "poll-info_counts"]]; + + token = state.push("poll_open", "div", 1); + token.attrs = [["class", "poll-info_counts-count"]]; token = state.push("span_open", "span", 1); token.block = false; @@ -252,8 +252,7 @@ const rule = { token.content = I18n.t("poll.voters", { count: 0 }); state.push("span_close", "span", -1); - state.push("paragraph_close", "p", -1); - + state.push("poll_close", "div", -1); state.push("poll_close", "div", -1); state.push("poll_close", "div", -1); state.push("poll_close", "div", -1); @@ -277,6 +276,8 @@ export function setup(helper) { helper.allowList([ "div.poll", "div.poll-info", + "div.poll-info_counts", + "div.poll-info_counts-count", "div.poll-container", "div.poll-title", "div.poll-buttons", diff --git a/plugins/poll/assets/stylesheets/common/poll.scss b/plugins/poll/assets/stylesheets/common/poll.scss index c0db0f7a966..f92144a5d70 100644 --- a/plugins/poll/assets/stylesheets/common/poll.scss +++ b/plugins/poll/assets/stylesheets/common/poll.scss @@ -1,6 +1,15 @@ div.poll { + > * { + box-sizing: border-box; + } margin: 1em 0; border: 1px solid var(--primary-low); + display: grid; + grid-template-areas: "poll" "info" "buttons"; + @include breakpoint("mobile-extra-large", min-width) { + grid-template-columns: 1fr 10em; + grid-template-areas: "poll info" "buttons buttons"; + } ul, ol { @@ -11,11 +20,6 @@ div.poll { width: 100%; } - li { - cursor: pointer; - font-size: var(--font-up-1); - } - li[data-poll-option-id] { color: var(--primary); padding: 0.5em 0; @@ -34,38 +38,228 @@ div.poll { } .poll-info { + grid-area: info; + display: flex; + line-height: var(--line-height-medium); color: var(--primary-medium); - vertical-align: middle; - padding: 1em 0; - .info-label { - font-size: var(--font-up-4); - line-height: var(--line-height-medium); + @include breakpoint("mobile-extra-large") { + border-top: 1px solid var(--primary-low); + flex-direction: row-reverse; + &_counts, + &_instructions { + padding: 1em; + } + } + + @include breakpoint("mobile-extra-large", min-width) { + gap: 0 1em; + padding: 1em; + border-left: 1px solid var(--primary-low); + flex-direction: column; + justify-content: center; + align-items: center; + } + + &_counts { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.25em 0; + + @include breakpoint("mobile-extra-large", min-width) { + justify-content: center; + } + + @include breakpoint("mobile-extra-large") { + flex: 1 1 auto; + } + + &-count { + gap: 0.25em; + line-height: 1; + white-space: nowrap; + text-align: left; + + .info-label, + .info-number { + display: inline; + margin-right: 0.25em; + text-align: center; + } + + @include breakpoint("mobile-extra-large") { + &:not(:last-child) { + margin-right: 0.75em; + } + } + + @include breakpoint("mobile-extra-large", min-width) { + &:not(:last-child) { + margin-bottom: 0.25em; + } + display: flex; + flex-direction: column; + align-items: center; + + .poll-info_counts-count { + margin-top: 0.5em; + display: block; + .info-number { + margin-right: 0.33em; + } + .info-number, + .info-label { + font-size: var(--font-up-1); + } + } + } + } + @include breakpoint("mobile-extra-large", min-width) { + + .poll-info_instructions:not(:empty) { + margin-top: 1.25em; + } + } + } + + &_instructions { + box-sizing: border-box; + display: flex; + flex-direction: column; + justify-content: center; + align-self: start; + &:empty { + display: none; + } + + @include breakpoint("mobile-extra-large", min-width) { + padding-top: 1.25em; + &:not(:empty) { + border-top: 1px solid var(--primary-low); + } + } + + @include breakpoint("mobile-extra-large") { + padding-right: 1em; + height: 100%; + flex: 1 1 auto; + &:not(:empty) { + border-right: 1px solid var(--primary-low); + } + } + + li { + display: flex; + gap: 0.5em; + &:not(:last-child) { + margin-bottom: 0.5em; + } + + @include breakpoint("mobile-extra-large", min-width) { + &:not(:last-child) { + margin-bottom: 1em; + } + &:not(:first-child:last-child) { + // only applied when there are multiple items + .d-icon { + width: 15%; + } + span { + width: 85%; + } + } + &:first-child:last-child { + // when there's a single item, it looks better centered + display: inline; + text-align: center; + } + } + } + + .d-icon { + font-size: var(--font-down-1); + margin-top: 0.2em; + } } .info-text { margin: 0.25em 0; display: block; } + + @include breakpoint("mobile-extra-large", min-width) { + .info-label { + font-size: var(--font-up-2); + } + .info-number { + font-size: var(--font-up-6); + } + } } .poll-container { - vertical-align: middle; - padding: 0.5em 1em; + grid-area: poll; + padding: 1em; + width: 100%; + overflow: hidden; + align-self: center; + + li { + cursor: pointer; + font-size: var(--font-up-1); + } .poll-results-number-rating { font-size: var(--font-up-5); } } + .poll-title { + border-bottom: 1px solid var(--primary-low); + margin-bottom: 0.5em; + padding-bottom: 0.5em; + } + .poll-buttons { - .info-text { - margin: 0.25em 0; - color: var(--primary-medium); + grid-area: buttons; + display: flex; + flex-wrap: wrap; + gap: 0.5em; + width: 100%; + padding: 1em; + border-top: 1px solid var(--primary-low); + + button { + white-space: nowrap; + align-self: start; + .d-button-label { + @include ellipsis; + } + + @include breakpoint("tablet") { + flex: 1 1 0; + &:first-child:last-child { + // if there's only one button, + // don't expand the width + flex: 0 1 auto; + } + &.toggle-results:first-child { + // don't expand the back button + flex: 0 1 auto; + margin-right: auto; + } + } + + @include breakpoint("mobile-large") { + &:first-child:last-child, + &.cast-votes { + // ok to expand button width on smaller screens + flex: 1 1 100%; + } + } } - .info-text + .info-text, - button + .info-text { - margin-left: 0.5em; + + &:empty { + display: none; } } @@ -87,6 +281,33 @@ div.poll { } } + .poll-buttons-dropdown { + align-self: stretch; + + .label { + display: none; + } + .widget-dropdown { + height: 100%; + + &-header { + height: 100%; + .d-icon { + margin: 0; + } + } + } + } + + .poll-buttons-dropdown, + .export-results, + .toggle-status, + .show-breakdown { + // we want these controls to be separated + // from voting controls + margin-left: auto; + } + .results { > li { cursor: default; @@ -160,19 +381,27 @@ div.poll { overflow-y: auto; overflow-x: hidden; } - - .poll-show-breakdown { - margin-bottom: 0.25em; - } } -div.poll.pie { - .poll-container { - display: inline-block; - } - .poll-info { - display: inline-block; - width: 150px; +.d-editor-preview { + .poll { + li[data-poll-option-id]:before { + position: relative; + vertical-align: baseline; + border: 2px solid var(--primary); + border-radius: 50%; + display: inline-block; + margin-right: 0.5em; + width: 12px; + height: 12px; + content: ""; + } + + &[data-poll-type="multiple"] { + li[data-poll-option-id]:before { + border-radius: 3px; + } + } } } diff --git a/plugins/poll/assets/stylesheets/desktop/poll.scss b/plugins/poll/assets/stylesheets/desktop/poll.scss deleted file mode 100644 index ce9ad531ff7..00000000000 --- a/plugins/poll/assets/stylesheets/desktop/poll.scss +++ /dev/null @@ -1,94 +0,0 @@ -div.poll { - display: table; - width: 100%; - box-sizing: border-box; - - .poll-info { - min-width: 150px; - width: 100%; - display: table-cell; - text-align: center; - - .info-number { - font-size: 3.5em; - } - - p { - margin: 0.5em 0; - } - - .info-label { - display: block; - } - } - - .poll-container { - display: table-cell; - width: 100%; - border-right: 1px solid var(--primary-low); - } - - .poll-title { - border-bottom: 1px solid var(--primary-low); - margin-bottom: 0.5em; - padding: 0.5em 0; - } - - .poll-buttons { - border-top: 1px solid var(--primary-low); - padding: 1em; - display: flex; - flex-direction: row; - - .info-text { - line-height: 2em; - } - - button:not(:first-child) { - margin-left: 0.5em; - } - - .btn-danger.toggle-status { - margin-left: auto; - } - } -} - -div.poll.pie { - .poll-container { - width: calc(100% - 190px); - } - - .poll-info { - display: inline-block; - width: 150px; - } -} - -.d-editor-preview { - .poll-buttons { - a:not(:first-child) { - margin-left: 0.25em; - } - } - - .poll { - li[data-poll-option-id]:before { - position: relative; - vertical-align: baseline; - border: 2px solid var(--primary); - border-radius: 50%; - display: inline-block; - margin-right: 0.5em; - width: 12px; - height: 12px; - content: ""; - } - - &[data-poll-type="multiple"] { - li[data-poll-option-id]:before { - border-radius: 3px; - } - } - } -} diff --git a/plugins/poll/assets/stylesheets/mobile/poll.scss b/plugins/poll/assets/stylesheets/mobile/poll.scss deleted file mode 100644 index 63de31ec62e..00000000000 --- a/plugins/poll/assets/stylesheets/mobile/poll.scss +++ /dev/null @@ -1,46 +0,0 @@ -div.poll { - .poll-buttons { - display: inline-flex; - flex-wrap: wrap; - padding: 0.5em 1em 0.5em 1em; - - button { - margin: 0 0.5em 0.5em 0; - } - - button + .info-text { - margin: 0.4em 0 0 0.5em; - } - } - - .poll-info { - padding: 0 1em; - display: flex; - flex-wrap: wrap; - flex-direction: column; - .info-text { - display: inline; - } - .info-number { - font-size: var(--font-up-6); - } - p { - margin: 0; - width: 100%; - } - .info-label { - margin-left: 0.25em; - } - } - - .poll-show-breakdown { - display: none; - } -} - -div.poll.pie { - .poll-container { - width: calc(100% - 30px); - border-bottom: 1px solid var(--primary-low); - } -} diff --git a/plugins/poll/config/locales/client.en.yml b/plugins/poll/config/locales/client.en.yml index c7fa3890414..73d4557478b 100644 --- a/plugins/poll/config/locales/client.en.yml +++ b/plugins/poll/config/locales/client.en.yml @@ -26,15 +26,15 @@ en: multiple: help: at_least_min_options: - one: "Choose at least %{count} option." - other: "Choose at least %{count} options." + one: "Choose at least %{count} option." + other: "Choose at least %{count} options." up_to_max_options: - one: "Choose up to %{count} option." - other: "Choose up to %{count} options." + one: "Choose up to %{count} option." + other: "Choose up to %{count} options." x_options: - one: "Choose %{count} option." - other: "Choose %{count} options." - between_min_and_max_options: "Choose between %{min} and %{max} options." + one: "Choose %{count} option." + other: "Choose %{count} options." + between_min_and_max_options: "Choose between %{min} and %{max} options." cast-votes: title: "Cast your votes" @@ -42,15 +42,15 @@ en: show-results: title: "Display the poll results" - label: "Show results" + label: "Results" remove-vote: title: "Remove your vote" - label: "Remove vote" + label: "Undo vote" hide-results: title: "Back to your votes" - label: "Show vote" + label: "Vote" group-results: title: "Group votes by user field" @@ -80,6 +80,9 @@ en: breakdown: "Breakdown" percentage: "Percentage" count: "Count" + + options: + label: "Options" error_while_toggling_status: "Sorry, there was an error toggling the status of this poll." error_while_casting_votes: "Sorry, there was an error casting your votes." diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb index b656b7b4600..f79ab268934 100644 --- a/plugins/poll/plugin.rb +++ b/plugins/poll/plugin.rb @@ -7,8 +7,6 @@ # url: https://github.com/discourse/discourse/tree/main/plugins/poll register_asset "stylesheets/common/poll.scss" -register_asset "stylesheets/desktop/poll.scss", :desktop -register_asset "stylesheets/mobile/poll.scss", :mobile register_asset "stylesheets/common/poll-ui-builder.scss" register_asset "stylesheets/desktop/poll-ui-builder.scss", :desktop register_asset "stylesheets/common/poll-breakdown.scss" diff --git a/plugins/poll/spec/lib/pretty_text_spec.rb b/plugins/poll/spec/lib/pretty_text_spec.rb index 52fcdb354c1..ac35be9f1c1 100644 --- a/plugins/poll/spec/lib/pretty_text_spec.rb +++ b/plugins/poll/spec/lib/pretty_text_spec.rb @@ -93,17 +93,17 @@ RSpec.describe PrettyText do expected = <<~HTML
    -
    1. test 1 :slight_smile: test
    2. test 2
    -

    +

    +
    0 voters -

    +
    diff --git a/plugins/poll/test/javascripts/acceptance/poll-breakdown-test.js b/plugins/poll/test/javascripts/acceptance/poll-breakdown-test.js index 750a0530782..23f36ef9681 100644 --- a/plugins/poll/test/javascripts/acceptance/poll-breakdown-test.js +++ b/plugins/poll/test/javascripts/acceptance/poll-breakdown-test.js @@ -66,13 +66,14 @@ acceptance("Poll breakdown", function (needs) { test("Displaying the poll breakdown modal", async function (assert) { await visit("/t/-/topic_with_pie_chart_poll"); + await click(".widget-dropdown-header"); assert.ok( - exists(".poll-show-breakdown"), + exists(".item-showBreakdown"), "shows the breakdown button when poll_groupable_user_fields is non-empty" ); - await click(".poll-show-breakdown"); + await click(".item-showBreakdown"); assert.ok(exists(".poll-breakdown-total-votes"), "displays the vote count"); @@ -90,7 +91,8 @@ acceptance("Poll breakdown", function (needs) { test("Changing the display mode from percentage to count", async function (assert) { await visit("/t/-/topic_with_pie_chart_poll"); - await click(".poll-show-breakdown"); + await click(".widget-dropdown-header"); + await click(".item-showBreakdown"); assert.strictEqual( query(".poll-breakdown-option-count").textContent.trim(), diff --git a/plugins/poll/test/javascripts/acceptance/poll-results-test.js b/plugins/poll/test/javascripts/acceptance/poll-results-test.js index 3d23208bfec..b9188febf41 100644 --- a/plugins/poll/test/javascripts/acceptance/poll-results-test.js +++ b/plugins/poll/test/javascripts/acceptance/poll-results-test.js @@ -1,8 +1,8 @@ import { acceptance, count, + exists, publishToMessageBus, - query, } from "discourse/tests/helpers/qunit-helpers"; import { test } from "qunit"; import { clearPopupMenuOptionsCallback } from "discourse/controllers/composer"; @@ -1156,8 +1156,9 @@ acceptance("Poll results - no voters", function (needs) { }); }); - test("disables show results button", async function (assert) { + test("does not show results button", async function (assert) { await visit("/t/-/load-more-poll-voters"); - assert.ok(query(".toggle-results").disabled); + + assert.ok(!exists(".toggle-results")); }); });