mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-06 14:05:46 +01:00
closes #1995
This commit is contained in:
60
public/src/forum/admin/tags.js
Normal file
60
public/src/forum/admin/tags.js
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
"use strict";
|
||||||
|
/*global define, socket, app, admin*/
|
||||||
|
|
||||||
|
define('forum/admin/tags', [], function() {
|
||||||
|
var Tags = {};
|
||||||
|
|
||||||
|
Tags.init = function() {
|
||||||
|
handleColorPickers();
|
||||||
|
|
||||||
|
$('.tag-list').on('click', '.save', function() {
|
||||||
|
save($(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#tag-search').on('input propertychange', function() {
|
||||||
|
$('.tag-list').children().each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
$this.toggleClass('hide', $this.attr('data-tag').indexOf($('#tag-search').val()) === -1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleColorPickers() {
|
||||||
|
function enableColorPicker(idx, inputEl) {
|
||||||
|
var $inputEl = $(inputEl),
|
||||||
|
previewEl = $inputEl.parents('.tag-row').find('.tag-item');
|
||||||
|
|
||||||
|
admin.enableColorPicker($inputEl, function(hsb, hex) {
|
||||||
|
if ($inputEl.attr('data-name') === 'bgColor') {
|
||||||
|
previewEl.css('background-color', '#' + hex);
|
||||||
|
} else if ($inputEl.attr('data-name') === 'color') {
|
||||||
|
previewEl.css('color', '#' + hex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$('[data-name="bgColor"], [data-name="color"]').each(enableColorPicker);
|
||||||
|
}
|
||||||
|
|
||||||
|
function save(saveBtn) {
|
||||||
|
var tagRow = saveBtn.parents('.tag-row');
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
tag: tagRow.attr('data-tag'),
|
||||||
|
bgColor : tagRow.find('[data-name="bgColor"]').val(),
|
||||||
|
color : tagRow.find('[data-name="color"]').val()
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.emit('admin.tags.update', data, function(err) {
|
||||||
|
if (err) {
|
||||||
|
return app.alertError(err.message);
|
||||||
|
}
|
||||||
|
app.alertSuccess('Tag Updated!');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return Tags;
|
||||||
|
});
|
||||||
@@ -16,9 +16,9 @@ var async = require('async'),
|
|||||||
validator = require('validator');
|
validator = require('validator');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var adminController = {
|
var adminController = {
|
||||||
categories: {},
|
categories: {},
|
||||||
|
tags: {},
|
||||||
topics: {},
|
topics: {},
|
||||||
groups: {},
|
groups: {},
|
||||||
themes: {},
|
themes: {},
|
||||||
@@ -126,6 +126,16 @@ function filterAndRenderCategories(req, res, next, active) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adminController.tags.get = function(req, res, next) {
|
||||||
|
topics.getTags(0, -1, function(err, tags) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render('admin/tags', {tags: tags});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
adminController.database.get = function(req, res, next) {
|
adminController.database.get = function(req, res, next) {
|
||||||
db.info(function (err, data) {
|
db.info(function (err, data) {
|
||||||
res.render('admin/database', data);
|
res.render('admin/database', data);
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ function forumRoutes(app, middleware, controllers) {
|
|||||||
|
|
||||||
app.get('/admin/categories/disabled', middleware.admin.buildHeader, controllers.admin.categories.disabled);
|
app.get('/admin/categories/disabled', middleware.admin.buildHeader, controllers.admin.categories.disabled);
|
||||||
app.get('/api/admin/categories/disabled', controllers.admin.categories.disabled);
|
app.get('/api/admin/categories/disabled', controllers.admin.categories.disabled);
|
||||||
|
|
||||||
|
app.get('/admin/tags', middleware.admin.buildHeader, controllers.admin.tags.get);
|
||||||
|
app.get('/api/admin/tags', controllers.admin.tags.get);
|
||||||
}
|
}
|
||||||
|
|
||||||
function apiRoutes(app, middleware, controllers) {
|
function apiRoutes(app, middleware, controllers) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ var groups = require('../groups'),
|
|||||||
user: require('./admin/user'),
|
user: require('./admin/user'),
|
||||||
categories: require('./admin/categories'),
|
categories: require('./admin/categories'),
|
||||||
groups: require('./admin/groups'),
|
groups: require('./admin/groups'),
|
||||||
|
tags: require('./admin/tags'),
|
||||||
themes: {},
|
themes: {},
|
||||||
plugins: {},
|
plugins: {},
|
||||||
widgets: {},
|
widgets: {},
|
||||||
|
|||||||
15
src/socket.io/admin/tags.js
Normal file
15
src/socket.io/admin/tags.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
var topics = require('../../topics'),
|
||||||
|
Tags = {};
|
||||||
|
|
||||||
|
Tags.update = function(socket, data, callback) {
|
||||||
|
if (!data) {
|
||||||
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
topics.updateTag(data.tag, data, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = Tags;
|
||||||
@@ -57,6 +57,10 @@ module.exports = function(Topics) {
|
|||||||
return tag;
|
return tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Topics.updateTag = function(tag, data, callback) {
|
||||||
|
db.setObject('tag:' + tag, data, callback);
|
||||||
|
};
|
||||||
|
|
||||||
function updateTagCount(tag, callback) {
|
function updateTagCount(tag, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
Topics.getTagTopicCount(tag, function(err, count) {
|
Topics.getTagTopicCount(tag, function(err, count) {
|
||||||
@@ -80,9 +84,33 @@ module.exports = function(Topics) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Topics.getTags = function(start, end, callback) {
|
Topics.getTags = function(start, end, callback) {
|
||||||
db.getSortedSetRevRangeWithScores('tags:topic:count', start, end, callback);
|
db.getSortedSetRevRangeWithScores('tags:topic:count', start, end, function(err, tags) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
addTagData(tags, callback);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function addTagData(tags, callback) {
|
||||||
|
var keys = tags.map(function(tag) {
|
||||||
|
return 'tag:' + tag.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
db.getObjects(keys, function(err, tagData) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
tags.forEach(function(tag, index) {
|
||||||
|
tag.color = tagData[index] ? tagData[index].color : '';
|
||||||
|
tag.bgColor = tagData[index] ? tagData[index].bgColor : '';
|
||||||
|
});
|
||||||
|
callback(null, tags);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Topics.getTopicTags = function(tid, callback) {
|
Topics.getTopicTags = function(tid, callback) {
|
||||||
db.getSetMembers('topic:' + tid + ':tags', callback);
|
db.getSetMembers('topic:' + tid + ':tags', callback);
|
||||||
};
|
};
|
||||||
@@ -98,40 +126,46 @@ module.exports = function(Topics) {
|
|||||||
return 'topic:' + tid + ':tags';
|
return 'topic:' + tid + ':tags';
|
||||||
});
|
});
|
||||||
|
|
||||||
db.getSetsMembers(sets, function(err, members) {
|
db.getSetsMembers(sets, function(err, topicTags) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var uniqueTags = _.uniq(_.flatten(members));
|
var uniqueTopicTags = _.uniq(_.flatten(topicTags));
|
||||||
|
|
||||||
db.sortedSetScores('tags:topic:count', uniqueTags, function(err, data) {
|
var tags = uniqueTopicTags.map(function(tag) {
|
||||||
|
return {value: tag};
|
||||||
|
});
|
||||||
|
|
||||||
|
async.parallel({
|
||||||
|
tagData: function(next) {
|
||||||
|
addTagData(tags, next);
|
||||||
|
},
|
||||||
|
counts: function(next) {
|
||||||
|
db.sortedSetScores('tags:topic:count', uniqueTopicTags, next);
|
||||||
|
}
|
||||||
|
}, function(err, results) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tagCounts = _.object(uniqueTags, data);
|
results.tagData.forEach(function(tag, index) {
|
||||||
|
tag.score = results.counts[index] ? results.counts[index] : 0;
|
||||||
|
});
|
||||||
|
|
||||||
members.forEach(function(tags, index) {
|
var tagData = _.object(uniqueTopicTags, results.tagData);
|
||||||
|
|
||||||
|
topicTags.forEach(function(tags, index) {
|
||||||
if (Array.isArray(tags)) {
|
if (Array.isArray(tags)) {
|
||||||
members[index] = mapToObject(tags, tagCounts);
|
topicTags[index] = tags.map(function(tag) {return tagData[tag];});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
callback(null, members);
|
|
||||||
|
callback(null, topicTags);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapToObject(tags, tagCounts) {
|
|
||||||
if (!tags) {
|
|
||||||
return tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tags.map(function(tag) {
|
|
||||||
return {name: tag, score: tagCounts ? tagCounts[tag] : 0};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Topics.updateTags = function(tid, tags, callback) {
|
Topics.updateTags = function(tid, tags, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
Topics.getTopicField(tid, 'timestamp', function(err, timestamp) {
|
Topics.getTopicField(tid, 'timestamp', function(err, timestamp) {
|
||||||
|
|||||||
Reference in New Issue
Block a user