diff --git a/public/language/en-GB/admin/manage/admins-mods.json b/public/language/en-GB/admin/manage/admins-mods.json index e0f39ed5d4..f9bbc63632 100644 --- a/public/language/en-GB/admin/manage/admins-mods.json +++ b/public/language/en-GB/admin/manage/admins-mods.json @@ -1,8 +1,10 @@ { "administrators": "Administrators", "global-moderators": "Global Moderators", + "moderators": "Moderators", "no-global-moderators": "No Global Moderators", - "moderators-of-category": "%1 Moderators", + "no-sub-categories": "No subcategories", + "subcategories": "%1 subcategories", "no-moderators": "No Moderators", "add-administrator": "Add Administrator", "add-global-moderator": "Add Global Moderator", diff --git a/public/src/admin/manage/admins-mods.js b/public/src/admin/manage/admins-mods.js index d59cbba305..1f7ff012e2 100644 --- a/public/src/admin/manage/admins-mods.js +++ b/public/src/admin/manage/admins-mods.js @@ -78,6 +78,7 @@ define('admin/manage/admins-mods', [ categorySelector.init($('[component="category-selector"]'), { + parentCid: ajaxify.data.selectedCategory ? ajaxify.data.selectedCategory.cid : 0, onSelect: function (selectedCategory) { ajaxify.go('admin/manage/admins-mods' + (selectedCategory.cid ? '?cid=' + selectedCategory.cid : '')); }, diff --git a/src/controllers/admin/admins-mods.js b/src/controllers/admin/admins-mods.js index 286485e2b1..9d06044acd 100644 --- a/src/controllers/admin/admins-mods.js +++ b/src/controllers/admin/admins-mods.js @@ -6,36 +6,56 @@ const db = require('../../database'); const groups = require('../../groups'); const categories = require('../../categories'); const user = require('../../user'); +const meta = require('../../meta'); +const pagination = require('../../pagination'); +const categoriesController = require('./categories'); const AdminsMods = module.exports; -AdminsMods.get = async function (req, res, next) { - let cid = parseInt(req.query.cid, 10) || 0; - if (!cid) { - cid = (await db.getSortedSetRange('cid:0:children', 0, 0))[0]; - } - const selectedCategory = await categories.getCategoryData(cid); - if (!selectedCategory) { - return next(); - } - const [admins, globalMods, moderators] = await Promise.all([ +AdminsMods.get = async function (req, res) { + const rootCid = parseInt(req.query.cid, 10) || 0; + + const cidsCount = await db.sortedSetCard(`cid:${rootCid}:children`); + + const pageCount = Math.max(1, Math.ceil(cidsCount / meta.config.categoriesPerPage)); + const page = Math.min(parseInt(req.query.page, 10) || 1, pageCount); + const start = Math.max(0, (page - 1) * meta.config.categoriesPerPage); + const stop = start + meta.config.categoriesPerPage - 1; + + const cids = await db.getSortedSetRange(`cid:${rootCid}:children`, start, stop); + + const selectedCategory = rootCid ? await categories.getCategoryData(rootCid) : null; + const pageCategories = await categories.getCategoriesData(cids); + + const [admins, globalMods, moderators, crumbs] = await Promise.all([ groups.get('administrators', { uid: req.uid }), groups.get('Global Moderators', { uid: req.uid }), - getModeratorsOfCategories(selectedCategory), + getModeratorsOfCategories(pageCategories), + categoriesController.buildBreadCrumbs(selectedCategory, '/admin/manage/admins-mods'), ]); res.render('admin/manage/admins-mods', { admins: admins, globalMods: globalMods, - categoryMods: [moderators], + categoryMods: moderators, selectedCategory: selectedCategory, + pagination: pagination.create(page, pageCount, req.query), + breadcrumbs: crumbs, }); }; async function getModeratorsOfCategories(categoryData) { - const moderatorUids = await categories.getModeratorUids([categoryData.cid]); + const [moderatorUids, childrenCounts] = await Promise.all([ + categories.getModeratorUids(categoryData.map(c => c.cid)), + db.sortedSetsCard(categoryData.map(c => `cid:${c.cid}:children`)), + ]); + const uids = _.uniq(_.flatten(moderatorUids)); const moderatorData = await user.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture']); - categoryData.moderators = moderatorData; + const moderatorMap = _.zipObject(uids, moderatorData); + categoryData.forEach((c, index) => { + c.moderators = moderatorUids[index].map(uid => moderatorMap[uid]); + c.subCategoryCount = childrenCounts[index]; + }); return categoryData; } diff --git a/src/controllers/admin/categories.js b/src/controllers/admin/categories.js index e854f5898d..d901e65f0f 100644 --- a/src/controllers/admin/categories.js +++ b/src/controllers/admin/categories.js @@ -94,7 +94,7 @@ categoriesController.getAll = async function (req, res) { if (rootCid) { selectedCategory = await categories.getCategoryData(rootCid); } - const crumbs = await buildBreadcrumbs(req, selectedCategory); + const crumbs = await buildBreadcrumbs(selectedCategory, '/admin/manage/categories'); res.render('admin/manage/categories', { categoriesTree: tree, selectedCategory: selectedCategory, @@ -104,14 +104,14 @@ categoriesController.getAll = async function (req, res) { }); }; -async function buildBreadcrumbs(req, categoryData) { +async function buildBreadcrumbs(categoryData, url) { if (!categoryData) { return; } const breadcrumbs = [ { text: categoryData.name, - url: `${nconf.get('relative_path')}/admin/manage/categories?cid=${categoryData.cid}`, + url: `${nconf.get('relative_path')}${url}?cid=${categoryData.cid}`, cid: categoryData.cid, }, ]; @@ -119,16 +119,18 @@ async function buildBreadcrumbs(req, categoryData) { const crumbs = allCrumbs.filter(c => c.cid); crumbs.forEach((c) => { - c.url = `/admin/manage/categories?cid=${c.cid}`; + c.url = `${url}?cid=${c.cid}`; }); crumbs.unshift({ text: '[[admin/manage/categories:top-level]]', - url: '/admin/manage/categories', + url: url, }); return crumbs.concat(breadcrumbs); } +categoriesController.buildBreadCrumbs = buildBreadcrumbs; + categoriesController.getAnalytics = async function (req, res) { const [name, analyticsData] = await Promise.all([ categories.getCategoryField(req.params.category_id, 'name'), diff --git a/src/views/admin/manage/admins-mods.tpl b/src/views/admin/manage/admins-mods.tpl index cbe7198eae..cec7b0d22d 100644 --- a/src/views/admin/manage/admins-mods.tpl +++ b/src/views/admin/manage/admins-mods.tpl @@ -38,11 +38,19 @@
+

[[admin/manage/admins-mods:moderators]]

+ + + + {{{ if !categoryMods.length }}} +

[[admin/manage/admins-mods:no-sub-categories]]

+ {{{ end }}} + {{{ each categoryMods }}}
-

{{{ if categoryMods.icon }}} {{{ end }}}[[admin/manage/admins-mods:moderators-of-category, {categoryMods.name}]]{{{if categoryMods.disabled}}}[[admin/manage/admins-mods:disabled]]{{{end}}}

+

{{{ if categoryMods.icon }}} {{{ end }}}{categoryMods.name} {{{ if categoryMods.subCategoryCount }}}[[admin/manage/admins-mods:subcategories, {categoryMods.subCategoryCount}]]{{{ else }}}{{{ end }}}{{{if categoryMods.disabled}}}[[admin/manage/admins-mods:disabled]]{{{end}}}

{{{ each categoryMods.moderators }}}
@@ -63,4 +71,7 @@

{{{ end }}} +
+ +