From 40a05b70efec4d0e05d81c19722271600a60c465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Tue, 13 Oct 2020 01:29:21 -0400 Subject: [PATCH] feat: more work --- public/src/admin/manage/users.js | 79 +++++++++++++-------- src/controllers/admin/users.js | 113 +++---------------------------- src/routes/admin.js | 10 --- src/user/search.js | 13 ++-- src/views/admin/manage/users.tpl | 32 ++++----- 5 files changed, 83 insertions(+), 164 deletions(-) diff --git a/public/src/admin/manage/users.js b/public/src/admin/manage/users.js index bf2791ea1920..11bbf95b7b74 100644 --- a/public/src/admin/manage/users.js +++ b/public/src/admin/manage/users.js @@ -16,7 +16,8 @@ define('admin/manage/users', [ $('#results-per-page').val(ajaxify.data.resultsPerPage).on('change', function () { var query = utils.params(); query.resultsPerPage = $('#results-per-page').val(); - ajaxify.go(window.location.pathname + '?' + $.param(query)); + var qs = buildSearchQuery(query); + ajaxify.go(window.location.pathname + '?' + qs); }); function getSelectedUids() { @@ -403,26 +404,7 @@ define('admin/manage/users', [ }, err => errorEl.translateHtml('[[admin/manage/users:alerts.error-x, ' + err.status.message + ']]').removeClass('hidden')); } - var timeoutId = 0; - - $('#search-user-uid, #search-user-name, #search-user-email, #search-user-ip').on('keyup', function () { - if (timeoutId !== 0) { - clearTimeout(timeoutId); - timeoutId = 0; - } - - var $this = $(this); - var type = $this.attr('data-search-type'); - - timeoutId = setTimeout(function () { - $('.fa-spinner').removeClass('hidden'); - loadSearchPage({ - searchBy: type, - query: $this.val(), - page: 1, - }); - }, 250); - }); + handleSearch(); handleUserCreate(); @@ -431,9 +413,35 @@ define('admin/manage/users', [ handleSort(); }; + function handleSearch() { + var timeoutId = 0; + function doSearch() { + $('.fa-spinner').removeClass('hidden'); + loadSearchPage({ + searchBy: $('#user-search-by').val(), + query: $('#user-search').val(), + page: 1, + }); + } + $('#user-search').on('keyup', function () { + if (timeoutId !== 0) { + clearTimeout(timeoutId); + timeoutId = 0; + } + timeoutId = setTimeout(doSearch, 250); + }); + $('#user-search-by').on('change', function () { + doSearch(); + }); + } + function loadSearchPage(query) { - var qs = decodeURIComponent($.param(query)); - $.get(config.relative_path + '/api/admin/manage/users/search?' + qs, renderSearchResults).fail(function (xhrErr) { + var params = utils.params(); + params.searchBy = query.searchBy; + params.query = query.query; + params.page = query.page; + var qs = decodeURIComponent($.param(params)); + $.get(config.relative_path + '/api/admin/manage/users?' + qs, renderSearchResults).fail(function (xhrErr) { if (xhrErr && xhrErr.responseJSON && xhrErr.responseJSON.error) { app.alertError(xhrErr.responseJSON.error); } @@ -450,14 +458,19 @@ define('admin/manage/users', [ $('.users-table tbody').append(html); html.find('.timeago').timeago(); $('.fa-spinner').addClass('hidden'); - + if (!$('#user-search').val()) { + $('#user-found-notify').addClass('hidden'); + $('#user-notfound-notify').addClass('hidden'); + return; + } if (data && data.users.length === 0) { $('#user-notfound-notify').translateHtml('[[admin/manage/users:search.not-found]]') .removeClass('hidden'); $('#user-found-notify').addClass('hidden'); } else { - $('#user-found-notify').translateHtml(translator.compile('admin/manage/users:alerts.x-users-found', data.matchCount, data.timing)) - .removeClass('hidden'); + $('#user-found-notify').translateHtml( + translator.compile('admin/manage/users:alerts.x-users-found', data.matchCount, data.timing) + ).removeClass('hidden'); $('#user-notfound-notify').addClass('hidden'); } }); @@ -481,6 +494,17 @@ define('admin/manage/users', [ }); } + function buildSearchQuery(params) { + if ($('#user-search').val()) { + params.query = $('#user-search').val(); + params.searchBy = $('#user-search-by').val(); + } else { + params.query = undefined; + params.searchBy = undefined; + } + + return decodeURIComponent($.param(params)); + } function handleSort() { $('.users-table thead th').on('click', function () { var $this = $(this); @@ -495,7 +519,8 @@ define('admin/manage/users', [ } else { params.sortDirection = 'desc'; } - var qs = decodeURIComponent($.param(params)); + + var qs = buildSearchQuery(params); ajaxify.go('admin/manage/users?' + qs); }); } diff --git a/src/controllers/admin/users.js b/src/controllers/admin/users.js index 8b9da0f19969..722d5df0bd50 100644 --- a/src/controllers/admin/users.js +++ b/src/controllers/admin/users.js @@ -68,7 +68,6 @@ async function newGet(req, res) { 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']({ @@ -102,20 +101,19 @@ async function newGet(req, res) { getUsersWithFields(set), ]); - const data = { + render(req, res, { 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 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)) { @@ -125,6 +123,8 @@ usersController.search = async function (req, res) { uid: req.uid, query: req.query.query, searchBy: req.query.searchBy, + sortBy: req.query.sortBy, + sortDirection: sortDirection, page: page, resultsPerPage: resultsPerPage, findUids: async function (query, searchBy, hardCap) { @@ -157,48 +157,10 @@ usersController.search = async function (req, res) { } }); searchData.query = validator.escape(String(req.query.query || '')); - searchData.uidQuery = req.query.searchBy === 'uid' ? searchData.query : ''; - searchData.usernameQuery = req.query.searchBy === 'username' ? searchData.query : ''; - searchData.emailQuery = req.query.searchBy === 'email' ? searchData.query : ''; - searchData.ipQuery = req.query.searchBy === 'uid' ? searchData.query : ''; searchData.resultsPerPage = resultsPerPage; - searchData.pagination = pagination.create(page, searchData.pageCount, req.query); - searchData.search_display = ''; - res.render('admin/manage/users', searchData); -}; - -usersController.sortByJoinDate = async function (req, res) { - await getUsers('users:joindate', 'latest', undefined, undefined, req, res); -}; - -usersController.notValidated = async function (req, res) { - await getUsers('users:notvalidated', 'notvalidated', undefined, undefined, req, res); -}; - -usersController.noPosts = async function (req, res) { - await getUsers('users:postcount', 'noposts', '-inf', 0, req, res); -}; - -usersController.topPosters = async function (req, res) { - await getUsers('users:postcount', 'topposts', 0, '+inf', req, res); -}; - -usersController.mostReputaion = async function (req, res) { - await getUsers('users:reputation', 'mostreputation', 0, '+inf', req, res); -}; - -usersController.flagged = async function (req, res) { - await getUsers('users:flags', 'mostflags', 1, '+inf', req, res); -}; - -usersController.inactive = async function (req, res) { - const timeRange = 1000 * 60 * 60 * 24 * 30 * (parseInt(req.query.months, 10) || 3); - const cutoff = Date.now() - timeRange; - await getUsers('users:online', 'inactive', '-inf', cutoff, req, res); -}; - -usersController.banned = async function (req, res) { - await getUsers('users:banned', 'banned', undefined, undefined, req, res); + searchData.sortBy = req.query.sortBy; + searchData.reverse = reverse; + render(req, res, searchData); }; usersController.registrationQueue = async function (req, res) { @@ -248,61 +210,7 @@ async function getInvites() { return invitations; } -async function getUsers(set, section, min, max, req, res) { - 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 start = Math.max(0, page - 1) * resultsPerPage; - const stop = start + resultsPerPage - 1; - const byScore = min !== undefined && max !== undefined; - - async function getCount() { - if (byScore) { - return await db.sortedSetCount(set, min, max); - } else if (set === 'users:banned' || set === 'users:notvalidated') { - return await db.sortedSetCard(set); - } - return await db.getObjectField('global', 'userCount'); - } - - async function getUsersWithFields() { - let uids; - if (byScore) { - uids = await db.getSortedSetRevRangeByScore(set, start, resultsPerPage, max, min); - } else { - uids = await user.getUidsFromSet(set, start, stop); - } - 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 [count, users] = await Promise.all([ - getCount(), - getUsersWithFields(), - ]); - - const data = { - users: users.filter(user => user && parseInt(user.uid, 10)), - page: page, - pageCount: Math.max(1, Math.ceil(count / resultsPerPage)), - resultsPerPage: resultsPerPage, - }; - data[section] = true; - render(req, res, data); -} - function render(req, res, data) { - data.search_display = 'hidden'; data.pagination = pagination.create(data.page, data.pageCount, req.query); data.requireEmailConfirmation = meta.config.requireEmailConfirmation; @@ -310,7 +218,8 @@ function render(req, res, data) { data.inviteOnly = registrationType === 'invite-only' || registrationType === 'admin-invite-only'; data.adminInviteOnly = registrationType === 'admin-invite-only'; - + data['sort_' + data.sortBy] = true; + data['searchBy_' + validator.escape(String(req.query.searchBy))] = true; res.render('admin/manage/users', data); } diff --git a/src/routes/admin.js b/src/routes/admin.js index eeabb93cdc6b..e528a1506841 100644 --- a/src/routes/admin.js +++ b/src/routes/admin.js @@ -17,16 +17,6 @@ module.exports = function (app, middleware, controllers) { helpers.setupAdminPageRoute(app, '/admin/manage/tags', middleware, middlewares, controllers.admin.tags.get); 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/registration', middleware, middlewares, controllers.admin.users.registrationQueue); helpers.setupAdminPageRoute(app, '/admin/manage/admins-mods', middleware, middlewares, controllers.admin.adminsMods.get); diff --git a/src/user/search.js b/src/user/search.js index e2e94b19f6d6..0934371932b6 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -113,25 +113,28 @@ module.exports = function (User) { } if (data.sortBy) { - sortUsers(userData, data.sortBy); + sortUsers(userData, data.sortBy, data.sortDirection); } return userData.map(user => user.uid); } - function sortUsers(userData, sortBy) { + function sortUsers(userData, sortBy, sortDirection) { if (!userData || !userData.length) { return; } + sortDirection = sortDirection || 'desc'; + const direction = sortDirection === 'desc' ? 1 : -1; + const isNumeric = utils.isNumber(userData[0][sortBy]); if (isNumeric) { - userData.sort((u1, u2) => u2[sortBy] - u1[sortBy]); + userData.sort((u1, u2) => direction * (u2[sortBy] - u1[sortBy])); } else { userData.sort(function (u1, u2) { if (u1[sortBy] < u2[sortBy]) { - return -1; + return direction * -1; } else if (u1[sortBy] > u2[sortBy]) { - return 1; + return direction * 1; } return 0; }); diff --git a/src/views/admin/manage/users.tpl b/src/views/admin/manage/users.tpl index 0b538cc2c7db..fb05acb7b8df 100644 --- a/src/views/admin/manage/users.tpl +++ b/src/views/admin/manage/users.tpl @@ -30,12 +30,22 @@