FEATURE: Adds a pop up that shows a more detailed score for reviewables (#8035)

FEATURE: Adds a pop up that shows a more detailed score for reviewables (#8035)

If you click a (?) icon beside the reviewable status a pop up will appear with expanded informatio that explains how the reviewable got its score, and how it compares to system thresholds.

diff --git a/app/assets/javascripts/discourse/adapters/reviewable-explanation.js.es6 b/app/assets/javascripts/discourse/adapters/reviewable-explanation.js.es6
new file mode 100644
index 0000000..2ae3837
--- /dev/null
+++ b/app/assets/javascripts/discourse/adapters/reviewable-explanation.js.es6
@@ -0,0 +1,9 @@
+import RestAdapter from "discourse/adapters/rest";
+
+export default RestAdapter.extend({
+  jsonMode: true,
+
+  pathFor(store, type, id) {
+    return `/review/${id}/explain.json`;
+  }
+});
diff --git a/app/assets/javascripts/discourse/components/reviewable-item.js.es6 b/app/assets/javascripts/discourse/components/reviewable-item.js.es6
index d94128f..4507704 100644
--- a/app/assets/javascripts/discourse/components/reviewable-item.js.es6
+++ b/app/assets/javascripts/discourse/components/reviewable-item.js.es6
@@ -3,6 +3,7 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
 import computed from "ember-addons/ember-computed-decorators";
 import Category from "discourse/models/category";
 import optionalService from "discourse/lib/optional-service";
+import showModal from "discourse/lib/show-modal";
 
 let _components = {};
 
@@ -140,6 +141,13 @@ export default Ember.Component.extend({
   },
 
   actions: {
+    explainReviewable(reviewable) {
+      showModal("explain-reviewable", {
+        title: "review.explain.title",
+        model: reviewable
+      });
+    },
+
     edit() {
       this.set("editing", true);
       this._updates = { payload: {} };
diff --git a/app/assets/javascripts/discourse/controllers/explain-reviewable.js.es6 b/app/assets/javascripts/discourse/controllers/explain-reviewable.js.es6
new file mode 100644
index 0000000..49e5722
--- /dev/null
+++ b/app/assets/javascripts/discourse/controllers/explain-reviewable.js.es6
@@ -0,0 +1,15 @@
+import ModalFunctionality from "discourse/mixins/modal-functionality";
+
+export default Ember.Controller.extend(ModalFunctionality, {
+  loading: null,
+  reviewableExplanation: null,
+
+  onShow() {
+    this.setProperties({ loading: true, reviewableExplanation: null });
+
+    this.store
+      .find("reviewable-explanation", this.model.id)
+      .then(result => this.set("reviewableExplanation", result))
+      .finally(() => this.set("loading", false));
+  }
+});
diff --git a/app/assets/javascripts/discourse/helpers/float.js.es6 b/app/assets/javascripts/discourse/helpers/float.js.es6
new file mode 100644
index 0000000..4d0fa56
--- /dev/null
+++ b/app/assets/javascripts/discourse/helpers/float.js.es6
@@ -0,0 +1,5 @@
+import { registerUnbound } from "discourse-common/lib/helpers";
+
+registerUnbound("float", function(n) {
+  return parseFloat(n).toFixed(1);
+});
diff --git a/app/assets/javascripts/discourse/templates/components/reviewable-item.hbs b/app/assets/javascripts/discourse/templates/components/reviewable-item.hbs
index 7df7ee1..abd106a 100644
--- a/app/assets/javascripts/discourse/templates/components/reviewable-item.hbs
+++ b/app/assets/javascripts/discourse/templates/components/reviewable-item.hbs
@@ -10,6 +10,9 @@
     <span class='status'>
       {{reviewable-status reviewable.status}}
     </span>
+    <a {{action "explainReviewable" reviewable}} class='explain' title={{i18n "review.explain.why"}}>
+      {{d-icon "question-circle"}}
+    </a>
   </div>
 
   <div class='reviewable-contents'>
diff --git a/app/assets/javascripts/discourse/templates/components/score-value.hbs b/app/assets/javascripts/discourse/templates/components/score-value.hbs
new file mode 100644
index 0000000..e78eeb3
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/components/score-value.hbs
@@ -0,0 +1,11 @@
+{{#if value}}
+  <span class='score-value'>
+    <span class='score-number'>{{float value}}</span>
+    {{#if label}}
+      <span class='score-value-type' title={{i18n (concat "review.explain." label ".title")}}>
+        {{i18n (concat "review.explain." label ".name")}}
+      </span>
+    {{/if}}
+  </span>
+  <span class='op'>+</span>
+{{/if}}
diff --git a/app/assets/javascripts/discourse/templates/modal/explain-reviewable.hbs b/app/assets/javascripts/discourse/templates/modal/explain-reviewable.hbs
new file mode 100644
index 0000000..76f955c
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/modal/explain-reviewable.hbs
@@ -0,0 +1,47 @@
+{{#d-modal-body class="explain-reviewable"}}
+  {{#conditional-loading-spinner condition=loading}}
+    <table>
+      <tr>
+        <th>{{i18n "review.explain.formula"}}</th>
+        <th>{{i18n "review.explain.subtotal"}}</th>
+      </tr>
+    {{#each reviewableExplanation.scores as |s|}}
+      <tr>
+        <td>
+          {{score-value value="1.0" tagName=""}}
+          {{score-value value=s.type_bonus label="type_bonus" tagName=""}}
+          {{score-value value=s.take_action_bonus label="take_action_bonus" tagName=""}}
+          {{score-value value=s.trust_level_bonus label="trust_level_bonus" tagName=""}}
+          {{score-value value=s.user_accuracy_bonus label="user_accuracy_bonus" tagName=""}}
+        </td>
+        <td class='sum'>{{float s.score}}</td>
+      </tr>
+    {{/each}}
+      <tr class="total">
+        <td>{{i18n "review.explain.total"}}</td>
+        <td class='sum'>{{float reviewableExplanation.total_score}}</td>
+      </tr>
+    </table>
+
+    <table class='thresholds'>
+      <tr>
+        <td>{{i18n "review.explain.min_score_visibility"}}</td>
+        <td class='sum'>
+          {{float reviewableExplanation.min_score_visibility}}
+        </td>
+      </tr>
+      <tr>
+        <td>{{i18n "review.explain.score_to_hide"}}</td>
+        <td class='sum'>
+          {{float reviewableExplanation.hide_post_score}}
+        </td>
+      </tr>
+    </table>
+
+  {{/conditional-loading-spinner}}
+
+{{/d-modal-body}}
+
+<div class="modal-footer">
+  {{d-button action=(route-action "closeModal") label="close"}}
+</div>
diff --git a/app/assets/stylesheets/common/base/explain-reviewable.scss b/app/assets/stylesheets/common/base/explain-reviewable.scss
new file mode 100644
index 0000000..ec7026e
--- /dev/null
+++ b/app/assets/stylesheets/common/base/explain-reviewable.scss
@@ -0,0 +1,37 @@
+.explain-reviewable {
+  min-width: 500px;
+
+  .thresholds {
+    margin-top: 1em;
+  }
+  table {
+    width: 100%;
+  }
+  table td {
+    padding: 0.5em;
+  }
+  td.sum {
+    text-align: right;
+  }
+  td.sum.total {
+    font-weight: bold;
+  }
+  tr.total {
+    td {
+      background-color: $primary-low;
+      font-weight: bold;
+    }
+  }
+
+  .op {
+    font-weight: bold;
+  }
+
+  .score-value-type {
+    color: $primary-medium;
+  }
+
+  .op:last-of-type {
+    display: none;
+  }
+}
diff --git a/app/assets/stylesheets/common/base/reviewables.scss b/app/assets/stylesheets/common/base/reviewables.scss
index 31071ac..0228f0c 100644
--- a/app/assets/stylesheets/common/base/reviewables.scss
+++ b/app/assets/stylesheets/common/base/reviewables.scss
@@ -20,6 +20,9 @@
       }
     }
   }
+  .explain {
+    margin-left: 0.5em;
+  }
 
   .nav-pills {
     margin-bottom: 1em;
diff --git a/app/controllers/reviewables_controller.rb b/app/controllers/reviewables_controller.rb
index d2bed1f..dffe6cd 100644
--- a/app/controllers/reviewables_controller.rb
+++ b/app/controllers/reviewables_controller.rb
@@ -1,4 +1,5 @@
 # frozen_string_literal: true
+require_dependency 'reviewable_explanation_serializer'
 
 class ReviewablesController < ApplicationController
   requires_login
@@ -102,6 +103,17 @@ class ReviewablesController < ApplicationController
     )
   end
 
+  def explain
+    reviewable = find_reviewable
+
+    render_serialized(
+      { reviewable: reviewable, scores: reviewable.explain_score },
+      ReviewableExplanationSerializer,
+      rest_serializer: true,
+      root: 'reviewable_explanation'
+    )
+  end
+
   def show
     reviewable = find_reviewable
 
diff --git a/app/models/reviewable.rb b/app/models/reviewable.rb
index b0142d1..dd7be14 100644
--- a/app/models/reviewable.rb
+++ b/app/models/reviewable.rb

[... diff too long, it was truncated ...]

GitHub sha: bde0ef86

1 Like

Can I get an approval here @ZogStriP ? :stuck_out_tongue:

1 Like