{"version":3,"sources":["webpack:///./app/webpacker/src/javascripts/_availability_buttons.ts","webpack:///./app/webpacker/packs/index.js"],"names":["updateStatusElement","itemEl","item","arguments","length","undefined","availabilityEl","querySelector","availabilityBtn","availabilityText","itemStatus","itemLocation","onHold","holdCount","status","location","remove","statusCode","code","isOnlineItem","endsWith","statusDueDate","duedate","statusData","getStatusData","dataset","statusDesc","statusBtnClass","statusDisplay","desc","btnClass","label","classList","add","dueDate","moment","format","innerText","setAttribute","bsToggle","bsTitle","display","locationData","getLocationData","locationText","abbr","name","locationCode","append","statusText","modalText","title","elIcon","document","createElement","style","marginLeft","async","checkAvailability","chunkedItemBibs","getItemsIDs","allItemBibs","flat","getPlaceholderItemsElements","forEach","parent","parentNode","querySelectorAll","isOnlineOnly","availabilityTextEl","serviceDesk","getServiceDeskData","innerHTML","url","promises","map","callSierraApi","chunk","error","items","documentsEl","itemEls","node","updateUIError","filter","el","includes","Promise","allSettled","then","result","foundItems","itemsFromPromises","missingItems","id","updateUI","findMissing","finally","container","moreButton","checkButton","availInfo","usedText","infoEl","textContent","push","documentsList","loading","addEventListener","revealButtonContainers","getDocHistory","rotateSearchTips","replaceBookCovers","initFilters"],"mappings":"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","file":"js/index-d52721772df9d8860cb4.chunk.js","sourcesContent":["import moment from 'moment';\nimport {\n callSierraApi, findMissing, getItemsIDs, getLocationData, getPlaceholderItemsElements,\n getServiceDeskData, getStatusData, itemsFromPromises,\n} from './_availability_util';\nimport {\n StatusData, LocationData, ApiEntry,\n} from './@typings/interfaces.d';\n\n/**\n * FUNCTIONS FOR `INDEX` VIEWS\n */\nfunction updateStatusElement(itemEl: HTMLElement, item: ApiEntry | null = null): void {\n if (itemEl === null) return;\n const availabilityEl: HTMLElement | null = itemEl.querySelector('.blacklight-availability.result__value');\n if (availabilityEl === null) return;\n const availabilityBtn: HTMLElement | null = availabilityEl.querySelector('.availability-btn');\n const availabilityText: HTMLElement | null = availabilityEl.querySelector('.availability-text');\n let itemStatus;\n let itemLocation;\n let holdCount = 0;\n let onHold;\n\n if (item) {\n itemStatus = item.status;\n itemLocation = item.location;\n holdCount = item.holdCount;\n onHold = holdCount > 0;\n }\n\n if (!itemStatus) {\n itemEl.remove();\n return;\n }\n\n const statusCode = itemStatus.code;\n const isOnlineItem = statusCode === 'w' || (itemLocation && itemLocation.code.endsWith('www'));\n const statusDueDate = itemStatus.duedate;\n const statusData: StatusData[keyof StatusData] | null = getStatusData(statusCode);\n\n if (availabilityEl) {\n availabilityEl.dataset.statusCode = statusCode;\n }\n\n if (statusData) {\n let statusDesc;\n let statusBtnClass: string;\n let statusDisplay;\n\n if (onHold && statusCode === '-') {\n statusDesc = `${holdCount} other patron${holdCount > 1 ? 's have' : ' has'} requested this item and ${holdCount > 1 ? 'are' : ' is'} queued to check it out before it becomes available.`;\n statusBtnClass = 'checked-out';\n statusDisplay = 'On Hold';\n } else {\n statusDesc = statusData.desc;\n statusBtnClass = statusData.btnClass;\n statusDisplay = statusData.label;\n }\n\n // Hide the button if it's online, we already have buttons for that\n if (isOnlineItem) {\n availabilityEl.classList.add('d-none');\n itemEl.classList.add('m-0', 'p-0');\n return;\n }\n\n if (statusBtnClass && availabilityBtn) {\n availabilityBtn.classList.remove('disabled');\n availabilityBtn.classList.add(statusBtnClass);\n }\n\n // If the item is checked out\n if (statusDueDate && availabilityBtn && availabilityText) {\n const dueDate = moment(itemStatus.duedate).format('MMM DD, YYYY');\n availabilityBtn.innerText = 'Checked Out';\n availabilityText.innerText = `Due ${dueDate}`;\n availabilityBtn.setAttribute('ga-event-label', availabilityBtn.innerText);\n availabilityText.classList.remove('d-none');\n availabilityBtn.classList.remove('available');\n availabilityBtn.classList.add('checked-out');\n }\n\n if (statusDesc && !statusDueDate && availabilityBtn) {\n availabilityBtn.innerText = statusDisplay;\n availabilityBtn.dataset.bsToggle = 'tooltip';\n availabilityBtn.dataset.bsTitle = statusDesc;\n availabilityBtn.setAttribute('ga-event-label', availabilityBtn.innerText);\n }\n } else {\n // eslint-disable-next-line no-lonely-if\n if (availabilityBtn) {\n availabilityBtn.innerText = itemStatus.display;\n availabilityBtn.setAttribute('ga-event-label', itemStatus.display);\n }\n }\n\n if (itemLocation) {\n const locationData: LocationData[keyof LocationData] = getLocationData(itemLocation.code);\n const locationText: string = locationData.abbr ? locationData.abbr : (locationData.name || '');\n\n availabilityEl.dataset.locationCode = itemLocation.code;\n\n if (locationText && !isOnlineItem) {\n availabilityBtn?.append(` - ${locationText}`);\n availabilityBtn?.setAttribute('ga-event-label', availabilityBtn.innerText);\n\n // Check for location tooltip that would override status tooltip\n if ((locationData.statusText || locationData.modalText) && availabilityBtn) {\n if (locationData.modalText) {\n availabilityBtn.dataset.title = locationData.modalText;\n const elIcon = document.createElement('i');\n elIcon.classList.add('icon', 'fal', `fa-info-circle`);\n elIcon.style.marginLeft = '0.25em';\n availabilityBtn?.append(elIcon);\n } else {\n availabilityBtn.dataset.title = locationData.statusText;\n }\n }\n if (locationData.btnClass) availabilityBtn?.classList.add(`location-${locationData.btnClass}`);\n }\n }\n}\n\n/**\n * If no buttons remain but \"more\" items exist, hide \"more\" button and show \"check availability\"\n */\nfunction checkForNoButtons(): void {\n const buttonContainers = document.querySelectorAll('.item-availability');\n\n buttonContainers.forEach((container: Element) => {\n const buttons = container.querySelectorAll('div.result__field');\n\n if (buttons.length === 0) {\n const moreButton = container.querySelector('div.more-items-available');\n if (moreButton !== null) {\n if (moreButton.parentNode) {\n moreButton.remove();\n }\n }\n\n const checkButton = container.querySelector('.check-availability');\n if (checkButton) {\n checkButton.classList.remove('d-none');\n }\n }\n });\n}\n\n/**\n * Checks if the buttons include an online button, indicating that this is an online only item\n * @returns {boolean}\n */\nfunction isOnlineOnly(item: Element): boolean {\n const parent = item.parentNode;\n if (parent) {\n const onlineButtons = parent.querySelectorAll('[data-online].result__field');\n return onlineButtons.length > 0;\n }\n return false;\n}\n\n/**\n * Remove duplicate buttons within availability section\n */\nfunction combineDuplicates(): void {\n const buttonContainers = document.querySelectorAll('.item-availability');\n\n buttonContainers.forEach((container: Element) => {\n const availInfo = container.querySelectorAll('.result__field');\n if (availInfo.length === 0) return;\n\n const usedText: string[] = [];\n availInfo.forEach((infoEl: Element) => {\n const { textContent } = infoEl;\n if (textContent) {\n if (usedText.includes(textContent)) {\n infoEl.remove();\n } else {\n usedText.push(textContent);\n }\n }\n });\n });\n}\n\nfunction updateUIError(items: string[], error?: number): void {\n const documentsEl = document.querySelector('#documents');\n if (documentsEl === null) return;\n\n items.forEach((item: string) => {\n const itemEls: NodeListOf = documentsEl.querySelectorAll(`[data-item-id='${item}']`);\n if (itemEls && itemEls.length === 0) return;\n\n if (error === 107) {\n itemEls.forEach((node: HTMLElement) => {\n node.remove();\n });\n } else {\n itemEls.forEach((node: HTMLElement) => {\n const availabilityEl: HTMLElement | null = node.querySelector('.blacklight-availability.result__value');\n const availabilityBtn: HTMLElement | null | undefined = availabilityEl?.querySelector('.availability-btn');\n if (availabilityBtn) {\n availabilityBtn.innerText = 'Ask at the Service Desk';\n }\n });\n }\n });\n}\n\n/**\n * Calls UI update functions for items returned by the Sierra API as well as those missing\n * @param {Array} foundItems\n * @param {Array} missingItems\n */\nfunction updateUI(foundItems: ApiEntry[] = [], missingItems: string[] = []): void {\n const documentsEl = document.querySelector('#documents');\n if (documentsEl === null) return;\n\n foundItems.forEach((item: ApiEntry) => {\n if (item === undefined) return;\n const itemEls: NodeListOf = documentsEl.querySelectorAll(`[data-item-id='${item.id}']`);\n if (itemEls.length === 0) return;\n itemEls.forEach((node: HTMLElement) => {\n updateStatusElement(node, item);\n });\n });\n\n missingItems.forEach((item: string) => {\n const itemEls: NodeListOf = documentsEl.querySelectorAll(`[data-item-id='${item}']`);\n if (itemEls.length === 0) return;\n itemEls.forEach((node: HTMLElement) => {\n updateStatusElement(node);\n });\n });\n}\n\n/**\n * Update UI elements for items that are \"fake\" and should not be included in the API call\n */\nfunction updateNoApiItems(): void {\n const noApiElements = getPlaceholderItemsElements();\n\n noApiElements.forEach((item: HTMLElement) => {\n if (isOnlineOnly(item)) {\n item.remove();\n return;\n }\n\n const availabilityTextEl: HTMLElement | null = item.querySelector('.availability-text');\n const locationCode: string = availabilityTextEl?.dataset.itemLocation || '';\n const serviceDesk = getServiceDeskData(locationCode);\n if (availabilityTextEl) {\n availabilityTextEl.innerHTML = `Contact ${serviceDesk.name}`;\n }\n });\n}\n\nfunction revealButtonContainers(): void {\n const documentsList: HTMLElement | null = document.querySelector('#documents');\n if (documentsList === null) return;\n const buttonContainers: NodeListOf = documentsList.querySelectorAll('.item-availability');\n\n buttonContainers.forEach((node: HTMLElement) => {\n const parent: ParentNode | null = node.parentNode;\n const loading: HTMLElement | null | undefined = parent?.querySelector('.item-loading-spinner');\n if (!loading) return;\n\n loading.addEventListener('transitionend', () => {\n loading.remove();\n node.classList.add('show');\n });\n loading.classList.add('hide');\n });\n}\n\n/**\n * Main function for checking availability on Index view.\n * @returns {Promise}\n */\nasync function checkAvailability(): Promise {\n const chunkedItemBibs: string[][] = getItemsIDs();\n let allItemBibs: string[] = chunkedItemBibs.flat();\n\n updateNoApiItems();\n\n // Create a map of chunked bib numbers that will return promises\n const promises: Promise[] = chunkedItemBibs.map(async (chunk: string[]) => {\n try {\n return await callSierraApi(chunk);\n } catch (error: any) {\n // Update items that returned a Sierra API error and remove them from further UI updates\n // console.log(`Sierra API error ${error.code}: ${error.name}`);\n updateUIError(chunk, error.code);\n allItemBibs = allItemBibs.filter((el) => !chunk.includes(el));\n return error;\n }\n });\n\n await Promise.allSettled(promises)\n .then((result: PromiseSettledResult[]) => {\n let foundItems: ApiEntry[] = itemsFromPromises(result);\n\n // Error from the Sierra API\n if (foundItems[0] === undefined) {\n foundItems = [];\n }\n\n const missingItems: string[] = findMissing(foundItems, allItemBibs);\n updateUI(foundItems, missingItems);\n })\n .finally(() => {\n checkForNoButtons();\n combineDuplicates();\n revealButtonContainers();\n });\n}\n\nexport {\n // eslint-disable-next-line import/prefer-default-export\n checkAvailability,\n};\n","// import \"blacklight-frontend/app/assets/javascripts/blacklight/blacklight\";\nimport BlacklightRangeLimit from 'blacklight-range-limit/app/assets/javascripts/blacklight_range_limit/blacklight_range_limit.esm';\nimport 'blacklight-range-limit/vendor/assets/javascripts/bootstrap-slider';\n// jquery.canvaswrapper must come before the rest of Flot.\nimport 'blacklight-range-limit/vendor/assets/javascripts/flot/jquery.canvaswrapper';\nimport 'blacklight-range-limit/vendor/assets/javascripts/flot/jquery.flot';\nimport 'blacklight-range-limit/vendor/assets/javascripts/flot/jquery.colorhelpers';\nimport 'blacklight-range-limit/vendor/assets/javascripts/flot/jquery.event.drag';\nimport 'blacklight-range-limit/vendor/assets/javascripts/flot/jquery.flot.browser';\nimport 'blacklight-range-limit/vendor/assets/javascripts/flot/jquery.flot.drawSeries';\nimport 'blacklight-range-limit/vendor/assets/javascripts/flot/jquery.flot.hover';\nimport 'blacklight-range-limit/vendor/assets/javascripts/flot/jquery.flot.saturated';\nimport 'blacklight-range-limit/vendor/assets/javascripts/flot/jquery.flot.selection';\nimport 'blacklight-range-limit/vendor/assets/javascripts/flot/jquery.flot.uiConstants';\nimport { checkAvailability } from '../src/javascripts/_availability_buttons';\nimport { setDocHistory, getDocHistory } from '../src/javascripts/_history';\nimport { rotateSearchTips, initFilters } from '../src/javascripts/_search';\nimport { replaceBookCovers } from '../src/javascripts/_ui';\n\ndocument.addEventListener('turbolinks:load', () => {\n checkAvailability();\n getDocHistory();\n rotateSearchTips();\n replaceBookCovers();\n initFilters();\n});\n"],"sourceRoot":""}