Benutzer:Ladsgroup/dashboard.js
Erscheinungsbild
Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.
- Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
- Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
- Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
// License: GPL-v3 or later
// Keep in sync with https://gitlab.wikimedia.org/ladsgroup/dashboard-gadget/-/blob/main/main.js
function dashboardGadget() {
function msg( key ){
const i18n = {
'en': {
'dashboard': 'Dashboard',
'dashboard-message': 'Go to the dashboard',
'loading': 'Loading...',
'diff': 'Diff',
'refresh': 'Refresh',
'configuration': 'Configuration',
'pending-since': 'Pending since',
'default-config': 'User:Ladsgroup/defaultDashboardConfig.json'
},
'fa': {
'dashboard': 'پیشخوان',
'dashboard-message': 'رفتن به صفحهٔ پیشخوان عمومی',
'loading': 'در حال بارگذاری...',
'diff': 'تفاوت',
'refresh': 'بروزرسانی',
'configuration': 'تنظیمات',
'pending-since': 'در حال انتظار از',
'default-config': 'مدیاویکی:Gadget-dashboard/defaultConfig.json'
},
'de': {
'dashboard': 'Dashboard',
'dashboard-message': 'Go to the dashboard',
'loading': 'Laden...',
'diff': 'Unterschied',
'refresh': 'Neuladen',
'configuration': 'Einstellungen',
'pending-since': 'Ungesichtet seit',
'default-config': 'User:Ladsgroup/defaultConfig.json'
}
};
return i18n[ mw.config.get( 'wgUserLanguage' ).split('-')[0] ][ key ] || i18n.en[ key ];
}
// inject the link
if ($('.vector-user-links').length) {
// new vector
let dashboardLinkDiv = $('<div></div>');
dashboardLinkDiv.css('margin', '5px');
let link = $('<a></a>');
link.attr('href', '/wiki/Special:BlankPage/Dashboard');
link.text(msg('dashboard'))
dashboardLinkDiv.append(link);
dashboardLinkDiv.append(' - ');
$('.vector-user-links').prepend(dashboardLinkDiv);
} else {
// old vector
mw.util.addPortletLink('p-personal', '/wiki/Special:BlankPage/Dashboard', msg('dashboard'), 'p-dashboard', msg('dashboard-message'), null, '#pt-userpage');
}
if (
mw.config.get( 'wgCanonicalNamespace' ) != 'Special' ||
mw.config.get( 'wgCanonicalSpecialPageName' ) != 'Blankpage' ||
mw.config.get( 'wgPageName' ).search( '/Dashboard' ) == -1
) {
return;
}
document.documentElement.classList.remove('vector-feature-limited-width-clientpref-1');
document.documentElement.classList.add('vector-feature-limited-width-clientpref-0');
document.documentElement.classList.remove('vector-feature-page-tools-pinned-enabled');
document.documentElement.classList.add('vector-feature-page-tools-pinned-disabled');
$('.vector-page-toolbar').remove();
window.dispatchEvent( new Event( 'resize' ) );
$('.mw-first-heading').text(msg('dashboard'));
document.title = msg('dashboard');
$('.mw-body-content').text(msg('loading'));
async function loadConfig( title ) {
let response = await fetch("/wiki/" + encodeURIComponent(title) + '?action=raw');
return response.text();
}
async function contentForPageType( box ) {
let response = await fetch("/api/rest_v1/page/html/" + encodeURIComponent(box.pageTitle));
return response.text();
}
async function contentForRC( box ) {
let response = await fetch(box.url);
let data = await response.json();
data = data.query.recentchanges;
let content = $('<ul></ul>');
for ( i in data ) {
let diff = $('<a></a>');
diff.attr('href', '/wiki/Special:Diff/' + Number(data[i].revid));
diff.text(msg('diff'));
let liObj = $('<li></li>');
liObj.append('(');
liObj.append(diff);
liObj.append(') - ');
liObj.append(getPageLink(data[i].title));
liObj.append(' ');
liObj.append(getUser(data[i].user));
liObj.append( ' (' + data[i].parsedcomment + ')' );
content.append(liObj);
}
return content;
}
async function contentForWatchlist( box ) {
let response = await fetch(box.url);
let data = await response.json();
data = data.query.watchlist;
let content = $('<ul></ul>');
for ( i in data ) {
let diff = $('<a></a>');
diff.attr('href', '/wiki/Special:Diff/' + Number(data[i].revid));
diff.text(msg('diff'));
let liObj = $('<li></li>');
liObj.append('(');
liObj.append(diff);
liObj.append(') - ');
liObj.append(getPageLink(data[i].title));
liObj.append(' ');
liObj.append(getUser(data[i].user));
liObj.append( ' (' + data[i].parsedcomment + ')' );
content.append(liObj);
}
return content;
}
async function contentForPending( box ) {
let response = await fetch(box.url);
let data = await response.json();
data = data.query.oldreviewedpages;
if ( !data ) {
return 'Nothing to review!';
}
let content = $('<ul></ul>');
for ( i in data ) {
let diff = $('<a></a>');
diff.attr('href', '/wiki/Special:Diff/' + Number(data[i].revid));
diff.text(msg('diff'));
let liObj = $('<li></li>');
liObj.append('(');
liObj.append(diff);
liObj.append(') - ');
liObj.append(getPageLink(data[i].title));
liObj.append( ' (' + msg('pending-since') + ': ' + data[i].pending_since + ')' );
content.append(liObj);
}
return content;
}
async function contentForCategory( box ) {
let api = new mw.Api();
if (box.norandom) {
limit = 10;
} else {
limit = 100;
}
let data = await api.get( {
action: 'query',
list: 'categorymembers',
cmprop: 'title',
cmlimit: limit,
cmtitle: box.categoryTitle
} );
data = getMultipleRandom(data.query.categorymembers, 10);
let content = $('<ul></ul>');
for ( i in data ) {
let liObj = $('<li></li>');
liObj.append(getPageLink(data[i].title));
content.append(liObj);
}
return content;
}
async function contentForLinks( box ) {
let content = $('<ul></ul>');
for ( i in box.links ) {
let link = box.links[i];
if ( link.page ) {
let liObj = $('<li></li>');
liObj.append(getPageLink(link.page));
content.append(liObj);
} else if ( link.url ) {
let link = $('<a>');
link.attr('href', encodeURIComponent(link.url));
link.text(link.text);
let liObj = $('<li></li>');
liObj.append(link);
content.append(liObj);
}
}
return content;
}
async function contnetForStats() {
let api = new mw.Api();
let data = await api.get( {
action: 'query',
meta: 'siteinfo',
siprop: 'statistics',
} );
let content = '<ul>';
content += '<li>تعداد مقالات: ' + mw.language.convertNumber(data.query.statistics.articles) + '</li>';
content += '<li>تعداد صفحات: ' + mw.language.convertNumber(data.query.statistics.pages) + '</li>';
content += '<li>تعداد ویرایشها: ' + mw.language.convertNumber(data.query.statistics.edits) + '</li>';
content += '<li>تعداد تصاویر: ' + mw.language.convertNumber(data.query.statistics.images) + '</li>';
content += '<li>تعداد کاربران فعال: ' + mw.language.convertNumber(data.query.statistics.activeusers) + '</li>';
return content + '</ul>';
}
async function contnetForCx() {
let api = new mw.Api();
let data = await api.get( {
action: 'query',
assert: 'user',
list: 'contenttranslationsuggestions',
from: 'en',
to: 'fa',
limit: 10,
seed: Math.floor(Math.random() * 100)
} );
data = data.query.contenttranslationsuggestions.lists;
let content = $('<ul></ul>');
for ( i in data ) {
for (j in data[i].suggestions) {
let link = $('<a>');
link.attr('href', 'https://en.wikipedia.org/wiki/' + encodeURIComponent(data[i].suggestions[j].title));
link.text(data[i].suggestions[j].title);
let liObj = $('<li></li>');
liObj.append(link);
content.append(liObj);
}
}
let divObj = $('<div direction="ltr"></div>');
divObj.append(content);
return divObj;
}
const handlers = {
'page': contentForPageType,
'rc': contentForRC,
'watchlist': contentForWatchlist,
'category': contentForCategory,
'pending': contentForPending,
'links': contentForLinks,
'stats': contnetForStats,
'cx': contnetForCx,
};
function getUser(username) {
let link = $('<a>');
link.attr('href', '/wiki/User:' + encodeURIComponent(username));
link.text(username);
return link;
}
function getPageLink( title ) {
let link = $('<a>');
link.attr('href', '/wiki/' + encodeURIComponent(title));
link.text(title);
return link;
}
function getMultipleRandom(arr, num) {
const shuffled = [...arr].sort(() => 0.5 - Math.random());
return shuffled.slice(0, num);
}
function loadBoxes() {
$('.mw-body-content').text(msg('loading'));
let tabs = $('<div class="cdx-tabs"></div>');
let tabsHeader = $('<div class="cdx-tabs__header"><div class="cdx-tabs__list"></div></div>');
let tabsContent = $( '<div class="cdx-tabs__content"></div>');
for ( let tabIndex in window.dashboardConfig.tabs ) {
let tabConfig = window.dashboardConfig.tabs[tabIndex];
let headerElement = $('<span class="cdx-tabs__list__item"></span>');
headerElement.text( tabConfig.title );
headerElement.on( 'click', () => {
window.dashboardActiveTab = tabIndex;
loadBoxes();
});
if ( tabIndex == ( window.dashboardActiveTab || 0 ) ) {
headerElement.attr('aria-selected', true);
}
tabsHeader.append(headerElement);
let tabContent = $( '<div class="cdx-tab"></div>');
tabContent.attr( 'id', 'tab-content-' + tabIndex );
tabContent.css('display', 'flex');
tabContent.css('flex-wrap', 'wrap');
tabContent.css('align-items', 'flex-start');
for (let i in tabConfig.boxes) {
i = Number(i);
let box = tabConfig.boxes[i];
let element = $('<span class="cdx-card__text"></span>');
let titleElement = $('<span class="cdx-card__text__title"></span>');
titleElement.text(box.title);
element.append(titleElement);
let contentElement = $('<span></span>');
contentElement.attr('class', 'cdx-card__text__supporting-text');
contentElement.attr('id', 'dashboard-box-' + i);
contentElement.append('<span class="cdx-css-icon--clock"></span>');
contentElement.append(msg('loading'));
contentElement.css('width', box.width || '300px' );
contentElement.css('height', box.height || '300px' );
contentElement.css('overflow', 'scroll' );
element.append(contentElement);
let wrapper = $( '<span class="cdx-card"></span>' );
wrapper.append(element);
wrapper.css('padding', '15px' );
wrapper.css('margin', '15px' );
const activeTab = window.dashboardActiveTab || 0;
if ( tabIndex == activeTab ) {
wrapper.css('display', 'inline-flex');
tabsContent.append(wrapper);
if ( handlers[box.type] ) {
handlerPromise = handlers[box.type](box);
} else {
handlerPromise = new Promise(() => { return 'No handler has been found' } );
}
handlerPromise.then( ( content ) => { $( '#dashboard-box-' + i).html( content )});
} else {
wrapper.css('display', 'none');
}
}
}
tabs.append(tabsHeader);
let direction = 'left';
if (document.dir == 'rtl') {
direction = 'right';
}
let refreshButton = $('<button class="cdx-button cdx-button--action-progressive"></button>');
refreshButton.append('<span class="cdx-button__icon cdx-css-icon--reload"></span>');
refreshButton.text(msg('refresh'));
refreshButton.css( 'align-self', 'flex-end' );
refreshButton.css( 'margin-bottom', '5px' );
refreshButton.css( 'margin-' + direction, '5px' );
refreshButton.on('click', loadBoxes );
let configButton = $('<button class="cdx-button cdx-button--action-progressive"></button>');
configButton.append('<span class="cdx-button__icon cdx-css-icon--reload"></span>');
configButton.text(msg('configuration'));
let configLink = $('<a></a>');
configLink.attr('href', '/wiki/ ' + encodeURIComponent( window.dashboardConfigLocation ));
configLink.attr('target', '_blank');
configLink.append(configButton);
configLink.css( 'margin-bottom', '5px' );
configLink.css( 'margin-' + direction, 'auto');
tabsHeader.append( configLink );
tabsHeader.append( refreshButton );
tabs.append(tabsContent);
$('.mw-body-content').html(tabs);
}
let configPromise = null;
if ( mw.util.getParamValue( 'dashboardConfig' ) ) {
configPromise = loadConfig( mw.util.getParamValue( 'dashboardConfig' ) );
window.dashboardConfigLocation = mw.util.getParamValue( 'dashboardConfig' );
} else {
configPromise = loadConfig('User:' + mw.config.get('wgUserName') + '/dashboardConfig.json' )
.then( function (res) {
try {
JSON.parse(res);
window.dashboardConfigLocation = 'User:' + mw.config.get('wgUserName') + '/dashboardConfig.json';
return res;
} catch (erorr) {
window.dashboardConfigLocation = msg('default-config');
return loadConfig(msg('default-config'));
}
} );
}
configPromise.then( function (res) {
let config = JSON.parse(res);
window.dashboardConfig = config;
mw.loader.using('codex-styles').then( loadBoxes() );
});
};
(function ($, mw) {
dashboardGadget();
}(jQuery, mediaWiki));