FEATURE: Add a messages view for all official warnings of a user (#12659)

FEATURE: Add a messages view for all official warnings of a user (#12659)

Moderators are allowed to see the warnings list, with an access warning.

Why aren't warnings easily accessible like suspensions are? - community - Discourse Meta

diff --git a/app/assets/javascripts/discourse/app/controllers/user-private-messages.js b/app/assets/javascripts/discourse/app/controllers/user-private-messages.js
index 222b819..3cc26e8 100644
--- a/app/assets/javascripts/discourse/app/controllers/user-private-messages.js
+++ b/app/assets/javascripts/discourse/app/controllers/user-private-messages.js
@@ -5,6 +5,7 @@ import I18n from "I18n";
 import Topic from "discourse/models/topic";
 import bootbox from "bootbox";
 import discourseComputed from "discourse-common/utils/decorators";
+import { VIEW_NAME_WARNINGS } from "discourse/routes/user-private-messages-warnings";
 
 export default Controller.extend({
   userTopicsList: controller("user-topics-list"),
@@ -27,6 +28,11 @@ export default Controller.extend({
     return bulkSelectEnabled && selected && selected.length > 0;
   },
 
+  @discourseComputed("viewingSelf", "pmView", "currentUser.admin")
+  showWarningsWarning(viewingSelf, pmView, isAdmin) {
+    return pmView === VIEW_NAME_WARNINGS && !viewingSelf && !isAdmin;
+  },
+
   bulkOperation(operation) {
     const selected = this.selected;
     let params = { type: operation };
diff --git a/app/assets/javascripts/discourse/app/routes/app-route-map.js b/app/assets/javascripts/discourse/app/routes/app-route-map.js
index 2bce5af..6ccf9c9 100644
--- a/app/assets/javascripts/discourse/app/routes/app-route-map.js
+++ b/app/assets/javascripts/discourse/app/routes/app-route-map.js
@@ -149,6 +149,7 @@ export default function () {
         function () {
           this.route("sent");
           this.route("archive");
+          this.route("warnings");
           this.route("group", { path: "group/:name" });
           this.route("groupArchive", { path: "group/:name/archive" });
           this.route("tags");
diff --git a/app/assets/javascripts/discourse/app/routes/user-private-messages-warnings.js b/app/assets/javascripts/discourse/app/routes/user-private-messages-warnings.js
new file mode 100644
index 0000000..a53e9b1
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/routes/user-private-messages-warnings.js
@@ -0,0 +1,9 @@
+import createPMRoute from "discourse/routes/build-private-messages-route";
+
+export const VIEW_NAME_WARNINGS = "warnings";
+
+export default createPMRoute(
+  VIEW_NAME_WARNINGS,
+  "private-messages-warnings",
+  null /* no message bus notifications */
+);
diff --git a/app/assets/javascripts/discourse/app/templates/user.hbs b/app/assets/javascripts/discourse/app/templates/user.hbs
index 0b6f752..1635bde 100644
--- a/app/assets/javascripts/discourse/app/templates/user.hbs
+++ b/app/assets/javascripts/discourse/app/templates/user.hbs
@@ -38,7 +38,11 @@
               </div>
             {{/if}}
             {{#if model.warnings_received_count}}
-              <div><span class="warnings-received">{{model.warnings_received_count}}</span>{{i18n "user.staff_counters.warnings_received"}}</div>
+              <div>
+                {{#link-to "userPrivateMessages.warnings" model}}
+                  <span class="warnings-received">{{model.warnings_received_count}}</span>{{i18n "user.staff_counters.warnings_received"}}
+                {{/link-to}}
+              </div>
             {{/if}}
           </div>
         {{/if}}
diff --git a/app/assets/javascripts/discourse/app/templates/user/messages.hbs b/app/assets/javascripts/discourse/app/templates/user/messages.hbs
index 004b58b..23eaded 100644
--- a/app/assets/javascripts/discourse/app/templates/user/messages.hbs
+++ b/app/assets/javascripts/discourse/app/templates/user/messages.hbs
@@ -87,5 +87,8 @@
       }}
     {{/if}}
   </div>
+  {{#if showWarningsWarning}}
+    <div class="alert alert-info">{{html-safe (i18n "admin.user.warnings_list_warning")}}</div>
+  {{/if}}
   {{outlet}}
 </section>
diff --git a/app/assets/javascripts/discourse/tests/acceptance/user-test.js b/app/assets/javascripts/discourse/tests/acceptance/user-test.js
index 7c4137a..371c8be 100644
--- a/app/assets/javascripts/discourse/tests/acceptance/user-test.js
+++ b/app/assets/javascripts/discourse/tests/acceptance/user-test.js
@@ -121,3 +121,18 @@ acceptance(
     });
   }
 );
+
+acceptance("User Routes - Moderator viewing warnings", function (needs) {
+  needs.user({
+    username: "notEviltrout",
+    moderator: true,
+    staff: true,
+    admin: false,
+  });
+
+  test("Messages - Warnings", async function (assert) {
+    await visit("/u/eviltrout/messages/warnings");
+    assert.ok($("body.user-messages-page").length, "has the body class");
+    assert.ok($("div.alert-info").length, "has the permissions alert");
+  });
+});
diff --git a/app/assets/javascripts/discourse/tests/helpers/create-pretender.js b/app/assets/javascripts/discourse/tests/helpers/create-pretender.js
index 4e2b1ad..2b843d6 100644
--- a/app/assets/javascripts/discourse/tests/helpers/create-pretender.js
+++ b/app/assets/javascripts/discourse/tests/helpers/create-pretender.js
@@ -210,6 +210,10 @@ export function applyDefaultHandlers(pretender) {
     return response(fixturesByUrl["/topics/private-messages/eviltrout.json"]);
   });
 
+  pretender.get("/topics/private-messages-warnings/eviltrout.json", () => {
+    return response(fixturesByUrl["/topics/private-messages/eviltrout.json"]);
+  });
+
   pretender.get("/topics/feature_stats.json", () => {
     return response({
       pinned_in_category_count: 0,
diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb
index f9f41f3..ecad047 100644
--- a/app/controllers/list_controller.rb
+++ b/app/controllers/list_controller.rb
@@ -168,7 +168,12 @@ class ListController < ApplicationController
 
   def message_route(action)
     target_user = fetch_user_from_params({ include_inactive: current_user.try(:staff?) }, [:user_stat, :user_option])
-    guardian.ensure_can_see_private_messages!(target_user.id)
+    case action
+    when :private_messages_warnings
+      guardian.ensure_can_see_warnings!(target_user)
+    else
+      guardian.ensure_can_see_private_messages!(target_user.id)
+    end
     list_opts = build_topic_list_options
     list = generate_list_for(action.to_s, target_user, list_opts)
     url_prefix = "topics"
@@ -185,6 +190,7 @@ class ListController < ApplicationController
     private_messages_group
     private_messages_group_archive
     private_messages_tag
+    private_messages_warnings
   }.each do |action|
     generate_message_route(action)
   end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 57ef0b2..6fc103c 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1177,6 +1177,7 @@ en:
         failed_to_move: "Failed to move selected messages (perhaps your network is down)"
         select_all: "Select All"
         tags: "Tags"
+        warnings: "Official Warnings"
 
       preferences_nav:
         account: "Account"
@@ -4912,6 +4913,8 @@ en:
         flags_given_count: Flags Given
         flags_received_count: Flags Received
         warnings_received_count: Warnings Received
+        warnings_list_warning: |
+          As a moderator, you may not be able to view all of these topics. If necessary, ask an admin or the issuing moderator to give <b>@moderators</b> access to the message.
         flags_given_received_count: "Flags Given / Received"
         approve: "Approve"
         approved_by: "approved by"
diff --git a/config/routes.rb b/config/routes.rb
index 6946889..ee1b264 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -762,6 +762,7 @@ Discourse::Application.routes.draw do
       get "private-messages-archive/:username" => "list#private_messages_archive", as: "topics_private_messages_archive", defaults: { format: :json }
       get "private-messages-unread/:username" => "list#private_messages_unread", as: "topics_private_messages_unread", defaults: { format: :json }
       get "private-messages-tags/:username/:tag_id.json" => "list#private_messages_tag", as: "topics_private_messages_tag", defaults: { format: :json }

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

GitHub sha: c780ae9d25f416f9134cbeab29d951ddc47d50ac

This commit appears in #12659 which was approved by eviltrout. It was merged by riking.