mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
feat: wip admin/users
This commit is contained in:
@@ -427,6 +427,8 @@ define('admin/manage/users', [
|
||||
handleUserCreate();
|
||||
|
||||
handleInvite();
|
||||
|
||||
handleSort();
|
||||
};
|
||||
|
||||
function loadSearchPage(query) {
|
||||
@@ -479,6 +481,24 @@ define('admin/manage/users', [
|
||||
});
|
||||
}
|
||||
|
||||
function handleSort() {
|
||||
$('.users-table thead th').on('click', function () {
|
||||
var $this = $(this);
|
||||
var sortBy = $this.attr('data-sort');
|
||||
if (!sortBy) {
|
||||
return;
|
||||
}
|
||||
var params = utils.params();
|
||||
params.sortBy = sortBy;
|
||||
if (ajaxify.data.sortBy === sortBy) {
|
||||
params.sortDirection = ajaxify.data.reverse ? 'asc' : 'desc';
|
||||
} else {
|
||||
params.sortDirection = 'desc';
|
||||
}
|
||||
var qs = decodeURIComponent($.param(params));
|
||||
ajaxify.go('admin/manage/users?' + qs);
|
||||
});
|
||||
}
|
||||
|
||||
return Users;
|
||||
});
|
||||
|
||||
@@ -13,8 +13,107 @@ const utils = require('../../utils');
|
||||
|
||||
const usersController = module.exports;
|
||||
|
||||
const userFields = ['uid', 'username', 'userslug', 'email', 'postcount', 'joindate', 'banned',
|
||||
'reputation', 'picture', 'flags', 'lastonline', 'email:confirmed'];
|
||||
const userFields = [
|
||||
'uid', 'username', 'userslug', 'email', 'postcount', 'joindate', 'banned',
|
||||
'reputation', 'picture', 'flags', 'lastonline', 'email:confirmed',
|
||||
];
|
||||
|
||||
usersController.index = async function (req, res) {
|
||||
if (req.query.query) {
|
||||
await usersController.search(req, res);
|
||||
} else {
|
||||
await newGet(req, res);
|
||||
}
|
||||
};
|
||||
|
||||
async function newGet(req, res) {
|
||||
const sortDirection = req.query.sortDirection || 'desc';
|
||||
const reverse = sortDirection === 'desc';
|
||||
|
||||
const page = parseInt(req.query.page, 10) || 1;
|
||||
let resultsPerPage = parseInt(req.query.resultsPerPage, 10) || 50;
|
||||
if (![50, 100, 250, 500].includes(resultsPerPage)) {
|
||||
resultsPerPage = 50;
|
||||
}
|
||||
const sortBy = validator.escape(req.query.sortBy || 'joindate');
|
||||
const filterBy = Array.isArray(req.query.filter) ? req.query.filter : [req.query.filter];
|
||||
const start = Math.max(0, page - 1) * resultsPerPage;
|
||||
const stop = start + resultsPerPage - 1;
|
||||
|
||||
function buildSet() {
|
||||
const sortToSet = {
|
||||
postcount: 'users:postcount',
|
||||
reputation: 'users:reputation',
|
||||
joindate: 'users:joindate',
|
||||
online: 'users:online',
|
||||
flags: 'users:flags',
|
||||
};
|
||||
|
||||
const set = [sortToSet[sortBy] || 'users:joindate'];
|
||||
if (filterBy.includes('notvalidated')) {
|
||||
set.push('users:notvalidated');
|
||||
}
|
||||
if (filterBy.includes('banned')) {
|
||||
set.push('users:banned');
|
||||
}
|
||||
return set.length > 1 ? set : set[0];
|
||||
}
|
||||
|
||||
async function getCount(set) {
|
||||
if (Array.isArray(set)) {
|
||||
return await db.sortedSetIntersectCard(set);
|
||||
}
|
||||
return await db.sortedSetCard(set);
|
||||
}
|
||||
|
||||
async function getUids(set) {
|
||||
let uids = [];
|
||||
console.log('get uids', set);
|
||||
if (Array.isArray(set)) {
|
||||
const weights = set.map((s, index) => (index ? 0 : 1));
|
||||
uids = await db[reverse ? 'getSortedSetRevIntersect' : 'getSortedSetIntersect']({
|
||||
sets: set,
|
||||
start: start,
|
||||
stop: stop,
|
||||
weights: weights,
|
||||
});
|
||||
} else {
|
||||
uids = await db[reverse ? 'getSortedSetRevRange' : 'getSortedSetRange'](set, start, stop);
|
||||
}
|
||||
return uids;
|
||||
}
|
||||
|
||||
async function getUsersWithFields(set) {
|
||||
const uids = await getUids(set);
|
||||
const [isAdmin, userData] = await Promise.all([
|
||||
user.isAdministrator(uids),
|
||||
user.getUsersWithFields(uids, userFields, req.uid),
|
||||
]);
|
||||
userData.forEach((user, index) => {
|
||||
if (user) {
|
||||
user.administrator = isAdmin[index];
|
||||
}
|
||||
});
|
||||
return userData;
|
||||
}
|
||||
const set = buildSet();
|
||||
const [count, users] = await Promise.all([
|
||||
getCount(set),
|
||||
getUsersWithFields(set),
|
||||
]);
|
||||
|
||||
const data = {
|
||||
users: users.filter(user => user && parseInt(user.uid, 10)),
|
||||
page: page,
|
||||
pageCount: Math.max(1, Math.ceil(count / resultsPerPage)),
|
||||
resultsPerPage: resultsPerPage,
|
||||
reverse: reverse,
|
||||
sortBy: sortBy,
|
||||
};
|
||||
data['sort_' + sortBy] = true;
|
||||
// data[section] = true;
|
||||
render(req, res, data);
|
||||
}
|
||||
|
||||
usersController.search = async function (req, res) {
|
||||
const page = parseInt(req.query.page, 10) || 1;
|
||||
|
||||
@@ -16,16 +16,17 @@ module.exports = function (app, middleware, controllers) {
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/privileges/:cid?', middleware, middlewares, controllers.admin.privileges.get);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/tags', middleware, middlewares, controllers.admin.tags.get);
|
||||
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users', middleware, middlewares, controllers.admin.users.sortByJoinDate);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users', middleware, middlewares, controllers.admin.users.index);
|
||||
// helpers.setupAdminPageRoute(app, '/admin/manage/users', middleware, middlewares, controllers.admin.users.sortByJoinDate);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users/search', middleware, middlewares, controllers.admin.users.search);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users/latest', middleware, middlewares, controllers.admin.users.sortByJoinDate);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users/not-validated', middleware, middlewares, controllers.admin.users.notValidated);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users/no-posts', middleware, middlewares, controllers.admin.users.noPosts);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users/top-posters', middleware, middlewares, controllers.admin.users.topPosters);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users/most-reputation', middleware, middlewares, controllers.admin.users.mostReputaion);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users/inactive', middleware, middlewares, controllers.admin.users.inactive);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users/flagged', middleware, middlewares, controllers.admin.users.flagged);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/users/banned', middleware, middlewares, controllers.admin.users.banned);
|
||||
// helpers.setupAdminPageRoute(app, '/admin/manage/users/latest', middleware, middlewares, controllers.admin.users.sortByJoinDate);
|
||||
// helpers.setupAdminPageRoute(app, '/admin/manage/users/not-validated', middleware, middlewares, controllers.admin.users.notValidated);
|
||||
// helpers.setupAdminPageRoute(app, '/admin/manage/users/no-posts', middleware, middlewares, controllers.admin.users.noPosts);
|
||||
// helpers.setupAdminPageRoute(app, '/admin/manage/users/top-posters', middleware, middlewares, controllers.admin.users.topPosters);
|
||||
// helpers.setupAdminPageRoute(app, '/admin/manage/users/most-reputation', middleware, middlewares, controllers.admin.users.mostReputaion);
|
||||
// helpers.setupAdminPageRoute(app, '/admin/manage/users/inactive', middleware, middlewares, controllers.admin.users.inactive);
|
||||
// helpers.setupAdminPageRoute(app, '/admin/manage/users/flagged', middleware, middlewares, controllers.admin.users.flagged);
|
||||
// helpers.setupAdminPageRoute(app, '/admin/manage/users/banned', middleware, middlewares, controllers.admin.users.banned);
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/registration', middleware, middlewares, controllers.admin.users.registrationQueue);
|
||||
|
||||
helpers.setupAdminPageRoute(app, '/admin/manage/admins-mods', middleware, middlewares, controllers.admin.adminsMods.get);
|
||||
|
||||
@@ -30,14 +30,9 @@
|
||||
</div>
|
||||
<hr/>
|
||||
<ul class="nav nav-pills">
|
||||
<li><a href='{config.relative_path}/admin/manage/users/latest?resultsPerPage={resultsPerPage}'>[[admin/manage/users:pills.latest]]</a></li>
|
||||
<li><a href='{config.relative_path}/admin/manage/users/not-validated?resultsPerPage={resultsPerPage}'>[[admin/manage/users:pills.unvalidated]]</a></li>
|
||||
<li><a href='{config.relative_path}/admin/manage/users/no-posts?resultsPerPage={resultsPerPage}'>[[admin/manage/users:pills.no-posts]]</a></li>
|
||||
<li><a href='{config.relative_path}/admin/manage/users/top-posters?resultsPerPage={resultsPerPage}'>[[admin/manage/users:pills.top-posters]]</a></li>
|
||||
<li><a href='{config.relative_path}/admin/manage/users/most-reputation?resultsPerPage={resultsPerPage}'>[[admin/manage/users:pills.top-rep]]</a></li>
|
||||
<li><a href='{config.relative_path}/admin/manage/users/inactive?resultsPerPage={resultsPerPage}'>[[admin/manage/users:pills.inactive]]</a></li>
|
||||
<li><a href='{config.relative_path}/admin/manage/users/flagged?resultsPerPage={resultsPerPage}'>[[admin/manage/users:pills.flagged]]</a></li>
|
||||
<li><a href='{config.relative_path}/admin/manage/users/banned?resultsPerPage={resultsPerPage}'>[[admin/manage/users:pills.banned]]</a></li>
|
||||
<li><a href='{config.relative_path}/admin/manage/users/?filter=not-validated&resultsPerPage={resultsPerPage}'>[[admin/manage/users:pills.unvalidated]]</a></li>
|
||||
|
||||
<li><a href='{config.relative_path}/admin/manage/users?filter=banned&resultsPerPage={resultsPerPage}'>[[admin/manage/users:pills.banned]]</a></li>
|
||||
<li><a href='{config.relative_path}/admin/manage/users/search'>[[admin/manage/users:pills.search]]</a></li>
|
||||
<li class="pull-right">
|
||||
<form class="form-inline">
|
||||
@@ -90,15 +85,14 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input component="user/select/all" type="checkbox"/></th>
|
||||
<th class="text-right">[[admin/manage/users:users.uid]]</th>
|
||||
<th>[[admin/manage/users:users.username]]</th>
|
||||
<th>[[admin/manage/users:users.email]]</th>
|
||||
<th class="text-right">[[admin/manage/users:users.postcount]]</th>
|
||||
<th class="text-right">[[admin/manage/users:users.reputation]]</th>
|
||||
<th class="text-right">[[admin/manage/users:users.flags]]</th>
|
||||
<th>[[admin/manage/users:users.joined]]</th>
|
||||
<th>[[admin/manage/users:users.last-online]]</th>
|
||||
<th>[[admin/manage/users:users.banned]]</th>
|
||||
<th class="text-right text-muted">[[admin/manage/users:users.uid]]</th>
|
||||
<th class="text-muted">[[admin/manage/users:users.username]]</th>
|
||||
<th class="text-muted">[[admin/manage/users:users.email]]</th>
|
||||
<th data-sort="postcount" class="text-right pointer">[[admin/manage/users:users.postcount]] {{{if sort_postcount}}}<i class="fa fa-sort-{{{if reverse}}}down{{{else}}}up{{{end}}}">{{{end}}}</th>
|
||||
<th data-sort="reputation" class="text-right pointer">[[admin/manage/users:users.reputation]] {{{if sort_reputation}}}<i class="fa fa-sort-{{{if reverse}}}down{{{else}}}up{{{end}}}">{{{end}}}</th>
|
||||
<th data-sort="flags" class="text-right pointer">[[admin/manage/users:users.flags]] {{{if sort_flags}}}<i class="fa fa-sort-{{{if reverse}}}down{{{else}}}up{{{end}}}">{{{end}}}</th>
|
||||
<th data-sort="joindate" class="pointer">[[admin/manage/users:users.joined]] {{{if sort_joindate}}}<i class="fa fa-sort-{{{if reverse}}}down{{{else}}}up{{{end}}}">{{{end}}}</th>
|
||||
<th data-sort="online" class="pointer">[[admin/manage/users:users.last-online]] {{{if sort_online}}}<i class="fa fa-sort-{{{if reverse}}}down{{{else}}}up{{{end}}}">{{{end}}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -106,7 +100,7 @@
|
||||
<tr class="user-row">
|
||||
<th><input component="user/select/single" data-uid="{users.uid}" type="checkbox"/></th>
|
||||
<td class="text-right">{users.uid}</td>
|
||||
<td><i class="administrator fa fa-shield text-success<!-- IF !users.administrator --> hidden<!-- ENDIF !users.administrator -->"></i><a href="{config.relative_path}/user/{users.userslug}"> {users.username}</a></td>
|
||||
<td><i title="[[admin/manage/users:users.banned]]" class="ban fa fa-gavel text-danger<!-- IF !users.banned --> hidden<!-- ENDIF !users.banned -->"></i><i class="administrator fa fa-shield text-success<!-- IF !users.administrator --> hidden<!-- ENDIF !users.administrator -->"></i><a href="{config.relative_path}/user/{users.userslug}"> {users.username}</a></td>
|
||||
|
||||
<td>
|
||||
<!-- IF config.requireEmailConfirmation -->
|
||||
@@ -118,7 +112,6 @@
|
||||
<td class="text-right"><!-- IF users.flags -->{users.flags}<!-- ELSE -->0<!-- ENDIF users.flags --></td>
|
||||
<td><span class="timeago" title="{users.joindateISO}"></span></td>
|
||||
<td><span class="timeago" title="{users.lastonlineISO}"></span></td>
|
||||
<td class="text-center"><i class="ban fa fa-gavel text-danger<!-- IF !users.banned --> hidden<!-- ENDIF !users.banned -->"></i></td>
|
||||
</tr>
|
||||
<!-- END users -->
|
||||
</tbody>
|
||||
|
||||
Reference in New Issue
Block a user