@bostonuniversity/bulib-wc
Version:
collection of web components and styles used at Boston University Libraries
165 lines (139 loc) • 6.81 kB
JavaScript
import {LitElement, html} from 'lit-element/lit-element';
import {readExpiringLocalValue, setExpiringLocalValue} from '../_helpers/storageUtility';
/* references to google sheets API and the entries within it */
const google_sheets_document_id = '1ElW0CUOV3LvcHuYxK2BZfFjo65a-XDrlNJtnrelA6tM';
const codes_that_map_to_api_entry = {
"primo-BU": 0, "primo": 1, "primo-BULAW": 2, "primo-journals": 3, "primo-test": 4, "primo-ISL": 5,
"testing": 6,
"wordpress": 7,
"libguides": 8,
"libcal": 9,
"libanswers": 10, "libanswers-business": 11, "libanswers-spring2020": 12,
"all": 13
}
const primo_specific_padding = html`
<style type="text/css">
/* site-specific code for primo's announce-banner.js - adds padding below the search bar */
prm-search-bar { padding-bottom: var(--primo-announce-padding, 60px); }
.__xs prm-search-bar, .__sm prm-search-bar { padding-bottom: var(--primo-announce-padding-small, 68px); }
</style>
`;
/**
* display time-sensitive message, call-to-action across the top of a screen
*/
export default class BULAnnounce extends LitElement {
// rendering the content into the light DOM enables it to be styled by the default css
createRenderRoot(){ return this; }
static get properties() {
return {
/** unique identifier */
code: {type: String},
/** information to display to the user */
message: {type: String},
/** (optional) main action displaying the */
cta_text: {type: String},
/** (optional) link the user should click to address/learn more about the message */
cta_url: {type: String},
/** (optional) type of message to display (determine ) [info, success, alert, warn] */
severity: {type: String},
/** (debugging) set the status to dismissed */
dismissed: {type: Boolean, reflect: true},
/** (debugging) enable logging (click tracking) */
debug: {type: Boolean},
/** (debugging) disable show/hide check, cta */
prevent_action: {type: Boolean}
};
}
/** when first connected, iff there's a special code, set contents based on the API */
connectedCallback(){
super.connectedCallback();
if(this.code in codes_that_map_to_api_entry){
this._logToConsole(`code '${this.code}' in codes_that_map dictionary.`);
if(this.prevent_action){
this._logToConsole("'prevent_action' stopped the API from being called!");
return;
}
else{
this.dismissed = true; // default to dismissed (don't flash before/during the API call)
this._logToConsole(`making a call to the SheetsAPI for '${this.code}'.`);
}
let row_id = codes_that_map_to_api_entry[this.code];
fetch('https://spreadsheets.google.com/feeds/list/'+google_sheets_document_id+'/1/public/values?alt=json', { method:'GET', mode:'cors', cache:'no-store' })
.then(response => response.json())
.then(json => json.feed.entry[row_id])
.then(data => this._setDataHelperWithDataFromAPI(data));
}
}
/** helper that updates the components information with the Sheets its given */
_setDataHelperWithDataFromAPI(data){
this._logToConsole(`'show_banner' in the google sheets for '${this.code}' is '${data.gsx$showbanner.$t}'.`);
// un-dismiss if the 'show_banner' checkbox has been selected
if(data.gsx$showbanner.$t == "TRUE"){
this.dismissed = false;
this.removeAttribute("dismissed");
}
// set the message from the API, but try not
let message = data.gsx$messagetext.$t;
if(message.length > 0){ this.message = message; }
// set additional data
this.cta_url = data.gsx$messagelink.$t;
this.severity = data.gsx$messageseverity.$t || 'info';
this.cta_text = data.gsx$ctatext.$t;
}
render(){
let icon = "";
switch(this.severity){ // material icon code [https://material.io/resources/icons/]
case "success": icon = "check_circle"; break;
case "alert": icon = "announcement"; break;
case "warn": icon = "report_problem"; break;
case "info":
default: icon = "info"; break;
}
let sanitized_message = this.message? this.message.replace(/'/g, "'") : "Please standby while we address an ongoing issue, and email 'ask@bu.edu' if the problem persists";
return html`
${ window.location.pathname.includes("primo-explore") && (this.debug || !this._getDismissedValue()) ? primo_specific_padding: html``}
<div class="announce-banner${ this.severity != undefined? " "+this.severity : ""}" disabled="${this._getDismissedValue()}">
<i class="material-icons">${icon}</i>
<span class="message">${sanitized_message}</span>
${!!this.cta_url? html`<span class="cta"><a href="${this.cta_url}">${this.cta_text}</a></span>`: ``}
<button type="button" ="${(e) => this._toggleDismissed()}">
<i class="material-icons">close</i> <span class="small-text">DISMISS</span>
</button>
</div>
`;
}
/**
* attempt to gather dismissal information from 'storageUtility' helper, iff a hardcoded dismissal
* is not already set/present (e.g `dismissed`, `dismissed="true"`, `dismissed="false"`)
*/
_getDismissedValue(){
if(this.hasAttribute("dismissed")){
// returns true if the attribute is present and set to anything other than 'false'
return this.hasAttribute("dismissed") && this.getAttribute("dismissed") !== "false";
}else{
// only check the value when it wouldn't be overwritten anyway
return readExpiringLocalValue(this._dismissedId(), false) || false;
}
}
/** create and return a unique id to distinguish 'dismissal' information from other instances */
_dismissedId(){
let dismissed_id = "announcement-dismissed";
try{ dismissed_id += "-"+this.code; }
catch(exception){ this._logToConsole("error slugifying message to get new id: " + exception.message); }
return dismissed_id;
}
/** react to user-triggered dismissal by setting the stored memory value and hardcoded attribute/property */
_toggleDismissed(){
let value_before = this._getDismissedValue();
// auto-update the property and attribute value for the currently loaded tag
this.setAttribute("dismissed", !value_before);
// ensure the component updates (re-renders) and hides (or shows) the component
this._logToConsole(`dismiss clicked, session's' '${this._dismissedId()}' value '${value_before}'->'${this._getDismissedValue()}'`);
this.requestUpdate("dismissed", value_before);
// save this updated setting in the localStorage
setExpiringLocalValue(this._dismissedId(), !value_before);
}
_logToConsole(message){
if(this.debug){ console.log("bulib-announce) " + message); }
}
}