mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	feat: add visibility option to, closes #12942
This commit is contained in:
		| @@ -20,5 +20,9 @@ | |||||||
| 	"minimum-reputation": "Minimum reputation", | 	"minimum-reputation": "Minimum reputation", | ||||||
| 	"minimum-reputation-help": "If a user has less than this value they won't be able to use this field", | 	"minimum-reputation-help": "If a user has less than this value they won't be able to use this field", | ||||||
| 	"delete-field-confirm-x": "Do you really want to delete custom field \"%1\"?", | 	"delete-field-confirm-x": "Do you really want to delete custom field \"%1\"?", | ||||||
| 	"custom-fields-saved": "Custom fields saved" | 	"custom-fields-saved": "Custom fields saved", | ||||||
|  | 	"visibility": "Visibility", | ||||||
|  | 	"visibility-all": "Everyone can see the field", | ||||||
|  | 	"visibility-loggedin": "Only logged in users can see the field", | ||||||
|  | 	"visibility-privileged": "Only privileged users like admins & moderators can see the field" | ||||||
| } | } | ||||||
| @@ -51,6 +51,7 @@ define('admin/manage/user/custom-fields', [ | |||||||
| 			icon: el.attr('data-icon'), | 			icon: el.attr('data-icon'), | ||||||
| 			type: el.attr('data-type'), | 			type: el.attr('data-type'), | ||||||
| 			'select-options': el.attr('data-select-options'), | 			'select-options': el.attr('data-select-options'), | ||||||
|  | 			visibility: el.attr('data-visibility'), | ||||||
| 			'min:rep': el.attr('data-min-rep'), | 			'min:rep': el.attr('data-min-rep'), | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ editController.get = async function (req, res, next) { | |||||||
| 	const [canUseSignature, canManageUsers, customUserFields] = await Promise.all([ | 	const [canUseSignature, canManageUsers, customUserFields] = await Promise.all([ | ||||||
| 		privileges.global.can('signature', req.uid), | 		privileges.global.can('signature', req.uid), | ||||||
| 		privileges.admin.can('admin:users', req.uid), | 		privileges.admin.can('admin:users', req.uid), | ||||||
| 		accountHelpers.getCustomUserFields(userData), | 		accountHelpers.getCustomUserFields(req.uid, userData), | ||||||
| 	]); | 	]); | ||||||
|  |  | ||||||
| 	userData.customUserFields = customUserFields; | 	userData.customUserFields = customUserFields; | ||||||
|   | |||||||
| @@ -129,13 +129,26 @@ helpers.getUserDataByUserSlug = async function (userslug, callerUID, query = {}) | |||||||
| 	return hookData.userData; | 	return hookData.userData; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| helpers.getCustomUserFields = async function (userData) { | helpers.getCustomUserFields = async function (callerUID, userData) { | ||||||
| 	const keys = await db.getSortedSetRange('user-custom-fields', 0, -1); | 	const keys = await db.getSortedSetRange('user-custom-fields', 0, -1); | ||||||
| 	const allFields = (await db.getObjects(keys.map(k => `user-custom-field:${k}`))).filter(Boolean); | 	const allFields = (await db.getObjects(keys.map(k => `user-custom-field:${k}`))).filter(Boolean); | ||||||
|  |  | ||||||
|  | 	const isSelf = String(callerUID) === String(userData.uid); | ||||||
|  | 	const [isAdmin, isModOfAny] = await Promise.all([ | ||||||
|  | 		privileges.users.isAdministrator(callerUID), | ||||||
|  | 		user.isModeratorOfAnyCategory(callerUID), | ||||||
|  | 	]); | ||||||
|  |  | ||||||
| 	const fields = allFields.filter((field) => { | 	const fields = allFields.filter((field) => { | ||||||
|  | 		const visibilityCheck = isAdmin || isModOfAny || isSelf || field.visibility === 'all' || | ||||||
|  | 			( | ||||||
|  | 				field.visibility === 'loggedin' && | ||||||
|  | 				String(callerUID) !== '0' && | ||||||
|  | 				String(callerUID) !== '-1' | ||||||
|  | 			); | ||||||
| 		const minRep = field['min:rep'] || 0; | 		const minRep = field['min:rep'] || 0; | ||||||
| 		return userData.reputation >= minRep || meta.config['reputation:disabled']; | 		const repCheck = userData.reputation >= minRep || meta.config['reputation:disabled']; | ||||||
|  | 		return visibilityCheck && repCheck; | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	fields.forEach((f) => { | 	fields.forEach((f) => { | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ profileController.get = async function (req, res, next) { | |||||||
| 	const [latestPosts, bestPosts, customUserFields] = await Promise.all([ | 	const [latestPosts, bestPosts, customUserFields] = await Promise.all([ | ||||||
| 		getLatestPosts(req.uid, userData), | 		getLatestPosts(req.uid, userData), | ||||||
| 		getBestPosts(req.uid, userData), | 		getBestPosts(req.uid, userData), | ||||||
| 		accountHelpers.getCustomUserFields(userData), | 		accountHelpers.getCustomUserFields(req.uid, userData), | ||||||
| 		posts.parseSignature(userData, req.uid), | 		posts.parseSignature(userData, req.uid), | ||||||
| 	]); | 	]); | ||||||
| 	userData.customUserFields = customUserFields; | 	userData.customUserFields = customUserFields; | ||||||
|   | |||||||
| @@ -310,6 +310,7 @@ usersController.customFields = async function (req, res) { | |||||||
| 			field.selectOptionsFormatted = field['select-options'].trim().split('\n').join(', '); | 			field.selectOptionsFormatted = field['select-options'].trim().split('\n').join(', '); | ||||||
| 		} | 		} | ||||||
| 		field['min:rep'] = field['min:rep'] || 0; | 		field['min:rep'] = field['min:rep'] || 0; | ||||||
|  | 		field.visibility = field.visibility || 'all'; | ||||||
| 	}); | 	}); | ||||||
| 	res.render('admin/manage/users/custom-fields', { fields: fields }); | 	res.render('admin/manage/users/custom-fields', { fields: fields }); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -21,13 +21,14 @@ | |||||||
| 							<th class="text-muted">[[admin/manage/user-custom-fields:key]]</th> | 							<th class="text-muted">[[admin/manage/user-custom-fields:key]]</th> | ||||||
| 							<th class="text-muted">[[admin/manage/user-custom-fields:name]]</th> | 							<th class="text-muted">[[admin/manage/user-custom-fields:name]]</th> | ||||||
| 							<th class="text-muted">[[admin/manage/user-custom-fields:type]]</th> | 							<th class="text-muted">[[admin/manage/user-custom-fields:type]]</th> | ||||||
|  | 							<th class="text-muted">[[admin/manage/user-custom-fields:visibility]]</th> | ||||||
| 							<th class="text-muted text-end">[[admin/manage/user-custom-fields:min-rep]]</th> | 							<th class="text-muted text-end">[[admin/manage/user-custom-fields:min-rep]]</th> | ||||||
| 							<th></th> | 							<th></th> | ||||||
| 						</tr> | 						</tr> | ||||||
| 					</thead> | 					</thead> | ||||||
| 					<tbody> | 					<tbody> | ||||||
| 						{{{ each fields }}} | 						{{{ each fields }}} | ||||||
| 						<tr data-key="{./key}" data-name="{./name}" data-icon="{./icon}" data-type="{./type}" data-min-rep="{./min:rep}" data-select-options="{./select-options}" class="align-middle"> | 						<tr data-key="{./key}" data-name="{./name}" data-icon="{./icon}" data-type="{./type}" data-min-rep="{./min:rep}" data-select-options="{./select-options}" data-visibility="{./visibility}" class="align-middle"> | ||||||
| 							<td style="width: 32px;"> | 							<td style="width: 32px;"> | ||||||
| 								<a href="#" component="sort/handle" class="btn btn-light btn-sm d-none d-md-block ui-sortable-handle" style="cursor:grab;"><i class="fa fa-arrows-up-down text-muted"></i></a> | 								<a href="#" component="sort/handle" class="btn btn-light btn-sm d-none d-md-block ui-sortable-handle" style="cursor:grab;"><i class="fa fa-arrows-up-down text-muted"></i></a> | ||||||
| 							</td> | 							</td> | ||||||
| @@ -41,6 +42,9 @@ | |||||||
| 								</div> | 								</div> | ||||||
| 								{{{ end }}} | 								{{{ end }}} | ||||||
| 							</td> | 							</td> | ||||||
|  | 							<td> | ||||||
|  | 								{./visibility} | ||||||
|  | 							</td> | ||||||
| 							<td class="text-end"> | 							<td class="text-end"> | ||||||
| 								{./min:rep} | 								{./min:rep} | ||||||
| 							</td> | 							</td> | ||||||
|   | |||||||
| @@ -29,6 +29,15 @@ | |||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
|  |  | ||||||
|  | 	<div class="mb-3"> | ||||||
|  | 		<label class="form-label">[[admin/manage/user-custom-fields:visibility]]</label> | ||||||
|  | 		<select name="visibility" class="form-select"> | ||||||
|  | 			<option value="all">[[admin/manage/user-custom-fields:visibility-all]]</option> | ||||||
|  | 			<option value="loggedin">[[admin/manage/user-custom-fields:visibility-loggedin]]</option> | ||||||
|  | 			<option value="privileged">[[admin/manage/user-custom-fields:visibility-privileged]]</option> | ||||||
|  | 		</select> | ||||||
|  | 	</div> | ||||||
|  |  | ||||||
| 	<div class="mb-3"> | 	<div class="mb-3"> | ||||||
| 		<label class="form-label">[[admin/manage/user-custom-fields:minimum-reputation]]</label> | 		<label class="form-label">[[admin/manage/user-custom-fields:minimum-reputation]]</label> | ||||||
| 		<input class="form-control" type="number" name="min:rep" value="{./min:rep}" placeholder="0"> | 		<input class="form-control" type="number" name="min:rep" value="{./min:rep}" placeholder="0"> | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ | |||||||
| 					<label for="downvote:disabled" class="form-check-label">[[admin/settings/reputation:disable-down-voting]]</label> | 					<label for="downvote:disabled" class="form-check-label">[[admin/settings/reputation:disable-down-voting]]</label> | ||||||
| 				</div> | 				</div> | ||||||
| 				<div class="mb-3"> | 				<div class="mb-3"> | ||||||
| 					<label for="upvoteVisibility" class="form-check-label">[[admin/settings/reputation:upvote-visibility]]</label> | 					<label for="upvoteVisibility" class="form-label">[[admin/settings/reputation:upvote-visibility]]</label> | ||||||
| 					<select id="upvoteVisibility" data-field="upvoteVisibility" class="form-select"> | 					<select id="upvoteVisibility" data-field="upvoteVisibility" class="form-select"> | ||||||
| 						<option value="all">[[admin/settings/reputation:upvote-visibility-all]]</option> | 						<option value="all">[[admin/settings/reputation:upvote-visibility-all]]</option> | ||||||
| 						<option value="loggedin">[[admin/settings/reputation:upvote-visibility-loggedin]]</option> | 						<option value="loggedin">[[admin/settings/reputation:upvote-visibility-loggedin]]</option> | ||||||
| @@ -23,7 +23,7 @@ | |||||||
| 					</select> | 					</select> | ||||||
| 				</div> | 				</div> | ||||||
| 				<div> | 				<div> | ||||||
| 					<label for="downvoteVisibility" class="form-check-label">[[admin/settings/reputation:downvote-visibility]]</label> | 					<label for="downvoteVisibility" class="form-label">[[admin/settings/reputation:downvote-visibility]]</label> | ||||||
| 					<select id="downvoteVisibility" data-field="downvoteVisibility" class="form-select"> | 					<select id="downvoteVisibility" data-field="downvoteVisibility" class="form-select"> | ||||||
| 						<option value="all">[[admin/settings/reputation:downvote-visibility-all]]</option> | 						<option value="all">[[admin/settings/reputation:downvote-visibility-all]]</option> | ||||||
| 						<option value="loggedin">[[admin/settings/reputation:downvote-visibility-loggedin]]</option> | 						<option value="loggedin">[[admin/settings/reputation:downvote-visibility-loggedin]]</option> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user