diff --git a/plugins/poll/app/models/poll.rb b/plugins/poll/app/models/poll.rb index e8ae6942e1b..1dd0d0b7181 100644 --- a/plugins/poll/app/models/poll.rb +++ b/plugins/poll/app/models/poll.rb @@ -24,6 +24,7 @@ class Poll < ActiveRecord::Base always: 0, on_vote: 1, on_close: 2, + staff_only: 3, } enum visibility: { @@ -40,7 +41,10 @@ class Poll < ActiveRecord::Base end def can_see_results?(user) - always? || is_closed? || (on_vote? && has_voted?(user)) + return true if always? + return !!user&.staff? if staff_only? + return has_voted?(user) if on_vote? + is_closed? end def has_voted?(user) diff --git a/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 b/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 index 0f85aedc2df..916b73f65e8 100644 --- a/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 +++ b/plugins/poll/assets/javascripts/controllers/poll-ui-builder.js.es6 @@ -12,6 +12,7 @@ export default Ember.Controller.extend({ alwaysPollResult: "always", votePollResult: "on_vote", closedPollResult: "on_close", + staffPollResult: "staff_only", init() { this._super(...arguments); @@ -36,8 +37,8 @@ export default Ember.Controller.extend({ ]; }, - @computed("alwaysPollResult", "votePollResult", "closedPollResult") - pollResults(alwaysPollResult, votePollResult, closedPollResult) { + @computed("alwaysPollResult", "votePollResult", "closedPollResult", "staffPollResult") + pollResults(alwaysPollResult, votePollResult, closedPollResult, staffPollResult) { return [ { name: I18n.t("poll.ui_builder.poll_result.always"), @@ -50,6 +51,10 @@ export default Ember.Controller.extend({ { name: I18n.t("poll.ui_builder.poll_result.closed"), value: closedPollResult + }, + { + name: I18n.t("poll.ui_builder.poll_result.staff"), + value: staffPollResult } ]; }, diff --git a/plugins/poll/assets/javascripts/widgets/discourse-poll.js.es6 b/plugins/poll/assets/javascripts/widgets/discourse-poll.js.es6 index 1c2954faf63..3b589e80280 100644 --- a/plugins/poll/assets/javascripts/widgets/discourse-poll.js.es6 +++ b/plugins/poll/assets/javascripts/widgets/discourse-poll.js.es6 @@ -402,7 +402,7 @@ createWidget("discourse-poll-info", { } } - if (!attrs.isClosed && !attrs.showResults && poll.get("public")) { + if (!attrs.isClosed && !attrs.showResults && poll.public && (poll.results !== "staff_only")) { contents.push(infoTextHtml(I18n.t("poll.public.title"))); } @@ -418,7 +418,9 @@ createWidget("discourse-poll-buttons", { const { poll, post } = attrs; const topicArchived = post.get("topic.archived"); const closed = attrs.isClosed; - const hideResultsDisabled = closed || topicArchived; + const staffOnly = poll.results === "staff_only"; + const isStaff = this.currentUser && this.currentUser.staff; + const hideResultsDisabled = !staffOnly && (closed || topicArchived); if (attrs.isMultiple && !hideResultsDisabled) { const castVotesDisabled = !attrs.canCastVotes; @@ -452,6 +454,8 @@ createWidget("discourse-poll-buttons", { contents.push(infoTextHtml(I18n.t("poll.results.vote.title"))); } else if (poll.get("results") === "on_close" && !closed) { contents.push(infoTextHtml(I18n.t("poll.results.closed.title"))); + } else if (poll.results === "staff_only" && !isStaff) { + contents.push(infoTextHtml(I18n.t("poll.results.staff.title"))); } else { contents.push( this.attach("button", { @@ -491,7 +495,7 @@ createWidget("discourse-poll-buttons", { if ( this.currentUser && (this.currentUser.get("id") === post.get("user_id") || - this.currentUser.get("staff")) && + isStaff) && !topicArchived ) { if (closed) { @@ -536,18 +540,21 @@ export default createWidget("discourse-poll", { defaultState(attrs) { const { post, poll } = attrs; + const staffOnly = attrs.poll.results === "staff_only"; const showResults = - post.get("topic.archived") || - this.isClosed() || - (poll.get("results") !== "on_close" && this.hasVoted()); + (post.get("topic.archived") && !staffOnly) || + (this.isClosed() && !staffOnly) || + (poll.results !== "on_close" && + this.hasVoted() && !staffOnly); return { loading: false, showResults }; }, html(attrs, state) { + const staffOnly = attrs.poll.results === "staff_only"; const showResults = - state.showResults || attrs.post.get("topic.archived") || this.isClosed(); + state.showResults || (attrs.post.get("topic.archived") && !staffOnly) || (this.isClosed() && !staffOnly); const newAttrs = jQuery.extend({}, attrs, { canCastVotes: this.canCastVotes(), @@ -722,6 +729,13 @@ export default createWidget("discourse-poll", { if (attrs.poll.get("results") !== "on_close") { state.showResults = true; } + if (attrs.poll.results === "staff_only") { + if (this.currentUser && this.currentUser.get("staff")) { + state.showResults = true; + } else { + state.showResults = false; + } + } }) .catch(error => { if (error) { diff --git a/plugins/poll/config/locales/client.en.yml b/plugins/poll/config/locales/client.en.yml index 154399cd596..50a8b47d9e9 100644 --- a/plugins/poll/config/locales/client.en.yml +++ b/plugins/poll/config/locales/client.en.yml @@ -35,6 +35,8 @@ en: title: "Results will be shown on vote." closed: title: "Results will be shown once closed." + staff: + title: "Results are only shown to staff members." multiple: help: @@ -96,6 +98,7 @@ en: always: Always visible vote: On vote closed: When closed + staff: Staff only poll_config: max: Max min: Min