MediaWiki:Gadget-userRightsManager.js: Difference between revisions

From Test Wiki
Jump to navigation Jump to search
(clean out code for updating markadmins.json since it's no longer necessary due to gadget changes)
No edit summary
Tags: Mobile edit Mobile web edit
 
(15 intermediate revisions by 4 users not shown)
Line 1: Line 1:
// <nowiki>
// <nowiki>
// Adapted from [[mhtest:MediaWiki:Gadget-userRightsManagerTW.js]], itself adapted from [[w:User:MusikAnimal/userRightsManager.js]]
// 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() {
(function() {
if (mw.config.get('wgPageName') != 'Test_Wiki:Request_permissions' && !mw.config.get('wgPageName').includes('URMTW-TESTPAGE-RFP')) {
if (mw.config.get('wgPageName') != 'Test_Wiki:Request_for_permissions' && !mw.config.get('wgPageName').includes('URMTW-TESTPAGE-RFP')) {
return;
return;
}
}
Line 9: Line 9:
'sysop': 'Administrator',
'sysop': 'Administrator',
'bureaucrat': 'Bureaucrat',
'bureaucrat': 'Bureaucrat',
'interface-admin': 'Interface Administrator',
'interface-admin': 'Interface administrator',
'non-stewardsuppress': 'Suppressor',
}
}
var cannedResponses = {
var cannedResponses = {
'sysop': '{{done}}. ~~~~',
'sysop': '{{administrator granted}} ~~~~',
'bureaucrat': '{{done}}. ~~~~',
'bureaucrat': '{{bureaucrat granted}} ~~~~',
'interface-admin': '{{done}}. ~~~~',
'interface-admin': '{{interface administrator granted}} ~~~~',
'non-stewardsuppress': '{{done}}. ~~~~'
};
};


Line 69: Line 71:
this.groupsInterfaceAdminInput = new OO.ui.CheckboxInputWidget({
this.groupsInterfaceAdminInput = new OO.ui.CheckboxInputWidget({
selected: permissionText.includes('interface') && mw.config.get('wgUserGroups').includes('steward'),
selected: permissionText.includes('interface') && mw.config.get('wgUserGroups').includes('steward'),
disabled: !mw.config.get('wgUserGroups').includes('steward')
});
this.groupsNonStewardSuppressInput = new OO.ui.CheckboxInputWidget({
selected: permissionText.includes('suppress') && mw.config.get('wgUserGroups').includes('steward'),
disabled: !mw.config.get('wgUserGroups').includes('steward')
disabled: !mw.config.get('wgUserGroups').includes('steward')
});
});
Line 86: Line 92:
new OO.ui.FieldLayout(this.groupsBureaucratInput, {label: 'Bureaucrat', 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.groupsInterfaceAdminInput, {label: 'Interface administrator', align: 'inline'}),
new OO.ui.FieldLayout(this.groupsNonStewardSuppressInput, {label: 'Suppressor', align: 'inline'}),
]
]
})
})
Line 125: 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');
var self = this, promiseCount = 3;
var self = this, promiseCount = 2;


self.actions.setAbilities( { submit: false } );
self.actions.setAbilities( { submit: false } );
Line 208: Line 216:
user: userName.replace(/ /g, '_'),
user: userName.replace(/ /g, '_'),
add: perms.join('|'),
add: perms.join('|'),
reason: '+' + perms.join(', +') + '; ' + permaLink + ' at [[TW:RFP]]',
reason: '+' + perms.join(', +') + '; ' + permaLink + ' at [[TW:RfP]]',
expiry: 'infinity',
expiry: 'infinity',
tags: 'userRightsManagerTW'
tags: 'userRightsManager'
});
});
}
}
Line 230: Line 238:
'section': sectionId,
'section': sectionId,
'text': newContent,
'text': newContent,
'tags': 'userRightsManagerTW',
'tags': 'userRightsManager',
summary: '/* User:' + userName + ' */ done'
summary: '/* User:' + userName + ' */ done'
})
})

Latest revision as of 14:07, 27 February 2024

// <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',
		'non-stewardsuppress': 'Suppressor',
	}
	
	var cannedResponses = {
		'sysop': '{{administrator granted}} ~~~~',
		'bureaucrat': '{{bureaucrat granted}} ~~~~',
		'interface-admin': '{{interface administrator granted}} ~~~~',
		'non-stewardsuppress': '{{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.groupsNonStewardSuppressInput = new OO.ui.CheckboxInputWidget({
				selected: permissionText.includes('suppress') && 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.groupsNonStewardSuppressInput, {label: 'Suppressor', 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.groupsNonStewardSuppressInput.isSelected()) perms.push('non-stewardsuppress');
			
			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>