MediaWiki:Gadget-userRightsManager.js: Difference between revisions

From Test Wiki
Jump to navigation Jump to search
Content deleted Content added
upd as NSS is no longer granted, and fix an error
No edit summary
Line 132: Line 132:
if(this.groupsBureaucratInput.isSelected()) perms.push('bureaucrat');
if(this.groupsBureaucratInput.isSelected()) perms.push('bureaucrat');
if(this.groupsInterfaceAdminInput.isSelected()) perms.push('interface-admin');
if(this.groupsInterfaceAdminInput.isSelected()) perms.push('interface-admin');
if(this.groupsNonStewardSuppressInput.isSelected()) perms.push('non-stewardsuppress');
if(this.groupsAbuseFilterInput.isSelected()) perms.push('abusefilter-admin');
if(this.groupsAbuseFilterInput.isSelected()) perms.push('abusefilter-admin');

Revision as of 22:38, 16 April 2025

// <nowiki>
// Adapted from [[mhtest:MediaWiki:Gadget-userRightsManagerTW.js]], itself adapted from [[w:User:MusikAnimal/userRightsManager.js]], this code is therefore licensed under CC-BY-SA 4.0
(function() {
	if (mw.config.get('wgPageName') != 'Test_Wiki:Request_for_permissions' && !mw.config.get('wgPageName').includes('URMTW-TESTPAGE-RFP')) {
		return;
	}
	
	var names = {
		'sysop': 'Administrator',
		'bureaucrat': 'Bureaucrat',
		'interface-admin': 'Interface administrator',
		'abusefilter-admin': 'Abuse filter administrator',
	}
	
	var cannedResponses = {
		'sysop': '{{administrator granted}} ~~~~',
		'bureaucrat': '{{bureaucrat granted}} ~~~~',
		'interface-admin': '{{interface administrator granted}} ~~~~',
		'abusefilter-admin': '{{done}}. ~~~~',
	};

	var api,
		permission, perms/* = mw.config.get('wgTitle').split('/').slice(-1)[0]*/,
		revisionId = mw.config.get('wgRevisionId'),
		permaLink, userName, sectionId, dialog;

	mw.loader.using(['oojs-ui', 'mediawiki.api'], function() {
		api = new mw.Api();
		$('.assign-permissions-link').on('click', function(e) {
			e.preventDefault();
			permissionText = $(this).parent().parent().next().text().split(':')[1].trim().toLowerCase();
			permission = permissionText.includes('interface') ? 'interface-admin' : (permissionText.includes('crat') ? 'bureaucrat' : 'sysop');
			userName = $(this).siblings().eq(0).text();
			sectionId = $(this).parent().parent().prev().find(".mw-editsection a:not('.mw-editsection-visualeditor')").prop('href').match(/section=(\d+)/)[1];
			showDialog();
		});
	});

	function showDialog() {
		Dialog = function(config) {
			Dialog.super.call(this, config);
		};
		OO.inheritClass(Dialog, OO.ui.ProcessDialog);
		Dialog.static.name = 'user-rights-manager';
		Dialog.static.title = 'Granting rights';
		Dialog.static.actions = [
			{ action: 'submit', label: 'Grant', flags: ['primary', 'progressive'] },
			{ label: 'Cancel', flags: 'safe' }
		];
		Dialog.prototype.getApiManager = function() {
			return this.apiManager;
		};
		Dialog.prototype.getBodyHeight = function() {
			return 393;
		};
		Dialog.prototype.initialize = function() {
			Dialog.super.prototype.initialize.call( this );
			this.editFieldset = new OO.ui.FieldsetLayout( {
				classes: ['container']
			});
			this.editPanel = new OO.ui.PanelLayout({
				expanded: false
			});
			this.editPanel.$element.append( this.editFieldset.$element );
			this.groupsSysopInput = new OO.ui.CheckboxInputWidget({
				selected: permissionText.includes('sysop') || (permissionText.includes('admin') && (!permissionText.includes('interface') || permissionText.split('admin').length > 2)) || (!permissionText.includes('interface') && !permissionText.includes('crat')),
			});
			this.groupsBureaucratInput = new OO.ui.CheckboxInputWidget({
				selected: permissionText.includes('crat')
			});
			this.groupsInterfaceAdminInput = new OO.ui.CheckboxInputWidget({
				selected: permissionText.includes('interface') && mw.config.get('wgUserGroups').includes('steward'),
				disabled: !mw.config.get('wgUserGroups').includes('steward')
			});
			this.groupsAbuseFilterInput = new OO.ui.CheckboxInputWidget({
				selected: permissionText.includes('abusefilter-admin') && mw.config.get('wgUserGroups').includes('steward'),
				disabled: !mw.config.get('wgUserGroups').includes('steward')
			});
			this.userNameInput = new OO.ui.TextInputWidget({
				value: userName.replace(/_/g, ' ')
			});
			this.closingRemarksInput = new OO.ui.MultilineTextInputWidget({
				value: cannedResponses[permission],
				rows: 9
			});
			var formElements = [
				new OO.ui.FieldLayout(new OO.ui.Widget({
					content: [
						new OO.ui.FieldsetLayout({
							content: [
								new OO.ui.FieldLayout(this.groupsSysopInput, {label: 'Administrator', align: 'inline'}),
								new OO.ui.FieldLayout(this.groupsBureaucratInput, {label: 'Bureaucrat', align: 'inline'}),
								new OO.ui.FieldLayout(this.groupsInterfaceAdminInput, {label: 'Interface administrator', align: 'inline'}),
								new OO.ui.FieldLayout(this.groupsAbuseFilterInput, {label: 'Abuse filter administrator', align: 'inline'}),
							]
						})
					]
				}), {
					label: 'Rights',
				}),
				new OO.ui.FieldLayout(this.userNameInput, {
					label: 'Target user',
				}),
				new OO.ui.FieldLayout(this.closingRemarksInput, {
					label: 'Closing remarks',
				})
			];
			this.editFieldset.addItems(formElements);
			this.submitPanel = new OO.ui.PanelLayout( {
				$: this.$,
				expanded: false
			} );
			this.submitFieldset = new OO.ui.FieldsetLayout( {
				classes: ['container']
			} );
			this.submitPanel.$element.append( this.submitFieldset.$element );
			this.changeRightsProgressLabel = new OO.ui.LabelWidget();
			this.changeRightsProgressField = new OO.ui.FieldLayout( this.changeRightsProgressLabel );
			this.markAsDoneProgressLabel = new OO.ui.LabelWidget();
			this.markAsDoneProgressField = new OO.ui.FieldLayout( this.markAsDoneProgressLabel );
			this.stackLayout = new OO.ui.StackLayout( {
				items: [this.editPanel, this.submitPanel],
				padded: true
			} );
			this.$body.append( this.stackLayout.$element );
		};

		Dialog.prototype.onSubmit = function() {
			userName = this.userNameInput.getValue();
			perms = [];
			if(this.groupsSysopInput.isSelected()) perms.push('sysop');
			if(this.groupsBureaucratInput.isSelected()) perms.push('bureaucrat');
			if(this.groupsInterfaceAdminInput.isSelected()) perms.push('interface-admin');
			if(this.groupsAbuseFilterInput.isSelected()) perms.push('abusefilter-admin');
			
			var self = this, promiseCount = 2;

			self.actions.setAbilities( { submit: false } );

			addPromise = function( field, promise ) {
				self.pushPending();
				promise.done(function() {
					field.$field.append( $( '<span>' )
						.text( 'Complete!' )
						.prop('style', 'position:relative; top:0.5em; color: #009000; font-weight: bold')
					);
				}).fail(function(obj) {
					if ( obj && obj.error && obj.error.info ) {
						field.$field.append( $( '<span>' )
							.text('Error: ' + obj.error.info)
							.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')
						);
					} else {
						field.$field.append( $( '<span>' )
							.text('An unknown error occurred.')
							.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')
						);
					}
				}).always( function() {
					promiseCount--; // FIXME: maybe we could use a self.isPending() or something
					self.popPending();

					if (promiseCount === 0) {
						setTimeout(function() {
							location.reload(true);
						}, 1000);
					}
				});

				return promise;
			};

			self.markAsDoneProgressField.setLabel( 'Marking request as done...' );
			self.submitFieldset.addItems( [self.markAsDoneProgressField] );
			self.changeRightsProgressField.setLabel( 'Assigning rights...' );
			self.submitFieldset.addItems( [self.changeRightsProgressField] );

			addPromise(
				self.markAsDoneProgressField,
				markAsDone('\n:' + this.closingRemarksInput.getValue())
			).then(function(data) {
				addPromise(
					self.changeRightsProgressField,
					assignPermission(data.edit.newrevid)
				);
			}.bind(this));

			self.stackLayout.setItem( self.submitPanel );
		};

		Dialog.prototype.getActionProcess = function( action ) {
			return Dialog.super.prototype.getActionProcess.call( this, action ).next( function() {
				if ( action === 'submit' ) {
					return this.onSubmit();
				} else {
					return Dialog.super.prototype.getActionProcess.call( this, action );
				}
			}, this );
		};

		dialog = new Dialog({
			size: 'medium'
		});

		var windowManager = new OO.ui.WindowManager();
		$('body').append(windowManager.$element);
		windowManager.addWindows([dialog]);
		windowManager.openWindow(dialog);
	}

	function assignPermission(revId) {
		permaLink = '[[Special:Diff/' + revId + '|Requested]]';
		return api.postWithToken( 'userrights', {
			action: 'userrights',
			format: 'json',
			user: userName.replace(/ /g, '_'),
			add: perms.join('|'),
			reason: '+' + perms.join(', +') + '; ' + permaLink + ' at [[TW:RfP]]',
			expiry: 'infinity',
			tags: 'userRightsManager'
		});
	}

	function markAsDone(closingRemarks) {
		return api.get({
			'action': 'query', 
			'pageids': mw.config.get('wgArticleId'), 
			'prop': 'revisions', 
			'rvslots': '*', 
			'rvlimit': 1, 
			'rvprop': 'content', 
			'rvsection': sectionId
		}).then(function(data){
			var newContent = data['query']['pages'][mw.config.get('wgArticleId')]['revisions'][0]['slots']['main']['*'] + closingRemarks
			return api.postWithToken( 'edit', {
				'action': 'edit',
				'pageid': mw.config.get('wgArticleId'),
				'section': sectionId,
				'text': newContent,
				'tags': 'userRightsManager',
				summary: '/* User:' + userName + ' */ done'
			})
		});
	}
})();
// </nowiki>