mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-09 23:45:45 +01:00
closes #5722
This commit is contained in:
@@ -66,8 +66,8 @@
|
|||||||
"nodebb-plugin-spam-be-gone": "0.5.0",
|
"nodebb-plugin-spam-be-gone": "0.5.0",
|
||||||
"nodebb-rewards-essentials": "0.0.9",
|
"nodebb-rewards-essentials": "0.0.9",
|
||||||
"nodebb-theme-lavender": "4.0.1",
|
"nodebb-theme-lavender": "4.0.1",
|
||||||
"nodebb-theme-persona": "5.0.4",
|
"nodebb-theme-persona": "5.0.5",
|
||||||
"nodebb-theme-vanilla": "6.0.3",
|
"nodebb-theme-vanilla": "6.0.4",
|
||||||
"nodebb-widget-essentials": "3.0.0",
|
"nodebb-widget-essentials": "3.0.0",
|
||||||
"nodemailer": "2.6.4",
|
"nodemailer": "2.6.4",
|
||||||
"nodemailer-sendmail-transport": "1.0.0",
|
"nodemailer-sendmail-transport": "1.0.0",
|
||||||
|
|||||||
@@ -131,5 +131,6 @@
|
|||||||
"cookies.accept": "Got it!",
|
"cookies.accept": "Got it!",
|
||||||
"cookies.learn_more": "Learn More",
|
"cookies.learn_more": "Learn More",
|
||||||
|
|
||||||
"edited": "Edited"
|
"edited": "Edited",
|
||||||
|
"disabled": "Disabled"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
"thread_tools.unlock": "Unlock Topic",
|
"thread_tools.unlock": "Unlock Topic",
|
||||||
"thread_tools.move": "Move Topic",
|
"thread_tools.move": "Move Topic",
|
||||||
"thread_tools.move_all": "Move All",
|
"thread_tools.move_all": "Move All",
|
||||||
|
"thread_tools.select_category": "Select Category",
|
||||||
"thread_tools.fork": "Fork Topic",
|
"thread_tools.fork": "Fork Topic",
|
||||||
"thread_tools.delete": "Delete Topic",
|
"thread_tools.delete": "Delete Topic",
|
||||||
"thread_tools.delete-posts": "Delete Posts",
|
"thread_tools.delete-posts": "Delete Posts",
|
||||||
@@ -86,7 +87,6 @@
|
|||||||
"post_purge_confirm": "Are you sure you want to purge this post?",
|
"post_purge_confirm": "Are you sure you want to purge this post?",
|
||||||
|
|
||||||
"load_categories": "Loading Categories",
|
"load_categories": "Loading Categories",
|
||||||
"disabled_categories_note": "Disabled Categories are greyed out",
|
|
||||||
"confirm_move": "Move",
|
"confirm_move": "Move",
|
||||||
"confirm_fork": "Fork",
|
"confirm_fork": "Fork",
|
||||||
|
|
||||||
|
|||||||
@@ -297,47 +297,30 @@ define('admin/manage/category', [
|
|||||||
};
|
};
|
||||||
|
|
||||||
Category.launchParentSelector = function () {
|
Category.launchParentSelector = function () {
|
||||||
socket.emit('categories.get', function (err, categories) {
|
var categories = ajaxify.data.allCategories.filter(function (category) {
|
||||||
if (err) {
|
return category && !category.disabled && parseInt(category.cid, 10) !== parseInt(ajaxify.data.category.cid, 10);
|
||||||
return app.alertError(err.message);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
categories = categories.filter(function (category) {
|
selectCategoryModal(categories, function (parentCid) {
|
||||||
return category && !category.disabled && parseInt(category.cid, 10) !== parseInt(ajaxify.data.category.cid, 10);
|
var payload = {};
|
||||||
});
|
|
||||||
|
|
||||||
templates.parse('partials/category_list', {
|
payload[ajaxify.data.category.cid] = {
|
||||||
categories: categories,
|
parentCid: parentCid,
|
||||||
}, function (html) {
|
};
|
||||||
var modal = bootbox.dialog({
|
|
||||||
message: html,
|
socket.emit('admin.categories.update', payload, function (err) {
|
||||||
title: '[[admin/manage/categories:alert.set-parent-category]]',
|
if (err) {
|
||||||
|
return app.alertError(err.message);
|
||||||
|
}
|
||||||
|
var parent = ajaxify.data.allCategories.filter(function (category) {
|
||||||
|
return category && parseInt(category.cid, 10) === parseInt(parentCid, 10);
|
||||||
});
|
});
|
||||||
|
parent = parent[0];
|
||||||
|
|
||||||
modal.find('li[data-cid]').on('click', function () {
|
$('button[data-action="removeParent"]').parent().removeClass('hide');
|
||||||
var parentCid = $(this).attr('data-cid');
|
$('button[data-action="setParent"]').addClass('hide');
|
||||||
var payload = {};
|
var buttonHtml = '<i class="fa ' + parent.icon + '"></i> ' + parent.name;
|
||||||
|
$('button[data-action="changeParent"]').html(buttonHtml).parent().removeClass('hide');
|
||||||
payload[ajaxify.data.category.cid] = {
|
|
||||||
parentCid: parentCid,
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.emit('admin.categories.update', payload, function (err) {
|
|
||||||
if (err) {
|
|
||||||
return app.alertError(err.message);
|
|
||||||
}
|
|
||||||
var parent = categories.filter(function (category) {
|
|
||||||
return category && parseInt(category.cid, 10) === parseInt(parentCid, 10);
|
|
||||||
});
|
|
||||||
parent = parent[0];
|
|
||||||
|
|
||||||
modal.modal('hide');
|
|
||||||
$('button[data-action="removeParent"]').parent().removeClass('hide');
|
|
||||||
$('button[data-action="setParent"]').addClass('hide');
|
|
||||||
var buttonHtml = '<i class="fa ' + parent.icon + '"></i> ' + parent.name;
|
|
||||||
$('button[data-action="changeParent"]').html(buttonHtml).parent().removeClass('hide');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -418,37 +401,35 @@ define('admin/manage/category', [
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function selectCategoryModal(callback) {
|
function selectCategoryModal(categories, callback) {
|
||||||
socket.emit('admin.categories.getNames', function (err, categories) {
|
if (typeof categories === 'function') {
|
||||||
if (err) {
|
callback = categories;
|
||||||
return app.alertError(err.message);
|
categories = ajaxify.data.allCategories;
|
||||||
}
|
}
|
||||||
|
templates.parse('admin/partials/categories/select-category', {
|
||||||
templates.parse('admin/partials/categories/select-category', {
|
categories: categories,
|
||||||
categories: categories,
|
}, function (html) {
|
||||||
}, function (html) {
|
translator.translate(html, function (html) {
|
||||||
translator.translate(html, function (html) {
|
var modal = bootbox.dialog({
|
||||||
var modal = bootbox.dialog({
|
title: 'Select a Category',
|
||||||
title: 'Select a Category',
|
message: html,
|
||||||
message: html,
|
buttons: {
|
||||||
buttons: {
|
save: {
|
||||||
save: {
|
label: 'Copy',
|
||||||
label: 'Copy',
|
className: 'btn-primary',
|
||||||
className: 'btn-primary',
|
callback: submit,
|
||||||
callback: submit,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
},
|
||||||
|
|
||||||
function submit() {
|
|
||||||
var formData = modal.find('form').serializeObject();
|
|
||||||
callback(formData['select-cid']);
|
|
||||||
modal.modal('hide');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
modal.find('form').on('submit', submit);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function submit() {
|
||||||
|
var formData = modal.find('form').serializeObject();
|
||||||
|
callback(formData['select-cid']);
|
||||||
|
modal.modal('hide');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
modal.find('form').on('submit', submit);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
define('forum/topic/move', function () {
|
define('forum/topic/move', function () {
|
||||||
var Move = {};
|
var Move = {};
|
||||||
var modal;
|
var modal;
|
||||||
var selectedEl;
|
var selectedCategory;
|
||||||
|
|
||||||
Move.init = function (tids, currentCid, onComplete) {
|
Move.init = function (tids, currentCid, onComplete) {
|
||||||
Move.tids = tids;
|
Move.tids = tids;
|
||||||
@@ -31,8 +31,17 @@ define('forum/topic/move', function () {
|
|||||||
modal.find('.modal-header h3').translateText('[[topic:move_topics]]');
|
modal.find('.modal-header h3').translateText('[[topic:move_topics]]');
|
||||||
}
|
}
|
||||||
|
|
||||||
modal.on('click', '.category-list li[data-cid]', function () {
|
modal.find('#select-cid').on('change', function () {
|
||||||
selectCategory($(this));
|
var cid = $(this).val();
|
||||||
|
var optionEl = $(this).find('option[value="' + cid + '"]');
|
||||||
|
|
||||||
|
var selectedCategory = {
|
||||||
|
cid: cid,
|
||||||
|
name: optionEl.attr('data-name'),
|
||||||
|
text: optionEl.text(),
|
||||||
|
icon: optionEl.attr('data-icon'),
|
||||||
|
};
|
||||||
|
selectCategory(selectedCategory);
|
||||||
});
|
});
|
||||||
|
|
||||||
modal.find('#move_thread_commit').on('click', onCommitClicked);
|
modal.find('#move_thread_commit').on('click', onCommitClicked);
|
||||||
@@ -42,60 +51,25 @@ define('forum/topic/move', function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseModal(categories, callback) {
|
function parseModal(categories, callback) {
|
||||||
templates.parse('partials/move_thread_modal', { categories: [] }, function (html) {
|
app.parseAndTranslate('partials/move_thread_modal', { categories: categories }, function (html) {
|
||||||
require(['translator'], function (translator) {
|
modal = $(html);
|
||||||
translator.translate(html, function (html) {
|
|
||||||
modal = $(html);
|
|
||||||
categories.forEach(function (category) {
|
|
||||||
if (!category.link) {
|
|
||||||
buildRecursive(modal.find('.category-list'), category, '');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildRecursive(parentEl, category, level) {
|
callback();
|
||||||
var categoryEl = $('<li/>');
|
|
||||||
|
|
||||||
if (category.bgColor) {
|
|
||||||
categoryEl.css('background-color', category.bgColor);
|
|
||||||
}
|
|
||||||
if (category.color) {
|
|
||||||
categoryEl.css('color', category.color);
|
|
||||||
}
|
|
||||||
categoryEl.toggleClass('disabled', !!category.disabled);
|
|
||||||
categoryEl.attr('data-cid', category.cid);
|
|
||||||
categoryEl.attr('data-icon', category.icon);
|
|
||||||
categoryEl.attr('data-name', category.name);
|
|
||||||
categoryEl.html('<i class="fa fa-fw ' + category.icon + '"></i> ' + category.name);
|
|
||||||
|
|
||||||
parentEl.append(level);
|
|
||||||
parentEl.append(categoryEl);
|
|
||||||
parentEl.append('<br/>');
|
|
||||||
|
|
||||||
var indent = ' ';
|
|
||||||
category.children.forEach(function (childCategory) {
|
|
||||||
if (!childCategory.link) {
|
|
||||||
buildRecursive(parentEl, childCategory, indent + level);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectCategory(category) {
|
function selectCategory(category) {
|
||||||
modal.find('#confirm-category-name').html(category.html());
|
modal.find('#confirm-category-name').text(category.name);
|
||||||
modal.find('#move-confirm').removeClass('hide');
|
modal.find('#move-confirm').removeClass('hide');
|
||||||
|
|
||||||
selectedEl = category;
|
selectedCategory = category;
|
||||||
modal.find('#move_thread_commit').prop('disabled', false);
|
modal.find('#move_thread_commit').prop('disabled', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCommitClicked() {
|
function onCommitClicked() {
|
||||||
var commitEl = modal.find('#move_thread_commit');
|
var commitEl = modal.find('#move_thread_commit');
|
||||||
|
|
||||||
if (!commitEl.prop('disabled') && selectedEl.attr('data-cid')) {
|
if (!commitEl.prop('disabled') && selectedCategory && selectedCategory.cid) {
|
||||||
commitEl.prop('disabled', true);
|
commitEl.prop('disabled', true);
|
||||||
|
|
||||||
moveTopics();
|
moveTopics();
|
||||||
@@ -105,7 +79,7 @@ define('forum/topic/move', function () {
|
|||||||
function moveTopics() {
|
function moveTopics() {
|
||||||
socket.emit(Move.moveAll ? 'topics.moveAll' : 'topics.move', {
|
socket.emit(Move.moveAll ? 'topics.moveAll' : 'topics.move', {
|
||||||
tids: Move.tids,
|
tids: Move.tids,
|
||||||
cid: selectedEl.attr('data-cid'),
|
cid: selectedCategory.cid,
|
||||||
currentCid: Move.currentCid,
|
currentCid: Move.currentCid,
|
||||||
}, function (err) {
|
}, function (err) {
|
||||||
modal.modal('hide');
|
modal.modal('hide');
|
||||||
@@ -114,7 +88,7 @@ define('forum/topic/move', function () {
|
|||||||
return app.alertError(err.message);
|
return app.alertError(err.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.alertSuccess('[[topic:topic_move_success, ' + selectedEl.attr('data-name') + ']] <i class="fa fa-fw ' + selectedEl.attr('data-icon') + '"></i>');
|
app.alertSuccess('[[topic:topic_move_success, ' + selectedCategory.name + ']] <i class="fa fa-fw ' + selectedCategory.icon + '"></i>');
|
||||||
if (typeof Move.onComplete === 'function') {
|
if (typeof Move.onComplete === 'function') {
|
||||||
Move.onComplete();
|
Move.onComplete();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -315,6 +315,17 @@ Categories.getTree = function (categories, parentCid) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Categories.buildForSelect = function (uid, callback) {
|
Categories.buildForSelect = function (uid, callback) {
|
||||||
|
async.waterfall([
|
||||||
|
function (next) {
|
||||||
|
Categories.getCategoriesByPrivilege('cid:0:children', uid, 'read', next);
|
||||||
|
},
|
||||||
|
function (categories, next) {
|
||||||
|
Categories.buildForSelectCategories(categories, next);
|
||||||
|
},
|
||||||
|
], callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
Categories.buildForSelectCategories = function (categories, callback) {
|
||||||
function recursive(category, categoriesData, level) {
|
function recursive(category, categoriesData, level) {
|
||||||
if (category.link) {
|
if (category.link) {
|
||||||
return;
|
return;
|
||||||
@@ -329,23 +340,17 @@ Categories.buildForSelect = function (uid, callback) {
|
|||||||
recursive(child, categoriesData, ' ' + level);
|
recursive(child, categoriesData, ' ' + level);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async.waterfall([
|
|
||||||
function (next) {
|
|
||||||
Categories.getCategoriesByPrivilege('cid:0:children', uid, 'read', next);
|
|
||||||
},
|
|
||||||
function (categories, next) {
|
|
||||||
var categoriesData = [];
|
|
||||||
|
|
||||||
categories = categories.filter(function (category) {
|
var categoriesData = [];
|
||||||
return category && !category.link && !parseInt(category.parentCid, 10);
|
|
||||||
});
|
|
||||||
|
|
||||||
categories.forEach(function (category) {
|
categories = categories.filter(function (category) {
|
||||||
recursive(category, categoriesData, '');
|
return category && !category.link && !parseInt(category.parentCid, 10);
|
||||||
});
|
});
|
||||||
next(null, categoriesData);
|
|
||||||
},
|
categories.forEach(function (category) {
|
||||||
], callback);
|
recursive(category, categoriesData, '');
|
||||||
|
});
|
||||||
|
callback(null, categoriesData);
|
||||||
};
|
};
|
||||||
|
|
||||||
Categories.getIgnorers = function (cid, start, stop, callback) {
|
Categories.getIgnorers = function (cid, start, stop, callback) {
|
||||||
|
|||||||
@@ -160,12 +160,12 @@ SocketCategories.getMoveCategories = function (socket, data, callback) {
|
|||||||
function (next) {
|
function (next) {
|
||||||
db.getSortedSetRange('cid:0:children', 0, -1, next);
|
db.getSortedSetRange('cid:0:children', 0, -1, next);
|
||||||
},
|
},
|
||||||
function (cids, next) {
|
|
||||||
privileges.categories.filterCids('read', cids, socket.uid, next);
|
|
||||||
},
|
|
||||||
function (cids, next) {
|
function (cids, next) {
|
||||||
categories.getCategories(cids, socket.uid, next);
|
categories.getCategories(cids, socket.uid, next);
|
||||||
},
|
},
|
||||||
|
function (categoriesData, next) {
|
||||||
|
categories.buildForSelectCategories(categoriesData, next);
|
||||||
|
},
|
||||||
], next);
|
], next);
|
||||||
},
|
},
|
||||||
}, next);
|
}, next);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<label for="select-cid">[[admin/manage/categories:select-category]]</label>
|
<label for="select-cid">[[admin/manage/categories:select-category]]</label>
|
||||||
<select class="form-control" name="select-cid" id="select-cid">
|
<select class="form-control" name="select-cid" id="select-cid">
|
||||||
<!-- BEGIN categories -->
|
<!-- BEGIN categories -->
|
||||||
<option value="{categories.cid}">{categories.name}</option>
|
<option value="{categories.cid}">{categories.text}</option>
|
||||||
<!-- END categories -->
|
<!-- END categories -->
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
<div class="modal fade" id="setParent" tabindex="-1" role="dialog" aria-labelledby="setParentLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<button type="button" class="close" data-dismiss="modal">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
<span class="sr-only">[[global:buttons.close]]</span>
|
|
||||||
</button>
|
|
||||||
<h4 class="modal-title" id="setParentLabel">
|
|
||||||
[[admin/manage/categories:set-parent-category]]
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<!-- IMPORT partials/category_list.tpl -->
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">
|
|
||||||
[[global:buttons.close]]
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
Reference in New Issue
Block a user