mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
feat: add pagination to groups page, api routes
use page instead of after
This commit is contained in:
@@ -103,8 +103,6 @@ get:
|
||||
type: boolean
|
||||
sort:
|
||||
type: string
|
||||
nextStart:
|
||||
type: number
|
||||
title:
|
||||
type: string
|
||||
- $ref: ../components/schemas/Breadcrumbs.yaml#/Breadcrumbs
|
||||
|
||||
@@ -2,15 +2,15 @@ get:
|
||||
tags:
|
||||
- groups
|
||||
summary: list groups
|
||||
description: This operation returns a list of user groups. The number of groups returned is hardcoded to 10.
|
||||
description: This operation returns a list of user groups. The number of groups returned is hardcoded to 15 per page.
|
||||
parameters:
|
||||
- in: query
|
||||
name: 'after'
|
||||
name: 'page'
|
||||
schema:
|
||||
type: number
|
||||
required: false
|
||||
description: An offset used to display a different subset of groups.
|
||||
example: '0'
|
||||
description: Used for pagination
|
||||
example: '1'
|
||||
- in: query
|
||||
name: 'sort'
|
||||
schema:
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
define('admin/manage/groups', [
|
||||
'categorySelector',
|
||||
'slugify',
|
||||
'api',
|
||||
'bootbox',
|
||||
'alerts',
|
||||
], function (categorySelector, slugify, api, bootbox, alerts) {
|
||||
], function (slugify, api, bootbox, alerts) {
|
||||
const Groups = {};
|
||||
|
||||
Groups.init = function () {
|
||||
@@ -88,30 +87,27 @@ define('admin/manage/groups', [
|
||||
return ajaxify.refresh();
|
||||
}
|
||||
$('.pagination').addClass('hide');
|
||||
const groupsEl = $('.groups-list');
|
||||
socket.emit('groups.search', {
|
||||
api.get('/api/groups', {
|
||||
query: queryEl.val(),
|
||||
options: {
|
||||
sort: 'date',
|
||||
},
|
||||
}, function (err, groups) {
|
||||
if (err) {
|
||||
return alerts.error(err);
|
||||
}
|
||||
|
||||
app.parseAndTranslate('admin/manage/groups', 'groups', {
|
||||
groups: groups,
|
||||
categories: ajaxify.data.categories,
|
||||
}, function (html) {
|
||||
groupsEl.find('[data-groupname]').remove();
|
||||
groupsEl.find('tbody').append(html);
|
||||
});
|
||||
});
|
||||
sort: 'date',
|
||||
hideEphemeralGroups: true,
|
||||
}).then(renderSearchResults)
|
||||
.catch(alerts.error);
|
||||
}
|
||||
|
||||
queryEl.on('keyup', utils.debounce(doSearch, 200));
|
||||
}
|
||||
|
||||
function renderSearchResults(data) {
|
||||
const groupsEl = $('.groups-list');
|
||||
app.parseAndTranslate('admin/manage/groups', 'groups', {
|
||||
groups: data.groups,
|
||||
categories: ajaxify.data.categories,
|
||||
}, function (html) {
|
||||
groupsEl.find('[data-groupname]').remove();
|
||||
groupsEl.find('tbody').append(html);
|
||||
});
|
||||
}
|
||||
|
||||
return Groups;
|
||||
});
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
define('forum/groups/list', [
|
||||
'forum/infinitescroll', 'benchpress', 'api', 'bootbox', 'alerts',
|
||||
], function (infinitescroll, Benchpress, api, bootbox, alerts) {
|
||||
'api', 'bootbox', 'alerts',
|
||||
], function (api, bootbox, alerts) {
|
||||
const Groups = {};
|
||||
|
||||
Groups.init = function () {
|
||||
infinitescroll.init(Groups.loadMoreGroups);
|
||||
|
||||
// Group creation
|
||||
$('button[data-action="new"]').on('click', function () {
|
||||
bootbox.prompt('[[groups:new-group.group-name]]', function (name) {
|
||||
@@ -24,67 +22,40 @@ define('forum/groups/list', [
|
||||
$('#search-sort').val(params.sort || 'alpha');
|
||||
|
||||
// Group searching
|
||||
$('#search-text').on('keyup', Groups.search);
|
||||
$('#search-text').on('keyup', utils.debounce(Groups.search, 200));
|
||||
$('#search-button').on('click', Groups.search);
|
||||
$('#search-sort').on('change', function () {
|
||||
ajaxify.go('groups?sort=' + $('#search-sort').val());
|
||||
});
|
||||
};
|
||||
|
||||
Groups.loadMoreGroups = function (direction) {
|
||||
if (direction < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
infinitescroll.loadMore('/groups', {
|
||||
sort: $('#search-sort').val(),
|
||||
after: $('[component="groups/container"]').attr('data-nextstart'),
|
||||
}, function (data, done) {
|
||||
if (data && data.groups.length) {
|
||||
Benchpress.render('partials/groups/list', {
|
||||
groups: data.groups,
|
||||
}).then(function (html) {
|
||||
$('#groups-list').append(html);
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
|
||||
if (data && data.nextStart) {
|
||||
$('[component="groups/container"]').attr('data-nextstart', data.nextStart);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Groups.search = function () {
|
||||
const groupsEl = $('#groups-list');
|
||||
const queryEl = $('#search-text');
|
||||
const sortEl = $('#search-sort');
|
||||
api.get('/api/groups', {
|
||||
query: $('#search-text').val(),
|
||||
sort: $('#search-sort').val(),
|
||||
filterHidden: true,
|
||||
showMembers: true,
|
||||
hideEphemeralGroups: true,
|
||||
}).then(renderSearchResults)
|
||||
.catch(alerts.error);
|
||||
|
||||
socket.emit('groups.search', {
|
||||
query: queryEl.val(),
|
||||
options: {
|
||||
sort: sortEl.val(),
|
||||
filterHidden: true,
|
||||
showMembers: true,
|
||||
hideEphemeralGroups: true,
|
||||
},
|
||||
}, function (err, groups) {
|
||||
if (err) {
|
||||
return alerts.error(err);
|
||||
}
|
||||
groups = groups.filter(function (group) {
|
||||
return group.name !== 'registered-users' && group.name !== 'guests';
|
||||
});
|
||||
Benchpress.render('partials/groups/list', {
|
||||
groups: groups,
|
||||
}).then(function (html) {
|
||||
groupsEl.empty().append(html);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
};
|
||||
|
||||
function renderSearchResults(data) {
|
||||
app.parseAndTranslate('partials/paginator', {
|
||||
pagination: data.pagination,
|
||||
}).then(function (html) {
|
||||
$('.pagination-container').replaceWith(html);
|
||||
});
|
||||
|
||||
const groupsEl = $('#groups-list');
|
||||
app.parseAndTranslate('partials/groups/list', {
|
||||
groups: data.groups,
|
||||
}).then(function (html) {
|
||||
groupsEl.empty().append(html);
|
||||
});
|
||||
}
|
||||
|
||||
return Groups;
|
||||
});
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
|
||||
define('forum/users', [
|
||||
'benchpress', 'api', 'alerts', 'accounts/invite',
|
||||
], function (Benchpress, api, alerts, AccountInvite) {
|
||||
'api', 'alerts', 'accounts/invite',
|
||||
], function (api, alerts, AccountInvite) {
|
||||
const Users = {};
|
||||
|
||||
let searchResultCount = 0;
|
||||
@@ -88,7 +88,9 @@ define('forum/users', [
|
||||
}
|
||||
|
||||
function renderSearchResults(data) {
|
||||
Benchpress.render('partials/paginator', { pagination: data.pagination }).then(function (html) {
|
||||
app.parseAndTranslate('partials/paginator', {
|
||||
pagination: data.pagination,
|
||||
}).then(function (html) {
|
||||
$('.pagination-container').replaceWith(html);
|
||||
});
|
||||
|
||||
|
||||
@@ -13,8 +13,9 @@ const slugify = require('../slugify');
|
||||
const groupsAPI = module.exports;
|
||||
|
||||
groupsAPI.list = async (caller, data) => {
|
||||
const groupsPerPage = 10;
|
||||
const start = parseInt(data.after || 0, 10);
|
||||
const page = parseInt(data.page, 10) || 1;
|
||||
const groupsPerPage = 15;
|
||||
const start = Math.max(0, page - 1) * groupsPerPage;
|
||||
const stop = start + groupsPerPage - 1;
|
||||
const groupData = await groups.getGroupsBySort(data.sort, start, stop);
|
||||
|
||||
|
||||
@@ -14,22 +14,49 @@ const groupsController = module.exports;
|
||||
|
||||
groupsController.list = async function (req, res) {
|
||||
const sort = req.query.sort || 'alpha';
|
||||
|
||||
const [groupData, allowGroupCreation] = await Promise.all([
|
||||
groups.getGroupsBySort(sort, 0, 14),
|
||||
const page = parseInt(req.query.page, 10) || 1;
|
||||
const [allowGroupCreation, [groupData, pageCount]] = await Promise.all([
|
||||
privileges.global.can('group:create', req.uid),
|
||||
getGroups(req, sort, page),
|
||||
]);
|
||||
|
||||
res.render('groups/list', {
|
||||
groups: groupData,
|
||||
allowGroupCreation: allowGroupCreation,
|
||||
sort: validator.escape(String(sort)),
|
||||
nextStart: 15,
|
||||
pagination: pagination.create(page, pageCount, req.query),
|
||||
title: '[[pages:groups]]',
|
||||
breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[pages:groups]]' }]),
|
||||
});
|
||||
};
|
||||
|
||||
async function getGroups(req, sort, page) {
|
||||
const resultsPerPage = req.query.query ? 100 : 15;
|
||||
const start = Math.max(0, page - 1) * resultsPerPage;
|
||||
const stop = start + resultsPerPage - 1;
|
||||
|
||||
if (req.query.query) {
|
||||
const filterHidden = req.query.filterHidden === 'true' || !await user.isAdministrator(req.uid);
|
||||
const groupData = await groups.search(req.query.query, {
|
||||
sort,
|
||||
filterHidden: filterHidden,
|
||||
showMembers: req.query.showMembers === 'true',
|
||||
hideEphemeralGroups: req.query.hideEphemeralGroups === 'true',
|
||||
});
|
||||
const pageCount = Math.ceil(groupData.length / resultsPerPage);
|
||||
|
||||
return [groupData.slice(start, stop + 1), pageCount];
|
||||
}
|
||||
|
||||
const [groupData, groupCount] = await Promise.all([
|
||||
groups.getGroupsBySort(sort, start, stop),
|
||||
groups.getGroupCountBySort(sort),
|
||||
]);
|
||||
|
||||
const pageCount = Math.ceil(groupCount / resultsPerPage);
|
||||
return [groupData, pageCount];
|
||||
}
|
||||
|
||||
groupsController.details = async function (req, res, next) {
|
||||
const lowercaseSlug = req.params.slug.toLowerCase();
|
||||
if (req.params.slug !== lowercaseSlug) {
|
||||
|
||||
@@ -76,14 +76,22 @@ Groups.getGroupsFromSet = async function (set, start, stop) {
|
||||
};
|
||||
|
||||
Groups.getGroupsBySort = async function (sort, start, stop) {
|
||||
return await Groups.getGroupsFromSet(sortToSet(sort), start, stop);
|
||||
};
|
||||
|
||||
Groups.getGroupCountBySort = async function (sort) {
|
||||
return await db.sortedSetCard(sortToSet(sort));
|
||||
};
|
||||
|
||||
function sortToSet(sort) {
|
||||
let set = 'groups:visible:name';
|
||||
if (sort === 'count') {
|
||||
set = 'groups:visible:memberCount';
|
||||
} else if (sort === 'date') {
|
||||
set = 'groups:visible:createtime';
|
||||
}
|
||||
return await Groups.getGroupsFromSet(set, start, stop);
|
||||
};
|
||||
return set;
|
||||
}
|
||||
|
||||
Groups.getNonPrivilegeGroups = async function (set, start, stop, flags) {
|
||||
if (!flags) {
|
||||
|
||||
Reference in New Issue
Block a user