User:TheAstorPastor/common.js: Difference between revisions

From Test Wiki
Content deleted Content added
Undo revision 60266 by TheAstorPastor (talk)
Tags: Replaced Undo Reverted
No edit summary
Tag: Reverted
Line 1: Line 1:
// Only run on Test Wiki:Request for Permissions page
if (mw.config.get('wgTitle') === 'Request for permissions' &&
mw.config.get('wgNamespaceNumber') === 4) { // NS 4 is "Project" namespace (Test Wiki:)


$(document).ready(function() {
//importScript('User:Joepayne/grantBureaucrat.js'); // Backlink: [[User:Joepayne/grantBureaucrat.js]]
// Initialize the script
importScript('User:Joepayne/stripRights.js'); // Backlink: [[User:Joepayne/stripRights.js]]
testWikiRfPManager.init();
//importScript('User:MacFan4000/grantAdmin.js'); // Backlink: [[User:MacFan4000/grantAdmin.js]]
});
//importScript('User:Kiteretsu/js/all-in-one.js'); // Backlink: [[User:Kiteretsu/js/all-in-one.js]]

//importScript('User:DodoMan/chatbot.js'); // Backlink: [[User:DodoMan/chatbot.js]]
const testWikiRfPManager = {
importScript('User:JJBullet/findInactiveSysops.js'); // Backlink: [[User:JJBullet/findInactiveSysops.js]]
// Configuration
importScript('User:Harvici/find-archived-section.js'); // Backlink: [[User:Harvici/find-archived-section.js]]
config: {
importScript('User:Harvici/UTCLiveClock.js'); // Backlink: [[User:Harvici/UTCLiveClock.js]]
// Rights that can be assigned with corresponding templates
importScript('User:Harvici/Twinkle-preferences-toolbar.js'); // Backlink: [[User:Harvici/Twinkle-preferences-toolbar.js]]
rights: {
importScript('User:Kiteretsu/rollbackSum.js'); // Backlink: [[User:Kiteretsu/rollbackSum.js]]
'sysop': {
importScript('User:Kiteretsu/DiscussionCloser.js'); // Backlink: [[User:Kiteretsu/DiscussionCloser.js]]
displayName: 'Administrator',
importScript('User:TheAstorPastor/VisualEditorEverywhere.js'); // Backlink: [[User:TheAstorPastor/VisualEditorEverywhere.js]]
template: '{{administrator granted}} [[User:TheAstorPastor|<span style="font-family:Segoe print; color:#8B0000; text-shadow:gray 0.2em 0.2em 0.4em;">The AP </span>]] ([[User talk:TheAstorPastor|<span style="font-family:Segoe print; color:#AA336A">''talk''</span>]]) 13:57, 11 April 2025 (UTC)'
},
'bureaucrat': {
displayName: 'Bureaucrat',
template: '{{bureaucrat granted}} [[User:TheAstorPastor|<span style="font-family:Segoe print; color:#8B0000; text-shadow:gray 0.2em 0.2em 0.4em;">The AP </span>]] ([[User talk:TheAstorPastor|<span style="font-family:Segoe print; color:#AA336A">''talk''</span>]]) 13:57, 11 April 2025 (UTC)'
},
'interface-admin': {
displayName: 'Interface Administrator',
template: '{{interface administrator granted}} [[User:TheAstorPastor|<span style="font-family:Segoe print; color:#8B0000; text-shadow:gray 0.2em 0.2em 0.4em;">The AP </span>]] ([[User talk:TheAstorPastor|<span style="font-family:Segoe print; color:#AA336A">''talk''</span>]]) 13:57, 11 April 2025 (UTC)'
},
'non-stewardsuppress': {
displayName: 'Suppressor',
template: '{{done}}. [[User:TheAstorPastor|<span style="font-family:Segoe print; color:#8B0000; text-shadow:gray 0.2em 0.2em 0.4em;">The AP </span>]] ([[User talk:TheAstorPastor|<span style="font-family:Segoe print; color:#AA336A">''talk''</span>]]) 13:57, 11 April 2025 (UTC)'
},
'abusefilter-admin': {
displayName: 'Abuse Filter Administrator',
template: '{{done}}. [[User:TheAstorPastor|<span style="font-family:Segoe print; color:#8B0000; text-shadow:gray 0.2em 0.2em 0.4em;">The AP </span>]] ([[User talk:TheAstorPastor|<span style="font-family:Segoe print; color:#AA336A">''talk''</span>]]) 13:57, 11 April 2025 (UTC)'
}
}
},

// Initialize the script
init: function() {
// Check if user has the required permissions
if (!mw.config.get('wgUserGroups').includes('sysop')) {
console.log('TestWiki RfP Manager: User does not have sysop rights');
return;
}

// Load required styles
this.loadStyles();
// Process each RfP section
this.processRfPSections();
},

// Load CSS styles for the script
loadStyles: function() {
mw.loader.addStyleTag(`
.twrm-container {
background-color: #f8f9fa;
border: 1px solid #a2a9b1;
border-radius: 3px;
padding: 12px;
margin: 10px 0;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
}
.twrm-header {
font-weight: bold;
margin-bottom: 8px;
color: #222;
font-size: 14px;
padding-bottom: 5px;
border-bottom: 1px solid #eaecf0;
}
.twrm-controls {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
margin-bottom: 8px;
}
.twrm-select {
padding: 6px 8px;
border: 1px solid #a2a9b1;
border-radius: 2px;
background-color: white;
min-width: 200px;
}
.twrm-button {
padding: 6px 12px;
background-color: #36c;
color: white;
border: none;
border-radius: 2px;
cursor: pointer;
font-weight: bold;
}
.twrm-button:hover {
background-color: #447ff5;
}
.twrm-button:disabled {
background-color: #c8ccd1;
cursor: not-allowed;
}
.twrm-result {
margin-top: 10px;
padding: 8px;
background-color: #eaf3ff;
border: 1px solid #c8ccd1;
border-radius: 2px;
display: none;
}
.twrm-copy-button {
padding: 4px 8px;
background-color: #f8f9fa;
border: 1px solid #a2a9b1;
border-radius: 2px;
margin-top: 8px;
cursor: pointer;
}
.twrm-copy-button:hover {
background-color: #eaecf0;
}
.twrm-user-info {
margin-bottom: 8px;
font-style: italic;
}
.twrm-success {
color: #14866d;
font-weight: bold;
margin-top: 5px;
display: none;
}
`);
},

// Process all RfP sections on the page
processRfPSections: function() {
const self = this;
// Find all h2 headers which typically denote user request sections
$('.mw-parser-output > h2').each(function() {
const $header = $(this);
const username = $header.find('.mw-headline').text().trim();
if (username) {
// Find the section content
let $section = $header.nextUntil('h2, h1');
// Extract requested right from the section
const requestedRight = self.extractRequestedRight($section);
// Create rights manager UI
self.createRightsManagerUI($header, username, requestedRight);
}
});
},

// Extract the requested right from section content
extractRequestedRight: function($section) {
let rightText = '';
// Look for the "Requested right" line
$section.each(function() {
const text = $(this).text();
if (text.includes('Requested right')) {
// Extract the right from the text
const match = text.match(/Requested right[:\s]*([^*\n]+)/i);
if (match && match[1]) {
rightText = match[1].trim();
}
return false; // Break the loop
}
});

// Map common variations to our defined rights
const rightMap = {
'administrator': 'sysop',
'admin': 'sysop',
'sysop': 'sysop',
'bureaucrat': 'bureaucrat',
'crat': 'bureaucrat',
'interface administrator': 'interface-admin',
'interface admin': 'interface-admin',
'suppressor': 'non-stewardsuppress',
'suppress': 'non-stewardsuppress',
'abuse filter administrator': 'abusefilter-admin',
'abusefilter admin': 'abusefilter-admin',
'abuse filter admin': 'abusefilter-admin'
};
// Try to match the requested right
for (const [key, value] of Object.entries(rightMap)) {
if (rightText.toLowerCase().includes(key.toLowerCase())) {
return value;
}
}
return ''; // No match found
},

// Create the UI for managing rights
createRightsManagerUI: function($header, username, preselectedRight) {
const self = this;
// Create container
const $container = $('<div>')
.addClass('twrm-container')
.insertAfter($header);
// Create header
$('<div>')
.addClass('twrm-header')
.text('Rights Manager')
.appendTo($container);
// Add user info
$('<div>')
.addClass('twrm-user-info')
.text(`Request by: ${username}`)
.appendTo($container);
// Create controls container
const $controls = $('<div>')
.addClass('twrm-controls')
.appendTo($container);
// Create right selection dropdown
const $select = $('<select>')
.addClass('twrm-select')
.appendTo($controls);
// Add default option
$('<option>')
.val('')
.text('Select right to grant...')
.appendTo($select);
// Add options for each available right
for (const [right, config] of Object.entries(this.config.rights)) {
$('<option>')
.val(right)
.text(config.displayName)
.prop('selected', right === preselectedRight)
.appendTo($select);
}
// Create grant button
const $grantButton = $('<button>')
.addClass('twrm-button')
.text('Grant Rights')
.prop('disabled', !preselectedRight)
.appendTo($controls);
// Create API button
const $apiButton = $('<button>')
.addClass('twrm-button')
.text('Grant via API')
.prop('disabled', !preselectedRight)
.appendTo($controls);
// Create result container
const $result = $('<div>')
.addClass('twrm-result')
.appendTo($container);
// Create copy button
const $copyButton = $('<button>')
.addClass('twrm-copy-button')
.text('Copy to Clipboard')
.appendTo($result);
// Create success message
const $success = $('<div>')
.addClass('twrm-success')
.text('Rights granted successfully!')
.appendTo($container);
// Handle select change
$select.on('change', function() {
const hasSelection = $(this).val() !== '';
$grantButton.prop('disabled', !hasSelection);
$apiButton.prop('disabled', !hasSelection);
$result.hide();
$success.hide();
});
// Handle grant button click
$grantButton.on('click', function() {
const selectedRight = $select.val();
if (selectedRight && self.config.rights[selectedRight]) {
// Show template response
$result.show().text(self.config.rights[selectedRight].template);
}
});
// Handle API button click
$apiButton.on('click', function() {
const selectedRight = $select.val();
if (selectedRight && self.config.rights[selectedRight]) {
// Set button to loading state
const originalText = $apiButton.text();
$apiButton.text('Processing...').prop('disabled', true);
// Grant the right using MediaWiki API
self.grantRightViaAPI(username, selectedRight)
.then(function(success) {
if (success) {
$success.show();
$result.show().text(self.config.rights[selectedRight].template);
} else {
$result.show().text('Error granting rights. Please try again or use manual method.');
}
})
.catch(function() {
$result.show().text('Error granting rights. Please try again or use manual method.');
})
.finally(function() {
// Reset button state
$apiButton.text(originalText).prop('disabled', false);
});
}
});
// Handle copy button click
$copyButton.on('click', function() {
const textToCopy = $result.text();
navigator.clipboard.writeText(textToCopy).then(function() {
$copyButton.text('Copied!');
setTimeout(function() {
$copyButton.text('Copy to Clipboard');
}, 2000);
});
});
},

// Grant rights via MediaWiki API
grantRightViaAPI: function(username, right) {
return new Promise(function(resolve) {
// Get API token
mw.user.getToken('csrf').then(function(token) {
// Make API request to grant right
new mw.Api().postWithToken('csrf', {
action: 'userrights',
user: username,
add: right,
reason: 'Granted per request on [[Test Wiki:Request for Permissions]]',
token: token
})
.done(function() {
resolve(true);
})
.fail(function() {
resolve(false);
});
});
});
}
};
}