v1.18.x
Barış Soner Uşaklı 7 years ago
parent ea64a6060b
commit f3fda152bf

@ -6,6 +6,7 @@
"description": "Select tags via clicking and/or dragging, use shift to select multiple.",
"create": "Create Tag",
"modify": "Modify Tags",
"rename": "Rename Tags",
"delete": "Delete Selected Tags",
"search": "Search for tags...",
"settings": "Click <a href=\"%1\">here</a> to visit the tag settings page.",

@ -15,6 +15,7 @@ define('admin/manage/tags', [
handleCreate();
handleSearch();
handleModify();
handleRename();
handleDeleteSelected();
};
@ -103,15 +104,25 @@ define('admin/manage/tags', [
var modal = $('.bootbox');
var bgColor = modal.find('[data-name="bgColor"]').val();
var color = modal.find('[data-name="color"]').val();
var data = [];
tagsToModify.each(function (idx, tag) {
tag = $(tag);
data.push({
value: tag.attr('data-tag'),
color: modal.find('[data-name="color"]').val(),
bgColor: modal.find('[data-name="bgColor"]').val(),
});
tag.find('[data-name="bgColor"]').val(bgColor);
tag.find('[data-name="color"]').val(color);
tag.find('.tag-item').css('background-color', bgColor).css('color', color);
});
save(tag);
socket.emit('admin.tags.update', data, function (err) {
if (err) {
return app.alertError(err.message);
}
app.alertSuccess('[[admin/manage/tags:alerts.update-success]]');
});
},
},
@ -122,6 +133,46 @@ define('admin/manage/tags', [
});
}
function handleRename() {
$('#rename').on('click', function () {
var tagsToModify = $('.tag-row.ui-selected');
if (!tagsToModify.length) {
return;
}
var firstTag = $(tagsToModify[0]);
var title = tagsToModify.length > 1 ? '[[admin/manage/tags:alerts.editing-multiple]]' : '[[admin/manage/tags:alerts.editing-x, ' + firstTag.find('.tag-item').attr('data-tag') + ']]';
var modal = bootbox.dialog({
title: title,
message: $('.rename-modal').html(),
buttons: {
success: {
label: 'Save',
className: 'btn-primary save',
callback: function () {
var data = [];
tagsToModify.each(function (idx, tag) {
tag = $(tag);
data.push({
value: tag.attr('data-tag'),
newName: modal.find('[data-name="value"]').val(),
});
});
socket.emit('admin.tags.rename', data, function (err) {
if (err) {
return app.alertError(err.message);
}
app.alertSuccess('[[admin/manage/tags:alerts.update-success]]');
});
},
},
},
});
});
}
function handleDeleteSelected() {
$('#deleteSelected').on('click', function () {
var tagsToDelete = $('.tag-row.ui-selected');
@ -158,21 +209,5 @@ define('admin/manage/tags', [
modal.find('[data-name="bgColor"], [data-name="color"]').each(enableColorPicker);
}
function save(tag) {
var data = {
tag: tag.attr('data-tag'),
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);
}
app.alertSuccess('[[admin/manage/tags:alerts.update-success]]');
});
}
return Tags;
});

@ -140,7 +140,7 @@ module.exports = function (Posts) {
db.setObject('topic:' + tid, results.topic, next);
},
function (next) {
topics.updateTags(tid, data.tags, next);
topics.updateTopicTags(tid, data.tags, next);
},
function (next) {
topics.getTopicTagsObjects(tid, next);

@ -13,11 +13,19 @@ Tags.create = function (socket, data, callback) {
};
Tags.update = function (socket, data, callback) {
if (!data) {
if (!Array.isArray(data)) {
return callback(new Error('[[error:invalid-data]]'));
}
topics.updateTags(data, callback);
};
Tags.rename = function (socket, data, callback) {
if (!Array.isArray(data)) {
return callback(new Error('[[error:invalid-data]]'));
}
topics.updateTag(data.tag, data, callback);
topics.renameTags(data, callback);
};
Tags.deleteTags = function (socket, data, callback) {

@ -9,7 +9,7 @@ var meta = require('../meta');
var _ = require('lodash');
var plugins = require('../plugins');
var utils = require('../utils');
var batch = require('../batch');
module.exports = function (Topics) {
Topics.createTags = function (tags, tid, timestamp, callback) {
@ -96,13 +96,61 @@ module.exports = function (Topics) {
], callback);
};
Topics.updateTag = function (tag, data, callback) {
if (!tag) {
return setImmediate(callback, new Error('[[error:invalid-tag]]'));
}
db.setObject('tag:' + tag, data, callback);
Topics.updateTags = function (data, callback) {
async.eachSeries(data, function (tagData, next) {
db.setObject('tag:' + tagData.value, {
color: tagData.color,
bgColor: tagData.bgColor,
}, next);
}, callback);
};
Topics.renameTags = function (data, callback) {
async.eachSeries(data, function (tagData, next) {
renameTag(tagData.value, tagData.newName, next);
}, callback);
};
function renameTag(tag, newTagName, callback) {
if (!newTagName || tag === newTagName) {
return setImmediate(callback);
}
async.waterfall([
function (next) {
Topics.createEmptyTag(newTagName, next);
},
function (next) {
batch.processSortedSet('tag:' + tag + ':topics', function (tids, next) {
async.waterfall([
function (next) {
db.sortedSetScores('tag:' + tag + ':topics', tids, next);
},
function (scores, next) {
db.sortedSetAdd('tag:' + newTagName + ':topics', scores, tids, next);
},
function (next) {
var keys = tids.map(function (tid) {
return 'topic:' + tid + ':tags';
});
async.series([
async.apply(db.sortedSetRemove, 'tag:' + tag + ':topics', tids),
async.apply(db.setsRemove, keys, tag),
async.apply(db.setsAdd, keys, newTagName),
], next);
},
], next);
}, next);
},
function (next) {
Topics.deleteTag(tag, next);
},
function (next) {
updateTagCount(newTagName, next);
},
], callback);
}
function updateTagCount(tag, callback) {
callback = callback || function () {};
async.waterfall([
@ -148,7 +196,9 @@ module.exports = function (Topics) {
return 'tag:' + tag;
}), next);
},
], callback);
], function (err) {
callback(err);
});
};
function removeTagsFromTopics(tags, callback) {
@ -266,7 +316,7 @@ module.exports = function (Topics) {
], callback);
};
Topics.updateTags = function (tid, tags, callback) {
Topics.updateTopicTags = function (tid, tags, callback) {
callback = callback || function () {};
async.waterfall([
function (next) {

@ -41,6 +41,7 @@
<p>[[admin/manage/tags:description]]</p>
<button class="btn btn-primary btn-block" id="create">[[admin/manage/tags:create]]</button>
<button class="btn btn-primary btn-block" id="modify">[[admin/manage/tags:modify]]</button>
<button class="btn btn-primary btn-block" id="rename">[[admin/manage/tags:rename]]</button>
<button class="btn btn-warning btn-block" id="deleteSelected">[[admin/manage/tags:delete]]</button>
</div>
</div>
@ -74,4 +75,11 @@
</div>
</div>
</div>
<div class="rename-modal hidden">
<div class="form-group">
<label for="value">[[admin/manage/tags:name]]</label>
<input id="value" data-name="value" value="{tags.value}" class="form-control" />
</div>
</div>
</div>

@ -1350,22 +1350,22 @@ describe('Topic\'s', function () {
});
});
it('should error if data.tag is invalid', function (done) {
it('should error if data is not an array', function (done) {
socketAdmin.tags.update({ uid: adminUid }, {
bgColor: '#ff0000',
color: '#00ff00',
}, function (err) {
assert.equal(err.message, '[[error:invalid-tag]]');
assert.equal(err.message, '[[error:invalid-data]]');
done();
});
});
it('should update tag', function (done) {
socketAdmin.tags.update({ uid: adminUid }, {
tag: 'emptytag',
socketAdmin.tags.update({ uid: adminUid }, [{
value: 'emptytag',
bgColor: '#ff0000',
color: '#00ff00',
}, function (err) {
}], function (err) {
assert.ifError(err);
db.getObject('tag:emptytag', function (err, data) {
assert.ifError(err);
@ -1376,6 +1376,35 @@ describe('Topic\'s', function () {
});
});
it('should rename tags', function (done) {
async.parallel({
topic1: function (next) {
topics.post({ uid: adminUid, tags: ['plugins'], title: 'topic tagged with plugins', content: 'topic 1 content', cid: topic.categoryId }, next);
},
topic2: function (next) {
topics.post({ uid: adminUid, tags: ['plugin'], title: 'topic tagged with plugin', content: 'topic 2 content', cid: topic.categoryId }, next);
},
}, function (err, result) {
assert.ifError(err);
socketAdmin.tags.rename({ uid: adminUid }, [{
value: 'plugin',
newName: 'plugins',
}], function (err) {
assert.ifError(err);
topics.getTagTids('plugins', 0, -1, function (err, tids) {
assert.ifError(err);
assert.equal(tids.length, 2);
topics.getTopicTags(result.topic2.topicData.tid, function (err, tags) {
assert.ifError(err);
assert.equal(tags.length, 1);
assert.equal(tags[0], 'plugins');
done();
});
});
});
});
});
it('should return related topics', function (done) {
var meta = require('../src/meta');
meta.config.maximumRelatedTopics = 2;

Loading…
Cancel
Save