MediaWiki:Gadget-userRightsManagerTW.js

// // Adapted from w:User:MusikAnimal/userRightsManager.js (function {	if (mw.config.get('wgPageName') != 'TestWiki:Request_permissions' && !mw.config.get('wgPageName').includes('URMTW-TESTPAGE-RFP')) {		return;	}	var names = {		'sysop': 'Administrator',		'bureaucrat': 'Bureaucrat',		'interface-admin': 'Interface Administrator',	}	var cannedResponses = {		'sysop': '✅ Please ensure you follow our policies, especially Testing policy and Main policy, reverting every test administrative action in the reverse order performed. As a best practice, test blocks should be done on User:Example or yourself. ~',		'bureaucrat': '✅ Please continue to make sure you are following all policies and know that bureaucrat is, ultimately, a more senior, trusted testing permission. Ultimately, Consuls are the de facto non-test administrators on TestWiki and they, together with the community at Community portal, guide this wiki. If granting permissions, please try and link to the diff page of the given user\'s request when granting rights, and only grant rights upon request. ~',		'interface-admin': '✅ per the clear purpose articulated in your reason for requesting the permission, on an indefinite or time-limited basis. Where it is on a time-limited basis, please refer to a follow-up comment from the actioning Consul. Thank you. ~',	};

var api, permission/* = mw.config.get('wgTitle').split('/').slice(-1)[0]*/, revisionId = mw.config.get('wgRevisionId'), tagLine = ' (using userRightsManagerTW)', 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.siblings.eq(1).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.parent.prev.children('.mw-editsection').find("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 = 'Grant ' + names[permission] + ' to ' + userName; Dialog.static.actions = [ { action: 'submit', label: 'Grant', flags: ['primary', 'constructive'] }, { label: 'Cancel', flags: 'safe' } ];		Dialog.prototype.getApiManager = function { return this.apiManager; };		Dialog.prototype.getBodyHeight = function { return 208; };		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.closingRemarksInput = new OO.ui.MultilineTextInputWidget({				value: cannedResponses[permission],				rows: 9			}); var formElements = [ 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 { var self = this, promiseCount = 2;

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

addPromise = function( field, promise ) { self.pushPending; promise.done(function {					field.$field.append( $( ' ' ) .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( $( ' ' ) .text('Error: ' + obj.error.info) .prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold') );					} else {						field.$field.append( $( ' ' ) .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 = 'Requested'; return api.postWithToken( 'userrights', {			action: 'userrights',			format: 'json',			user: userName.replace(/ /g, '_'),			add: permission,			reason: '+' + permission + '; ' + permaLink + ' at RfP',			expiry: 'infinity',			tags: 'userRightsManagerTW'		}); }

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']['*'].replace('|status=|by=', '|status=done|by='+mw.config.get('wgUserName')) + closingRemarks			return api.postWithToken( 'edit', { 'action': 'edit', 'pageid': mw.config.get('wgArticleId'), 'section': sectionId, 'text': newContent, 'tags': 'userRightsManagerTW', summary: '/* User:' + userName + ' */ done' })		});	} }); //