mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FEATURE: list category moderators on the about page (#7916)
https://meta.discourse.org/t/category-group-review-moderation/116478?u=osama
This commit is contained in:
parent
8a6ee09008
commit
13e74151a9
@ -16,6 +16,14 @@ export default Discourse.Route.extend({
|
|||||||
});
|
});
|
||||||
result.about.admins = activeAdmins;
|
result.about.admins = activeAdmins;
|
||||||
result.about.moderators = activeModerators;
|
result.about.moderators = activeModerators;
|
||||||
|
|
||||||
|
const { category_moderators: categoryModerators } = result.about;
|
||||||
|
if (categoryModerators && categoryModerators.length) {
|
||||||
|
categoryModerators.forEach((obj, index) => {
|
||||||
|
const category = this.site.categories.findBy("id", obj.category_id);
|
||||||
|
result.about.category_moderators[index].category = category;
|
||||||
|
});
|
||||||
|
}
|
||||||
return result.about;
|
return result.about;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -57,6 +57,19 @@
|
|||||||
connectorTagName='section'
|
connectorTagName='section'
|
||||||
args=(hash model=model)}}
|
args=(hash model=model)}}
|
||||||
|
|
||||||
|
{{#if model.category_moderators.length}}
|
||||||
|
{{#each model.category_moderators as |cm|}}
|
||||||
|
<section class='about category-moderators'>
|
||||||
|
<h3>{{category-link cm.category}}{{i18n "about.moderators"}}</h3>
|
||||||
|
<div class='users'>
|
||||||
|
{{#each cm.moderators as |m|}}
|
||||||
|
{{user-info user=m}}
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
<div class='clearfix'></div>
|
||||||
|
</section>
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
<section class='about stats'>
|
<section class='about stats'>
|
||||||
<h3>{{d-icon "far-chart-bar"}} {{i18n 'about.stats'}}</h3>
|
<h3>{{d-icon "far-chart-bar"}} {{i18n 'about.stats'}}</h3>
|
||||||
|
|
||||||
|
@ -4,9 +4,14 @@
|
|||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
.about-page & {
|
.about-page & {
|
||||||
max-width: unset;
|
max-width: unset;
|
||||||
section:not(.admins):not(.moderators) {
|
section:not(.admins):not(.moderators):not(.category-moderators) {
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
}
|
}
|
||||||
|
.about.category-moderators {
|
||||||
|
.badge-wrapper.bullet .badge-category {
|
||||||
|
color: $primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.mobile-view & {
|
.mobile-view & {
|
||||||
font-size: $font-0;
|
font-size: $font-0;
|
||||||
|
@ -11,7 +11,7 @@ class AboutController < ApplicationController
|
|||||||
def index
|
def index
|
||||||
return redirect_to path('/login') if SiteSetting.login_required? && current_user.nil?
|
return redirect_to path('/login') if SiteSetting.login_required? && current_user.nil?
|
||||||
|
|
||||||
@about = About.new
|
@about = About.new(current_user)
|
||||||
@title = "#{I18n.t("js.about.simple_title")} - #{SiteSetting.title}"
|
@title = "#{I18n.t("js.about.simple_title")} - #{SiteSetting.title}"
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class About
|
class About
|
||||||
|
class CategoryMods
|
||||||
|
include ActiveModel::Serialization
|
||||||
|
attr_reader :category_id, :moderators
|
||||||
|
|
||||||
|
def initialize(category_id, moderators)
|
||||||
|
@category_id = category_id
|
||||||
|
@moderators = moderators
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
include ActiveModel::Serialization
|
include ActiveModel::Serialization
|
||||||
include StatsCacheable
|
include StatsCacheable
|
||||||
|
|
||||||
@ -15,6 +25,10 @@ class About
|
|||||||
About.new.stats
|
About.new.stats
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def initialize(user = nil)
|
||||||
|
@user = user
|
||||||
|
end
|
||||||
|
|
||||||
def version
|
def version
|
||||||
Discourse::VERSION::STRING
|
Discourse::VERSION::STRING
|
||||||
end
|
end
|
||||||
@ -66,4 +80,24 @@ class About
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def category_moderators
|
||||||
|
category_ids = Guardian.new(@user).allowed_category_ids
|
||||||
|
return [] if category_ids.blank?
|
||||||
|
results = DB.query(<<~SQL, category_ids: category_ids)
|
||||||
|
SELECT c.id category_id, array_agg(gu.user_id) user_ids
|
||||||
|
FROM categories c
|
||||||
|
JOIN group_users gu
|
||||||
|
ON gu.group_id = reviewable_by_group_id
|
||||||
|
WHERE c.id IN (:category_ids)
|
||||||
|
GROUP BY c.id
|
||||||
|
SQL
|
||||||
|
moderators = {}
|
||||||
|
User.where(id: results.map(&:user_ids).flatten).each do |user|
|
||||||
|
moderators[user.id] = user
|
||||||
|
end
|
||||||
|
moderators
|
||||||
|
results.map do |row|
|
||||||
|
CategoryMods.new(row.category_id, row.user_ids.map { |id| moderators[id] })
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -6,8 +6,15 @@ class AboutSerializer < ApplicationSerializer
|
|||||||
attributes :title, :last_seen_at
|
attributes :title, :last_seen_at
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class AboutCategoryModsSerializer < ApplicationSerializer
|
||||||
|
attributes :category_id
|
||||||
|
|
||||||
|
has_many :moderators, serializer: UserAboutSerializer, embed: :objects
|
||||||
|
end
|
||||||
|
|
||||||
has_many :moderators, serializer: UserAboutSerializer, embed: :objects
|
has_many :moderators, serializer: UserAboutSerializer, embed: :objects
|
||||||
has_many :admins, serializer: UserAboutSerializer, embed: :objects
|
has_many :admins, serializer: UserAboutSerializer, embed: :objects
|
||||||
|
has_many :category_moderators, serializer: AboutCategoryModsSerializer, embed: :objects
|
||||||
|
|
||||||
attributes :stats,
|
attributes :stats,
|
||||||
:description,
|
:description,
|
||||||
|
@ -274,6 +274,7 @@ en:
|
|||||||
stats: "Site Statistics"
|
stats: "Site Statistics"
|
||||||
our_admins: "Our Admins"
|
our_admins: "Our Admins"
|
||||||
our_moderators: "Our Moderators"
|
our_moderators: "Our Moderators"
|
||||||
|
moderators: "Moderators"
|
||||||
stat:
|
stat:
|
||||||
all_time: "All Time"
|
all_time: "All Time"
|
||||||
last_7_days: "Last 7"
|
last_7_days: "Last 7"
|
||||||
|
@ -8,4 +8,46 @@ describe About do
|
|||||||
include_examples 'stats cachable'
|
include_examples 'stats cachable'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#category_moderators" do
|
||||||
|
let(:user) { Fabricate(:user) }
|
||||||
|
let(:public_cat_moderator) { Fabricate(:user) }
|
||||||
|
let(:private_cat_moderator) { Fabricate(:user) }
|
||||||
|
let(:common_moderator) { Fabricate(:user) }
|
||||||
|
|
||||||
|
let(:public_group) do
|
||||||
|
group = Fabricate(:public_group)
|
||||||
|
group.add(public_cat_moderator)
|
||||||
|
group.add(common_moderator)
|
||||||
|
group
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:private_group) do
|
||||||
|
group = Fabricate(:group)
|
||||||
|
group.add(private_cat_moderator)
|
||||||
|
group.add(common_moderator)
|
||||||
|
group
|
||||||
|
end
|
||||||
|
|
||||||
|
let!(:public_cat) { Fabricate(:category, reviewable_by_group: public_group) }
|
||||||
|
let!(:private_cat) { Fabricate(:private_category, group: private_group, reviewable_by_group: private_group) }
|
||||||
|
|
||||||
|
it "lists moderators of the category that the current user can see" do
|
||||||
|
results = About.new(private_cat_moderator).category_moderators
|
||||||
|
expect(results.map(&:category_id)).to contain_exactly(public_cat.id, private_cat.id)
|
||||||
|
expect(results.map(&:moderators).flatten.map(&:id).uniq).to contain_exactly(
|
||||||
|
public_cat_moderator.id,
|
||||||
|
common_moderator.id,
|
||||||
|
private_cat_moderator.id
|
||||||
|
)
|
||||||
|
|
||||||
|
[public_cat_moderator, user, nil].each do |u|
|
||||||
|
results = About.new(u).category_moderators
|
||||||
|
expect(results.map(&:category_id)).to contain_exactly(public_cat.id)
|
||||||
|
expect(results.map(&:moderators).flatten.map(&:id)).to contain_exactly(
|
||||||
|
public_cat_moderator.id,
|
||||||
|
common_moderator.id
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user