{"version":3,"file":"js/search-page.9f16e84bdaf8b7fbebf4.js","mappings":"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","sources":["webpack:///./Features/Pages/SearchPage/_js/search-page.ts"],"sourcesContent":["/* Interfaces */\r\ninterface ISearchHit {\r\n heading: string;\r\n url: string;\r\n preamble: string;\r\n lastUpdatedDate: string;\r\n lastUpdatedDateISO: string;\r\n hitType: string;\r\n}\r\n\r\ninterface ISearchResult {\r\n searchHits: ISearchHit[];\r\n totalHits: number;\r\n}\r\n\r\ninterface ITextContent {\r\n noKeywords: string;\r\n noResults: string;\r\n resultFor: string;\r\n resultsFor: string;\r\n updated: string;\r\n showMore: string;\r\n}\r\n\r\n/* HTML elements */\r\nconst searchForm = document.querySelector('.search-page__form') as HTMLFormElement;\r\nconst searchInput = document.querySelector('.search-page__input') as HTMLInputElement;\r\nconst searchSubmitButton = document.querySelector('.search-page__submit-button') as HTMLButtonElement;\r\nconst searchResultSection = document.querySelector('.search-page__result') as HTMLElement;\r\nconst searchResultInfo = document.querySelector('.search-page__result-info') as HTMLParagraphElement;\r\n\r\n/* Data */\r\nconst { resultsToShow, resultsToAdd, currentLanguage, includeText } = searchForm.dataset;\r\n\r\n/* Text content (translated text) */\r\nlet includeTextArray = includeText?.split(', ') as string[];\r\nlet textContent: ITextContent = {\r\n noKeywords: includeTextArray[0],\r\n noResults: includeTextArray[1],\r\n resultFor: includeTextArray[2],\r\n resultsFor: includeTextArray[3],\r\n updated: includeTextArray[4],\r\n showMore: includeTextArray[5]\r\n};\r\n\r\n/* Global variables */\r\nlet query: string | null = null;\r\nlet apiSkipAmount = 0 as number;\r\nlet apiTakeAmount = parseInt(resultsToShow!, 10) as number;\r\n\r\n/* Functions – Reset and clear DOM */\r\nconst resetSearchResult = (): void => {\r\n searchInput.value = '';\r\n searchResultSection.classList.add('sr-only');\r\n searchResultInfo.textContent = textContent.noKeywords;\r\n}\r\n\r\nconst clearResultList = (): void => {\r\n const resultList: HTMLUListElement | null = document.querySelector('.search-page__result-list');\r\n const showMore: HTMLDivElement | null = document.querySelector('.search-page__show-more');\r\n\r\n if (resultList) {\r\n resultList.remove();\r\n }\r\n\r\n if (showMore) {\r\n showMore.remove();\r\n }\r\n}\r\n\r\n/* Functions – Get data from API */\r\nconst getSearchResult = async (): Promise => {\r\n try {\r\n const response = await fetch(`/api/search?query=${query}&take=${apiTakeAmount}&skip=${apiSkipAmount}&language=${currentLanguage}`, {\r\n method: 'GET',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'application/json'\r\n }\r\n });\r\n\r\n const result = await response.json();\r\n\r\n if (!response.ok) {\r\n throw new Error(response.statusText);\r\n }\r\n\r\n return result;\r\n } catch (error) {\r\n console.log(error);\r\n }\r\n}\r\n\r\n/* Functions – Render DOM */\r\nconst renderResultItems = (searchHits: ISearchHit[], resultList: HTMLUListElement): void => {\r\n searchHits.forEach(item => {\r\n const resultItem = document.createElement('li') as HTMLLIElement;\r\n resultItem.classList.add('search-page__result-item');\r\n\r\n if (item.hitType === 'Media') {\r\n resultItem.classList.add('search-page__result-item--media');\r\n }\r\n\r\n const link = document.createElement('a') as HTMLAnchorElement;\r\n link.classList.add('search-page__result-item-link');\r\n link.setAttribute('href', item.url);\r\n resultItem.appendChild(link);\r\n\r\n if (item.hitType === 'Media') {\r\n link.classList.add('search-page__result-item-link--icon-document');\r\n }\r\n\r\n const date = document.createElement('p') as HTMLParagraphElement;\r\n date.classList.add('search-page__result-item-date');\r\n date.innerHTML = `${textContent.updated}: `;\r\n link.appendChild(date);\r\n\r\n // Removed for now\r\n // const time = document.createElement('time') as HTMLTimeElement;\r\n // time.setAttribute('datetime', item.lastUpdatedDateISO);\r\n // time.textContent = item.lastUpdatedDate;\r\n // date.appendChild(time);\r\n\r\n const heading = document.createElement('h3') as HTMLHeadingElement;\r\n heading.classList.add('search-page__result-item-heading');\r\n heading.textContent = item.heading.replace(/­/g, '\\u00AD');;\r\n link.appendChild(heading);\r\n\r\n if (item.preamble) {\r\n const preamble = document.createElement('p') as HTMLParagraphElement;\r\n preamble.classList.add('search-page__result-item-preamble');\r\n preamble.textContent = item.preamble;\r\n link.appendChild(preamble);\r\n }\r\n\r\n resultList.appendChild(resultItem);\r\n });\r\n}\r\n\r\nconst renderShowMoreButton = (): void => {\r\n const showMoreContainer = document.createElement('div');\r\n showMoreContainer.classList.add('search-page__show-more');\r\n\r\n const showMoreButton = document.createElement('button');\r\n showMoreButton.classList.add('search-page__show-more-button', 'button', 'button--secondary');\r\n showMoreButton.setAttribute('type', 'button');\r\n showMoreButton.textContent = textContent.showMore;\r\n\r\n showMoreButton.addEventListener('click', (event: MouseEvent) => {\r\n addMoreResultItems(showMoreButton);\r\n });\r\n\r\n showMoreContainer.appendChild(showMoreButton);\r\n searchResultSection.appendChild(showMoreContainer);\r\n}\r\n\r\nconst renderResult = (searchResult: ISearchResult): void => {\r\n clearResultList();\r\n\r\n if (searchResult.totalHits > 0) {\r\n if (searchResult.totalHits === 1) {\r\n searchResultInfo.innerHTML = `${searchResult.totalHits} ${textContent.resultFor} ${query}.`;\r\n } else {\r\n searchResultInfo.innerHTML = `${searchResult.totalHits} ${textContent.resultsFor} ${query}.`;\r\n }\r\n\r\n const resultList = document.createElement('ul') as HTMLUListElement;\r\n resultList.classList.add('search-page__result-list');\r\n searchResultSection.appendChild(resultList);\r\n\r\n renderResultItems(searchResult.searchHits, resultList);\r\n\r\n if (searchResult.searchHits.length < searchResult.totalHits) {\r\n renderShowMoreButton();\r\n }\r\n } else {\r\n searchResultInfo.textContent = textContent.noResults;\r\n }\r\n\r\n searchResultSection.classList.remove('sr-only');\r\n}\r\n\r\nconst renderWithoutResult = (): void => {\r\n clearResultList();\r\n\r\n searchInput.value = '';\r\n searchResultInfo.textContent = textContent.noKeywords;\r\n searchResultSection.classList.remove('sr-only');\r\n}\r\n\r\n/* Functions - Search */\r\nconst search = async (): Promise => {\r\n apiSkipAmount = 0;\r\n\r\n let searchResult = await getSearchResult();\r\n if (searchResult) {\r\n renderResult(searchResult);\r\n }\r\n}\r\n\r\nconst searchFromQueryString = (): void => {\r\n const urlParams = new URLSearchParams(window.location.search) as URLSearchParams;\r\n let queryFromParam: string | null = urlParams.get('query');\r\n let takeFromParam: string | null = urlParams.get('take');\r\n\r\n query = queryFromParam;\r\n\r\n if (query) {\r\n query = query.trim();\r\n searchInput.value = query;\r\n } else {\r\n query = '';\r\n }\r\n\r\n if (takeFromParam && !isNaN(parseInt(takeFromParam, 10))) {\r\n apiTakeAmount = parseInt(takeFromParam, 10);\r\n }\r\n\r\n if (query.length > 0) {\r\n search();\r\n } else {\r\n renderWithoutResult();\r\n }\r\n}\r\n\r\nconst addMoreResultItems = async (showMoreButton: HTMLButtonElement): Promise => {\r\n apiSkipAmount += apiTakeAmount;\r\n apiTakeAmount = parseInt(resultsToAdd!, 10);\r\n\r\n let searchResult = await getSearchResult();\r\n if (searchResult) {\r\n const resultList = document.querySelector('.search-page__result-list') as HTMLUListElement;\r\n const resultItemsCount = resultList.children.length as number;\r\n\r\n let takeAmount = resultItemsCount + parseInt(resultsToAdd!, 10);\r\n\r\n if (searchResult.totalHits < takeAmount) {\r\n takeAmount = searchResult.totalHits;\r\n }\r\n\r\n window.history.replaceState({},'', `?query=${query}&take=${takeAmount}`);\r\n\r\n renderResultItems(searchResult.searchHits, resultList);\r\n\r\n if (resultList.children.length === searchResult.totalHits) {\r\n showMoreButton.remove();\r\n }\r\n\r\n let resultItems = resultList.children as HTMLCollection;\r\n let firstAddedResultItem = resultItems[resultItemsCount] as HTMLLIElement;\r\n let firstAddedResultItemLink = firstAddedResultItem.querySelector('a') as HTMLAnchorElement;\r\n firstAddedResultItemLink.focus();\r\n }\r\n}\r\n\r\n/* Event listeners */\r\n\r\n// Event that happens if someone enters url with query string\r\nwindow.addEventListener('load', (): void => {\r\n if (window.location.search) {\r\n searchFromQueryString();\r\n }\r\n\r\n searchInput.focus();\r\n});\r\n\r\n// Event that happens when users browse through their browser history, e.g. use the back button.\r\nwindow.addEventListener('popstate', (): void => {\r\n if (window.location.search) {\r\n searchFromQueryString();\r\n } else {\r\n resetSearchResult();\r\n }\r\n\r\n searchInput.focus();\r\n});\r\n\r\n// Event that happens when user submits a search with the form\r\nsearchForm.addEventListener('submit', (event: SubmitEvent): void => {\r\n event.preventDefault();\r\n\r\n query = searchInput.value.trim();\r\n\r\n window.history.pushState({},'', `?query=${query}`);\r\n\r\n if (query.length > 0) {\r\n search();\r\n } else {\r\n renderWithoutResult();\r\n }\r\n});"],"names":["searchForm","document","querySelector","searchInput","searchResultSection","searchResultInfo","resultsToShow","resultsToAdd","currentLanguage","includeText","dataset","includeTextArray","split","textContent","noKeywords","noResults","resultFor","resultsFor","updated","showMore","query","apiSkipAmount","apiTakeAmount","parseInt","clearResultList","resultList","remove","getSearchResult","async","response","fetch","method","headers","result","json","ok","Error","statusText","error","console","log","renderResultItems","searchHits","forEach","item","resultItem","createElement","classList","add","hitType","link","setAttribute","url","appendChild","date","innerHTML","heading","replace","preamble","renderResult","searchResult","totalHits","length","showMoreContainer","showMoreButton","addEventListener","event","addMoreResultItems","renderShowMoreButton","renderWithoutResult","value","search","searchFromQueryString","urlParams","URLSearchParams","window","location","queryFromParam","get","takeFromParam","trim","isNaN","resultItemsCount","children","takeAmount","history","replaceState","focus","preventDefault","pushState"],"sourceRoot":""}