{"version":3,"file":"Src_Scripts_components_project-overview_js.2534285dbfc18ff9ec1e.js","sources":["webpack://AlmenNet.Setup/./Src/Scripts/components/project-overview.js"],"sourcesContent":["function generateUrl(status, categoryList) {\r\n const paramList = [];\r\n if (status !== '') {\r\n paramList.push('status=' + status);\r\n }\r\n\r\n const catagoryParamList = categoryList.map((item) => { return 'categories=' + item; });\r\n paramList.push(...catagoryParamList);\r\n\r\n if (paramList.length === 0) {\r\n return 'https://' + window.location.host + window.location.pathname;\r\n }\r\n\r\n return 'https://' + window.location.host + window.location.pathname + '?' + paramList.join('&');\r\n}\r\n\r\nfunction parseUrl() {\r\n const searchString = window.location.search;\r\n if (searchString === '') {\r\n return {};\r\n }\r\n\r\n const paramString = searchString.split('?')[1];\r\n const rawParamItems = paramString.split('&');\r\n const paramItems = rawParamItems.map((item) => {\r\n return item.split('=');\r\n });\r\n\r\n const returnValues = {};\r\n for (let i = 0; i < paramItems.length; i++) {\r\n const [key, value] = paramItems[i];\r\n\r\n if (key === 'categories') {\r\n let current = returnValues[key];\r\n\r\n if (current === undefined) {\r\n current = [];\r\n }\r\n\r\n current.push(decodeURI(value));\r\n returnValues[key] = current;\r\n } else {\r\n returnValues[key] = decodeURI(value);\r\n }\r\n }\r\n\r\n return returnValues;\r\n}\r\n\r\nasync function getContentBreakers() {\r\n const searchUrl = '/umbraco/api/content/contentbreakers';\r\n\r\n const responseText = await fetch(searchUrl);\r\n const contentBreakerList = await responseText.json();\r\n\r\n const contentBreakerLookup = {};\r\n\r\n for (let i = 0; i < contentBreakerList.length; i++) {\r\n const contentBreakerItem = contentBreakerList[i];\r\n contentBreakerLookup[contentBreakerItem.gridPlacement] = contentBreakerItem;\r\n }\r\n\r\n return contentBreakerLookup;\r\n}\r\n\r\nexport default class ProjectOverview {\r\n constructor(elm) {\r\n const categoryContainer = elm.querySelector('#category-container-body');\r\n const mainCategories = categoryContainer.querySelectorAll('.main-category');\r\n const statusContainerDesktop = elm.querySelector('#status-container');\r\n const resetCategories = elm.querySelector('#remove-all-categories');\r\n const subCategoryCheckboxList = elm.querySelectorAll('.sub-category-checkbox');\r\n const statusCheckboxList = elm.querySelectorAll('.status-checkbox');\r\n const statusToggleButton = elm.querySelector('#status-toggle-button');\r\n const loadMoreButtonProjects = elm.querySelector('#show-more--projects');\r\n\r\n let page = 0;\r\n const pageSize = 10;\r\n let categoryList = [];\r\n let status = '';\r\n let contentBreakerLookup = {};\r\n let results = [];\r\n let allActiveCategories = [];\r\n\r\n // ** TOGGLING MAIN CATEGORIES & STATUS ** //\r\n function toggleFilter(item) {\r\n if (!item.classList.contains('open')) {\r\n item.classList.add('open');\r\n } else {\r\n item.classList.remove('open');\r\n }\r\n }\r\n\r\n function toggleOpenClose(item) {\r\n if (!item.classList.contains('active')) {\r\n item.classList.add('active');\r\n } else {\r\n item.classList.remove('active');\r\n }\r\n }\r\n\r\n mainCategories.forEach(mainCategory => {\r\n mainCategory.onclick = function () {\r\n toggleFilter(mainCategory);\r\n };\r\n });\r\n\r\n statusContainerDesktop.onclick = function () {\r\n toggleFilter(statusContainerDesktop);\r\n toggleOpenClose(statusToggleButton);\r\n };\r\n\r\n // ** STICKIFY FILTERS ** //\r\n const stickifyElement = elm.querySelector('#sticky-element');\r\n const sticky = stickifyElement.offsetTop;\r\n const filterContainerBarMobile = elm.querySelector('#filter-container-bar-mobile');\r\n const filterContainerBarMobileScroll = elm.querySelector('#filter-container-bar-mobile-scroll');\r\n const stickyMobile = filterContainerBarMobile.offsetTop;\r\n\r\n function stickify() {\r\n if (window.scrollY + 40 > sticky) {\r\n stickifyElement.classList.add('sticky');\r\n } else {\r\n stickifyElement.classList.remove('sticky');\r\n }\r\n }\r\n\r\n function stickifyMobile() {\r\n if ((window.scrollY > stickyMobile + 40) && (window.innerWidth < 992)) {\r\n filterContainerBarMobileScroll.style.display = 'flex';\r\n } else {\r\n filterContainerBarMobileScroll.style.display = 'none';\r\n }\r\n }\r\n\r\n setTimeout(() => {\r\n window.onscroll = function () {\r\n stickify();\r\n stickifyMobile();\r\n };\r\n });\r\n\r\n // ** FILTER CONTAINER TOGGLING - MOBILE ** //\r\n const mobileFilterOverlay = document.querySelector('#filter-overlay');\r\n const categoryContainerMobileOverlay = elm.querySelector('.category-container');\r\n const statusContainerMobileOverlay = elm.querySelector('.status-container');\r\n const categoryContainerMobile = filterContainerBarMobile.querySelector('.category-container-mobile');\r\n const categoryContainerMobileSticky = filterContainerBarMobileScroll.querySelector('.category-container-mobile--sticky');\r\n const statusContainerMobile = filterContainerBarMobile.querySelector('.status-container-mobile');\r\n const statusContainerMobileSticky = filterContainerBarMobileScroll.querySelector('.status-container-mobile--sticky');\r\n const closeButtonCategoryMobile = elm.querySelector('.close-button--category');\r\n const closeButtonStatusMobile = elm.querySelector('.close-button--status');\r\n\r\n function openFilterContainerMobile(filterItem) {\r\n mobileFilterOverlay.style.display = 'block';\r\n filterItem.style.opacity = '1';\r\n filterItem.style.transform = 'translateY(0)';\r\n filterItem.style.webkitTransform = 'translateY(0)';\r\n document.body.classList.add('stop-scrolling');\r\n }\r\n\r\n function closeFilterContainerMobile(filterItem) {\r\n mobileFilterOverlay.style.display = 'none';\r\n filterItem.style.opacity = '0';\r\n filterItem.style.transform = 'translateY(100%)';\r\n filterItem.style.webkitTransform = 'translateY(100%)';\r\n document.body.classList.remove('stop-scrolling');\r\n }\r\n\r\n function toggleCategoryMobile() {\r\n openFilterContainerMobile(categoryContainerMobileOverlay);\r\n\r\n mobileFilterOverlay.onclick = function () {\r\n closeFilterContainerMobile(categoryContainerMobileOverlay);\r\n };\r\n }\r\n\r\n function toggleStatusMobile() {\r\n if (!statusContainerDesktop.classList.contains('open')) {\r\n statusContainerDesktop.click();\r\n }\r\n\r\n openFilterContainerMobile(statusContainerMobileOverlay);\r\n\r\n mobileFilterOverlay.onclick = function () {\r\n statusContainerDesktop.click();\r\n closeFilterContainerMobile(statusContainerMobileOverlay);\r\n };\r\n }\r\n\r\n categoryContainerMobile.onclick = function () {\r\n toggleCategoryMobile();\r\n };\r\n\r\n categoryContainerMobileSticky.onclick = function () {\r\n toggleCategoryMobile();\r\n };\r\n\r\n statusContainerMobile.onclick = function () {\r\n toggleStatusMobile();\r\n };\r\n\r\n statusContainerMobileSticky.onclick = function () {\r\n toggleStatusMobile();\r\n };\r\n\r\n closeButtonCategoryMobile.onclick = function () {\r\n closeFilterContainerMobile(categoryContainerMobileOverlay);\r\n };\r\n\r\n closeButtonStatusMobile.onclick = function () {\r\n closeFilterContainerMobile(statusContainerMobileOverlay);\r\n };\r\n\r\n // ** Check Active Categories ** //\r\n function checkActiveCategories() {\r\n let foundMatch = false;\r\n for (const labelElement of labelElements) {\r\n labelElement.classList.remove('active');\r\n labelElement.style.cursor = 'pointer'; \r\n }\r\n\r\n const matchedCategories = new Set(); // Store matched categories\r\n\r\n for (const category of allActiveCategories) {\r\n const labelElement = findLabelByExactCategory(category);\r\n if (labelElement) {\r\n labelElement.classList.add('active');\r\n matchedCategories.add(category);\r\n foundMatch = true;\r\n }\r\n }\r\n\r\n for (const labelElement of labelElements) {\r\n const category = labelElement.getAttribute('data-category');\r\n if (!matchedCategories.has(category)) {\r\n labelElement.style.cursor = 'default'; // Remove cursor pointer from labels with no matches\r\n }\r\n }\r\n }\r\n\r\n function findLabelByExactCategory(category) {\r\n for (const labelElement of labelElements) {\r\n const labelCategory = labelElement.getAttribute('data-category');\r\n if (labelCategory && labelCategory.trim() === category.trim()) {\r\n return labelElement;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n // Select all label elements with the data-category attribute\r\n const labelElements = document.querySelectorAll('label[data-category]');\r\n\r\n // Attach click event to each label element\r\n labelElements.forEach(labelElement => {\r\n labelElement.addEventListener('click', () => {\r\n const category = labelElement.getAttribute('data-category');\r\n checkActiveCategories();\r\n });\r\n });\r\n\r\n // ** LOAD MORE & FILTER FUNCTIONALITIES ** //\r\n async function performSearch(resetSearch = true) {\r\n const overviewGridItems = elm.querySelector('#overview-grid__items');\r\n\r\n if (resetSearch) {\r\n page = 0;\r\n\r\n while (overviewGridItems.firstChild) {\r\n overviewGridItems.removeChild(overviewGridItems.firstChild);\r\n }\r\n } else {\r\n page += 1;\r\n }\r\n\r\n const categoryUrlItems = categoryList.map((item) => { return 'categories=' + item; });\r\n const categoryUrl = categoryUrlItems.join('&');\r\n\r\n let statusUrl = '';\r\n if (status !== '') {\r\n statusUrl = 'projectStatuses=' + status;\r\n }\r\n\r\n const searchUrl = '/Umbraco/Api/Search/GetProjectOverviewItems?page=' + page + '&pageSize=' + pageSize + '&' + categoryUrl + '&' + statusUrl;\r\n\r\n const responseText = await fetch(searchUrl);\r\n const response = await responseText.json();\r\n results = response.results; // Assign the results from the response\r\n allActiveCategories = response.allResultCategories;\r\n const gridItemTemplate = elm.querySelector('#grid-item-template');\r\n const templateBody = gridItemTemplate.querySelector('.row.project-row');\r\n const templateContentBreakerBody = gridItemTemplate.querySelector('.row.content-breaker-row');\r\n console.log(\"allActiveCategories: \" + allActiveCategories);\r\n for (let i = 0; i < results.length; i = i + 2) {\r\n const gridPlacement = ((i / 2) + ((page * pageSize) / 2)) + 1;\r\n const contentBreaker = contentBreakerLookup[gridPlacement];\r\n\r\n // Content breakers will only show if they exist (obviously), and there are no filters - status or subcategories - set\r\n if (contentBreaker && status === '' && categoryList.length === 0) {\r\n const contentBreakerItem = templateContentBreakerBody.cloneNode(true);\r\n\r\n let alignment = '';\r\n if (contentBreaker.alignment.toLowerCase() === 'right') {\r\n alignment = 'right';\r\n } else {\r\n alignment = 'left';\r\n }\r\n contentBreakerItem.classList.add(alignment);\r\n contentBreakerItem.querySelector('.project-overview-page__body__breaker').classList.add(alignment);\r\n contentBreakerItem.querySelector('.project-overview-page__body__breaker').classList.add('theme-' + contentBreaker.themeColor.toLowerCase());\r\n contentBreakerItem.querySelector('.breaker-content__label').innerText = contentBreaker.prelabel;\r\n contentBreakerItem.querySelector('.breaker-content__headline').innerText = contentBreaker.headline;\r\n\r\n const bodyTextFrag = document.createRange().createContextualFragment(contentBreaker.bodyText);\r\n contentBreakerItem.querySelector('.breaker-content__bodytext').appendChild(bodyTextFrag);\r\n\r\n contentBreakerItem.querySelector('.breaker-content__button').innerText = contentBreaker.ctaButtonText;\r\n contentBreakerItem.querySelector('.breaker-content__button').href = contentBreaker.ctaButtonUrl;\r\n if (window.innerWidth > 991) {\r\n contentBreakerItem.querySelector('.breaker-media').src = contentBreaker.imageUrl + '?width=1000&height=982&format=webp&quality=90';\r\n } else {\r\n contentBreakerItem.querySelector('.breaker-media').src = contentBreaker.imageUrl + '?width=800&height=542&format=webp&quality=90';\r\n }\r\n overviewGridItems.appendChild(contentBreakerItem);\r\n }\r\n\r\n const item = templateBody.cloneNode(true);\r\n\r\n // Project cards //\r\n // The odd - first in the row (above lg) - project card\r\n const itemOdd = item.querySelector('#item--odd');\r\n itemOdd.href = results[i].url;\r\n itemOdd.querySelector('.theme-card-2__image').src = results[i].imageUrl;\r\n itemOdd.querySelector('.theme-card-2__headline').innerText = results[i].headline;\r\n itemOdd.querySelector('.theme-card-2__manchet').innerText = results[i].manchet;\r\n overviewGridItems.appendChild(item);\r\n\r\n // If there is an odd number of project cards stop here, else continue\r\n const itemEven = item.querySelector('#item--even');\r\n if (i + 1 >= results.length) {\r\n itemEven.parentNode.removeChild(itemEven);\r\n continue;\r\n }\r\n\r\n // The even - second in the row (above lg) - project card\r\n itemEven.href = results[i + 1].url;\r\n itemEven.querySelector('.theme-card-2__image').src = results[i + 1].imageUrl;\r\n itemEven.querySelector('.theme-card-2__headline').innerText = results[i + 1].headline;\r\n itemEven.querySelector('.theme-card-2__manchet').innerText = results[i + 1].manchet;\r\n }\r\n\r\n if (response.totalResultCount <= pageSize * (page + 1)) {\r\n loadMoreButtonProjects.classList.add('hidden');\r\n } else {\r\n loadMoreButtonProjects.classList.remove('hidden');\r\n }\r\n\r\n checkActiveCategories();\r\n // Return the results array\r\n return results;\r\n }\r\n\r\n // ** FILTER SUBCATEGORIES ** //\r\n subCategoryCheckboxList.forEach(subCategoryCheckbox => {\r\n subCategoryCheckbox.onchange = function () {\r\n if (subCategoryCheckbox.checked) {\r\n if (categoryList.indexOf(subCategoryCheckbox.id) === -1) {\r\n categoryList.push(subCategoryCheckbox.id);\r\n }\r\n } else {\r\n categoryList.splice(categoryList.indexOf(subCategoryCheckbox.id), 1);\r\n }\r\n\r\n const newUrl = generateUrl(status, categoryList);\r\n history.pushState({}, '', newUrl);\r\n performSearch();\r\n };\r\n });\r\n\r\n // ** FILTER STATUS ** //\r\n statusCheckboxList.forEach(statusCheckboxItem => {\r\n statusCheckboxItem.onchange = function () {\r\n for (let i = 0; i < statusCheckboxList.length; i++) {\r\n const element = statusCheckboxList[i];\r\n\r\n if (element.id !== statusCheckboxItem.id) {\r\n element.checked = false;\r\n }\r\n }\r\n\r\n if (statusCheckboxItem.checked) {\r\n status = statusCheckboxItem.id;\r\n } else {\r\n status = '';\r\n }\r\n\r\n performSearch();\r\n const newUrl = generateUrl(status, categoryList);\r\n history.pushState({}, '', newUrl);\r\n };\r\n });\r\n\r\n // ** RESET CATEGORIES: Remove checked subcategory filters ** //\r\n function resetCategoryFilter() {\r\n for (let i = 0; i < subCategoryCheckboxList.length; i++) {\r\n const subCategoryCheckbox = subCategoryCheckboxList[i];\r\n subCategoryCheckbox.checked = false;\r\n }\r\n categoryList.splice(0, categoryList.length);\r\n performSearch();\r\n\r\n const newUrl = generateUrl(status, categoryList);\r\n history.pushState({}, '', newUrl);\r\n }\r\n\r\n resetCategories.onclick = function () { resetCategoryFilter(); };\r\n\r\n // Load more projects (button)\r\n loadMoreButtonProjects.addEventListener('click', e => {\r\n e.preventDefault();\r\n if (!loadMoreButtonProjects.classList.contains('disabled')) {\r\n performSearch(false);\r\n }\r\n });\r\n\r\n const urlParamsObj = parseUrl();\r\n if (urlParamsObj.status) {\r\n status = urlParamsObj.status;\r\n }\r\n\r\n if (urlParamsObj.categories) {\r\n categoryList = urlParamsObj.categories;\r\n }\r\n\r\n async function initSearch(searchState) {\r\n for (let i = 0; i < subCategoryCheckboxList.length; i++) {\r\n const subcategory = subCategoryCheckboxList[i];\r\n if (searchState.checkedSubCategories.indexOf(subcategory.id) !== -1) {\r\n subcategory.checked = true;\r\n if (!subcategory.closest('.sub-category-container').previousElementSibling.classList.contains('open')) {\r\n subcategory.closest('.sub-category-container').previousElementSibling.click();\r\n }\r\n }\r\n }\r\n\r\n for (let i = 0; i < statusCheckboxList.length; i++) {\r\n const statusCheckbox = statusCheckboxList[i];\r\n\r\n if (searchState.checkedStatus.indexOf(statusCheckbox.id) !== -1) {\r\n statusCheckbox.checked = true;\r\n statusToggleButton.click();\r\n }\r\n }\r\n\r\n contentBreakerLookup = await getContentBreakers();\r\n performSearch();\r\n }\r\n\r\n initSearch({ checkedSubCategories: categoryList, checkedStatus: status });\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AAAA;AACA;AACA;AA5YA;AACA;A;;A;;A","sourceRoot":""}