mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 19:15:58 +01:00 
			
		
		
		
	feat: allow adding multiple users to group
This commit is contained in:
		| @@ -1,7 +1,7 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
|  |  | ||||||
| define('forum/groups/memberlist', ['autocomplete'], function (autocomplete) { | define('forum/groups/memberlist', function () { | ||||||
| 	var MemberList = {}; | 	var MemberList = {}; | ||||||
| 	var searchInterval; | 	var searchInterval; | ||||||
| 	var groupName; | 	var groupName; | ||||||
| @@ -18,35 +18,72 @@ define('forum/groups/memberlist', ['autocomplete'], function (autocomplete) { | |||||||
|  |  | ||||||
| 	function handleMemberAdd() { | 	function handleMemberAdd() { | ||||||
| 		$('[component="groups/members/add"]').on('click', function () { | 		$('[component="groups/members/add"]').on('click', function () { | ||||||
| 			var modal = bootbox.dialog({ | 			app.parseAndTranslate('admin/partials/groups/add-members', {}, function (html) { | ||||||
| 				title: '[[groups:details.add-member]]', | 				var foundUsers = []; | ||||||
| 				message: '<input class="form-control" type="text" placeholder="[[global:search]]"/>', | 				var modal = bootbox.dialog({ | ||||||
| 			}); | 					title: '[[groups:details.add-member]]', | ||||||
| 			autocomplete.user(modal.find('input'), function (ev, ui) { | 					message: html, | ||||||
| 				var user = ui.item.user; | 					buttons: { | ||||||
| 				if (user) { | 						ok: { | ||||||
| 					addUserToGroup(user, function () { | 							callback: function () { | ||||||
| 						modal.modal('hide'); | 								var users = []; | ||||||
|  | 								modal.find('[data-uid][data-selected]').each(function (index, el) { | ||||||
|  | 									users.push(foundUsers[$(el).attr('data-uid')]); | ||||||
|  | 								}); | ||||||
|  | 								addUserToGroup(users, function () { | ||||||
|  | 									modal.modal('hide'); | ||||||
|  | 								}); | ||||||
|  | 							}, | ||||||
|  | 						}, | ||||||
|  | 					}, | ||||||
|  | 				}); | ||||||
|  | 				modal.on('click', '[data-username]', function () { | ||||||
|  | 					var isSelected = $(this).attr('data-selected') === '1'; | ||||||
|  | 					if (isSelected) { | ||||||
|  | 						$(this).removeAttr('data-selected'); | ||||||
|  | 					} else { | ||||||
|  | 						$(this).attr('data-selected', 1); | ||||||
|  | 					} | ||||||
|  | 					$(this).find('i').toggleClass('invisible'); | ||||||
|  | 				}); | ||||||
|  | 				modal.find('input').on('keyup', function () { | ||||||
|  | 					socket.emit('user.search', { | ||||||
|  | 						query: $(this).val(), | ||||||
|  | 						paginate: false, | ||||||
|  | 					}, function (err, result) { | ||||||
|  | 						if (err) { | ||||||
|  | 							return app.alertError(err.message); | ||||||
|  | 						} | ||||||
|  | 						result.users.forEach(function (user) { | ||||||
|  | 							foundUsers[user.uid] = user; | ||||||
|  | 						}); | ||||||
|  | 						app.parseAndTranslate('admin/partials/groups/add-members', 'users', { users: result.users }, function (html) { | ||||||
|  | 							modal.find('#search-result').html(html); | ||||||
|  | 						}); | ||||||
| 					}); | 					}); | ||||||
| 				} | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function addUserToGroup(user, callback) { | 	function addUserToGroup(users, callback) { | ||||||
| 		function done(err) { | 		function done(err) { | ||||||
| 			if (err) { | 			if (err) { | ||||||
| 				return app.alertError(err); | 				return app.alertError(err); | ||||||
| 			} | 			} | ||||||
| 			parseAndTranslate([user], function (html) { | 			users = users.filter(function (user) { | ||||||
|  | 				return !$('[component="groups/members"] [data-uid="' + user.uid + '"]').length; | ||||||
|  | 			}); | ||||||
|  | 			parseAndTranslate(users, function (html) { | ||||||
| 				$('[component="groups/members"] tbody').prepend(html); | 				$('[component="groups/members"] tbody').prepend(html); | ||||||
| 			}); | 			}); | ||||||
| 			callback(); | 			callback(); | ||||||
| 		} | 		} | ||||||
|  | 		var uids = users.map(function (user) { return user.uid; }); | ||||||
| 		if (groupName === 'administrators') { | 		if (groupName === 'administrators') { | ||||||
| 			socket.emit('admin.user.makeAdmins', [user.uid], done); | 			socket.emit('admin.user.makeAdmins', uids, done); | ||||||
| 		} else { | 		} else { | ||||||
| 			socket.emit('groups.addMember', { groupName: groupName, uid: user.uid }, done); | 			socket.emit('groups.addMember', { groupName: groupName, uid: uids }, done); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -104,10 +104,21 @@ SocketGroups.addMember = async (socket, data) => { | |||||||
| 	if (data.groupName === 'administrators' || groups.isPrivilegeGroup(data.groupName)) { | 	if (data.groupName === 'administrators' || groups.isPrivilegeGroup(data.groupName)) { | ||||||
| 		throw new Error('[[error:not-allowed]]'); | 		throw new Error('[[error:not-allowed]]'); | ||||||
| 	} | 	} | ||||||
| 	await groups.join(data.groupName, data.uid); | 	if (!data.uid) { | ||||||
|  | 		throw new Error('[[error:invalid-data]]'); | ||||||
|  | 	} | ||||||
|  | 	data.uid = !Array.isArray(data.uid) ? [data.uid] : data.uid; | ||||||
|  | 	if (data.uid.filter(uid => !(parseInt(uid, 10) > 0)).length) { | ||||||
|  | 		throw new Error('[[error:invalid-uid]]'); | ||||||
|  | 	} | ||||||
|  | 	for (const uid of data.uid) { | ||||||
|  | 		// eslint-disable-next-line no-await-in-loop | ||||||
|  | 		await groups.join(data.groupName, uid); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	logGroupEvent(socket, 'group-add-member', { | 	logGroupEvent(socket, 'group-add-member', { | ||||||
| 		groupName: data.groupName, | 		groupName: data.groupName, | ||||||
| 		targetUid: data.uid, | 		targetUid: String(data.uid), | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								src/views/admin/partials/groups/add-members.tpl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/views/admin/partials/groups/add-members.tpl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  |  | ||||||
|  | <input class="form-control" type="text" placeholder="[[global:search]]"/> | ||||||
|  |  | ||||||
|  | <div class="list-group" id="search-result"> | ||||||
|  |     {{{each users}}} | ||||||
|  |     <a href="#" class="list-group-item" data-username="{users.username}" data-uid="{users.uid}"><i class="fa fa-fw fa-check invisible"></i>{users.username}</a> | ||||||
|  |     {{{end}}} | ||||||
|  | </div> | ||||||
		Reference in New Issue
	
	Block a user