MediaWiki:Gadget-userRightsManagerTW.js

// // Adapted from enwiki: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',	}	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. ~',	};

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; permission = $(this).parent.parent.siblings.eq(1).text.split(':')[1].trim.toLowerCase.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' + tagLine,			expiry: 'infinity'		}); }

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, summary: '/* User:' + userName + ' */ done' + tagLine })		});	} }); //