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);
});