{"version":3,"sources":["hicomPage.ts"],"names":["HicomPage","Name","Controller","Action","Area","BaseUrl","Key","LoadedDateTime","SessionTimerConfig","PageState","constructor","name","controller","action","baseUrl","key","area","this","Date","_init","let","page","hQueryReady","console","debug","_setUA","$","document","ajaxError","event","jqxhr","settings","thrownError","status","getAllResponseHeaders","exceptionId","responseJSON","e","window","location","href","uaResult","UAParser","getResult","device","vendor","model","type","ua","browser","version","os","cookie","encodeURI","startSessionTimer","showSessionExpiryWarningFrom","getTime","sessionLengthMinutes","minutesBeforeSessionTimeoutToShowWarning","callback","interval","setInterval","fn","clearInterval","logOffCallback","sessionEndDateTime","resetSessionTimer","fetchGet","then","ready","kendoReady","kendo","syncReady","fetchPost","url","data","requestVerificationToken","parseResultAsJSON","bearerAuthorizationToken","headers","Headers","response","append","await","fetch","method","mode","cache","credentials","redirect","referrerPolicy","body","ok","result","text","JSON","parse","message","Error","fetchPostJson","stringify","wrappedResponse","FetchResponse","StatusCode","Success","Data","URLSearchParams","toString","fetchGetReturnsResponse","HE-Page","fetchGetJson","json","loadHtml","selector","querySelector","setAttribute","html","UpdateRowVersion","id","rowVersionElementId","BaseUrlWithAreaAndController","getElementById","value","ReturnValue","error","filter","Boolean","join","hicomPage","querySelectorAll","forEach","el","addEventListener","clearPageState","PageStateTabs","PageStateAccordion","getPageState","pageState","sessionStorage","pageStateIndex","findIndex","x","pageKey","setPageState","state","pageStateData","splice","items","push","removeItem","getPageStateItem","index","setPageStateItem","itemState"],"mappings":"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","file":"hicomPage.js","sourcesContent":["/// \n/// \n\nclass HicomPage implements IHicomPage {\n Name: string;\n Controller: string;\n Action: string;\n Area: string;\n BaseUrl: string;\n Key: string;\n LoadedDateTime: Date;\n SessionTimerConfig: SessionTimerConfig;\n PageState: PageState;\n\n constructor(name, controller, action, baseUrl, key, area) {\n this.Name = name;\n this.Controller = controller;\n this.Action = action;\n this.Area = area;\n this.BaseUrl = baseUrl;\n this.Key = key;\n this.LoadedDateTime = new Date();\n this.PageState = new PageState(this);\n this._init();\n }\n\n /** \n * Initialisation of the HicomPage \n */\n _init() {\n let page = this;\n\n // @ts-ignore\n hQueryReady(() => {\n console.debug(`Page initialised: ${page.Name}`);\n console.debug(`Page Key: ${page.Key}`);\n page._setUA();\n })\n\n // Global Ajax error handler (only fires if global not set)\n $(document).ajaxError(function (event, jqxhr, settings, thrownError) {\n\n if (jqxhr.status === 409) { // Concurrency issue detected\n } else if (jqxhr.status === 500) { // Concurrency issue detected\n // Checking if the page is reloaded before the ajax calls were completed.\n if (jqxhr.getAllResponseHeaders() != '') {\n // Redirect to the error page\n let exceptionId;\n try {\n // @ts-ignore\n exceptionId = jqxhr.responseJSON.exceptionId;\n } catch (e) { }\n\n if (exceptionId) {\n // Pass the exceptionId to the primary error page\n window.location.href = page.BaseUrl + \"/Error?exceptionId=\" + exceptionId;\n }\n else {\n // Fallback error page\n window.location.href = page.BaseUrl + \"/Error/HttpStatusCodeError/500\";\n }\n }\n }\n });\n }\n\n /**\n * Set Parsed User Agent cookie\n */\n _setUA() {\n let uaResult = new UAParser().getResult();\n let device = typeof uaResult.device.vendor === 'undefined' ? '' : uaResult.device.vendor +\n typeof uaResult.device.model === 'undefined' ? '' : uaResult.device.model +\n typeof uaResult.device.type === 'undefined' ? '' : uaResult.device.type;\n device = device === '' ? 'Other' : device;\n let ua = `Browser: ${uaResult.browser.name} ${uaResult.browser.version} | OS: ${uaResult.os.name} ${uaResult.os.version} | Device: ${device}`;\n document.cookie = encodeURI(`ParsedUA=${ua};secure;path=/;samesite=Strict`);\n }\n\n startSessionTimer() {\n let showSessionExpiryWarningFrom = new Date(this.LoadedDateTime.getTime() + ((this.SessionTimerConfig.sessionLengthMinutes - this.SessionTimerConfig.minutesBeforeSessionTimeoutToShowWarning) * 60000));\n console.debug(`HicomPage::startSessionTimer - Session started - warning set to ${showSessionExpiryWarningFrom} millseconds before session expiry`);\n if (this.SessionTimerConfig.callback) {\n // Every 30 seconds, check whether we're past the time to execute the session expiry callback.\n this.SessionTimerConfig.interval = setInterval(fn => {\n if (showSessionExpiryWarningFrom < new Date()) {\n // Yes - execute the callback function and stop the timer\n this.SessionTimerConfig.callback();\n clearInterval(this.SessionTimerConfig.interval);\n\n // Now start another timer (running every 10 seconds) to call the logoff callback function when we reach the end of the session\n if (this.SessionTimerConfig.logOffCallback) {\n let sessionEndDateTime = new Date(this.LoadedDateTime.getTime() + (this.SessionTimerConfig.sessionLengthMinutes * 60000));\n this.SessionTimerConfig.interval = setInterval(fn => {\n if (sessionEndDateTime < new Date()) {\n // Yes - execute the callback function and stop the timer\n this.SessionTimerConfig.logOffCallback();\n clearInterval(this.SessionTimerConfig.interval);\n }\n }, 10000);\n }\n }\n }, 30000);\n }\n }\n\n resetSessionTimer() {\n this.fetchGet(`${this.BaseUrl}/WebApi/RenewSession`).then(() => {\n console.debug('HicomPage::resetSessionTimer - Session reset');\n clearInterval(this.SessionTimerConfig.interval);\n this.LoadedDateTime = new Date();\n this.startSessionTimer();\n });\n }\n\n /**\n * \n * @param fn - function to execute once the DOM is ready\n */\n ready(fn) {\n // @ts-ignore\n hQueryReady(fn);\n }\n\n /**\n * \n * @param fn - function to execute once the DOM & KendoSync is ready\n */\n kendoReady(fn) {\n // @ts-ignore\n hQueryReady(() => {\n // @ts-ignore\n kendo.syncReady(fn);\n })\n }\n\n //#region fetch helpers\n /**\n * POST non-JSON data to a url using the fetch api - IT'S VITAL YOU DON'T SET THE CONTENT-TYPE IF NOT SENDING A JSON PAYLOAD\n * @param url - url to send the data to\n * @param data - JS object to send\n * @param requestVerificationToken - XCRF token\n * \n * @returns {Object} - JSON response parsed into a JS Object\n */\n async fetchPost(url = '', data = null, requestVerificationToken = null, parseResultAsJSON = true, bearerAuthorizationToken = null) {\n\r\n const headers = new Headers();\r\n\r\n // Set the headers, we always send HE-Page\r\n headers.append('HE-Page', 'true');\n\n if (requestVerificationToken != null) {\n // A request verification token has been provided, add it to the headers\n headers.append('RequestVerificationToken', requestVerificationToken);\r\n }\n\n if (bearerAuthorizationToken != null) {\r\n // An authorization bearer token has been provided, add it to the headers\r\n headers.append('Authorization', `Bearer ${bearerAuthorizationToken}`);\r\n }\n\n // Default options are marked with *\n const response = await fetch(url, {\n method: 'POST', // *GET, POST, PUT, DELETE, etc.\n mode: 'cors', // no-cors, *cors, same-origin\n cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached\n credentials: 'same-origin', // include, *same-origin, omit\n headers: headers, // headers array\n redirect: 'follow', // manual, *follow, error\n referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url\n body: data\n });\n\n if (!response.ok && response.status === 500) {\n const message = await response.text();\n let exceptionId;\n try {\n // @ts-ignore\n exceptionId = JSON.parse(message).exceptionId;\n } catch (e) { }\n\n if (exceptionId) {\n // Pass the exceptionId to the primary error page\n window.location.href = this.BaseUrl + \"/Error?exceptionId=\" + exceptionId;\n }\n else {\n // Fallback error page\n window.location.href = this.BaseUrl + \"/Error/HttpStatusCodeError/500\";\n }\n\n throw new Error(message);\n }\n\n const result = await response.text();\n\n if (result === null || result === undefined || result === '') {\n return null;\n }\n\n if (!parseResultAsJSON) {\r\n return result;\r\n }\n\n return JSON.parse(result); // parses JSON response into native JavaScript objects\n }\n\n /**\n * POST JSON data to a url using the fetch api\n * @param url - url to send the data to\n * @param data - JS object to send\n * @param requestVerificationToken - XCRF token\n * \n * @returns {FetchResponse} - JS object wrapper, with StatusCode, Success, and Data properties - Data is the JSON response parsed into a JS Object.\n */\n async fetchPostJson(url = '', data = {}, requestVerificationToken = null, bearerAuthorizationToken = null): Promise {\n\n const headers = new Headers();\r\n\r\n // Set the headers, we always send HE-Page\r\n headers.append('HE-Page', 'true');\n headers.append('Content-Type', 'application/json');\n\n if (requestVerificationToken != null) {\n // A request verification token has been provided, add it to the headers\n headers.append('RequestVerificationToken', requestVerificationToken);\r\n }\n\n if (bearerAuthorizationToken != null) {\r\n // An authorization bearer token has been provided, add it to the headers\r\n headers.append('Authorization', `Bearer ${bearerAuthorizationToken}`);\r\n }\n\n // Default options are marked with *\n const response = await fetch(url, {\n method: 'POST', // *GET, POST, PUT, DELETE, etc.\n mode: 'cors', // no-cors, *cors, same-origin\n cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached\n credentials: 'same-origin', // include, *same-origin, omit\n headers: headers, // headers array\n redirect: 'follow', // manual, *follow, error\n referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url\n body: JSON.stringify(data) // body data type must match \"Content-Type\" header\n });\n\n if (!response.ok && response.status === 500) {\n const message = await response.text();\n let exceptionId;\n try {\n // @ts-ignore\n exceptionId = JSON.parse(message).exceptionId;\n } catch (e) { }\n\n if (exceptionId) {\n // Pass the exceptionId to the primary error page\n window.location.href = this.BaseUrl + \"/Error?exceptionId=\" + exceptionId;\n }\n else {\n // Fallback error page\n window.location.href = this.BaseUrl + \"/Error/HttpStatusCodeError/500\";\n }\n\n throw new Error(message);\n }\n\n let wrappedResponse: FetchResponse = new FetchResponse();\n wrappedResponse.StatusCode = response.status;\n wrappedResponse.Success = response.ok;\n\n const result = await response.text();\n\n if (result === null || result === undefined || result === '') {\n return wrappedResponse;\n }\n\n wrappedResponse.Data = JSON.parse(result); // parses JSON response into native JavaScript objects\n\n return wrappedResponse;\n }\n\n /**\n * GET data to a url using the fetch api\n * @param url - url to send the data to\n * @param data - JS object to send\n * \n * @returns {String} - string response\n */\n async fetchGet(url = '', data = null, bearerAuthorizationToken = null) {\n // Default options are marked with *\n\n if (data) {\r\n url += '?' + (new URLSearchParams(data)).toString();\n }\n\n const headers = new Headers();\r\n\r\n // Set the headers, we always send HE-Page\r\n headers.append('HE-Page', 'true');\n\n if (bearerAuthorizationToken != null) {\r\n // An authorization bearer token has been provided, add it to the headers\r\n headers.append('Authorization', `Bearer ${bearerAuthorizationToken}`);\r\n }\n\n const response = await fetch(url, {\n method: 'GET', // *GET, POST, PUT, DELETE, etc.\n mode: 'cors', // no-cors, *cors, same-origin\n cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached\n credentials: 'same-origin', // include, *same-origin, omit\n headers: headers, // headers array\n redirect: 'follow', // manual, *follow, error\n referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url\n });\n\n if (!response.ok && response.status === 500) {\n const message = await response.text();\n let exceptionId;\n try {\n // @ts-ignore\n exceptionId = JSON.parse(message).exceptionId;\n } catch (e) { }\n\n if (exceptionId) {\n // Pass the exceptionId to the primary error page\n window.location.href = this.BaseUrl + \"/Error?exceptionId=\" + exceptionId;\n }\n else {\n // Fallback error page\n window.location.href = this.BaseUrl + \"/Error/HttpStatusCodeError/500\";\n }\n\n throw new Error(message);\n }\n\n return response.text();\n }\n\n /**\n * GET the response object from a url using the fetch api\n * @param url - url to send the data to\n * @param data - JS object to send\n * \n * @returns response object\n */\n async fetchGetReturnsResponse(url = '', data = {}) {\n // Default options are marked with *\n url += '?' + (new URLSearchParams(data)).toString();\n\n const response = await fetch(url, {\n method: 'GET', // *GET, POST, PUT, DELETE, etc.\n mode: 'cors', // no-cors, *cors, same-origin\n cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached\n credentials: 'same-origin', // include, *same-origin, omit\n headers: {\n 'HE-Page': 'true'\n },\n redirect: 'follow', // manual, *follow, error\n referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url\n });\n\n return response;\n }\n\n /**\n * GET data to a url using the fetch api\n * @param url - url to send the data to\n * @param data - JS object to send\n * \n * @returns {Object} - JSON response parsed into a JS Object\n */\n async fetchGetJson(url = '', data = null, bearerAuthorizationToken = null) {\n // Default options are marked with *\n\n if (data) {\r\n url += '?' + (new URLSearchParams(data)).toString();\n }\n\n const headers = new Headers();\r\n\r\n // Set the headers, we always send HE-Page\r\n headers.append('HE-Page', 'true');\n\n if (bearerAuthorizationToken != null) {\r\n // An authorization bearer token has been provided, add it to the headers\r\n headers.append('Authorization', `Bearer ${bearerAuthorizationToken}`);\r\n }\n\n const response = await fetch(url, {\n method: 'GET', // *GET, POST, PUT, DELETE, etc.\n mode: 'cors', // no-cors, *cors, same-origin\n cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached\n credentials: 'same-origin', // include, *same-origin, omit\n headers: headers, // headers array\n redirect: 'follow', // manual, *follow, error\n referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url\n });\n\n if (!response.ok && response.status === 500) {\n const message = await response.json();\n let exceptionId;\n try {\n // @ts-ignore\n exceptionId = message.exceptionId;\n } catch (e) { }\n\n if (exceptionId) {\n // Pass the exceptionId to the primary error page\n window.location.href = this.BaseUrl + \"/Error?exceptionId=\" + exceptionId;\n }\n else {\n // Fallback error page\n window.location.href = this.BaseUrl + \"/Error/HttpStatusCodeError/500\";\n }\n\n throw new Error(message);\n }\n\n return response.json();\n }\n\n async loadHtml(url: string, selector: string) {\n await this.fetchGet(url)\n .then((response) => {\n document.querySelector(selector).setAttribute('data-url-loaded', 'true');\n $(selector).html(response);\n });\n };\n\n //#endregion\n\n async UpdateRowVersion(id: string, rowVersionElementId: string): Promise {\n var result = await this.fetchGetJson(`${this.BaseUrlWithAreaAndController()}/GetRowVersion/${id}`);\n if (result.Success) {\n (document.getElementById(rowVersionElementId)).value = result.ReturnValue;\r\n return true;\r\n }\n\n console.error(\"Failed to retrieve a RowVersion from hicomPage.GetUpdatedRowVersion().\");\n return false;\n }\n\n BaseUrlWithAreaAndController(): string {\n return `${[this.BaseUrl, this.Area, this.Controller].filter(Boolean).join(\"/\")}`;\n }\n}\n\n/**\n * Wrapper around responses returned by HTTP Fetch calls\n */\nclass FetchResponse {\n StatusCode: number;\n Success: boolean;\n Data: any;\n}\n\n/**\n * Handles the persistence of state for a HicomPage\n */\nclass PageState {\n hicomPage: HicomPage;\n\n constructor(hicomPage: HicomPage) {\n this.hicomPage = hicomPage;\n this._init();\n }\n\n /** \n * Initialisation of PageState\n */\n private _init() {\n this.hicomPage.ready(() => {\n\n // add event listeners for clearing the page state\n const clearStateList = document.querySelectorAll('.engine-clear-page-state:not(.nav-item-link.active)')\n clearStateList.forEach(el => {\n el.addEventListener('click', e => {\n this.clearPageState();\n });\n })\n\n // Create instances of implemented IPageStateComponent class:\n\n // Tabs from hicomWidgets.ts\n if (typeof (PageStateTabs) !== 'undefined') { new PageStateTabs(this); }\n // Accordion from hicomWidgets.ts\n if (typeof (PageStateAccordion) !== 'undefined') { new PageStateAccordion(this); }\n });\n }\n\n //#region PageState persistance helpers\n\n /**\n * Persists the state for the item in the page state for the page it is on\n * @param key {string} - unique identifier for the item\n * @param state {any} - the state data to persist\n */\n private getPageState(): any {\n let pageState = JSON.parse(sessionStorage['page-state'] || '[]');\n let pageStateIndex = pageState.findIndex(x => x.pageKey === this.hicomPage.Key);\n if (pageStateIndex != -1) {\n return pageState[pageStateIndex];\n }\n }\n\n /**\n * Persists the state for the item in the page state for the page it is on\n * @param key {string} - unique identifier for the item\n * @param state {any} - the state data to persist\n */\n private setPageState(state) {\n let pageState = JSON.parse(sessionStorage['page-state'] || '[]');\n let pageStateIndex = pageState.findIndex(x => x.pageKey === this.hicomPage.Key);\n if (pageStateIndex != -1) { // if already exists, delete\n pageState.splice(pageStateIndex, 1);\n }\n const pageStateData = {\n pageKey: this.hicomPage.Key,\n items: state.items\n };\n pageState.push(pageStateData);\n sessionStorage['page-state'] = JSON.stringify(pageState);\n }\n\n /**\n * Persists the state for the item in the page state for the page it is on\n * @param key {string} - unique identifier for the item\n * @param state {any} - the state data to persist\n */\n private clearPageState() {\n // Now we just remove page-state from session storage rather than trying \n // to delete the entry that correlates with the page we are moving away from\n sessionStorage.removeItem('page-state');\n }\n\n /**\n * Persists the state for the item in the page state for the page it is on\n * @param key {string} - unique identifier for the item\n * @param state {any} - the state data to persist\n */\n getPageStateItem(key: string) {\n let pageState = this.getPageState();\n if (!pageState) {\n return;\n }\n let index = pageState.items.findIndex(x => x.key === key);\n if (index != -1) {\n return pageState.items[index];\n }\n }\n\n /**\n * Persists the state for the item in the page state for the page it is on\n * @param key {string} - unique identifier for the item\n * @param state {any} - the state data to persist\n */\n setPageStateItem(key: string, itemState) {\n let pageState = this.getPageState();\n if (!pageState) {\n pageState = { items: [] };\n this.setPageState(pageState);\n }\n let index = pageState.items.findIndex(x => x.key === key);\n if (index != -1) { // if already exists, delete\n pageState.items.splice(index, 1);\n }\n pageState.items.push(itemState);\n\n this.setPageState(pageState);\n }\n\n //#endregion\n}\n\nclass SessionTimerConfig {\n sessionLengthMinutes: number;\n minutesBeforeSessionTimeoutToShowWarning: number;\n callback: Function;\n logOffCallback: Function;\n interval: number;\n\n constructor(sessionLengthMinutes: number, minutesBeforeSessionTimeoutToShowWarning: number, callback: Function, logOffCallback: Function) {\n this.sessionLengthMinutes = sessionLengthMinutes;\n this.minutesBeforeSessionTimeoutToShowWarning = minutesBeforeSessionTimeoutToShowWarning;\n this.callback = callback;\n this.logOffCallback = logOffCallback;\n }\n}"]}