Usuário(a):Lucas.Belo/API-test.js
Nota: Depois de publicar, poderá ter de contornar a cache do seu navegador para ver as alterações.
- Firefox / Safari: Pressione Shift enquanto clica Recarregar, ou pressione Ctrl-F5 ou Ctrl-R (⌘-R no Mac)
- Google Chrome: Pressione Ctrl-Shift-R (⌘-Shift-R no Mac)
- Edge: Pressione Ctrl enquanto clica Recarregar, ou pressione Ctrl-F5.
const elementRevisions = document.getElementById('revisions');
const elementTableRevisions = document.getElementById('table-revisions');
elementTableRevisions.setAttribute('class', 'wikitable sortable');
mw.loader.using('@wikimedia/codex').then(function (require) {
const Vue = require('vue');
const Codex = require('@wikimedia/codex');
const mountPoint = elementRevisions.appendChild(document.createElement('div'));
Vue.createMwApp({
template: `
<cdx-lookup
v-model:selected="selection"
placeholder="Pesquise na Wikipédia"
:style="{ width: '400px' }"
:clearable="true"
:start-icon="cdxIconSearch"
:menu-items="menuItems"
:menu-config="menuConfig"
@input="onInput"
@load-more="onLoadMore"
>
<template #no-results>
Nenhum resultado encontrado
</template>
</cdx-lookup>
<cdx-button-group
:buttons="buttons"
@click="onClick"
></cdx-button-group>
<div id="message"></div>
`,
setup() {
function ref(value) {
return Vue.ref(value);
}
const selection = ref( null );
const menuItems = ref( [] );
const currentSearchTerm = ref( '' );
const buttons = [
{ value: 'getRevisions', label: 'Obter histórico'},
{ value: 'donwloadCSV', label: 'Baixar CSV'}
];
function onClick( value ) {
if (value == 'getRevisions'){
getRevisions();
}
else{
donwloadCSV();
}
}
function getRevisions() {
let title = currentSearchTerm.value;
var api = new mw.Api();
api.get({
action: 'query',
prop: 'revisions',
titles: title,
rvslots: "*",
rvlimit: "max",
rvprop: 'user|comment|size|timestamp',
})
.then(function(data) {
const message = document.getElementById('message');
message.innerHTML = `
<br>
<p>A tabela a seguir é o histórico de edição da página <b>${title}</b>.
Clique no botão Baixar CSV para fazer donwload do conteúdo. A lista mosta dados das últimas 500 edições.
</p>
`;
const existingTable = elementTableRevisions.querySelector('tbody');
if (existingTable) {
elementTableRevisions.removeChild(existingTable);
}
const tableBody = document.createElement('tbody');
elementTableRevisions.appendChild(tableBody);
const header = document.createElement('tr');
header.innerHTML = `
<th>Usuário</th>
<th>Data e Hora</th>
<th>Bytes</th>
<th>Comentário</th>
`;
tableBody.appendChild(header);
const pages = data.query.pages;
const revisions = Object.values(pages)[0].revisions;
revisions.forEach(revision => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${revision.user}</td>
<td>${new Date(revision.timestamp).toLocaleString()}</td>
<td>${revision.size}</td>
<td>${revision.comment}</td>
`;
tableBody.appendChild(row);
});
})
.catch(function(error) {
console.error('Erro na requisição de API:', error);
});
}
function donwloadCSV() {
const headers = ['Usuário', 'Data e Hora', 'Bytes', 'Comentário'];
const rows = Array.from(elementTableRevisions.querySelectorAll('tbody tr')).map(tr =>
Array.from(tr.querySelectorAll('td')).map(td => td.innerText)
);
rows[0] = headers;
const csvContent = [
...rows.map(e => e.join('\t'))
].join('\n');
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'Histórico da página - ' + currentSearchTerm.value + '.csv';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
/**
* Get search results.
*
* @param {string} searchTerm
* @param {number} offset Optional result offset
*
* @return {Promise}
*/
function fetchResults( searchTerm, offset ) {
const params = new URLSearchParams( {
q: searchTerm,
limit: "10"
} );
if ( offset ) {
params.set( 'limit', String( offset + 10 ) );
}
return fetch( `https://pt.wikipedia.org/w/rest.php/v1/search/title?${ params.toString() }` )
.then( ( response ) => response.json() );
}
/**
* Handle lookup input.
*
* TODO: this should be debounced.
*
* @param {string} value
*/
function onInput( value ) {
// Internally track the current search term.
currentSearchTerm.value = value;
// Do nothing if we have no input.
if ( !value ) {
menuItems.value = [];
return;
}
fetchResults( value )
.then( ( data ) => {
// Make sure this data is still relevant first.
if ( currentSearchTerm.value !== value ) {
return;
}
// Reset the menu items if there are no results.
if ( !data.pages || data.pages.length === 0 ) {
menuItems.value = [];
return;
}
// Build an array of menu items.
const results = data.pages.map( ( result ) => {
return {
value: result.id,
label: result.title,
description: result.description
};
} );
// Update menuItems.
menuItems.value = results;
} )
.catch( () => {
// On error, set results to empty.
menuItems.value = [];
} );
}
function deduplicateResults( results ) {
const seen = new Set( menuItems.value.map( ( result ) => result.value ) );
return results.filter( ( result ) => !seen.has( result.value ) );
}
function onLoadMore() {
if ( !currentSearchTerm.value ) {
return;
}
fetchResults( currentSearchTerm.value, menuItems.value.length )
.then( ( data ) => {
if ( !data.pages || data.pages.length === 0 ) {
return;
}
const results = data.pages.map( ( result ) => {
return {
value: result.id,
label: result.title,
description: result.description,
};
} );
// Update menuItems.
const deduplicatedResults = deduplicateResults( results );
menuItems.value.push( ...deduplicatedResults );
} );
}
const menuConfig = {
visibleItemLimit: 6
};
return {
buttons,
onClick,
selection,
menuItems,
menuConfig,
onInput,
onLoadMore
};
}
})
.component('cdx-lookup', Codex.CdxLookup)
.component('cdx-button-group', Codex.CdxButtonGroup)
.mount(mountPoint);
});