UNPKG

@dbp-topics/authentic-document

Version:

[GitLab Repository](https://gitlab.tugraz.at/dbp/authentic-documents/authenticdocument) | [npmjs package](https://www.npmjs.com/package/@dbp-topics/authentic-document) | [Unpkg CDN](https://unpkg.com/browse/@dbp-topics/authentic-document/) | [Authentic Do

388 lines (344 loc) 13.7 kB
import {createInstance} from './i18n.js'; import {css, html} from 'lit'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonUtils from '@dbp-toolkit/common/utils'; import {Button, Icon, MiniSpinner} from '@dbp-toolkit/common'; import * as commonStyles from '@dbp-toolkit/common/styles'; import {TextSwitch} from './textswitch.js'; import {send} from '@dbp-toolkit/common/notification'; import {AdapterLitElement} from '@dbp-toolkit/common'; import {Activity} from './activity.js'; import metadata from './dbp-authentic-image-request.metadata.json'; class AuthenticImageRequest extends ScopedElementsMixin(AdapterLitElement) { constructor() { super(); this._i18n = createInstance(); this.auth = {}; this.lang = this._i18n.language; this.entryPointUrl = ''; this.access_token = ''; this.given_name = ''; this.family_name = ''; this.fullResponse = ''; this.responseFromServer = ''; this.itemsAvailable = []; this.itemsRequested = []; this.itemsNotAvailable = []; this.gridContainer = 'display:none'; this.imageSrc = null; } static get scopedElements() { return { 'dbp-icon': Icon, 'dbp-mini-spinner': MiniSpinner, 'dbp-button': Button, 'dbp-textswitch': TextSwitch, }; } static get properties() { return { ...super.properties, lang: {type: String}, entryPointUrl: {type: String, attribute: 'entry-point-url'}, access_token: {type: String, attribute: false}, given_name: {type: String, attribute: false}, family_name: {type: String, attribute: false}, fullResponse: {type: String, attribute: false}, responseFromServer: {type: String, attribute: false}, itemsAvailable: {type: Array, attribute: false}, itemsRequested: {type: Array, attribute: false}, itemsNotAvailable: {type: Array, attribute: false}, gridContainer: {type: String, attribute: false}, imageSrc: {type: String, attribute: false}, auth: {type: Object}, }; } connectedCallback() { super.connectedCallback(); } update(changedProperties) { changedProperties.forEach((oldValue, propName) => { switch (propName) { case 'lang': this._i18n.changeLanguage(this.lang); break; } // console.log(propName, oldValue); }); super.update(changedProperties); } parseAvailableDocumentTypes() { let numTypes = parseInt(this.responseFromServer['hydra:totalItems']); if (isNaN(numTypes)) { numTypes = 0; } for (let i = 0; i < numTypes; i++) { let entry = this.responseFromServer['hydra:member'][i]; if (entry['availabilityStatus'] === 'available') { this.itemsAvailable[i] = entry; } else if (entry['availabilityStatus'] === 'requested') { this.itemsRequested[i] = entry; } else { this.itemsNotAvailable[i] = entry; } } } async httpGetAsync(url, options) { let response = await fetch(url, options).then((result) => { if (!result.ok) throw result; return result.json(); }); return response; } parseJwt(token) { var base64Url = token.split('.')[1]; var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); var jsonPayload = decodeURIComponent( atob(base64) .split('') .map(function (c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }) .join('') ); return JSON.parse(jsonPayload); } async retrieveToken() { let response; //Retrieve token from KC const options_get_access_token = { headers: { Authorization: 'Bearer ' + this.auth.token, }, }; response = await this.httpGetAsync( 'https://auth-dev.tugraz.at/auth/realms/tugraz-vpu/broker/eid-oidc/token', options_get_access_token ); if (response && response.access_token) { // XXX: demo response.access_token = 'photo-jpeg-available-token'; this.access_token = response.access_token; this.fullResponse = this.parseJwt(response.id_token); this.family_name = this.fullResponse.family_name; this.given_name = this.fullResponse.given_name; } console.log(this.access_token); //Retrieve a list of available document types const options_send_api_request_doc_types = { method: 'GET', headers: { 'Content-Type': 'application/ld+json', Authorization: 'Bearer ' + this.auth.token, Token: this.access_token, }, }; const url = this.entryPointUrl + '/authentic_document_types?page=1'; if (this.access_token !== '') { try { this.responseFromServer = await this.httpGetAsync( url, options_send_api_request_doc_types ); } catch (e) { if (e.status == 403) { send({ body: 'eid token expired', type: 'danger', timeout: 10, }); } throw e; } } this.parseAvailableDocumentTypes(); this.gridContainer = 'display:flex'; /* //Retrieve document const options_send_api_request_for_type = { method: 'GET', headers: { 'Content-Type': 'application/ld+json', 'Authorization': 'Bearer ' + this.auth.token, } }; const url_document = this.entryPointUrl + '/authentic_documents/' + 'cGhvdG8tanBlZy1hdmFpbGFibGU%253D' + '?token=' + 'photo-jpeg-available-token'; //TODO: replace id; token if (this.access_token !== '') { this.responseFromServer2 = await this.httpGetAsync(url_document, options_send_api_request_for_type); } */ } async buttonPressSuccessMessage(event, entry) { this.shadowRoot.getElementById('btn-' + entry['identifier']).setAttribute('disabled', ''); let url = this.entryPointUrl + '/authentic_document_requests'; let body = { typeId: entry['identifier'], token: this.access_token, }; let response = await fetch(url, { method: 'POST', headers: { Authorization: 'Bearer ' + this.auth.token, 'Content-Type': 'application/json', Token: this.access_token, }, body: JSON.stringify(body), }); if (!response.ok) { this.shadowRoot .getElementById('btn-' + entry['identifier']) .removeAttribute('disabled'); return; } let data = await response.json(); let arrivalDate = new Date(data['estimatedTimeOfArrival']); console.log(arrivalDate.toLocaleString()); send({ summary: this._i18n.t('authentic-image-request.request-success-title'), body: this._i18n.t('authentic-image-request.request-success-body', { name: entry['name'], }), type: 'success', timeout: 10, }); } async buttonPressShowDocument(event, data) { const options = { headers: { Authorization: 'Bearer ' + this.auth.token, Accept: 'application/ld+json', Token: this.access_token, }, }; this.imageSrc = null; let url = this.entryPointUrl + '/authentic_documents/' + data['identifier']; let resp = await this.httpGetAsync(url, options); this.imageSrc = resp['contentUrl']; } static get styles() { // language=css return css` ${commonStyles.getThemeCSS()} ${commonStyles.getGeneralCSS(false)} ${commonStyles.getButtonCSS()} ${commonStyles.getNotificationCSS()} #documents { display: grid; grid-template-columns: repeat(3, max-content); column-gap: 15px; row-gap: 1.5em; align-items: center; margin-top: 2em; margin-bottom: 2em; } .header { display: grid; align-items: center; grid-template-columns: 1fr auto; gap: 10px; } .border { border-top: var(--dbp-border); } #grid-container { margin-top: 2rem; padding-top: 2rem; display: flex; flex-flow: column; } h2:first-child { margin-top: 0px; margin-bottom: 0px; } h2 { margin-bottom: 10px; } .subheadline { font-style: italic; padding-left: 2em; margin-top: -1px; /*line-height: 1.8;*/ margin-bottom: 1.2em; } `; } render() { const activity = new Activity(metadata); const i18n = this._i18n; return html` <h2>${i18n.t('authentic-image-request.title')}</h2> <p class="subheadline">${activity.getDescription(this.lang)}</p> <p>${i18n.t('authentic-image-request.description')}</p> <button class="button is-primary" @click="${this.retrieveToken}" title="${i18n.t('authentic-image-request.request-button')}"> ${i18n.t('authentic-image-request.retrieve-token')} </button> <div id="grid-container" class="border" style="${this.gridContainer}"> <h3 id="doc-headline"> ${i18n.t('authentic-image-request.available-documents')} ${this.given_name} ${this.family_name}: </h3> <div id="documents"> ${this.itemsRequested.map( (i) => html` <span class="header"> <strong>${i['name']}</strong> ${i18n.t('authentic-image-request.request-text')}. </span> <button id="btn-${i['identifier']}" class="button is-primary" @click="${(e) => this.buttonPressSuccessMessage(e, i)}"> ${i18n.t('authentic-image-request.request-document')} </button> <button class="button is-primary" disabled> ${i18n.t('authentic-image-request.show-document')} </button> ` )} ${this.itemsAvailable.map( (i) => html` <span class="header"> <strong>${i['name']}</strong> ${i18n.t('authentic-image-request.available-text')}. </span> <button id="btn-${i['identifier']}" class="button is-primary" @click="${(e) => this.buttonPressSuccessMessage(e, i)}"> ${i18n.t('authentic-image-request.request-document')} </button> <button class="button is-primary" @click="${(e) => this.buttonPressShowDocument(e, i)}"> ${i18n.t('authentic-image-request.show-document')} </button> ` )} ${this.itemsNotAvailable.map( (i) => html` <span class="header"> <strong>${i['name']}</strong> ${i18n.t('authentic-image-request.not-available-text')}. </span> <button id="btn-${i['identifier']}" class="button is-primary" disabled> ${i18n.t('authentic-image-request.request-document')} </button> <button class="button is-primary" disabled> ${i18n.t('authentic-image-request.show-document')} </button> ` )} </div> </div> ${this.imageSrc ? html` <img src="${this.imageSrc}" /> ` : ``} `; } } commonUtils.defineCustomElement('dbp-authentic-image-request', AuthenticImageRequest);