mirror of
https://github.com/discourse/discourse.git
synced 2025-02-16 18:24:52 -06:00
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. https://meta.discourse.org/t/why-arent-warnings-easily-accessible-like-suspensions-are/164043
This commit is contained in:
parent
7d8483f698
commit
c780ae9d25
@ -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 };
|
||||
|
@ -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");
|
||||
|
@ -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 */
|
||||
);
|
@ -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}}
|
||||
|
@ -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>
|
||||
|
@ -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");
|
||||
});
|
||||
});
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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 }
|
||||
get "private-messages-warnings/:username" => "list#private_messages_warnings", as: "topics_private_messages_warnings", defaults: { format: :json }
|
||||
get "groups/:group_name" => "list#group_topics", as: "group_topics", group_name: RouteFormat.username
|
||||
|
||||
scope "/private-messages-group/:username", group_name: RouteFormat.username do
|
||||
|
@ -84,6 +84,10 @@ module UserGuardian
|
||||
can_merge_user?(source_user) && !target_user.nil?
|
||||
end
|
||||
|
||||
def can_see_warnings?(user)
|
||||
user && (is_me?(user) || is_staff?)
|
||||
end
|
||||
|
||||
def can_reset_bounce_score?(user)
|
||||
user && is_staff?
|
||||
end
|
||||
|
@ -365,6 +365,14 @@ class TopicQuery
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_private_messages_warnings(user)
|
||||
list = private_messages_for(user, :user)
|
||||
list = list.where('topics.subtype = ?', TopicSubtype.moderator_warning)
|
||||
# Exclude official warnings that the user created, instead of received
|
||||
list = list.where('topics.user_id <> ?', user.id)
|
||||
create_list(:private_messages, {}, list)
|
||||
end
|
||||
|
||||
def list_category_topic_ids(category)
|
||||
query = default_results(category: category.id)
|
||||
pinned_ids = query.where('topics.pinned_at IS NOT NULL AND topics.category_id = ?', category.id).limit(nil).order('pinned_at DESC').pluck(:id)
|
||||
|
@ -703,6 +703,58 @@ RSpec.describe ListController do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#private_messages_warnings" do
|
||||
let(:target_user) { Fabricate(:user) }
|
||||
let(:admin) { Fabricate(:admin) }
|
||||
let(:moderator1) { Fabricate(:moderator) }
|
||||
let(:moderator2) { Fabricate(:moderator) }
|
||||
|
||||
let(:create_args) do
|
||||
{ title: 'you need a warning buddy!',
|
||||
raw: "you did something bad and I'm telling you about it!",
|
||||
is_warning: true,
|
||||
target_usernames: target_user.username,
|
||||
archetype: Archetype.private_message }
|
||||
end
|
||||
|
||||
let(:warning_post) do
|
||||
creator = PostCreator.new(moderator1, create_args)
|
||||
creator.create
|
||||
end
|
||||
let(:warning_topic) { warning_post.topic }
|
||||
|
||||
before do
|
||||
warning_topic
|
||||
end
|
||||
|
||||
it "returns 403 error for unrelated users" do
|
||||
sign_in(Fabricate(:user))
|
||||
get "/topics/private-messages-warnings/#{target_user.username}.json"
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "shows the warning to moderators and admins" do
|
||||
[moderator1, moderator2, admin].each do |viewer|
|
||||
sign_in(viewer)
|
||||
get "/topics/private-messages-warnings/#{target_user.username}.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["topic_list"]["topics"].size).to eq(1)
|
||||
expect(json["topic_list"]["topics"][0]["id"]).to eq(warning_topic.id)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not show the warning as applying to the authoring moderator" do
|
||||
sign_in(admin)
|
||||
get "/topics/private-messages-warnings/#{moderator1.username}.json"
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
json = response.parsed_body
|
||||
expect(json["topic_list"]["topics"].size).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'read' do
|
||||
it 'raises an error when not logged in' do
|
||||
get "/read"
|
||||
|
Loading…
Reference in New Issue
Block a user