Diferencia entre revisiones de «MediaWiki:Common.js»
Página de la interfaz de MediaWiki
Más acciones
Sin resumen de edición |
Sin resumen de edición |
||
Línea 1: | Línea 1: | ||
/* ===== | /* ===== MEDIAWIKI COMMON.JS - PANEL DE ADMINISTRACIÓN PROFESIONAL ===== */ | ||
$( function() { | $(function() { | ||
// | |||
if ( mw.config. | // Panel de administración mejorado (solo para admins) | ||
if (mw.config.get('wgUserGroups').includes('sysop')) { | |||
initAdminPanel(); | |||
} | } | ||
// | // 3. Cargar FontAwesome si no está presente | ||
loadFontAwesome(); | |||
}); | |||
/* ===== FUNCIONES PRINCIPALES ===== */ | |||
function initAdminPanel() { | |||
// Añadir enlace rápido al panel | |||
mw.util.addPortletLink( | |||
'p-tb', | |||
mw.util.getUrl('Special:Analytics'), | |||
'<i class="fas fa-chart-line"></i> Panel', | |||
't-adminpanel', | |||
); | 'Acceso rápido al panel de administración' | ||
); | |||
// Botón flotante para móviles | |||
$('body').append( | |||
'<a href="' + mw.util.getUrl('Special:Analytics') + '" ' + | |||
'class="admin-float-btn" title="Panel de administración">' + | |||
'<i class="fas fa-cogs"></i></a>' | |||
); | |||
// Cargar estadísticas en tiempo real | |||
loadRealTimeStats(); | |||
// | // Mejorar dashboard de Analytics si estamos en esa página | ||
if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Analytics' ) { | if (mw.config.get('wgCanonicalSpecialPageName') === 'Analytics') { | ||
enhanceAnalyticsDashboard(); | enhanceAnalyticsDashboard(); | ||
} | } | ||
}); | } | ||
/* ===== FUNCIONES DE DATOS EN TIEMPO REAL ===== */ | |||
function loadRealTimeStats() { | |||
// Actualizar cada 60 segundos | |||
setInterval(fetchAdminStats, 60000); | |||
fetchAdminStats(); // Carga inicial | |||
} | |||
function fetchAdminStats() { | |||
// 1. Estadísticas generales del sitio | |||
$.get(mw.util.wikiScript('api'), { | |||
action: 'query', | |||
meta: 'siteinfo', | |||
siprop: 'statistics', | |||
format: 'json' | |||
}).done(function(data) { | |||
updateBadge('total-users', data.query.statistics.users); | |||
updateBadge('active-users', data.query.statistics.activeusers); | |||
updateBadge('total-pages', data.query.statistics.articles); | |||
}); | |||
// 2. Cambios recientes | |||
$.get(mw.util.wikiScript('api'), { | |||
// | |||
$.get( mw.util.wikiScript( 'api' ), { | |||
action: 'query', | action: 'query', | ||
list: 'recentchanges', | list: 'recentchanges', | ||
rclimit: 1, | rclimit: 1, | ||
format: 'json' | format: 'json' | ||
} ).done( function( data ) { | }).done(function(data) { | ||
updateBadge('recent-changes', data.query.recentchanges.length); | |||
}); | |||
} ); | |||
// | // 3. Páginas nuevas (últimas 24h) | ||
$.get( mw.util.wikiScript( 'api' ), { | $.get(mw.util.wikiScript('api'), { | ||
action: 'query', | action: 'query', | ||
list: 'recentchanges', | list: 'recentchanges', | ||
rctype: 'new', | |||
rclimit: 1, | rclimit: 1, | ||
rcend: new Date(Date.now() - 86400000).toISOString(), | |||
format: 'json' | |||
}).done(function(data) { | |||
updateBadge('new-pages-24h', data.query.recentchanges.length); | |||
}); | |||
// 4. Bloqueos activos | |||
$.get(mw.util.wikiScript('api'), { | |||
action: 'query', | |||
list: 'blocks', | |||
bklimit: 1, | |||
bkprop: 'id', | |||
format: 'json' | format: 'json' | ||
} ).done( function( data ) { | }).done(function(data) { | ||
updateBadge('active-blocks', data.query.blocks.length); | |||
}); | |||
} | |||
} ); | |||
function updateBadge(elementId, value) { | |||
$('[data-source="' + elementId + '"]').text(value).addClass('updated'); | |||
setTimeout(function() { | |||
$('[data-source="' + elementId + '"]').removeClass('updated'); | |||
}, 1000); | |||
} | } | ||
/* ===== MEJORAS PARA EL DASHBOARD ===== */ | |||
function enhanceAnalyticsDashboard() { | function enhanceAnalyticsDashboard() { | ||
// | // 1. Hacer tablas responsivas | ||
$( '.wikitable' ).each( function() { | $('.wikitable').each(function() { | ||
var $table = $( this ); | var $table = $(this); | ||
if ( $table.find( 'th' ).length > 1 ) { | if ($table.find('th').length > 1) { | ||
$table.addClass( 'analytics-table' ) | $table.addClass('analytics-table') | ||
.wrap('<div class="table-responsive"></div>'); | |||
// Añadir | // Añadir botones de acción | ||
$table.before( | var tableId = 'table-' + Math.random().toString(36).substr(2, 9); | ||
'<button class="export-btn" data-table="' + | $table.attr('id', tableId); | ||
'<i class="fas fa- | |||
$table.before( | |||
'<div class="table-actions">' + | |||
'<button class="export-btn" data-table="' + tableId + '">' + | |||
'<i class="fas fa-download"></i> Exportar CSV</button>' + | |||
'<button class="expand-btn" data-table="' + tableId + '">' + | |||
'<i class="fas fa-expand"></i> Expandir</button>' + | |||
'</div>' | |||
); | ); | ||
} | } | ||
}); | }); | ||
// Configurar eventos | // 2. Configurar eventos | ||
$( '.export-btn' ).on( 'click', function() { | $('.export-btn').on('click', function() { | ||
exportTableToCSV($(this).data('table')); | |||
}); | }); | ||
$('.expand-btn').on('click', function() { | |||
$('#' + $(this).data('table')).toggleClass('fullscreen-table'); | |||
$(this).find('i').toggleClass('fa-expand fa-compress'); | |||
}); | |||
// 3. Gráficos interactivos | |||
if ($('#mw-content-text table').length > 0) { | |||
initDataVisualization(); | |||
} | |||
} | } | ||
function exportTableToCSV( tableId ) { | function exportTableToCSV(tableId) { | ||
var $table = $( '#' + tableId ); | var $table = $('#' + tableId); | ||
var csv = []; | var csv = []; | ||
$ | $table.find('tr').each(function() { | ||
var row = []; | var row = []; | ||
$( this ).find( 'th, td' ).each( function() { | $(this).find('th, td').each(function() { | ||
row.push( $( this ).text().trim() ); | row.push($(this).text().trim().replace(/"/g, '""')); | ||
}); | }); | ||
csv.push( row.join( ',' ) ); | csv.push('"' + row.join('","') + '"'); | ||
}); | }); | ||
var csvContent = csv.join( '\n' ); | var csvContent = csv.join('\n'); | ||
var encodedUri = encodeURI( 'data:text/csv;charset=utf-8,' + csvContent ); | var encodedUri = encodeURI('data:text/csv;charset=utf-8,' + csvContent); | ||
var link = document.createElement( 'a' ); | var link = document.createElement('a'); | ||
link.setAttribute( 'href', encodedUri ); | link.setAttribute('href', encodedUri); | ||
link.setAttribute( 'download', ' | link.setAttribute('download', 'reporte_' + new Date().toISOString().slice(0, 10) + '.csv'); | ||
document.body.appendChild( link ); | document.body.appendChild(link); | ||
link.click(); | link.click(); | ||
document.body.removeChild( link ); | document.body.removeChild(link); | ||
} | } | ||
/ | function initDataVisualization() { | ||
// Usar Chart.js si está disponible | |||
$( | if (typeof Chart !== 'undefined') { | ||
$('.analytics-table').each(function() { | |||
var | var $table = $(this); | ||
var headers = []; | |||
var data = []; | |||
$table.find('th').each(function() { | |||
headers.push($(this).text().trim()); | |||
}); | |||
$table.find('tr:gt(0)').each(function() { | |||
var rowData = []; | |||
$(this).find('td').each(function() { | |||
rowData.push($(this).text().trim()); | |||
}); | |||
data.push(rowData); | |||
}); | |||
if (headers.length > 1 && data.length > 0) { | |||
renderChart($table, headers, data); | |||
} | |||
}); | |||
} | |||
} | |||
function renderChart($table, headers, data) { | |||
var canvasId = 'chart-' + $table.attr('id'); | |||
$table.after('<div class="chart-container"><canvas id="' + canvasId + '"></canvas></div>'); | |||
var ctx = document.getElementById(canvasId).getContext('2d'); | |||
var chartData = { | |||
labels: data.map(function(row) { return row[0]; }), | |||
datasets: [{ | |||
label: headers[1], | |||
data: data.map(function(row) { return row[1]; }), | |||
backgroundColor: 'rgba(54, 162, 235, 0.5)', | |||
borderColor: 'rgba(54, 162, 235, 1)', | |||
borderWidth: 1 | |||
}] | |||
}; | |||
new Chart(ctx, { | |||
type: 'bar', | |||
data: chartData, | |||
options: { | |||
responsive: true, | |||
scales: { | |||
y: { | |||
beginAtZero: true | |||
} | |||
} | |||
} | |||
}); | }); | ||
} | } | ||
// | /* ===== FUNCIONES AUXILIARES ===== */ | ||
if ( !$( 'link[href*="font-awesome"]' ).length ) { | function loadFontAwesome() { | ||
if (!$('link[href*="font-awesome"]').length) { | |||
$('head').append( | |||
'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">' | |||
); | |||
} | |||
} | } | ||
/* ===== EVENTOS DINÁMICOS ===== */ | |||
$(document).on('mouseenter', '#adminlinks [class^="fa-"]', function() { | |||
var $icon = $(this); | |||
$icon.parent().attr('title', $icon.parent().text().trim()); | |||
}); | |||
/* ===== ESTILOS DINÁMICOS ===== */ | |||
$('head').append( | |||
'<style>' + | |||
'.admin-float-btn {' + | |||
' position: fixed;' + | |||
' right: 20px;' + | |||
' bottom: 20px;' + | |||
' z-index: 1000;' + | |||
' background: #ff9d00;' + | |||
' color: white;' + | |||
' width: 50px;' + | |||
' height: 50px;' + | |||
' border-radius: 50%;' + | |||
' display: flex;' + | |||
' align-items: center;' + | |||
' justify-content: center;' + | |||
' box-shadow: 0 2px 10px rgba(0,0,0,0.2);' + | |||
' font-size: 20px;' + | |||
'}' + | |||
'.updated {' + | |||
' animation: highlight 1s;' + | |||
'}' + | |||
'@keyframes highlight {' + | |||
' 0% { color: inherit; }' + | |||
' 50% { color: #e74c3c; transform: scale(1.1); }' + | |||
' 100% { color: inherit; }' + | |||
'}' + | |||
'.table-actions {' + | |||
' margin-bottom: 10px;' + | |||
'}' + | |||
'.table-actions button {' + | |||
' margin-right: 5px;' + | |||
'}' + | |||
'.fullscreen-table {' + | |||
' position: fixed;' + | |||
' top: 0;' + | |||
' left: 0;' + | |||
' width: 100%;' + | |||
' height: 100%;' + | |||
' z-index: 1050;' + | |||
' background: white;' + | |||
' padding: 20px;' + | |||
' overflow: auto;' + | |||
'}' + | |||
'</style>' | |||
); |
Revisión del 12:03 6 julio 2025
/* ===== MEDIAWIKI COMMON.JS - PANEL DE ADMINISTRACIÓN PROFESIONAL ===== */
$(function() {
// Panel de administración mejorado (solo para admins)
if (mw.config.get('wgUserGroups').includes('sysop')) {
initAdminPanel();
}
// 3. Cargar FontAwesome si no está presente
loadFontAwesome();
});
/* ===== FUNCIONES PRINCIPALES ===== */
function initAdminPanel() {
// Añadir enlace rápido al panel
mw.util.addPortletLink(
'p-tb',
mw.util.getUrl('Special:Analytics'),
'<i class="fas fa-chart-line"></i> Panel',
't-adminpanel',
'Acceso rápido al panel de administración'
);
// Botón flotante para móviles
$('body').append(
'<a href="' + mw.util.getUrl('Special:Analytics') + '" ' +
'class="admin-float-btn" title="Panel de administración">' +
'<i class="fas fa-cogs"></i></a>'
);
// Cargar estadísticas en tiempo real
loadRealTimeStats();
// Mejorar dashboard de Analytics si estamos en esa página
if (mw.config.get('wgCanonicalSpecialPageName') === 'Analytics') {
enhanceAnalyticsDashboard();
}
}
/* ===== FUNCIONES DE DATOS EN TIEMPO REAL ===== */
function loadRealTimeStats() {
// Actualizar cada 60 segundos
setInterval(fetchAdminStats, 60000);
fetchAdminStats(); // Carga inicial
}
function fetchAdminStats() {
// 1. Estadísticas generales del sitio
$.get(mw.util.wikiScript('api'), {
action: 'query',
meta: 'siteinfo',
siprop: 'statistics',
format: 'json'
}).done(function(data) {
updateBadge('total-users', data.query.statistics.users);
updateBadge('active-users', data.query.statistics.activeusers);
updateBadge('total-pages', data.query.statistics.articles);
});
// 2. Cambios recientes
$.get(mw.util.wikiScript('api'), {
action: 'query',
list: 'recentchanges',
rclimit: 1,
format: 'json'
}).done(function(data) {
updateBadge('recent-changes', data.query.recentchanges.length);
});
// 3. Páginas nuevas (últimas 24h)
$.get(mw.util.wikiScript('api'), {
action: 'query',
list: 'recentchanges',
rctype: 'new',
rclimit: 1,
rcend: new Date(Date.now() - 86400000).toISOString(),
format: 'json'
}).done(function(data) {
updateBadge('new-pages-24h', data.query.recentchanges.length);
});
// 4. Bloqueos activos
$.get(mw.util.wikiScript('api'), {
action: 'query',
list: 'blocks',
bklimit: 1,
bkprop: 'id',
format: 'json'
}).done(function(data) {
updateBadge('active-blocks', data.query.blocks.length);
});
}
function updateBadge(elementId, value) {
$('[data-source="' + elementId + '"]').text(value).addClass('updated');
setTimeout(function() {
$('[data-source="' + elementId + '"]').removeClass('updated');
}, 1000);
}
/* ===== MEJORAS PARA EL DASHBOARD ===== */
function enhanceAnalyticsDashboard() {
// 1. Hacer tablas responsivas
$('.wikitable').each(function() {
var $table = $(this);
if ($table.find('th').length > 1) {
$table.addClass('analytics-table')
.wrap('<div class="table-responsive"></div>');
// Añadir botones de acción
var tableId = 'table-' + Math.random().toString(36).substr(2, 9);
$table.attr('id', tableId);
$table.before(
'<div class="table-actions">' +
'<button class="export-btn" data-table="' + tableId + '">' +
'<i class="fas fa-download"></i> Exportar CSV</button>' +
'<button class="expand-btn" data-table="' + tableId + '">' +
'<i class="fas fa-expand"></i> Expandir</button>' +
'</div>'
);
}
});
// 2. Configurar eventos
$('.export-btn').on('click', function() {
exportTableToCSV($(this).data('table'));
});
$('.expand-btn').on('click', function() {
$('#' + $(this).data('table')).toggleClass('fullscreen-table');
$(this).find('i').toggleClass('fa-expand fa-compress');
});
// 3. Gráficos interactivos
if ($('#mw-content-text table').length > 0) {
initDataVisualization();
}
}
function exportTableToCSV(tableId) {
var $table = $('#' + tableId);
var csv = [];
$table.find('tr').each(function() {
var row = [];
$(this).find('th, td').each(function() {
row.push($(this).text().trim().replace(/"/g, '""'));
});
csv.push('"' + row.join('","') + '"');
});
var csvContent = csv.join('\n');
var encodedUri = encodeURI('data:text/csv;charset=utf-8,' + csvContent);
var link = document.createElement('a');
link.setAttribute('href', encodedUri);
link.setAttribute('download', 'reporte_' + new Date().toISOString().slice(0, 10) + '.csv');
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
function initDataVisualization() {
// Usar Chart.js si está disponible
if (typeof Chart !== 'undefined') {
$('.analytics-table').each(function() {
var $table = $(this);
var headers = [];
var data = [];
$table.find('th').each(function() {
headers.push($(this).text().trim());
});
$table.find('tr:gt(0)').each(function() {
var rowData = [];
$(this).find('td').each(function() {
rowData.push($(this).text().trim());
});
data.push(rowData);
});
if (headers.length > 1 && data.length > 0) {
renderChart($table, headers, data);
}
});
}
}
function renderChart($table, headers, data) {
var canvasId = 'chart-' + $table.attr('id');
$table.after('<div class="chart-container"><canvas id="' + canvasId + '"></canvas></div>');
var ctx = document.getElementById(canvasId).getContext('2d');
var chartData = {
labels: data.map(function(row) { return row[0]; }),
datasets: [{
label: headers[1],
data: data.map(function(row) { return row[1]; }),
backgroundColor: 'rgba(54, 162, 235, 0.5)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
};
new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
/* ===== FUNCIONES AUXILIARES ===== */
function loadFontAwesome() {
if (!$('link[href*="font-awesome"]').length) {
$('head').append(
'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">'
);
}
}
/* ===== EVENTOS DINÁMICOS ===== */
$(document).on('mouseenter', '#adminlinks [class^="fa-"]', function() {
var $icon = $(this);
$icon.parent().attr('title', $icon.parent().text().trim());
});
/* ===== ESTILOS DINÁMICOS ===== */
$('head').append(
'<style>' +
'.admin-float-btn {' +
' position: fixed;' +
' right: 20px;' +
' bottom: 20px;' +
' z-index: 1000;' +
' background: #ff9d00;' +
' color: white;' +
' width: 50px;' +
' height: 50px;' +
' border-radius: 50%;' +
' display: flex;' +
' align-items: center;' +
' justify-content: center;' +
' box-shadow: 0 2px 10px rgba(0,0,0,0.2);' +
' font-size: 20px;' +
'}' +
'.updated {' +
' animation: highlight 1s;' +
'}' +
'@keyframes highlight {' +
' 0% { color: inherit; }' +
' 50% { color: #e74c3c; transform: scale(1.1); }' +
' 100% { color: inherit; }' +
'}' +
'.table-actions {' +
' margin-bottom: 10px;' +
'}' +
'.table-actions button {' +
' margin-right: 5px;' +
'}' +
'.fullscreen-table {' +
' position: fixed;' +
' top: 0;' +
' left: 0;' +
' width: 100%;' +
' height: 100%;' +
' z-index: 1050;' +
' background: white;' +
' padding: 20px;' +
' overflow: auto;' +
'}' +
'</style>'
);