UNPKG

@digital-blueprint/checkin-app

Version:

[GitHub Repository](https://github.com/digital-blueprint/checkin-app) | [npmjs package](https://www.npmjs.com/package/@digital-blueprint/checkin-app) | [Unpkg CDN](https://unpkg.com/browse/@digital-blueprint/checkin-app/) | [Checkin Bundle](https://github

352 lines (316 loc) 11.9 kB
import {createInstance} from './i18n.js'; import {css, html} from 'lit'; import DBPCheckInLitElement from './dbp-check-in-lit-element'; import {classMap} from 'lit/directives/class-map.js'; import {ScopedElementsMixin} from '@open-wc/scoped-elements'; import * as commonUtils from '@dbp-toolkit/common/utils'; import {Icon, LoadingButton, 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 * as CheckinStyles from './styles'; import {Activity} from './activity.js'; import metadata from './dbp-check-out-request.metadata.json'; class CheckOut extends ScopedElementsMixin(DBPCheckInLitElement) { constructor() { super(); this._i18n = createInstance(); this.lang = this._i18n.language; this.activity = new Activity(metadata); this.entryPointUrl = ''; this.activeCheckins = []; this.loading = false; this._initialFetchDone = false; } static get scopedElements() { return { 'dbp-icon': Icon, 'dbp-mini-spinner': MiniSpinner, 'dbp-loading-button': LoadingButton, 'dbp-textswitch': TextSwitch, }; } static get properties() { return { ...super.properties, lang: {type: String}, entryPointUrl: {type: String, attribute: 'entry-point-url'}, activeCheckins: {type: Array, attribute: false}, initialCheckinsLoading: {type: Boolean, attribute: false}, loading: {type: Boolean, attribute: false}, }; } 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); } /** * Init a checkout request at a specific location and send notification if it worked or not * * @param event * @param entry */ async doCheckOut(event, entry) { let locationHash = ''; let seatNr = ''; let locationName = ''; let button = event.target; const i18n = this._i18n; if (entry !== undefined) { locationHash = entry['location'] ? entry['location']['identifier'] : ''; seatNr = entry['seatNumber']; locationName = entry['location'] ? entry['location']['name'] : ''; } if (locationHash.length === 0) { send({ summary: i18n.t('check-out.checkout-failed-title'), body: i18n.t('check-out.checkout-failed-body', {room: locationName}), type: 'warning', timeout: 5, }); await this.sendErrorAnalyticsEvent( 'CheckOutRequest', 'CheckOutFailed', this.checkedInRoom ); } else { let response; this.loading = true; button.start(); try { response = await this.sendCheckOutRequest(locationHash, seatNr); await this.getListOfActiveCheckins(); } finally { button.stop(); this.loading = false; } await this.checkCheckoutResponse( response, locationHash, seatNr, locationName, 'CheckOutRequest' ); } } /** * Parses the active checkins response * * @param response * @returns {Array} list */ parseActiveCheckins(response) { let list = Array.from(response['hydra:member']); list.sort(this.compareListItems); return list; } compareListItems(a, b) { if (a.location.name < b.location.name) { return -1; } else if (a.location.name > b.location.name) { return 1; } else { if (a.seatNumber < b.seatNumber) { return -1; } else if (a.seatNumber > b.seatNumber) { return 1; } else { return 0; } } } /** * Get a list of active checkins * * @returns {Array} list */ async getListOfActiveCheckins() { this.initialCheckinsLoading = !this._initialFetchDone; try { let response = await this.getActiveCheckIns(); let responseBody = await response.json(); if (responseBody !== undefined && responseBody.status !== 403) { this.activeCheckins = this.parseActiveCheckins(responseBody); } } finally { this.initialCheckinsLoading = false; this._initialFetchDone = true; } } /** * Init a session refresh * * @param event * @param entry */ async doRefreshSession(event, entry) { let locationHash = entry['location']['identifier']; let seatNr = entry['seatNumber']; let locationName = entry['location']['name']; let button = event.target; button.start(); this.loading = true; try { await this.refreshSession(locationHash, seatNr, locationName, 'CheckOutRequest'); await this.getListOfActiveCheckins(); } finally { button.stop(); this.loading = false; } } static get styles() { // language=css return css` ${commonStyles.getThemeCSS()} ${commonStyles.getGeneralCSS(false)} ${commonStyles.getButtonCSS()} ${commonStyles.getNotificationCSS()} ${commonStyles.getActivityCSS()} ${CheckinStyles.getCheckinCss()} .checkins { display: grid; grid-template-columns: repeat(3, max-content); column-gap: 15px; row-gap: 1.5em; align-items: center; margin-top: 2em; } .header { display: grid; align-items: center; } .border { margin-top: 2rem; padding-top: 2rem; border-top: var(--dbp-border); } @media only screen and (orientation: portrait) and (max-width: 768px) { .checkins { display: block; } .header { margin-bottom: 0.5rem; } #refresh-btn { margin-top: 0.5rem; margin-bottom: 2rem; } .btn { display: flex; flex-direction: column; } .loading { justify-content: center; } } `; } render() { const i18n = this._i18n; if ( this.isLoggedIn() && !this.isLoading() && !this._initialFetchDone && !this.initialCheckinsLoading ) { this.getListOfActiveCheckins(); } return html` <div class="notification is-warning ${classMap({ hidden: this.isLoggedIn() || this.isLoading(), })}"> ${i18n.t('error-login-message')} </div> <div class="control ${classMap({hidden: this.isLoggedIn() || !this.isLoading()})}"> <span class="loading"> <dbp-mini-spinner text=${i18n.t('check-out.loading-message')}></dbp-mini-spinner> </span> </div> <div class="${classMap({hidden: !this.isLoggedIn() || this.isLoading()})}"> <h2>${this.activity.getName(this.lang)}</h2> <p class="subheadline"> <slot name="description">${this.activity.getDescription(this.lang)}</slot> </p> <div class="border checkins ${classMap({ hidden: !this.isLoggedIn() || this.isLoading(), })}"> ${this.activeCheckins.map( (i) => html` <span class="header"> <strong>${i.location.name}</strong> ${i.seatNumber !== null ? html` ${i18n.t('check-in.seatNr')}: ${i.seatNumber} <br /> ` : ``} ${i18n.t('check-out.checkin-until')} ${this.getReadableDate(i.endTime)} </span> <div> <div class="btn"> <dbp-loading-button type="is-primary" ?disabled="${this.loading}" value="${i18n.t('check-out.button-text')}" @click="${(event) => { this.doCheckOut(event, i); }}" title="${i18n.t( 'check-out.button-text' )}"></dbp-loading-button> </div> </div> <div> <div class="btn"> <dbp-loading-button id="refresh-btn" ?disabled="${this.loading}" value="${i18n.t('check-in.refresh-button-text')}" @click="${(event) => { this.doRefreshSession(event, i); }}" title="${i18n.t( 'check-in.refresh-button-text' )}"></dbp-loading-button> </div> </div> ` )} <span class="control ${classMap({ hidden: this.isLoggedIn() && !this.initialCheckinsLoading, })}"> <span class="loading"> <dbp-mini-spinner text=${i18n.t('check-out.loading-message')}></dbp-mini-spinner> </span> </span> <div class="no-checkins ${classMap({ hidden: !this.isLoggedIn() || this.initialCheckinsLoading || this.activeCheckins.length !== 0, })}"> ${i18n.t('check-out.no-checkins-message')} </div> </div> </div> `; } } commonUtils.defineCustomElement('dbp-check-out-request', CheckOut);