From de55c8e43176f90970dddc9d035d27d57a2bfd66 Mon Sep 17 00:00:00 2001 From: Baris Usakli Date: Wed, 2 Aug 2017 13:03:34 -0400 Subject: [PATCH] closes #4070 --- public/src/admin/manage/category.js | 4 +- public/src/admin/manage/group.js | 4 ++ src/controllers/admin/groups.js | 50 +++++++++++++++++++------ src/controllers/groups.js | 58 +++++++++++++---------------- src/groups.js | 2 +- src/views/admin/manage/group.tpl | 7 ++++ test/groups.js | 13 ++++++- 7 files changed, 89 insertions(+), 49 deletions(-) diff --git a/public/src/admin/manage/category.js b/public/src/admin/manage/category.js index 65ff87e683..2115db338e 100644 --- a/public/src/admin/manage/category.js +++ b/public/src/admin/manage/category.js @@ -37,6 +37,7 @@ define('admin/manage/category', [ }); } + handleTags(); $('#category-settings input, #category-settings select').not($('.privilege-table-container input')) .on('change', function (ev) { @@ -169,8 +170,6 @@ define('admin/manage/category', [ }); Category.setupPrivilegeTable(); - - handleTags(); }; function modified(el) { @@ -202,6 +201,7 @@ define('admin/manage/category', [ ajaxify.data.category.tagWhitelist.forEach(function (tag) { tagEl.tagsinput('add', tag); }); + tagEl.on('itemAdded itemRemoved', function () { modified(tagEl); }); diff --git a/public/src/admin/manage/group.js b/public/src/admin/manage/group.js index 17e7ddc44d..b334dcb3fb 100644 --- a/public/src/admin/manage/group.js +++ b/public/src/admin/manage/group.js @@ -21,6 +21,10 @@ define('admin/manage/group', [ var groupName = ajaxify.data.group.name; + $('#group-selector').on('change', function () { + ajaxify.go('admin/manage/groups/' + $(this).val() + window.location.hash); + }); + memberList.init('admin/manage/group'); changeGroupUserTitle.keyup(function () { diff --git a/src/controllers/admin/groups.js b/src/controllers/admin/groups.js index b8d9291474..a8a4f269b7 100644 --- a/src/controllers/admin/groups.js +++ b/src/controllers/admin/groups.js @@ -1,6 +1,7 @@ 'use strict'; var async = require('async'); +var validator = require('validator'); var db = require('../../database'); var groups = require('../../groups'); @@ -16,12 +17,9 @@ groupsController.list = function (req, res, next) { async.waterfall([ function (next) { - db.getSortedSetRange('groups:createtime', 0, -1, next); + getGroupNames(next); }, function (groupNames, next) { - groupNames = groupNames.filter(function (name) { - return name.indexOf(':privileges:') === -1 && name !== 'registered-users'; - }); pageCount = Math.ceil(groupNames.length / groupsPerPage); var start = (page - 1) * groupsPerPage; @@ -44,20 +42,48 @@ groupsController.get = function (req, res, callback) { var groupName = req.params.name; async.waterfall([ function (next) { - groups.exists(groupName, next); + async.parallel({ + groupNames: function (next) { + getGroupNames(next); + }, + group: function (next) { + groups.get(groupName, { uid: req.uid, truncateUserList: true, userListCount: 20 }, next); + }, + }, next); }, - function (exists, next) { - if (!exists) { + function (result) { + if (!result.group) { return callback(); } - groups.get(groupName, { uid: req.uid, truncateUserList: true, userListCount: 20 }, next); - }, - function (group) { - group.isOwner = true; + result.group.isOwner = true; + + result.groupNames = result.groupNames.map(function (name) { + return { + encodedName: encodeURIComponent(name), + displayName: validator.escape(String(name)), + selected: name === groupName, + }; + }); + res.render('admin/manage/group', { - group: group, + group: result.group, + groupNames: result.groupNames, allowPrivateGroups: parseInt(meta.config.allowPrivateGroups, 10) === 1, }); }, ], callback); }; + +function getGroupNames(callback) { + async.waterfall([ + function (next) { + db.getSortedSetRange('groups:createtime', 0, -1, next); + }, + function (groupNames, next) { + groupNames = groupNames.filter(function (name) { + return name !== 'registered-users' && !groups.isPrivilegeGroup(name); + }); + next(null, groupNames); + }, + ], callback); +} diff --git a/src/controllers/groups.js b/src/controllers/groups.js index 94f5469ef4..0703915e6f 100644 --- a/src/controllers/groups.js +++ b/src/controllers/groups.js @@ -98,21 +98,18 @@ groupsController.details = function (req, res, callback) { }, }, next); }, - ], function (err, results) { - if (err) { - return callback(err); - } - - if (!results.group) { - return callback(); - } - results.group.isOwner = results.group.isOwner || results.isAdmin || (results.isGlobalMod && !results.group.system); - results.title = '[[pages:group, ' + results.group.displayName + ']]'; - results.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[pages:groups]]', url: '/groups' }, { text: results.group.displayName }]); - results.allowPrivateGroups = parseInt(meta.config.allowPrivateGroups, 10) === 1; + function (results) { + if (!results.group) { + return callback(); + } + results.group.isOwner = results.group.isOwner || results.isAdmin || (results.isGlobalMod && !results.group.system); + results.title = '[[pages:group, ' + results.group.displayName + ']]'; + results.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[pages:groups]]', url: '/groups' }, { text: results.group.displayName }]); + results.allowPrivateGroups = parseInt(meta.config.allowPrivateGroups, 10) === 1; - res.render('groups/details', results); - }); + res.render('groups/details', results); + }, + ], callback); }; groupsController.members = function (req, res, callback) { @@ -139,24 +136,21 @@ groupsController.members = function (req, res, callback) { user.getUsersFromSet('group:' + groupName + ':members', req.uid, 0, 49, next); }, - ], function (err, users) { - if (err) { - return callback(err); - } - - var breadcrumbs = helpers.buildBreadcrumbs([ - { text: '[[pages:groups]]', url: '/groups' }, - { text: validator.escape(String(groupName)), url: '/groups/' + req.params.slug }, - { text: '[[groups:details.members]]' }, - ]); - - res.render('groups/members', { - users: users, - nextStart: 50, - loadmore_display: users.length > 50 ? 'block' : 'hide', - breadcrumbs: breadcrumbs, - }); - }); + function (users) { + var breadcrumbs = helpers.buildBreadcrumbs([ + { text: '[[pages:groups]]', url: '/groups' }, + { text: validator.escape(String(groupName)), url: '/groups/' + req.params.slug }, + { text: '[[groups:details.members]]' }, + ]); + + res.render('groups/members', { + users: users, + nextStart: 50, + loadmore_display: users.length > 50 ? 'block' : 'hide', + breadcrumbs: breadcrumbs, + }); + }, + ], callback); }; groupsController.uploadCover = function (req, res, next) { diff --git a/src/groups.js b/src/groups.js index 6462819e9e..ed96f415b0 100644 --- a/src/groups.js +++ b/src/groups.js @@ -135,7 +135,7 @@ Groups.get = function (groupName, options, callback) { function (_results, next) { results = _results; if (!results.base) { - return callback(new Error('[[error:no-group]]')); + return callback(null, null); } plugins.fireHook('filter:parse.raw', results.base.description, next); }, diff --git a/src/views/admin/manage/group.tpl b/src/views/admin/manage/group.tpl index 0805da3e06..b9170df21a 100644 --- a/src/views/admin/manage/group.tpl +++ b/src/views/admin/manage/group.tpl @@ -93,6 +93,13 @@ +
+ +
diff --git a/test/groups.js b/test/groups.js index d245f5744d..311e4ab93b 100644 --- a/test/groups.js +++ b/test/groups.js @@ -97,6 +97,14 @@ describe('Groups', function () { done(); }); }); + + it('should return null if group does not exist', function (done) { + Groups.get('doesnotexist', {}, function (err, groupObj) { + assert.ifError(err); + assert.strictEqual(groupObj, null); + done(); + }); + }); }); describe('.search()', function () { @@ -375,8 +383,9 @@ describe('Groups', function () { Groups.destroy('foobar?', function (err) { assert.ifError(err); - Groups.get('foobar?', {}, function (err) { - assert(err, 'Group still exists!'); + Groups.get('foobar?', {}, function (err, groupObj) { + assert.ifError(err); + assert.strictEqual(groupObj, null); done(); });