mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 12:05:57 +01:00
admin panel integration for category whitelisting
This commit is contained in:
@@ -19,14 +19,14 @@ define(function() {
|
|||||||
|
|
||||||
function select_icon(el) {
|
function select_icon(el) {
|
||||||
var selected = el.attr('class').replace(' fa-2x', '');
|
var selected = el.attr('class').replace(' fa-2x', '');
|
||||||
jQuery('#icons .selected').removeClass('selected');
|
$('#icons .selected').removeClass('selected');
|
||||||
if (selected)
|
if (selected)
|
||||||
jQuery('#icons .' + selected).parent().addClass('selected');
|
$('#icons .' + selected).parent().addClass('selected');
|
||||||
|
|
||||||
|
|
||||||
bootbox.confirm('<h2>Select an icon.</h2>' + document.getElementById('icons').innerHTML, function(confirm) {
|
bootbox.confirm('<h2>Select an icon.</h2>' + document.getElementById('icons').innerHTML, function(confirm) {
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
var iconClass = jQuery('.bootbox .selected').children(':first').attr('class');
|
var iconClass = $('.bootbox .selected').children(':first').attr('class');
|
||||||
|
|
||||||
el.attr('class', iconClass + ' fa-2x');
|
el.attr('class', iconClass + ' fa-2x');
|
||||||
|
|
||||||
@@ -40,9 +40,9 @@ define(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(function() { //bootbox was rewritten for BS3 and I had to add this timeout for the previous code to work. TODO: to look into
|
setTimeout(function() { //bootbox was rewritten for BS3 and I had to add this timeout for the previous code to work. TODO: to look into
|
||||||
jQuery('.bootbox .col-md-3').on('click', function() {
|
$('.bootbox .col-md-3').on('click', function() {
|
||||||
jQuery('.bootbox .selected').removeClass('selected');
|
$('.bootbox .selected').removeClass('selected');
|
||||||
jQuery(this).addClass('selected');
|
$(this).addClass('selected');
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
@@ -62,13 +62,13 @@ define(function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jQuery('#entry-container').sortable({
|
$('#entry-container').sortable({
|
||||||
stop: function( event, ui ) {
|
stop: function( event, ui ) {
|
||||||
updateCategoryOrders();
|
updateCategoryOrders();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
jQuery('.blockclass').each(function() {
|
$('.blockclass').each(function() {
|
||||||
jQuery(this).val(this.getAttribute('data-value'));
|
$(this).val(this.getAttribute('data-value'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -105,46 +105,46 @@ define(function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
jQuery('document').ready(function() {
|
$('document').ready(function() {
|
||||||
var url = window.location.href,
|
var url = window.location.href,
|
||||||
parts = url.split('/'),
|
parts = url.split('/'),
|
||||||
active = parts[parts.length - 1];
|
active = parts[parts.length - 1];
|
||||||
|
|
||||||
jQuery('.nav-pills li').removeClass('active');
|
$('.nav-pills li').removeClass('active');
|
||||||
jQuery('.nav-pills li a').each(function() {
|
$('.nav-pills li a').each(function() {
|
||||||
if (this.getAttribute('href').match(active)) {
|
if (this.getAttribute('href').match(active)) {
|
||||||
jQuery(this.parentNode).addClass('active');
|
$(this.parentNode).addClass('active');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
jQuery('#save').on('click', save);
|
$('#save').on('click', save);
|
||||||
jQuery('#addNew').on('click', showCreateCategoryModal);
|
$('#addNew').on('click', showCreateCategoryModal);
|
||||||
jQuery('#create-category-btn').on('click', createNewCategory);
|
$('#create-category-btn').on('click', createNewCategory);
|
||||||
|
|
||||||
jQuery('#entry-container').on('click', '.icon', function(ev) {
|
$('#entry-container').on('click', '.icon', function(ev) {
|
||||||
select_icon($(this).find('i'));
|
select_icon($(this).find('i'));
|
||||||
});
|
});
|
||||||
|
|
||||||
jQuery('#new-category-modal').on('click', '.icon', function(ev) {
|
$('#new-category-modal').on('click', '.icon', function(ev) {
|
||||||
select_icon($(this).find('i'));
|
select_icon($(this).find('i'));
|
||||||
});
|
});
|
||||||
|
|
||||||
jQuery('.admin-categories form input').on('change', function(ev) {
|
$('.admin-categories form input').on('change', function(ev) {
|
||||||
modified(ev.target);
|
modified(ev.target);
|
||||||
});
|
});
|
||||||
|
|
||||||
jQuery('.entry-row button').each(function(index, element) {
|
$('.entry-row button[data-disabled]').each(function(index, element) {
|
||||||
var disabled = $(element).attr('data-disabled');
|
var disabled = $(element).attr('data-disabled');
|
||||||
if (disabled == "0" || disabled == "")
|
if (disabled == "0" || disabled == "") {
|
||||||
$(element).html('Disable');
|
$(element).html('Disable');
|
||||||
else
|
} else {
|
||||||
$(element).html('Enable');
|
$(element).html('Enable');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
jQuery('#entry-container').on('click', '.disable-btn', function(ev) {
|
$('#entry-container').on('click', '.disable-btn', function(ev) {
|
||||||
var btn = jQuery(this);
|
var btn = $(this);
|
||||||
var categoryRow = btn.parents('li');
|
var categoryRow = btn.parents('li');
|
||||||
var cid = categoryRow.attr('data-cid');
|
var cid = categoryRow.attr('data-cid');
|
||||||
|
|
||||||
@@ -172,6 +172,105 @@ define(function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Permissions modal
|
||||||
|
$('.permissions').on('click', function() {
|
||||||
|
var cid = $(this).parents('li[data-cid]').attr('data-cid');
|
||||||
|
Categories.launchPermissionsModal(cid);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Categories.launchPermissionsModal = function(cid) {
|
||||||
|
var modal = $('#category-permissions-modal'),
|
||||||
|
searchEl = modal.find('#permission-search'),
|
||||||
|
resultsEl = modal.find('.search-results'),
|
||||||
|
searchDelay;
|
||||||
|
|
||||||
|
searchEl.off('keyup').on('keyup', function() {
|
||||||
|
var searchEl = this,
|
||||||
|
resultsFrag = document.createDocumentFragment(),
|
||||||
|
liEl = document.createElement('li');
|
||||||
|
clearTimeout(searchDelay);
|
||||||
|
|
||||||
|
searchDelay = setTimeout(function() {
|
||||||
|
socket.emit('api:admin.categories.search', searchEl.value, cid, function(err, results) {
|
||||||
|
var numResults = results.length,
|
||||||
|
resultObj;
|
||||||
|
for(var x=0;x<numResults;x++) {
|
||||||
|
resultObj = results[x];
|
||||||
|
|
||||||
|
liEl.setAttribute('data-uid', resultObj.uid);
|
||||||
|
liEl.innerHTML = '<div class="pull-right">' +
|
||||||
|
'<div class="btn-group">' +
|
||||||
|
'<button type="button" data-priv="+r" class="btn btn-default' + (resultObj.privileges['+r'] ? ' active' : '') + '">Read</button>' +
|
||||||
|
'<button type="button" data-priv="+w" class="btn btn-default' + (resultObj.privileges['+w'] ? ' active' : '') + '">Write</button>' +
|
||||||
|
'</div>' +
|
||||||
|
'</div>' +
|
||||||
|
'<img src="' + resultObj.picture + '" /> ' + resultObj.username;
|
||||||
|
|
||||||
|
resultsFrag.appendChild(liEl.cloneNode(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
resultsEl.html(resultsFrag);
|
||||||
|
});
|
||||||
|
}, 250);
|
||||||
|
});
|
||||||
|
|
||||||
|
Categories.refreshPrivilegeList(cid);
|
||||||
|
|
||||||
|
resultsEl.on('click', '[data-priv]', function(e) {
|
||||||
|
var btnEl = $(this),
|
||||||
|
uid = btnEl.parents('li[data-uid]').attr('data-uid'),
|
||||||
|
privilege = this.getAttribute('data-priv');
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
socket.emit('api:admin.categories.setPrivilege', cid, uid, privilege, !btnEl.hasClass('active'), function(err, privileges) {
|
||||||
|
btnEl.toggleClass('active', privileges[privilege]);
|
||||||
|
|
||||||
|
Categories.refreshPrivilegeList(cid);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.on('click', '.members li > img', function() {
|
||||||
|
console.log('clicked', this);
|
||||||
|
searchEl.val(this.getAttribute('title'));
|
||||||
|
searchEl.keyup();
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.modal();
|
||||||
|
};
|
||||||
|
|
||||||
|
Categories.refreshPrivilegeList = function (cid) {
|
||||||
|
var modalEl = $('#category-permissions-modal'),
|
||||||
|
readMembers = modalEl.find('#category-permissions-read'),
|
||||||
|
writeMembers = modalEl.find('#category-permissions-write');
|
||||||
|
socket.emit('api:admin.categories.getPrivilegeSettings', cid, function(err, privilegeList) {
|
||||||
|
var readLength = privilegeList['+r'].members.length,
|
||||||
|
writeLength = privilegeList['+w'].members.length,
|
||||||
|
readFrag = document.createDocumentFragment(),
|
||||||
|
writeFrag = document.createDocumentFragment(),
|
||||||
|
liEl = document.createElement('li'),
|
||||||
|
x, userObj;
|
||||||
|
|
||||||
|
for(x=0;x<readLength;x++) {
|
||||||
|
userObj = privilegeList['+r'].members[x];
|
||||||
|
liEl.setAttribute('data-uid', userObj.uid);
|
||||||
|
|
||||||
|
liEl.innerHTML = '<img src="' + userObj.picture + '" title="' + userObj.username + '" />';
|
||||||
|
readFrag.appendChild(liEl.cloneNode(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(x=0;x<writeLength;x++) {
|
||||||
|
userObj = privilegeList['+w'].members[x];
|
||||||
|
liEl.setAttribute('data-uid', userObj.uid);
|
||||||
|
|
||||||
|
liEl.innerHTML = '<img src="' + userObj.picture + '" title="' + userObj.username + '" />';
|
||||||
|
writeFrag.appendChild(liEl.cloneNode(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
readMembers.html(readFrag);
|
||||||
|
writeMembers.html(writeFrag);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -33,6 +33,8 @@ CategoryTools.privileges = function(cid, uid, callback) {
|
|||||||
}
|
}
|
||||||
}, function(err, privileges) {
|
}, function(err, privileges) {
|
||||||
callback(err, !privileges ? null : {
|
callback(err, !privileges ? null : {
|
||||||
|
"+r": privileges['+r'],
|
||||||
|
"+w": privileges['+w'],
|
||||||
read: privileges['+r'] || privileges.moderator || privileges.admin,
|
read: privileges['+r'] || privileges.moderator || privileges.admin,
|
||||||
write: privileges['+w'] || privileges.moderator || privileges.admin,
|
write: privileges['+w'] || privileges.moderator || privileges.admin,
|
||||||
editable: privileges.moderator || privileges.admin,
|
editable: privileges.moderator || privileges.admin,
|
||||||
|
|||||||
@@ -63,6 +63,16 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Groups.getByGroupName = function(groupName, options, callback) {
|
||||||
|
Groups.getGidFromName(groupName, function(err, gid) {
|
||||||
|
if (err || !gid) {
|
||||||
|
callback(new Error('gid-not-found'));
|
||||||
|
} else {
|
||||||
|
Groups.get(gid, options, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Groups.isDeleted = function(gid, callback) {
|
Groups.isDeleted = function(gid, callback) {
|
||||||
RDB.hget('gid:' + gid, 'deleted', function(err, deleted) {
|
RDB.hget('gid:' + gid, 'deleted', function(err, deleted) {
|
||||||
callback(err, deleted === '1');
|
callback(err, deleted === '1');
|
||||||
@@ -156,8 +166,28 @@
|
|||||||
RDB.sadd('gid:' + gid + ':members', uid, callback);
|
RDB.sadd('gid:' + gid + ':members', uid, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Groups.joinByGroupName = function(groupName, uid, callback) {
|
||||||
|
Groups.getGidFromName(groupName, function(err, gid) {
|
||||||
|
if (err || !gid) {
|
||||||
|
callback(new Error('gid-not-found'));
|
||||||
|
} else {
|
||||||
|
Groups.join(gid, uid, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Groups.leave = function(gid, uid, callback) {
|
Groups.leave = function(gid, uid, callback) {
|
||||||
RDB.srem('gid:' + gid + ':members', uid, callback);
|
RDB.srem('gid:' + gid + ':members', uid, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Groups.leaveByGroupName = function(groupName, uid, callback) {
|
||||||
|
Groups.getGidFromName(groupName, function(err, gid) {
|
||||||
|
if (err || !gid) {
|
||||||
|
callback(new Error('gid-not-found'));
|
||||||
|
} else {
|
||||||
|
Groups.leave(gid, uid, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
}(module.exports));
|
}(module.exports));
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ var cookie = require('cookie'),
|
|||||||
utils = require('../public/src/utils'),
|
utils = require('../public/src/utils'),
|
||||||
topics = require('./topics'),
|
topics = require('./topics'),
|
||||||
categories = require('./categories'),
|
categories = require('./categories'),
|
||||||
|
CategoryTools = require('./categoryTools'),
|
||||||
notifications = require('./notifications'),
|
notifications = require('./notifications'),
|
||||||
threadTools = require('./threadTools'),
|
threadTools = require('./threadTools'),
|
||||||
postTools = require('./postTools'),
|
postTools = require('./postTools'),
|
||||||
@@ -971,6 +972,53 @@ module.exports.init = function(io) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('api:admin.categories.search', function(username, cid, callback) {
|
||||||
|
if (uid && uid > 0) {
|
||||||
|
user.search(username, function(data) {
|
||||||
|
async.map(data, function(userObj, next) {
|
||||||
|
CategoryTools.privileges(cid, userObj.uid, function(err, privileges) {
|
||||||
|
if (!err) {
|
||||||
|
userObj.privileges = privileges;
|
||||||
|
} else {
|
||||||
|
winston.error('[socket api:admin.categories.search] Could not retrieve permissions');
|
||||||
|
}
|
||||||
|
|
||||||
|
next(null, userObj);
|
||||||
|
});
|
||||||
|
}, function(err, data) {
|
||||||
|
if (!callback) socket.emit('api:admin.categories.search', data);
|
||||||
|
else callback(null, data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (!callback) socket.emit('api:admin.user.search', null);
|
||||||
|
else callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('api:admin.categories.setPrivilege', function(cid, uid, privilege, set, callback) {
|
||||||
|
var cb = function(err) {
|
||||||
|
CategoryTools.privileges(cid, uid, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (set) {
|
||||||
|
Groups.joinByGroupName('cid:' + cid + ':privileges:' + privilege, uid, cb);
|
||||||
|
} else {
|
||||||
|
Groups.leaveByGroupName('cid:' + cid + ':privileges:' + privilege, uid, cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('api:admin.categories.getPrivilegeSettings', function(cid, callback) {
|
||||||
|
async.parallel({
|
||||||
|
"+r": function(next) {
|
||||||
|
Groups.getByGroupName('cid:' + cid + ':privileges:+r', { expand: true }, next);
|
||||||
|
},
|
||||||
|
"+w": function(next) {
|
||||||
|
Groups.getByGroupName('cid:' + cid + ':privileges:+w', { expand: true }, next);
|
||||||
|
}
|
||||||
|
}, callback);
|
||||||
|
});
|
||||||
|
|
||||||
socket.on('api:admin.themes.getInstalled', function(callback) {
|
socket.on('api:admin.themes.getInstalled', function(callback) {
|
||||||
meta.themes.get(function(err, themeArr) {
|
meta.themes.get(function(err, themeArr) {
|
||||||
callback(themeArr);
|
callback(themeArr);
|
||||||
|
|||||||
Reference in New Issue
Block a user