mirror of
https://github.com/discourse/discourse.git
synced 2025-05-24 03:36:18 +08:00
Add a page in admin to view trust level 3 requirements for a user. Only shows for users who are currently at trust level 2.
This commit is contained in:
@ -6,7 +6,7 @@
|
|||||||
@namespace Discourse
|
@namespace Discourse
|
||||||
@module Discourse
|
@module Discourse
|
||||||
**/
|
**/
|
||||||
Discourse.AdminUserController = Discourse.ObjectController.extend({
|
Discourse.AdminUserIndexController = Discourse.ObjectController.extend({
|
||||||
editingTitle: false,
|
editingTitle: false,
|
||||||
|
|
||||||
showApproval: function() {
|
showApproval: function() {
|
||||||
|
@ -42,7 +42,9 @@ Discourse.Route.buildRoutes(function() {
|
|||||||
this.route('groups', {path: '/groups'});
|
this.route('groups', {path: '/groups'});
|
||||||
|
|
||||||
this.resource('adminUsers', { path: '/users' }, function() {
|
this.resource('adminUsers', { path: '/users' }, function() {
|
||||||
this.resource('adminUser', { path: '/:username' });
|
this.resource('adminUser', { path: '/:username' }, function() {
|
||||||
|
this.route('leaderRequirements', { path: '/leader_requirements' });
|
||||||
|
});
|
||||||
this.resource('adminUsersList', { path: '/list' }, function() {
|
this.resource('adminUsersList', { path: '/list' }, function() {
|
||||||
_.each(['active', 'new', 'pending', 'admins', 'moderators', 'blocked', 'suspended',
|
_.each(['active', 'new', 'pending', 'admins', 'moderators', 'blocked', 'suspended',
|
||||||
'newuser', 'basic', 'regular', 'leaders', 'elders'], function(x) {
|
'newuser', 'basic', 'regular', 'leaders', 'elders'], function(x) {
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
Shows all the requirements for being at trust level 3 and if the
|
||||||
|
given user is meeting them.
|
||||||
|
|
||||||
|
@class AdminUserLeaderRequirementsRoute
|
||||||
|
@extends Discourse.Route
|
||||||
|
@namespace Discourse
|
||||||
|
@module Discourse
|
||||||
|
**/
|
||||||
|
Discourse.AdminUserLeaderRequirementsRoute = Discourse.Route.extend({
|
||||||
|
model: function() {
|
||||||
|
return this.controllerFor('adminUser').get('model');
|
||||||
|
}
|
||||||
|
});
|
@ -38,3 +38,9 @@ Discourse.AdminUserRoute = Discourse.Route.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Discourse.AdminUserIndexRoute = Discourse.Route.extend({
|
||||||
|
setupController: function(c) {
|
||||||
|
c.set('model', this.controllerFor('adminUser').get('model'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
@ -189,12 +189,16 @@
|
|||||||
{{combobox content=trustLevels value=trust_level nameProperty="detailedName"}}
|
{{combobox content=trustLevels value=trust_level nameProperty="detailedName"}}
|
||||||
</div>
|
</div>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{#if dirty}}
|
{{#if leader_requirements}}
|
||||||
<div>
|
{{#link-to 'adminUser.leaderRequirements' this class="btn"}}{{i18n admin.user.trust_level_3_requirements}}{{/link-to}}
|
||||||
<button class='btn ok' {{action saveTrustLevel target="content"}}><i class='fa fa-check'></i></button>
|
{{/if}}
|
||||||
<button class='btn cancel' {{action restoreTrustLevel target="content"}}><i class='fa fa-times'></i></button>
|
|
||||||
</div>
|
{{#if dirty}}
|
||||||
{{/if}}
|
<div>
|
||||||
|
<button class='btn ok' {{action saveTrustLevel target="content"}}><i class='fa fa-check'></i></button>
|
||||||
|
<button class='btn cancel' {{action restoreTrustLevel target="content"}}><i class='fa fa-times'></i></button>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
<div class='admin-controls'>
|
||||||
|
<div class='span15'>
|
||||||
|
<ul class="nav nav-pills">
|
||||||
|
<li>{{#link-to 'adminUser' this}}{{i18n go_back}}{{/link-to}}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="admin-container">
|
||||||
|
<h2>{{username}} - {{i18n admin.user.tl3_requirements.title}}</h2>
|
||||||
|
<br/>
|
||||||
|
<p>{{i18n admin.user.tl3_requirements.table_title}}</p>
|
||||||
|
|
||||||
|
{{#with leader_requirements}}
|
||||||
|
<table class="table" style="width: 50%;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>{{i18n admin.user.tl3_requirements.visits}}</th>
|
||||||
|
<td>
|
||||||
|
<strong>{{days_visited_percent}}%</strong> ({{days_visited}} / {{time_period}} {{i18n admin.user.tl3_requirements.days}})
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{i18n admin.user.tl3_requirements.topics_with_replies}}</th>
|
||||||
|
<td>
|
||||||
|
{{num_topics_with_replies}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{i18n admin.user.tl3_requirements.topics_replied_to}}</th>
|
||||||
|
<td>
|
||||||
|
{{num_topics_replied_to}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{i18n admin.user.tl3_requirements.quality_content}}</th>
|
||||||
|
<td style="color: #ccc;">
|
||||||
|
TODO
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{i18n admin.user.tl3_requirements.reading}}</th>
|
||||||
|
<td style="color: #ccc;">
|
||||||
|
TODO
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{i18n admin.user.tl3_requirements.site_promotion}}</th>
|
||||||
|
<td style="color: #ccc;">
|
||||||
|
TODO
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>{{i18n admin.user.tl3_requirements.flagged_posts}}</th>
|
||||||
|
<td>
|
||||||
|
{{num_flagged_posts}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{/with}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
34
app/models/leader_requirements.rb
Normal file
34
app/models/leader_requirements.rb
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# This class performs calculations to determine if a user qualifies for
|
||||||
|
# the Leader (3) trust level.
|
||||||
|
class LeaderRequirements
|
||||||
|
|
||||||
|
include ActiveModel::Serialization
|
||||||
|
|
||||||
|
attr_accessor :days_visited, :time_period, :num_topics_with_replies, :num_topics_replied_to,
|
||||||
|
:num_flagged_posts
|
||||||
|
|
||||||
|
def initialize(user)
|
||||||
|
@user = user
|
||||||
|
end
|
||||||
|
|
||||||
|
def time_period
|
||||||
|
100 # days
|
||||||
|
end
|
||||||
|
|
||||||
|
def days_visited
|
||||||
|
# This is naive. The user may have visited the site, but not read any posts.
|
||||||
|
@user.user_visits.where("visited_at >= ?", time_period.days.ago).count
|
||||||
|
end
|
||||||
|
|
||||||
|
def num_topics_with_replies
|
||||||
|
@user.topics.where('posts_count > 1 AND participant_count > 1 AND created_at > ?', time_period.days.ago).count
|
||||||
|
end
|
||||||
|
|
||||||
|
def num_topics_replied_to
|
||||||
|
@user.posts.select('distinct topic_id').where('created_at > ? AND post_number > 1', time_period.days.ago).count
|
||||||
|
end
|
||||||
|
|
||||||
|
def num_flagged_posts
|
||||||
|
@user.posts.where('created_at > ? AND (off_topic_count > 0 OR spam_count > 0 OR illegal_count > 0 OR inappropriate_count > 0 OR notify_moderators_count > 0)', time_period.days.ago).count
|
||||||
|
end
|
||||||
|
end
|
@ -527,6 +527,10 @@ class User < ActiveRecord::Base
|
|||||||
last_sent_email_address || email
|
last_sent_email_address || email
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def leader_requirements
|
||||||
|
@lq ||= LeaderRequirements.new(self)
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def cook
|
def cook
|
||||||
|
@ -19,6 +19,7 @@ class AdminDetailedUserSerializer < AdminUserSerializer
|
|||||||
has_one :approved_by, serializer: BasicUserSerializer, embed: :objects
|
has_one :approved_by, serializer: BasicUserSerializer, embed: :objects
|
||||||
has_one :api_key, serializer: ApiKeySerializer, embed: :objects
|
has_one :api_key, serializer: ApiKeySerializer, embed: :objects
|
||||||
has_one :suspended_by, serializer: BasicUserSerializer, embed: :objects
|
has_one :suspended_by, serializer: BasicUserSerializer, embed: :objects
|
||||||
|
has_one :leader_requirements, serializer: LeaderRequirementsSerializer, embed: :objects
|
||||||
|
|
||||||
def can_revoke_admin
|
def can_revoke_admin
|
||||||
scope.can_revoke_admin?(object)
|
scope.can_revoke_admin?(object)
|
||||||
@ -60,4 +61,12 @@ class AdminDetailedUserSerializer < AdminUserSerializer
|
|||||||
object.suspend_record.try(:acting_user)
|
object.suspend_record.try(:acting_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def leader_requirements
|
||||||
|
object.leader_requirements
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_leader_requirements?
|
||||||
|
object.trust_level == TrustLevel.levels[:regular]
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
8
app/serializers/leader_requirements_serializer.rb
Normal file
8
app/serializers/leader_requirements_serializer.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
class LeaderRequirementsSerializer < ApplicationSerializer
|
||||||
|
attributes :time_period, :days_visited, :days_visited_percent,
|
||||||
|
:num_topics_with_replies, :num_topics_replied_to, :num_flagged_posts
|
||||||
|
|
||||||
|
def days_visited_percent
|
||||||
|
(days_visited * 100) / time_period
|
||||||
|
end
|
||||||
|
end
|
@ -1486,6 +1486,18 @@ en:
|
|||||||
block_explanation: "A blocked user can't post or start topics."
|
block_explanation: "A blocked user can't post or start topics."
|
||||||
trust_level_change_failed: "There was a problem changing the user's trust level."
|
trust_level_change_failed: "There was a problem changing the user's trust level."
|
||||||
suspend_modal_title: "Suspend User"
|
suspend_modal_title: "Suspend User"
|
||||||
|
trust_level_3_requirements: "Trust Level 3 Requirements"
|
||||||
|
tl3_requirements:
|
||||||
|
title: "Requirements for Trust Level 3"
|
||||||
|
table_title: "In the last 100 days:"
|
||||||
|
visits: "Visits"
|
||||||
|
days: "days"
|
||||||
|
topics_with_replies: "Topics with Replies"
|
||||||
|
topics_replied_to: "Topics Replied To"
|
||||||
|
quality_content: "Quality Content"
|
||||||
|
reading: "Reading"
|
||||||
|
site_promotion: "Site Promotion"
|
||||||
|
flagged_posts: "Flagged Posts"
|
||||||
|
|
||||||
site_content:
|
site_content:
|
||||||
none: "Choose a type of content to begin editing."
|
none: "Choose a type of content to begin editing."
|
||||||
|
Reference in New Issue
Block a user