diff --git a/public/src/admin/manage/tags.js b/public/src/admin/manage/tags.js index 84cd492ea0..8bb8284331 100644 --- a/public/src/admin/manage/tags.js +++ b/public/src/admin/manage/tags.js @@ -9,6 +9,12 @@ define('admin/manage/tags', ['forum/infinitescroll', 'admin/modules/selectable'] handleColorPickers(); selectable.enable('.tag-management', '.tag-row'); + handleSearch(); + handleModify(); + handleDeleteSelected(); + }; + + function handleSearch() { $('#tag-search').on('input propertychange', function() { if (timeoutId) { clearTimeout(timeoutId); @@ -31,7 +37,9 @@ define('admin/manage/tags', ['forum/infinitescroll', 'admin/modules/selectable'] }); }, 100); }); + } + function handleModify() { $('#modify').on('click', function(ev) { var tagsToModify = $('.tag-row.selected'); if (!tagsToModify.length) { @@ -71,7 +79,32 @@ define('admin/manage/tags', ['forum/infinitescroll', 'admin/modules/selectable'] handleColorPickers(); }, 500); }); - }; + } + + function handleDeleteSelected() { + $('#deleteSelected').on('click', function() { + var tagsToDelete = $('.tag-row.selected'); + if (!tagsToDelete.length) { + return; + } + + bootbox.confirm('Do you want to delete the selected tags?', function(confirm) { + if (!confirm) { + return; + } + var tags = []; + tagsToDelete.each(function(index, el) { + tags.push($(el).attr('data-tag')); + }); + socket.emit('admin.tags.deleteTags', {tags: tags}, function(err) { + if (err) { + return app.alertError(err.message); + } + tagsToDelete.remove(); + }); + }); + }); + } function handleColorPickers() { function enableColorPicker(idx, inputEl) { @@ -96,7 +129,7 @@ define('admin/manage/tags', ['forum/infinitescroll', 'admin/modules/selectable'] bgColor : tag.find('[data-name="bgColor"]').val(), color : tag.find('[data-name="color"]').val() }; - + socket.emit('admin.tags.update', data, function(err) { if (err) { return app.alertError(err.message); diff --git a/src/controllers/tags.js b/src/controllers/tags.js index 53b418f6b9..fb97f1a24f 100644 --- a/src/controllers/tags.js +++ b/src/controllers/tags.js @@ -49,7 +49,7 @@ tagsController.getTag = function(req, res, next) { }; tagsController.getTags = function(req, res, next) { - topics.getTags(0, 99, function(err, tags) { + topics.getTags(0, 100, function(err, tags) { if (err) { return next(err); } diff --git a/src/socket.io/admin/tags.js b/src/socket.io/admin/tags.js index 08ceca1a9f..ad7ffa7201 100644 --- a/src/socket.io/admin/tags.js +++ b/src/socket.io/admin/tags.js @@ -11,5 +11,9 @@ Tags.update = function(socket, data, callback) { topics.updateTag(data.tag, data, callback); }; +Tags.deleteTags = function(socket, data, callback) { + topics.deleteTags(data.tags, callback); +}; + module.exports = Tags; \ No newline at end of file diff --git a/src/topics/tags.js b/src/topics/tags.js index 07b65b9ceb..4cd650850f 100644 --- a/src/topics/tags.js +++ b/src/topics/tags.js @@ -64,7 +64,7 @@ module.exports = function(Topics) { function updateTagCount(tag, callback) { callback = callback || function() {}; Topics.getTagTopicCount(tag, function(err, count) { - if (!err) { + if (!err && count) { db.sortedSetAdd('tags:topic:count', count, tag, callback); } }); @@ -78,13 +78,49 @@ module.exports = function(Topics) { db.sortedSetCard('tag:' + tag + ':topics', callback); }; + Topics.deleteTags = function(tags, callback) { + if (!Array.isArray(tags) || !tags.length) { + return callback(); + } + + async.series([ + function(next) { + removeTagsFromTopics(tags, next); + }, + function(next) { + var keys = tags.map(function(tag) { + return 'tag:' + tag + ':topics'; + }); + db.deleteAll(keys, next); + }, + function(next) { + db.sortedSetRemove('tags:topic:count', tags, next); + } + ], callback); + }; + + function removeTagsFromTopics(tags, callback) { + async.eachLimit(tags, 50, function(tag, next) { + db.getSortedSetRange('tag:' + tag + ':topics', 0, -1, function(err, tids) { + if (err || !tids.length) { + return next(err); + } + var keys = tids.map(function(tid) { + return 'topic:' + tid + ':tags'; + }); + + db.setsRemove(keys, tag, next); + }); + }, callback); + } + Topics.deleteTag = function(tag) { db.delete('tag:' + tag + ':topics'); db.sortedSetRemove('tags:topic:count', tag); }; - Topics.getTags = function(start, end, callback) { - db.getSortedSetRevRangeWithScores('tags:topic:count', start, end, function(err, tags) { + Topics.getTags = function(start, count, callback) { + db.getSortedSetRevRangeByScoreWithScores('tags:topic:count', start, count, '+inf', 1, function(err, tags) { if (err) { return callback(err); } diff --git a/src/views/admin/manage/tags.tpl b/src/views/admin/manage/tags.tpl index c83aff9d2e..afacffb2d4 100644 --- a/src/views/admin/manage/tags.tpl +++ b/src/views/admin/manage/tags.tpl @@ -40,6 +40,7 @@

Select tags via clicking and/or dragging, use shift to select multiple.

+
@@ -50,5 +51,5 @@ - + \ No newline at end of file