mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-02-04 13:49:56 +01:00
ability to filter flags by category
This commit is contained in:
@@ -12,8 +12,6 @@ define('admin/manage/flags', [
|
||||
Flags.init = function() {
|
||||
$('.post-container .content img:not(.not-responsive)').addClass('img-responsive');
|
||||
|
||||
var params = utils.params();
|
||||
$('#flag-sort-by').val(params.sortBy);
|
||||
autocomplete.user($('#byUsername'));
|
||||
|
||||
handleDismiss();
|
||||
|
||||
@@ -305,6 +305,39 @@ var privileges = require('./privileges');
|
||||
return tree;
|
||||
};
|
||||
|
||||
Categories.buildForSelect = function(uid, callback) {
|
||||
function recursive(category, categoriesData, level) {
|
||||
if (category.link) {
|
||||
return;
|
||||
}
|
||||
|
||||
var bullet = level ? '• ' : '';
|
||||
category.value = category.cid;
|
||||
category.text = level + bullet + category.name
|
||||
categoriesData.push(category);
|
||||
|
||||
category.children.forEach(function(child) {
|
||||
recursive(child, categoriesData, ' ' + level);
|
||||
});
|
||||
}
|
||||
Categories.getCategoriesByPrivilege('cid:0:children', uid, 'read', function(err, categories) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var categoriesData = [];
|
||||
|
||||
categories = categories.filter(function(category) {
|
||||
return category && !category.link && !parseInt(category.parentCid, 10);
|
||||
});
|
||||
|
||||
categories.forEach(function(category) {
|
||||
recursive(category, categoriesData, '');
|
||||
});
|
||||
callback(null, categoriesData);
|
||||
});
|
||||
};
|
||||
|
||||
Categories.getIgnorers = function(cid, start, stop, callback) {
|
||||
db.getSortedSetRevRange('cid:' + cid + ':ignorers', start, stop, callback);
|
||||
};
|
||||
|
||||
@@ -3,28 +3,26 @@
|
||||
var async = require('async');
|
||||
var posts = require('../../posts');
|
||||
var user = require('../../user');
|
||||
var categories = require('../../categories');
|
||||
var analytics = require('../../analytics');
|
||||
var pagination = require('../../pagination');
|
||||
|
||||
var flagsController = {};
|
||||
|
||||
flagsController.get = function(req, res, next) {
|
||||
var sortBy = req.query.sortBy || 'count';
|
||||
var byUsername = req.query.byUsername || '';
|
||||
var itemsPerPage = 20;
|
||||
|
||||
flagsController.get = function(req, res, next) {
|
||||
var byUsername = req.query.byUsername || '';
|
||||
var cid = req.query.cid || 0;
|
||||
var sortBy = req.query.sortBy || 'count';
|
||||
var page = parseInt(req.query.page, 10) || 1;
|
||||
var itemsPerPage = 20;
|
||||
var start = (page - 1) * itemsPerPage;
|
||||
var stop = start + itemsPerPage - 1;
|
||||
|
||||
async.parallel({
|
||||
categories: function(next) {
|
||||
categories.buildForSelect(req.uid, next);
|
||||
},
|
||||
flagData: function(next) {
|
||||
if (byUsername) {
|
||||
posts.getUserFlags(byUsername, sortBy, req.uid, start, stop, next);
|
||||
} else {
|
||||
var set = sortBy === 'count' ? 'posts:flags:count' : 'posts:flagged';
|
||||
posts.getFlags(set, req.uid, start, stop, next);
|
||||
}
|
||||
getFlagData(req, next);
|
||||
},
|
||||
analytics: function(next) {
|
||||
analytics.getDailyStatsForSet('analytics:flags', Date.now(), 30, next);
|
||||
@@ -47,12 +45,18 @@ flagsController.get = function(req, res, next) {
|
||||
|
||||
var pageCount = Math.max(1, Math.ceil(results.flagData.count / itemsPerPage));
|
||||
|
||||
results.categories.forEach(function(category) {
|
||||
category.selected = parseInt(category.cid, 10) === parseInt(cid, 10);
|
||||
});
|
||||
|
||||
var data = {
|
||||
posts: results.flagData.posts,
|
||||
assignees: results.assignees,
|
||||
analytics: results.analytics,
|
||||
next: stop + 1,
|
||||
categories: results.categories,
|
||||
byUsername: byUsername,
|
||||
sortByCount: sortBy === 'count',
|
||||
sortByTime: sortBy === 'time',
|
||||
pagination: pagination.create(page, pageCount, req.query),
|
||||
title: '[[pages:flagged-posts]]'
|
||||
};
|
||||
@@ -60,5 +64,36 @@ flagsController.get = function(req, res, next) {
|
||||
});
|
||||
};
|
||||
|
||||
function getFlagData(req, callback) {
|
||||
var sortBy = req.query.sortBy || 'count';
|
||||
var byUsername = req.query.byUsername || '';
|
||||
var cid = req.query.cid || 0;
|
||||
var page = parseInt(req.query.page, 10) || 1;
|
||||
var start = (page - 1) * itemsPerPage;
|
||||
var stop = start + itemsPerPage - 1;
|
||||
|
||||
var sets = [sortBy === 'count' ? 'posts:flags:count' : 'posts:flagged'];
|
||||
if (cid) {
|
||||
sets.push('cid:' + cid + ':pids');
|
||||
}
|
||||
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
if (byUsername) {
|
||||
user.getUidByUsername(byUsername, next);
|
||||
} else {
|
||||
process.nextTick(next, null, 0);
|
||||
}
|
||||
},
|
||||
function(uid, next) {
|
||||
if (uid) {
|
||||
sets.push('uid:' + uid + ':flag:pids');
|
||||
}
|
||||
|
||||
posts.getFlags(sets, req.uid, start, stop, next);
|
||||
}
|
||||
], callback);
|
||||
}
|
||||
|
||||
|
||||
module.exports = flagsController;
|
||||
|
||||
@@ -45,14 +45,20 @@ searchController.search = function(req, res, next) {
|
||||
};
|
||||
|
||||
async.parallel({
|
||||
categories: async.apply(buildCategories, req.uid),
|
||||
categories: async.apply(categories.buildForSelect, req.uid),
|
||||
search: async.apply(search.search, data)
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
var categoriesData = [
|
||||
{value: 'all', text: '[[unread:all_categories]]'},
|
||||
{value: 'watched', text: '[[category:watched-categories]]'}
|
||||
].concat(results.categories);
|
||||
|
||||
var searchData = results.search;
|
||||
searchData.categories = results.categories;
|
||||
searchData.categories = categoriesData;
|
||||
searchData.categoriesCount = results.categories.length;
|
||||
searchData.pagination = pagination.create(page, searchData.pageCount, req.query);
|
||||
searchData.showAsPosts = !req.query.showAs || req.query.showAs === 'posts';
|
||||
@@ -65,44 +71,4 @@ searchController.search = function(req, res, next) {
|
||||
});
|
||||
};
|
||||
|
||||
function buildCategories(uid, callback) {
|
||||
categories.getCategoriesByPrivilege('cid:0:children', uid, 'read', function(err, categories) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var categoriesData = [
|
||||
{value: 'all', text: '[[unread:all_categories]]'},
|
||||
{value: 'watched', text: '[[category:watched-categories]]'}
|
||||
];
|
||||
|
||||
categories = categories.filter(function(category) {
|
||||
return category && !category.link && !parseInt(category.parentCid, 10);
|
||||
});
|
||||
|
||||
categories.forEach(function(category) {
|
||||
recursive(category, categoriesData, '');
|
||||
});
|
||||
callback(null, categoriesData);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function recursive(category, categoriesData, level) {
|
||||
if (category.link) {
|
||||
return;
|
||||
}
|
||||
|
||||
var bullet = level ? '• ' : '';
|
||||
|
||||
categoriesData.push({
|
||||
value: category.cid,
|
||||
text: level + bullet + category.name
|
||||
});
|
||||
|
||||
category.children.forEach(function(child) {
|
||||
recursive(child, categoriesData, ' ' + level);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = searchController;
|
||||
|
||||
@@ -260,6 +260,7 @@ var middleware;
|
||||
}, function(err, res, body) {
|
||||
if (err) {
|
||||
winston.error('Error parsing plugins : ' + err.message);
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
Plugins.normalise(body, callback);
|
||||
|
||||
@@ -154,14 +154,23 @@ module.exports = function(Posts) {
|
||||
};
|
||||
|
||||
Posts.getFlags = function(set, uid, start, stop, callback) {
|
||||
set = set.length > 1 ? set : set[0];
|
||||
async.parallel({
|
||||
count: function(next) {
|
||||
db.sortedSetCard(set, next);
|
||||
if (Array.isArray(set)) {
|
||||
db.sortedSetIntersectCard(set, next);
|
||||
} else {
|
||||
db.sortedSetCard(set, next);
|
||||
}
|
||||
},
|
||||
posts: function(next) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.getSortedSetRevRange(set, start, stop, next);
|
||||
if (Array.isArray(set)) {
|
||||
db.getSortedSetRevIntersect({sets: set, start: start, stop: stop, aggregate: 'MAX'}, next);
|
||||
} else {
|
||||
db.getSortedSetRevRange(set, start, stop, next);
|
||||
}
|
||||
},
|
||||
function (pids, next) {
|
||||
getFlaggedPostsWithReasons(pids, uid, next);
|
||||
@@ -171,35 +180,6 @@ module.exports = function(Posts) {
|
||||
}, callback);
|
||||
};
|
||||
|
||||
Posts.getUserFlags = function(byUsername, sortBy, callerUID, start, stop, callback) {
|
||||
var count = 0;
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
user.getUidByUsername(byUsername, next);
|
||||
},
|
||||
function(uid, next) {
|
||||
if (!uid) {
|
||||
return next(null, []);
|
||||
}
|
||||
|
||||
db.getSortedSetRevRange('uid:' + uid + ':flag:pids', 0, -1, next);
|
||||
},
|
||||
function(pids, next) {
|
||||
count = pids.length;
|
||||
getFlaggedPostsWithReasons(pids, callerUID, next);
|
||||
},
|
||||
function(posts, next) {
|
||||
if (sortBy === 'count') {
|
||||
posts.sort(function(a, b) {
|
||||
return b.flags - a.flags;
|
||||
});
|
||||
}
|
||||
|
||||
next(null, {posts: posts.slice(start, stop === -1 ? undefined : stop + 1), count: count});
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
function getFlaggedPostsWithReasons(pids, uid, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
@@ -229,8 +209,6 @@ module.exports = function(Posts) {
|
||||
}
|
||||
|
||||
results.posts.forEach(function(post, index) {
|
||||
var history;
|
||||
|
||||
if (post) {
|
||||
post.flagReasons = reasons[index];
|
||||
}
|
||||
@@ -352,11 +330,12 @@ module.exports = function(Posts) {
|
||||
Posts.expandFlagHistory = function(posts, callback) {
|
||||
// Expand flag history
|
||||
async.map(posts, function(post, next) {
|
||||
var history;
|
||||
try {
|
||||
var history = JSON.parse(post['flag:history'] || '[]');
|
||||
history = JSON.parse(post['flag:history'] || '[]');
|
||||
} catch (e) {
|
||||
winston.warn('[posts/getFlags] Unable to deserialise post flag history, likely malformed data');
|
||||
callback(e);
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
async.map(history, function(event, next) {
|
||||
@@ -392,7 +371,7 @@ module.exports = function(Posts) {
|
||||
}
|
||||
], function(err) {
|
||||
next(err, event);
|
||||
})
|
||||
});
|
||||
}, function(err, history) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
@@ -402,5 +381,5 @@ module.exports = function(Posts) {
|
||||
next(null, post);
|
||||
});
|
||||
}, callback);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
var express = require('express');
|
||||
var nconf = require('nconf');
|
||||
var winston = require('winston');
|
||||
var user = require('./../user');
|
||||
var categories = require('./../categories');
|
||||
var topics = require('./../topics');
|
||||
var posts = require('./../posts');
|
||||
var user = require('../user');
|
||||
var categories = require('../categories');
|
||||
var topics = require('../topics');
|
||||
var posts = require('../posts');
|
||||
var db = require('../database');
|
||||
|
||||
module.exports = function(app, middleware, controllers) {
|
||||
var router = express.Router();
|
||||
|
||||
@@ -24,13 +24,27 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<div>
|
||||
<label>Category</label>
|
||||
<select class="form-control" id="category-selector" name="cid">
|
||||
<option value="">[[unread:all_categories]]</option>
|
||||
<!-- BEGIN categories -->
|
||||
<option value="{categories.cid}" <!-- IF categories.selected -->selected<!-- ENDIF categories.selected -->>{categories.text}</option>
|
||||
<!-- END categories -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Sort By</label>
|
||||
<div>
|
||||
<div>
|
||||
<select id="flag-sort-by" class="form-control" name="sortBy">
|
||||
<option value="count">Most Flags</option>
|
||||
<option value="time">Most Recent</option>
|
||||
<option value="count" <!-- IF sortByCount -->selected<!-- ENDIF sortByCount -->>Most Flags</option>
|
||||
<option value="time" <!-- IF sortByTime -->selected<!-- ENDIF sortByTime -->>Most Recent</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user