ability to filter flags by category

v1.18.x
barisusakli 9 years ago
parent 990ecc8cd2
commit 2c140c2107

@ -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 = {};
var itemsPerPage = 20;
flagsController.get = function(req, res, next) {
var sortBy = req.query.sortBy || 'count';
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>

Loading…
Cancel
Save