var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var DataFeedApp; (function (DataFeedApp) { const resultsPerPage = 12, paginationContainer = 'pagination', activeFiltersContainer = 'active-filters', defaultVisibleFilters = 6, eachSideInactivePagesCount = 4; var cardsRenderer, resultsRenderer, activeFilterRenderer, yourSelectionsText, clearAllFiltersButton, allFilters = [], searchBar, paginationSRLabelRenderer, paginationPrevRenderer, paginationItemRenderer, paginationNextRenderer, cards, filteredCards, currentPage = 0, urlParams, activeFilters = [], search = ''; function getUnprocessedData(arrayName) { return __awaiter(this, void 0, void 0, function* () { let source = document.getElementById('data-feed-source-endpoint').getAttribute("data-source"), data; source = Common.environmentSwitch(source); yield fetch(source) .then((response) => { if (!response.ok) { showSpecialMessage(".main-content .special-message.error"); return; } return response.json(); }) .then((json) => { if (json[arrayName].length == 0) { showSpecialMessage(".main-content .special-message.no-data"); return; } data = json; }); return data; }); } DataFeedApp.getUnprocessedData = getUnprocessedData; function initialRender(data) { cardsRenderer = new Common.MustacheElement('dfa-target', 'card-template'); resultsRenderer = new Common.MustacheElement('resultsLabel', 'results-template'); activeFilterRenderer = new Common.MustacheElement(activeFiltersContainer, 'active-filter-template'); paginationSRLabelRenderer = new Common.MustacheElement(paginationContainer, 'pag-sr-label'); paginationPrevRenderer = new Common.MustacheElement(paginationContainer, 'pag-prev'); paginationItemRenderer = new Common.MustacheElement(paginationContainer, 'pag-item'); paginationNextRenderer = new Common.MustacheElement(paginationContainer, 'pag-next'); yourSelectionsText = document.getElementById('yourSelectionsLabel'); clearAllFiltersButton = document.getElementById('clearAllButton'); clearAllFiltersButton.onclick = (e) => { e.preventDefault(); activeFilters = []; updateFiltering(); }; let mainFiltersShowHideButton = document.getElementById('filterControlButton'), filterRegion = document.getElementById('filterRegion'); mainFiltersShowHideButton.onclick = (e) => { e.preventDefault(); if (mainFiltersShowHideButton.classList.contains('closed')) { mainFiltersShowHideButton.classList.replace('closed', 'open'); mainFiltersShowHideButton.classList.replace('glyph-downArrow', 'glyph-upArrow'); } else { mainFiltersShowHideButton.classList.replace('open', 'closed'); mainFiltersShowHideButton.classList.replace('glyph-upArrow', 'glyph-downArrow'); } let newText = mainFiltersShowHideButton.getAttribute('data-text'), newAria = mainFiltersShowHideButton.getAttribute('data-aria'), oldText = mainFiltersShowHideButton.innerText, oldAria = mainFiltersShowHideButton.getAttribute('aria-label'); mainFiltersShowHideButton.innerText = newText; mainFiltersShowHideButton.setAttribute('aria-label', newAria); mainFiltersShowHideButton.setAttribute('data-text', oldText); mainFiltersShowHideButton.setAttribute('data-aria', oldAria); filterRegion.classList.toggle('display-none'); }; searchBar = document.getElementById('dfa-search'); searchBar.oninput = (e) => { e.preventDefault(); search = e.target.value.toLowerCase(); updateFiltering(); }; cardsRenderer.update(data); cards = [...document.querySelectorAll(".card")]; return cards; } DataFeedApp.initialRender = initialRender; function generateDynamicFilter(id, data) { let dynamic = document.getElementById(id), name = dynamic.getAttribute("data-name"), filters = new Common.MustacheElement("filter-target", `${name}-template`); filters.append({}); let category = new Common.MustacheElement(`${name}-target`, `${name}-filter`); category.update(data); } DataFeedApp.generateDynamicFilter = generateDynamicFilter; function initializeFilters() { let filterElements = [...document.querySelectorAll('.filters .filter')].map(value => value); filterElements.forEach(element => { let filterType = getFilterType(element), newFilter; switch (filterType) { case FilterType.Custom: return; case FilterType.Range: newFilter = new RangeFilter(element); break; case FilterType.Boolean: newFilter = new BooleanFilter(element); break; case FilterType.String: newFilter = new StringFilter(element); } allFilters.push(newFilter); }); allFilters.forEach(filter => { let input = filter.filterElement.input; input.onchange = (e) => { e.preventDefault(); if (filter.filterElement.disabled) return; if (input.checked) { activeFilters.push(filter); } else { let index = activeFilters.findIndex(active => active.filterElement.name == filter.filterElement.name && active.filterElement.value == filter.filterElement.value); if (index != -1) activeFilters.splice(index, 1); } updateFiltering(); }; }); urlParams = new URL(window.location.href).searchParams; let uniqueKeys = []; for (let key of urlParams.keys()) { if (uniqueKeys.indexOf(key) == -1 && allFilters.some(filter => filter.filterElement.name == key)) uniqueKeys.push(key); } uniqueKeys.forEach((key) => { let values = urlParams.getAll(key); values.forEach((value) => { let index = allFilters.findIndex(filter => filter.filterElement.name == key && filter.filterElement.value == value); if (index == -1) { console.log(`Failed to find a filter element matching the filter with key ${key} and value ${value}`); return; } activeFilters.push(allFilters[index]); }); }); updateFiltering(); let categories = [...document.querySelectorAll('.category')]; categories.forEach((category) => { let childFilters = [...category.querySelectorAll('.filter')]; if (childFilters.length > defaultVisibleFilters) { for (let i = defaultVisibleFilters; i < childFilters.length; i++) { childFilters[i].classList.add("display-none"); } let showButton = category.querySelector('.category-show-all'); showButton.onclick = (e) => { e.preventDefault(); for (let i = defaultVisibleFilters; i < childFilters.length; i++) { childFilters[i].classList.remove("display-none"); } childFilters[defaultVisibleFilters - 1].querySelector('input').focus(); showButton.classList.toggle('display-none'); }; showButton.classList.toggle('display-none'); } }); } DataFeedApp.initializeFilters = initializeFilters; function resetFilteredCards() { filteredCards = cards; } function updateFiltering() { resetFilteredCards(); if (search != '') { filteredCards = filteredCards.filter((card) => card.innerText.toLowerCase().indexOf(search) != -1); } filteredCards = filteredCards.filter((card) => allFiltersApply(card)); allFilters.forEach(filter => { filter.filterElement.setInput(activeFilters.findIndex(active => active.filterElement.name == filter.filterElement.name && active.filterElement.value == filter.filterElement.value) != -1); filter.updateCount(filteredCards); }); [...urlParams.entries()].forEach(([key, _value]) => { if (allFilters.some(filter => filter.filterElement.name == key)) urlParams.delete(key); }); for (let i = 0; i < activeFilters.length; i++) { urlParams.append(activeFilters[i].filterElement.name, activeFilters[i].filterElement.value); } let newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname + (urlParams.toString() != '' ? '?' + urlParams.toString() : ''); if (window.location.href != newUrl) window.history.pushState({ path: newUrl }, "", newUrl); resultsRenderer.update({ results: filteredCards.length, activeFilters: activeFilters.length > 0 }); activeFilterRenderer.update({ filters: activeFilters }); let removeButtons = [].slice.call(document.getElementById(activeFiltersContainer).getElementsByClassName('remove-filter')); removeButtons.forEach((button) => { let HTMLButton = button; HTMLButton.onclick = (e) => { e.preventDefault(); let index = activeFilters.findIndex(item => item.filterElement.name == HTMLButton.getAttribute("data-name") && item.filterElement.value == HTMLButton.getAttribute("data-value")); activeFilters.splice(index, 1); updateFiltering(); }; }); if (activeFilters.length > 0) { if (clearAllFiltersButton.classList.contains("display-none")) clearAllFiltersButton.classList.remove("display-none"); if (yourSelectionsText.classList.contains("display-none")) yourSelectionsText.classList.remove("display-none"); } else { if (!clearAllFiltersButton.classList.contains("display-none")) clearAllFiltersButton.classList.add("display-none"); if (!yourSelectionsText.classList.contains("display-none")) yourSelectionsText.classList.add("display-none"); } updatePagination(0); } function updatePagination(newPage) { let totalPages = Math.ceil(filteredCards.length / resultsPerPage); currentPage = newPage; let paginationTarget = document.getElementById(paginationContainer); paginationTarget.innerHTML = ''; hideAll(); let start = resultsPerPage * currentPage; showRange(start, start + resultsPerPage); if (totalPages <= 1) { return; } paginationSRLabelRenderer.append({ page: currentPage + 1 }); if (currentPage > 0) { paginationPrevRenderer.append({ truePage: currentPage - 1, page: currentPage }); } let lowerBound = currentPage - eachSideInactivePagesCount, upperBound = currentPage + eachSideInactivePagesCount + 1, lowerOffset = 0, upperOffset = 0; if (lowerBound < 0) { upperOffset = lowerBound; lowerBound = 0; } if (upperBound > totalPages) { lowerOffset = upperBound - totalPages; upperBound = totalPages; } lowerBound -= lowerOffset; if (lowerBound < 0) lowerBound = 0; upperBound -= upperOffset; if (upperBound > totalPages) upperBound = totalPages; let paginationItems = []; for (let i = lowerBound; i < upperBound; i++) { paginationItems[i - lowerBound] = { truePage: i, page: i + 1 }; } paginationItemRenderer.append({ pagination: paginationItems }); if (currentPage < totalPages - 1) { paginationNextRenderer.append({ truePage: currentPage + 1, page: currentPage + 2 }); } let anchors = [...paginationTarget.querySelectorAll("[data-page]")].map(anchor => anchor); anchors.forEach((anchor) => { anchor.onclick = (e) => { e.preventDefault(); updatePagination(parseInt(anchor.getAttribute("data-page"))); const $target = document.querySelector(".filterable-collection"); window.scrollTo({ 'behavior': 'smooth', 'left': 0, 'top': $target.offsetTop - 40 }); document.getElementById("dfa-search").focus(); }; }); anchors.find(anchor => anchor.getAttribute("data-page") == currentPage.toString()) .parentElement .classList .add('f-active'); } function addCustomFilter(filterElement, appliesFunction) { let customFilter = new CustomFilter(filterElement, appliesFunction); allFilters.push(customFilter); } DataFeedApp.addCustomFilter = addCustomFilter; function hideAll() { cards.forEach((card) => { if (!card.classList.contains("display-none")) card.classList.add("display-none"); }); } function showRange(from, to) { for (let i = from; i < to; i++) { if (filteredCards[i] != undefined && filteredCards[i].classList.contains("display-none")) filteredCards[i].classList.remove("display-none"); } } function showSpecialMessage(selector) { document.querySelector("#mainFilters").style.display = "none"; document.querySelector(".filterable-collection .top-content").style.display = "none"; document.querySelector(".loadingio-spinner-spinner-99on9vxtj3").style.display = "none"; document.querySelector(selector).style.display = "block"; } function allFiltersApply(card) { for (let i = 0; i < activeFilters.length; i++) { if (!activeFilters[i].applies(card)) return false; } return true; } let FilterType; (function (FilterType) { FilterType[FilterType["Custom"] = 0] = "Custom"; FilterType[FilterType["Boolean"] = 1] = "Boolean"; FilterType[FilterType["Range"] = 2] = "Range"; FilterType[FilterType["String"] = 3] = "String"; })(FilterType || (FilterType = {})); function getFilterType(filterElement) { if (filterElement.getAttribute('data-custom').toLowerCase() == 'true') return FilterType.Custom; else if (filterElement.getAttribute('data-bool').toLowerCase() == 'true') return FilterType.Boolean; else if (filterElement.getAttribute('data-range').toLowerCase() == 'true') return FilterType.Range; else return FilterType.String; } class FilterElement { constructor(filterElement) { this.setInput = (checked) => { this.input.checked = checked; }; this.setCount = (amount) => { this.countLabel.innerText = `(${amount})`; if (amount == 0) { this.input.setAttribute("disabled", ""); this.disabled = true; } else { this.input.removeAttribute("disabled"); this.disabled = false; } }; this.base = filterElement; this.name = filterElement.getAttribute('data-name'); this.friendlyName = filterElement.getAttribute('data-friendly'); this.value = filterElement.getAttribute('data-value'); this.input = filterElement.getElementsByClassName('filter-input')[0]; this.countLabel = filterElement.getElementsByClassName('filter-count')[0]; } } class Filter { constructor(filterElement) { this.applies = (card) => { if (card != null) return true; }; this.nameToAttribute = () => { return "data-" + this.filterElement.name; }; this.updateCount = (filteredCards) => { let count = 0; filteredCards.forEach((card) => { if (this.applies(card)) count++; }); this.filterElement.setCount(count); }; this.filterElement = new FilterElement(filterElement); } } class CustomFilter extends Filter { constructor(filterElement, applies) { super(filterElement); this.applies = applies; } } class BooleanFilter extends Filter { constructor(filterElement) { super(filterElement); this.applies = (card) => { return card.getAttribute(this.nameToAttribute()) == this.filterElement.value; }; } } class RangeFilter extends Filter { constructor(filterElement) { super(filterElement); this.applies = (card) => { let value = parseInt(card.getAttribute(this.nameToAttribute())); if (value > this.from && value < this.to) return true; return false; }; let split = this.filterElement.value.split(','); this.from = parseInt(split[0]); this.to = parseInt(split[1]); } } class StringFilter extends Filter { constructor(filterElement) { super(filterElement); this.applies = (card) => { return card.hasAttribute(this.nameToAttribute()) && card.getAttribute(this.nameToAttribute()).indexOf('|' + this.filterElement.value + '|') != -1; }; } } class DynamicFilter { constructor(value, friendlyText, useIcon = false, iconSrc = "") { this.value = value; this.friendlyText = friendlyText; this.useIcon = useIcon; this.iconSrc = iconSrc; } } DataFeedApp.DynamicFilter = DynamicFilter; })(DataFeedApp || (DataFeedApp = {}));