diff --git a/public/src/admin/manage/group.js b/public/src/admin/manage/group.js
new file mode 100644
index 0000000000..08feeb726c
--- /dev/null
+++ b/public/src/admin/manage/group.js
@@ -0,0 +1,144 @@
+"use strict";
+/*global define, templates, socket, ajaxify, app, admin, bootbox, utils, config */
+
+define('admin/manage/group', [
+ 'iconSelect',
+ 'admin/modules/colorpicker'
+], function(iconSelect, colorpicker) {
+ var Groups = {};
+
+ Groups.init = function() {
+ var groupDetailsSearch = $('#group-details-search'),
+ groupDetailsSearchResults = $('#group-details-search-results'),
+ groupMembersEl = $('ul.current_members'),
+ groupIcon = $('#group-icon'),
+ changeGroupUserTitle = $('#change-group-user-title'),
+ changeGroupLabelColor = $('#change-group-label-color'),
+ groupLabelPreview = $('#group-label-preview'),
+ searchDelay;
+
+
+ var groupName = ajaxify.variables.get('groupName');
+
+ changeGroupUserTitle.keyup(function() {
+ groupLabelPreview.text(changeGroupUserTitle.val());
+ });
+
+ changeGroupLabelColor.keyup(function() {
+ groupLabelPreview.css('background', changeGroupLabelColor.val() || '#000000');
+ });
+
+ groupDetailsSearch.on('keyup', function() {
+
+ if (searchDelay) {
+ clearTimeout(searchDelay);
+ }
+
+ searchDelay = setTimeout(function() {
+ var searchText = groupDetailsSearch.val(),
+ foundUser;
+
+ socket.emit('admin.user.search', {query: searchText}, function(err, results) {
+ if (!err && results && results.users.length > 0) {
+ var numResults = results.users.length, x;
+ if (numResults > 20) {
+ numResults = 20;
+ }
+
+ groupDetailsSearchResults.empty();
+ for (x = 0; x < numResults; x++) {
+ foundUser = $('
');
+ foundUser
+ .attr({title: results.users[x].username, 'data-uid': results.users[x].uid})
+ .append($('
').attr('src', results.users[x].picture))
+ .append($('').html(results.users[x].username));
+
+ groupDetailsSearchResults.append(foundUser);
+ }
+ } else {
+ groupDetailsSearchResults.html('No Users Found');
+ }
+ });
+ }, 200);
+ });
+
+ groupDetailsSearchResults.on('click', 'li[data-uid]', function() {
+ var userLabel = $(this),
+ uid = parseInt(userLabel.attr('data-uid'), 10),
+ members = [];
+
+ groupMembersEl.find('li[data-uid]').each(function() {
+ members.push(parseInt($(this).attr('data-uid'), 10));
+ });
+
+ if (members.indexOf(uid) === -1) {
+ socket.emit('admin.groups.join', {
+ groupName: groupName,
+ uid: uid
+ }, function(err, data) {
+ if (!err) {
+ groupMembersEl.append(userLabel.clone(true));
+ }
+ });
+ }
+ });
+
+ groupMembersEl.on('click', 'li[data-uid]', function() {
+ var uid = $(this).attr('data-uid');
+
+ socket.emit('admin.groups.get', groupName, function(err, groupObj){
+ if (err) {
+ return app.alertError(err.message);
+ }
+
+ bootbox.confirm('Are you sure you want to remove this user?', function(confirm) {
+ if (!confirm) {
+ return;
+ }
+
+ socket.emit('admin.groups.leave', {
+ groupName: groupName,
+ uid: uid
+ }, function(err, data) {
+ if (err) {
+ return app.alertError(err.message);
+ }
+ groupMembersEl.find('li[data-uid="' + uid + '"]').remove();
+ });
+ });
+ });
+ });
+
+ $('#group-icon').on('click', function() {
+ iconSelect.init(groupIcon);
+ });
+
+ colorpicker.enable(changeGroupLabelColor, function(hsb, hex) {
+ groupLabelPreview.css('background-color', '#' + hex);
+ });
+
+ $('.save').on('click', function() {
+ socket.emit('admin.groups.update', {
+ groupName: groupName,
+ values: {
+ name: $('#change-group-name').val(),
+ userTitle: changeGroupUserTitle.val(),
+ description: $('#change-group-desc').val(),
+ icon: groupIcon.attr('value'),
+ labelColor: changeGroupLabelColor.val(),
+ private: $('#group-private').is(':checked'),
+ hidden: $('#group-hidden').is(':checked')
+ }
+ }, function(err) {
+ if (err) {
+ return app.alertError(err.message);
+ }
+ app.alertSuccess('Changes saved!');
+ });
+ return false;
+ });
+
+ };
+
+ return Groups;
+});
diff --git a/public/src/admin/manage/groups.js b/public/src/admin/manage/groups.js
index e0b27a674d..2bf84d4f18 100644
--- a/public/src/admin/manage/groups.js
+++ b/public/src/admin/manage/groups.js
@@ -2,30 +2,16 @@
/*global define, templates, socket, ajaxify, app, admin, bootbox, utils, config */
define('admin/manage/groups', [
- 'iconSelect',
- 'admin/modules/colorpicker',
'translator',
'components'
-], function(iconSelect, colorpicker, translator, components) {
+], function(translator, components) {
var Groups = {};
Groups.init = function() {
var createModal = $('#create-modal'),
createGroupName = $('#create-group-name'),
createModalGo = $('#create-modal-go'),
- createModalError = $('#create-modal-error'),
- groupDetailsModal = $('#group-details-modal'),
- groupDetailsSearch = $('#group-details-search'),
- groupDetailsSearchResults = $('#group-details-search-results'),
- groupMembersEl = $('ul.current_members'),
- detailsModalSave = $('#details-modal-save'),
- groupIcon = $('#group-icon'),
- changeGroupName = $('#change-group-name'),
- changeGroupDesc = $('#change-group-desc'),
- changeGroupUserTitle = $('#change-group-user-title'),
- changeGroupLabelColor = $('#change-group-label-color'),
- groupLabelPreview = $('#group-label-preview'),
- searchDelay;
+ createModalError = $('#create-modal-error');
createModal.on('keypress', function(e) {
if (e.keyCode === 13) {
@@ -67,24 +53,6 @@ define('admin/manage/groups', [
});
});
- groupDetailsModal.find('form').keypress(function(e) {
- if (e.keyCode === 13) {
- detailsModalSave.click();
- }
- });
-
- changeGroupUserTitle.keydown(function() {
- setTimeout(function() {
- groupLabelPreview.text(changeGroupUserTitle.val());
- }, 0);
- });
-
- changeGroupLabelColor.keydown(function() {
- setTimeout(function() {
- groupLabelPreview.css('background', changeGroupLabelColor.val() || '#000000');
- }, 0);
- });
-
$('.groups-list').on('click', 'button[data-action]', function() {
var el = $(this),
action = el.attr('data-action'),
@@ -106,139 +74,9 @@ define('admin/manage/groups', [
}
});
break;
- case 'members':
- socket.emit('admin.groups.get', groupName, function(err, groupObj) {
- changeGroupName.val(groupObj.name).prop('readonly', groupObj.system);
- changeGroupDesc.val(groupObj.description);
- changeGroupUserTitle.val(groupObj.userTitle);
- groupIcon.attr('class', 'fa fa-2x ' + groupObj.icon).attr('value', groupObj.icon);
- changeGroupLabelColor.val(groupObj.labelColor);
- groupLabelPreview.css('background', groupObj.labelColor || '#000000').text(groupObj.userTitle);
- groupMembersEl.empty();
-
- if (groupObj.members.length > 0) {
- for (var x = 0; x < groupObj.members.length; x++) {
- var memberIcon = $('')
- .attr('data-uid', groupObj.members[x].uid)
- .append($('
').attr('src', groupObj.members[x].picture))
- .append($('').html(groupObj.members[x].username));
- groupMembersEl.append(memberIcon);
- }
- }
-
- groupDetailsModal.attr('data-groupname', groupObj.name);
- groupDetailsModal.modal('show');
- });
- break;
}
});
- groupDetailsSearch.on('keyup', function() {
-
- if (searchDelay) {
- clearTimeout(searchDelay);
- }
-
- searchDelay = setTimeout(function() {
- var searchText = groupDetailsSearch.val(),
- foundUser;
-
- socket.emit('admin.user.search', {query: searchText}, function(err, results) {
- if (!err && results && results.users.length > 0) {
- var numResults = results.users.length, x;
- if (numResults > 20) {
- numResults = 20;
- }
-
- groupDetailsSearchResults.empty();
- for (x = 0; x < numResults; x++) {
- foundUser = $('');
- foundUser
- .attr({title: results.users[x].username, 'data-uid': results.users[x].uid})
- .append($('
').attr('src', results.users[x].picture))
- .append($('').html(results.users[x].username));
-
- groupDetailsSearchResults.append(foundUser);
- }
- } else {
- groupDetailsSearchResults.html('No Users Found');
- }
- });
- }, 200);
- });
-
- groupDetailsSearchResults.on('click', 'li[data-uid]', function() {
- var userLabel = $(this),
- uid = parseInt(userLabel.attr('data-uid'), 10),
- groupName = groupDetailsModal.attr('data-groupname'),
- members = [];
-
- groupMembersEl.find('li[data-uid]').each(function() {
- members.push(parseInt($(this).attr('data-uid'), 10));
- });
-
- if (members.indexOf(uid) === -1) {
- socket.emit('admin.groups.join', {
- groupName: groupName,
- uid: uid
- }, function(err, data) {
- if (!err) {
- groupMembersEl.append(userLabel.clone(true));
- }
- });
- }
- });
-
- groupMembersEl.on('click', 'li[data-uid]', function() {
- var uid = $(this).attr('data-uid'),
- groupName = groupDetailsModal.attr('data-groupname');
-
- socket.emit('admin.groups.get', groupName, function(err, groupObj){
- if (!err){
- bootbox.confirm('Are you sure you want to remove this user?', function(confirm) {
- if (confirm){
- socket.emit('admin.groups.leave', {
- groupName: groupName,
- uid: uid
- }, function(err, data) {
- if (!err) {
- groupMembersEl.find('li[data-uid="' + uid + '"]').remove();
- }
- });
- }
- });
- }
- });
- });
-
- $('#change-group-icon').on('click', function() {
- iconSelect.init(groupIcon);
- });
-
- colorpicker.enable(changeGroupLabelColor, function(hsb, hex) {
- groupLabelPreview.css('background-color', '#' + hex);
- });
-
- detailsModalSave.on('click', function() {
- socket.emit('admin.groups.update', {
- groupName: groupDetailsModal.attr('data-groupname'),
- values: {
- name: changeGroupName.val(),
- userTitle: changeGroupUserTitle.val(),
- description: changeGroupDesc.val(),
- icon: groupIcon.attr('value'),
- labelColor: changeGroupLabelColor.val()
- }
- }, function(err) {
- if (!err) {
- groupDetailsModal.on('hidden.bs.modal', function() {
- ajaxify.go('admin/manage/groups');
- });
- groupDetailsModal.modal('hide');
- }
- });
- });
-
};
return Groups;
diff --git a/src/controllers/admin.js b/src/controllers/admin.js
index 19688bff45..6ad32991eb 100644
--- a/src/controllers/admin.js
+++ b/src/controllers/admin.js
@@ -15,7 +15,6 @@ var async = require('async'),
events = require('../events'),
languages = require('../languages'),
plugins = require('../plugins'),
- groups = require('../groups'),
validator = require('validator');
@@ -24,7 +23,7 @@ var adminController = {
tags: {},
flags: {},
topics: {},
- groups: {},
+ groups: require('./admin/groups'),
appearance: {},
extend: {
widgets: {}
@@ -376,23 +375,6 @@ adminController.extend.rewards = function(req, res, next) {
});
};
-adminController.groups.get = function(req, res, next) {
- groups.getGroupsFromSet('groups:createtime', req.uid, 0, -1, function(err, groups) {
- if (err) {
- return next(err);
- }
-
- groups = groups.filter(function(group) {
- return group && group.name.indexOf(':privileges:') === -1 && group.name !== 'registered-users';
- });
-
- res.render('admin/manage/groups', {
- groups: groups,
- yourid: req.user.uid
- });
- });
-};
-
adminController.themes.get = function(req, res, next) {
var themeDir = path.join(__dirname, '../../node_modules/' + req.params.theme);
fs.exists(themeDir, function(exists) {
diff --git a/src/controllers/admin/groups.js b/src/controllers/admin/groups.js
new file mode 100644
index 0000000000..e30bf150c3
--- /dev/null
+++ b/src/controllers/admin/groups.js
@@ -0,0 +1,49 @@
+"use strict";
+
+var async = require('async'),
+ groups = require('../../groups'),
+ meta = require('../../meta'),
+ helpers = require('../helpers');
+
+
+var groupsController = {};
+
+
+groupsController.list = function(req, res, next) {
+ groups.getGroupsFromSet('groups:createtime', req.uid, 0, -1, function(err, groups) {
+ if (err) {
+ return next(err);
+ }
+
+ groups = groups.filter(function(group) {
+ return group && group.name.indexOf(':privileges:') === -1 && group.name !== 'registered-users';
+ });
+
+ res.render('admin/manage/groups', {
+ groups: groups,
+ yourid: req.user.uid
+ });
+ });
+};
+
+groupsController.get = function(req, res, next) {
+ var groupName = res.locals.groupName;
+ async.waterfall([
+ function(next){
+ groups.exists(groupName, next);
+ },
+ function(exists, next) {
+ if (!exists) {
+ helpers.notFound(req, res);
+ }
+ groups.get(groupName, {uid: req.uid}, next);
+ }
+ ], function(err, group) {
+ if (err) {
+ return next(err);
+ }
+ res.render('admin/manage/group', {group: group});
+ });
+};
+
+module.exports = groupsController;
diff --git a/src/groups.js b/src/groups.js
index 10bdd46fcc..ea5730c9a9 100644
--- a/src/groups.js
+++ b/src/groups.js
@@ -211,7 +211,7 @@ var async = require('async'),
if (group) {
group.name = validator.escape(group.name);
group.description = validator.escape(group.description);
- group.userTitle = validator.escape(group.userTitle);
+ group.userTitle = validator.escape(group.userTitle) || group.name;
}
};
diff --git a/src/routes/admin.js b/src/routes/admin.js
index 46459be436..d60d547d29 100644
--- a/src/routes/admin.js
+++ b/src/routes/admin.js
@@ -59,7 +59,8 @@ function addRoutes(router, middleware, controllers) {
router.get('/manage/users/sort-reputation', controllers.admin.users.sortByReputation);
router.get('/manage/users/banned', controllers.admin.users.banned);
- router.get('/manage/groups', controllers.admin.groups.get);
+ router.get('/manage/groups', controllers.admin.groups.list);
+ router.get('/manage/groups/:slug', middleware.exposeGroupName, controllers.admin.groups.get);
router.get('/settings/:term?', controllers.admin.settings.get);
diff --git a/src/socket.io/admin/groups.js b/src/socket.io/admin/groups.js
index 10917ad9c0..ce3d86593b 100644
--- a/src/socket.io/admin/groups.js
+++ b/src/socket.io/admin/groups.js
@@ -38,15 +38,12 @@ Groups.leave = function(socket, data, callback) {
groups.leave(data.groupName, data.uid, callback);
};
-// Possibly remove this and call SocketGroups.update instead
Groups.update = function(socket, data, callback) {
- if(!data) {
+ if (!data) {
return callback(new Error('[[error:invalid-data]]'));
}
- groups.update(data.groupName, data.values, function(err) {
- callback(err ? err.message : null);
- });
+ groups.update(data.groupName, data.values, callback);
};
module.exports = Groups;
\ No newline at end of file
diff --git a/src/views/admin/manage/group.tpl b/src/views/admin/manage/group.tpl
new file mode 100644
index 0000000000..3836cb74ee
--- /dev/null
+++ b/src/views/admin/manage/group.tpl
@@ -0,0 +1,126 @@
+
-
-
-
+