From b948e031f6e3220dd8763022c3c3bbd486dbff6d Mon Sep 17 00:00:00 2001 From: barisusakli Date: Fri, 1 Apr 2016 15:02:17 +0300 Subject: [PATCH] closes #2779 --- public/src/admin/manage/category.js | 42 +++++++ src/categories/create.js | 109 ++++++++++++++++-- src/socket.io/admin/categories.js | 22 ++-- src/views/admin/manage/category.tpl | 3 +- .../admin/partials/categories/create.tpl | 10 ++ .../partials/categories/select-category.tpl | 10 ++ 6 files changed, 178 insertions(+), 18 deletions(-) create mode 100644 src/views/admin/partials/categories/select-category.tpl diff --git a/public/src/admin/manage/category.js b/public/src/admin/manage/category.js index 289afa0de4..d37fac64b0 100644 --- a/public/src/admin/manage/category.js +++ b/public/src/admin/manage/category.js @@ -99,6 +99,48 @@ define('admin/manage/category', [ }); }); + $('.copy-settings').on('click', function(e) { + e.preventDefault(); + socket.emit('admin.categories.getNames', function(err, categories) { + if (err) { + return app.alertError(err.message); + } + + templates.parse('admin/partials/categories/select-category', { + categories: categories + }, function(html) { + function submit() { + var formData = modal.find('form').serializeObject(); + + socket.emit('admin.categories.copySettingsFrom', {fromCid: formData['select-cid'], toCid: ajaxify.data.category.cid}, function(err) { + if (err) { + return app.alertError(err.message); + } + app.alertSuccess('Settings Copied!'); + ajaxify.refresh(); + }); + + modal.modal('hide'); + return false; + } + + var modal = bootbox.dialog({ + title: 'Select a Category', + message: html, + buttons: { + save: { + label: 'Copy', + className: 'btn-primary', + callback: submit + } + } + }); + + modal.find('form').on('submit', submit); + }); + }); + }); + $('.upload-button').on('click', function() { var inputEl = $(this); var cid = inputEl.attr('data-cid'); diff --git a/src/categories/create.js b/src/categories/create.js index 69d1f4dcd8..7f1f3955f7 100644 --- a/src/categories/create.js +++ b/src/categories/create.js @@ -1,10 +1,12 @@ 'use strict'; -var async = require('async'), - db = require('../database'), - privileges = require('../privileges'), - plugins = require('../plugins'), - utils = require('../../public/src/utils'); +var async = require('async'); + +var db = require('../database'); +var privileges = require('../privileges'); +var groups = require('../groups'); +var plugins = require('../plugins'); +var utils = require('../../public/src/utils'); module.exports = function(Categories) { @@ -17,6 +19,7 @@ module.exports = function(Categories) { db.incrObjectField('global', 'nextCid', next); }, function(cid, next) { + data.name = data.name || 'Category ' + cid; var slug = cid + '/' + utils.slugify(data.name); var order = data.order || cid; // If no order provided, place it at the end var colours = Categories.assignColours(); @@ -58,6 +61,12 @@ module.exports = function(Categories) { ], next); }, function(results, next) { + if (data.cloneFromCid && parseInt(data.cloneFromCid, 10)) { + return Categories.copySettingsFrom(data.cloneFromCid, category.cid, next); + } + next(null, category); + }, + function(category, next) { plugins.fireHook('action:category.create', category); next(null, category); } @@ -65,10 +74,94 @@ module.exports = function(Categories) { }; Categories.assignColours = function() { - var backgrounds = ['#AB4642', '#DC9656', '#F7CA88', '#A1B56C', '#86C1B9', '#7CAFC2', '#BA8BAF', '#A16946'], - text = ['#fff', '#fff', '#333', '#fff', '#333', '#fff', '#fff', '#fff'], - index = Math.floor(Math.random() * backgrounds.length); + var backgrounds = ['#AB4642', '#DC9656', '#F7CA88', '#A1B56C', '#86C1B9', '#7CAFC2', '#BA8BAF', '#A16946']; + var text = ['#fff', '#fff', '#333', '#fff', '#333', '#fff', '#fff', '#fff']; + var index = Math.floor(Math.random() * backgrounds.length); return [backgrounds[index], text[index]]; }; + + Categories.copySettingsFrom = function(fromCid, toCid, callback) { + var destination; + async.waterfall([ + function (next) { + async.parallel({ + source: async.apply(db.getObject, 'category:' + fromCid), + destination: async.apply(db.getObject, 'category:' + toCid) + }, next); + }, + function (results, next) { + if (!results.source) { + return next(new Error('[[error:invalid-cid]]')); + } + destination = results.destination; + + var tasks = []; + if (parseInt(results.source.parentCid, 10)) { + tasks.push(async.apply(db.sortedSetAdd, 'cid:' + results.source.parentCid + ':children', results.source.order, toCid)); + } + + if (destination && parseInt(destination.parentCid, 10)) { + tasks.push(async.apply(db.sortedSetRemove, 'cid:' + destination.parentCid + ':children', toCid)); + } + + destination.description = results.source.description; + destination.descriptionParsed = results.source.descriptionParsed; + destination.icon = results.source.icon; + destination.bgColor = results.source.bgColor; + destination.color = results.source.color; + destination.link = results.source.link; + destination.numRecentReplies = results.source.numRecentReplies; + destination.class = results.source.class; + destination.imageClass = results.source.imageClass; + destination.parentCid = results.source.parentCid || 0; + + tasks.push(async.apply(db.setObject, 'category:' + toCid, destination)); + + async.series(tasks, next); + }, + function (results, next) { + Categories.copyPrivilegesFrom(fromCid, toCid, next); + } + ], function(err) { + callback(err, destination); + }); + }; + + Categories.copyPrivilegesFrom = function(fromCid, toCid, callback) { + var privilegeList = [ + 'find', 'read', 'topics:create', 'topics:reply', 'purge', 'mods', + 'groups:find', 'groups:read', 'groups:topics:create', 'groups:topics:reply', 'groups:purge', 'groups:moderate' + ]; + + async.each(privilegeList, function(privilege, next) { + copyPrivilege(privilege, fromCid, toCid, next); + }, callback); + }; + + function copyPrivilege(privilege, fromCid, toCid, callback) { + async.waterfall([ + function (next) { + db.getSortedSetRange('group:cid:' + toCid + ':privileges:' + privilege + ':members', 0, -1, next); + }, + function (currentMembers, next) { + async.eachSeries(currentMembers, function(member, next) { + groups.leave('cid:' + toCid + ':privileges:' + privilege, member, next); + }, next); + }, + function (next) { + db.getSortedSetRange('group:cid:' + fromCid + ':privileges:' + privilege + ':members', 0, -1, next); + }, + function (members, next) { + if (!members || !members.length) { + return callback(); + } + + async.eachSeries(members, function(member, next) { + groups.join('cid:' + toCid + ':privileges:' + privilege, member, next); + }, next); + } + ], callback); + } + }; diff --git a/src/socket.io/admin/categories.js b/src/socket.io/admin/categories.js index 288e395837..3b35847366 100644 --- a/src/socket.io/admin/categories.js +++ b/src/socket.io/admin/categories.js @@ -1,16 +1,16 @@ "use strict"; -var async = require('async'), +var async = require('async'); - db = require('../../database'), - groups = require('../../groups'), - categories = require('../../categories'), - privileges = require('../../privileges'), - plugins = require('../../plugins'), - Categories = {}; +var db = require('../../database'); +var groups = require('../../groups'); +var categories = require('../../categories'); +var privileges = require('../../privileges'); +var plugins = require('../../plugins'); +var Categories = {}; Categories.create = function(socket, data, callback) { - if(!data) { + if (!data) { return callback(new Error('[[error:invalid-data]]')); } @@ -46,7 +46,7 @@ Categories.purge = function(socket, cid, callback) { }; Categories.update = function(socket, data, callback) { - if(!data) { + if (!data) { return callback(new Error('[[error:invalid-data]]')); } @@ -108,4 +108,8 @@ function copyPrivilegesToChildrenRecursive(category, privilegeGroups, callback) }); } +Categories.copySettingsFrom = function(socket, data, callback) { + categories.copySettingsFrom(data.fromCid, data.toCid, callback); +}; + module.exports = Categories; \ No newline at end of file diff --git a/src/views/admin/manage/category.tpl b/src/views/admin/manage/category.tpl index ab7540d4fd..814b319913 100644 --- a/src/views/admin/manage/category.tpl +++ b/src/views/admin/manage/category.tpl @@ -105,7 +105,8 @@ - +
+
diff --git a/src/views/admin/partials/categories/create.tpl b/src/views/admin/partials/categories/create.tpl index 52e218fc0e..d4c551f1bf 100644 --- a/src/views/admin/partials/categories/create.tpl +++ b/src/views/admin/partials/categories/create.tpl @@ -12,4 +12,14 @@ + +
+ + +
\ No newline at end of file diff --git a/src/views/admin/partials/categories/select-category.tpl b/src/views/admin/partials/categories/select-category.tpl new file mode 100644 index 0000000000..7e1f9f0d28 --- /dev/null +++ b/src/views/admin/partials/categories/select-category.tpl @@ -0,0 +1,10 @@ +
+
+ + +
+
\ No newline at end of file