Categories refactor (#9257)
* feat: wip categories pagination * feat: add subCategoriesPerPage setting * feat: add load more sub categories button to category page * fix: openapi spec * feat: show sub categories left on category page hide button when no more categories left * breaking: rename categories to allCategories on /search categories contains the search results * fix: spec * refactor: remove cidsPerPage * fix: tests * feat: use component for subcategories * fix: prevent negative subCategoriesLeft * feat: new category filter/search WIP * feat: remove categories from /tag * fix: dont load all categories when showing move modal * feat: allow adding custom categories to list * breaking: dont load entire category tree on post queue removed unused code add hooks to filter/selector add options to filter/selector * feat: make selector modal work again * feat: replace old search module * fix: topic move selector * feat: dont load all categories on create category modal * fix: fix more categorySelectors * feat: dont load entire category tree on group details page * feat: dont load all categories on home page and user settings page * feat: add pagination to /user/:userslug/categories * fix: update schemas * fix: more tests * fix: test * feat: flags page, dont return entire category tree * fix: flag test * feat: categories manage page dont load all categories allow changing root category clear caches properly * fix: spec * feat: admins&mods page dont load all categories * fix: spec * fix: dont load all children when opening dropdown * fix: on search results dont return all children * refactor: pass all options, rename options.cids to options.selectedCids * fix: #9266 * fix: index 0 * fix: spec * feat: #9265, add setObjectBulk * refactor: shoter updateOrder * feat: selectors on categories/category * fix: tests and search filter * fix: category update test * feat: pagination on acp categories page show order in set order modal * fix: allow drag&drop on pages > 1 in /admin/manage/categories * fix: teasers for deep nested categories fix sub category display on /category page * fix: spec * refactor: use eslint-disable-next-line * refactor: shorterv1.18.x
parent
2cfab3678e
commit
47299ea587
@ -0,0 +1,94 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const _ = require('lodash');
|
||||||
|
|
||||||
|
const meta = require('../../meta');
|
||||||
|
const categories = require('../../categories');
|
||||||
|
const privileges = require('../../privileges');
|
||||||
|
const controllersHelpers = require('../../controllers/helpers');
|
||||||
|
|
||||||
|
module.exports = function (SocketCategories) {
|
||||||
|
// used by categorySeach module
|
||||||
|
SocketCategories.categorySearch = async function (socket, data) {
|
||||||
|
let cids = [];
|
||||||
|
let matchedCids = [];
|
||||||
|
const privilege = data.privilege || 'topics:read';
|
||||||
|
data.states = (data.states || ['watching', 'notwatching', 'ignoring']).map(
|
||||||
|
state => categories.watchStates[state]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (data.query) {
|
||||||
|
({ cids, matchedCids } = await findMatchedCids(socket.uid, data));
|
||||||
|
} else {
|
||||||
|
cids = await loadCids(socket.uid, data.parentCid);
|
||||||
|
}
|
||||||
|
|
||||||
|
const visibleCategories = await controllersHelpers.getVisibleCategories({
|
||||||
|
cids, uid: socket.uid, states: data.states, privilege, showLinks: data.showLinks, parentCid: data.parentCid,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (Array.isArray(data.selectedCids)) {
|
||||||
|
data.selectedCids = data.selectedCids.map(cid => parseInt(cid, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
let categoriesData = categories.buildForSelectCategories(visibleCategories, ['disabledClass'], data.parentCid);
|
||||||
|
categoriesData = categoriesData.slice(0, 200);
|
||||||
|
|
||||||
|
categoriesData.forEach(function (category) {
|
||||||
|
category.selected = data.selectedCids ? data.selectedCids.includes(category.cid) : false;
|
||||||
|
if (matchedCids.includes(category.cid)) {
|
||||||
|
category.match = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return categoriesData;
|
||||||
|
};
|
||||||
|
|
||||||
|
async function findMatchedCids(uid, data) {
|
||||||
|
const result = await categories.search({
|
||||||
|
query: data.query,
|
||||||
|
paginate: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let matchedCids = result.categories.map(c => c.cid);
|
||||||
|
// no need to filter if all 3 states are used
|
||||||
|
const filterByWatchState = !Object.values(categories.watchStates)
|
||||||
|
.every(state => data.states.includes(state));
|
||||||
|
|
||||||
|
if (filterByWatchState) {
|
||||||
|
const states = await categories.getWatchState(matchedCids, uid);
|
||||||
|
matchedCids = matchedCids.filter((cid, index) => data.states.includes(states[index]));
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootCids = _.uniq(_.flatten(await Promise.all(matchedCids.map(categories.getParentCids))));
|
||||||
|
const allChildCids = _.uniq(_.flatten(await Promise.all(matchedCids.map(categories.getChildrenCids))));
|
||||||
|
|
||||||
|
return {
|
||||||
|
cids: _.uniq(rootCids.concat(allChildCids).concat(matchedCids)),
|
||||||
|
matchedCids: matchedCids,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadCids(uid, parentCid) {
|
||||||
|
let resultCids = [];
|
||||||
|
async function getCidsRecursive(cids) {
|
||||||
|
const categoryData = await categories.getCategoriesFields(cids, ['subCategoriesPerPage']);
|
||||||
|
const cidToData = _.zipObject(cids, categoryData);
|
||||||
|
await Promise.all(cids.map(async (cid) => {
|
||||||
|
const allChildCids = await categories.getAllCidsFromSet('cid:' + cid + ':children');
|
||||||
|
if (allChildCids.length) {
|
||||||
|
const childCids = await privileges.categories.filterCids('find', allChildCids, uid);
|
||||||
|
resultCids.push(...childCids.slice(0, cidToData[cid].subCategoriesPerPage));
|
||||||
|
await getCidsRecursive(childCids);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const allRootCids = await categories.getAllCidsFromSet('cid:' + parentCid + ':children');
|
||||||
|
const rootCids = await privileges.categories.filterCids('find', allRootCids, uid);
|
||||||
|
const pageCids = rootCids.slice(0, meta.config.categoriesPerPage);
|
||||||
|
resultCids = pageCids;
|
||||||
|
await getCidsRecursive(pageCids);
|
||||||
|
return resultCids;
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue