FEATURE: Staff only poll results (#7984)

FEATURE: Staff only poll results (#7984)

  • FEATURE: Staff only poll results

These changes allow only staff to see the results of a poll.

Non-staff users will be shown a screen like this:

https://aws1.discourse-cdn.com/review/original/1X/1b8bd76013363860f2bc455049cf35e69ef44e0a.png

The “Votes are public” message has been removed from the info section, and the button to show the votes has been replaced with a message stating the results will only be shown to staff.

  • Update PR based on feedback

  • Update plugins/poll/app/models/poll.rb

make sure we return a boolean

Co-Authored-By: Régis Hanol regis@hanol.fr

diff --git a/plugins/poll/app/models/poll.rb b/plugins/poll/app/models/poll.rb
index e8ae694..1dd0d0b 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 0f85aed..916b73f 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 1c2954f..3b589e8 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 154399c..50a8b47 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 <strong>vote</strong>."
         closed:
           title: "Results will be shown once <strong>closed</strong>."
+        staff:
+          title: "Results are only shown to <strong>staff</strong> 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

GitHub sha: 69498a58