// Change Information // ---------------------------------------------------------------------------------------------- // Number Date Version Changed By Change // ---------------------------------------------------------------------------------------------- // 0001 2022-07-01 001 Hermanus Smalman Initial creation for SEA - Integration of Dashboards into Web // 0002 2023-04-01 002 Hermanus Smalman I5601 - SEA Context Sensitive Filtering // 0003 2023-04-12 003 Hermanus Smalman 123515- SEA Context Sensitive Filtering Enhanced for modal window binding // 0004 2023-10-27 004 Hermanus Smalman 125583- Check if the sysproInterop layer is ready before rendering Dashboards const embAna_getEmbedSetting = () => { const value = { "interactivityProfileName":"interactive", "interactivityOverrides": { "name": "interactive", "type": "SYSTEM", "overrideVisualInteractivity": true, "settings": { "REFRESH": true, "CHANGE_LAYOUT": true, "RENAME": false, "SHARE_FILTER_SETS": true, "DASHBOARD_INTERACTIONS": false, "ADD_TO_FAVORITES": false, "DELETE": false, "FILTER": true, //"FILTER": false, "EXPORT_PNG_PDF": false, "ADD_VISUALS": false, "EXPORT_CONFIGURATION": false, "DASHBOARD_LINKS": false, "SAVE": false }, "visualSettings": { "ACTIONS_ACTION": true, "RULERS": true, "ZOOM_ACTION": true, "FILTER_ACTION": true, "COLORS": true, "METRICS": true, "ACTIONS": true, "TREND_ACTION": true, "VISUAL_STYLE": true, "KEYSET_ACTION": true, "KEYSET": undefined, "COPY": true, "SETTINGS": true, "EXPORT": true, "TIMEBAR_PANEL": true, "DETAILS_ACTION": true, "MAXIMIZE": true, "LINK_ACTION": true, "FILTER": true, //"FILTER": false, "REMOVE": true, "GROUPING": true, "RENAME": false, "SORT": true, "TIMEBAR_FIELD": true } }, "editor": { "placement": "dockRight" }, "header": { "showActions": true, "showTitle": false, "visible": true }}; return value; }; const embAna_isNullCheck = d => typeof d === 'undefined' || d === null; const embAna_isUndefinedCheck = d => typeof d === 'undefined'; const embAna_isNotNullCheck = d => !embAna_isNullCheck(d); const embAna_isNullOrEmptyCheck = d => embAna_isNullCheck(d) || d.trim().length <= 0; const embAna_isNotNullOrEmptyCheck = d => embAna_isNotNullCheck(d) && d.trim().length > 0; const embAna_GetStringValueOrDefault = (aString, theDefault) => embAna_isNotNullCheck(sString) ? aString : theDefault; const embAna_GetStringValue = (aString) => embAna_GetStringValueOrDefault(sString, ""); const embAna_getDashboardUuid = (dashboardId, modelId) => dashboardId + modelId; const embAna_getDashboardByIds = (dashboardId, componentInstanceId) => dashboardId + componentInstanceId; const embAna_getUniqueId = (dashboardId, componentInstanceId, modelId) => embAna_GetStringValue(dashboardId) + embAna_GetStringValue(componentInstanceId) + embAna_GetStringValue(modelId); const embAna_getDashboardUniqueId = (aDashboard, modelId) => embAna_getUniqueId(aDashboard.id, aDashboard.componentInstanceId, modelId); embAna_hideDone = true; embAna_observerTargetNode = document.documentElement; const embAna_observerOptions = { childList: true, attributes: false, subtree: false } embAna_stylingObserver = null; class LogiDashboard { constructor(dashboardId, modelId, sysproProgram) { this.dashboardId = dashboardId; this.modelId = modelId; this.uuid = embAna_getDashboardUuid(dashboardId, modelId); this.dashboard = null; this.logiScript = null; this.active = false; this.name = ""; this.sysproProgram = sysproProgram; this.componentInstanceId = null; this.filterArray = null; } embAna_setDashboard(aDashboard) { if (embAna_isNotNullCheck(this.componentInstanceId)) { return; } this.dashboard = aDashboard; this.name = aDashboard.name; this.componentInstanceId = aDashboard.componentInstanceId; this.filterArray = null; } embAna_setScript(script) { this.logiScript = script; } setFilterArray(filterArray) { this.filterArray = filterArray; } clearFilterArray() { this.filterArray = null; } noFilter() { return this.filterArray == null; } filtersChanged(filters) { if (this.noFilter()) { this.setFilterArray(filters); return true; } if (embAna_compareArrays(filters, this.filterArray)) { return false; } this.setFilterArray(filters); return true; } get embAna_isSet() { return embAna_isNotNullCheck(this.dashboard); } get embAna_isNotSet() { return embAna_isNullCheck(this.dashboard); } get Ids() { return this.embAna_isSet ? embAna_getDashboardByIds(this.dashboard.id, this.dashboard.componentInstanceId) : null; } get UniqueId() { return this.mbAna_isSet ? embAna_getUniqueId(this.dashboard.id, this.dashboard.componentInstanceId, this.modelId) : null; // if (embAna_isNullCheck(this.dashboard)) { // return null; // } // return embAna_getUniqueId(this.dashboard.id, this.dashboard.componentInstanceId, this.modelId); } get UniqueIdByModel() { return embAna_getDashboardUuid(this.dashboardId, this.modelId); } static GetName(dashboardId) { try { if (embAna_isNullOrEmptyCheck(dashboardId) || embAna_InValidArray(logiDashboards)) { return null; } const dashboard = logiDashboards.find(f => f.dashboardId === dashboardId); if (embAna_isNullCheck(dashboard)) { return ""; } return dashboard.name; } catch(ex) { console.log("LogiDashboard class GetName() exception: " + ex.message); } } static GetDashboard(dashboardId, modelId) { try { if (embAna_isNullOrEmptyCheck(dashboardId) || embAna_isNullOrEmptyCheck(modelId) || embAna_InValidArray(logiDashboards)) { return null; } const dashboard = logiDashboards.find(f => f.dashboardId === dashboardId && f.modelId === modelId); if (embAna_isNullCheck(dashboard)) { return null; } return dashboard; } catch(ex) { console.log("LogiDashboard class GetDashboard() exception: " + ex.message); } } static GetVisualDashboard(visual) { try { if (embAna_isNullCheck(visual)) { return null; } const modelId = embAna_findElementLogiDivId(visual); const dashboardId = embAna_getVisualDashboardId(visual); return LogiDashboard.GetDashboard(dashboardId, modelId); } catch(ex) { console.log("LogiDashboard class GetVisualDashboard() exception: " + ex.message); } } } const embAna_assignDashboard = (aDashboard) => { //let dashboard = logiDashboards.find(f => f.dashboardId === aDashboard.id); //let dashboard = logiDashboards.find(f => f.UniqueIdByModel === embAna_getDashboardUuid(aDashboard.id, modelId) let dashboard = logiDashboards.find(f => f.dashboardId === aDashboard.id && f.componentInstanceId === null); if (embAna_isNotNullCheck(dashboard)) { dashboard.embAna_setDashboard(aDashboard); embAna_canLoadDashboard(dashboard.modelId, true); } } const embAna_getVisualDashboardId = (visual) => visual.config.tags.dashboardId; const embAna_getVisualId = (visual) => visual.config.tags.visualizationId; let embAna_logiBaseUrl = null; let embAna_logiUserAccessToken = null; const embAna_logiBaseUrlIsSet = () => embAna_isNotNullCheck(embAna_logiBaseUrl); const embAna_logiUserAccessTokenIsSet = () => embAna_isNotNullCheck(embAna_logiUserAccessToken); const embAna_logiIsSet = () => embAna_logiBaseUrlIsSet() && embAna_logiUserAccessTokenIsSet(); const embAna_logiApiTrustedAccessTokenUrl = "api/trusted-access/token"; const embAna_logiEmbedJS = "embed/embed.js"; const embAna_logiEmbedDataName = "composer-embed"; let logiDashboards = []; let embAna_visuals = []; let embAna_orgVisuals = []; let embAna_docKeyValue = ""; let allDashboardData = null; let busyDashboards = []; let embAna_callStackCount = 0; function embAna_Sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function embAna_Style() { try { let logiModalRoot = document.getElementById("logi-modal-root"); if (embAna_isNotNullCheck(logiModalRoot)) { logiModalRoot.style.zIndex = 9999999; } } catch(ex) { console.log("embAna_Style() exception: " + ex.message); } } function embAna_RemoveFlickerStyle() { try { let elements = document.querySelectorAll('.css-1g7kyxl'); elements.forEach(function(element) { element.style.overflow = 'unset'; }); } catch(ex) { console.log("embAna_RemoveFlicker() exception: " + ex.message); } } async function embAna_HideVisualSaveButtonAsync() { //embAna_hideDone = false; let i = 1; //while (!embAna_hideDone && i <= 1) while (i <= 1) { ++i; await embAna_Sleep(2000); embAna_HideVisualSaveButton(); await embAna_Sleep(2500); embAna_HideVisualSaveButton(); await embAna_Sleep(4000); embAna_HideVisualSaveButton(); } //embAna_hideDone = true; } async function embAna_HideVisualSaveButton() { try { let buttonElements = document.getElementsByTagName("button"); if (embAna_isNullCheck(buttonElements)) { return; } for (let i = 0, len = buttonElements.length; i < len; i++) { let name = buttonElements[i].getAttribute("name"); if (embAna_isNullCheck(name) || name.toLowerCase() !== "fullscreen_min") { continue; } if (buttonElements[i].classList.contains("bp3-button") && buttonElements[i].classList.contains("bp3-minimal") && buttonElements[i].classList.contains("bp3-small")) { buttonElements[i].style.display = "none"; if (embAna_isNullCheck(buttonElements[i].parentElement)) { continue; } buttonElements[i].parentElement.style.display = "none"; } } } catch(e) { console.error("$$$ embAna_HideVisualSaveButton error: " + e.message) ; } } function embAna_Styling (count) { try { } catch { //Does nothing by default } } const LogiGetUUID = (factor) => { if (embAna_isNullCheck(factor) || typeof(factor) !== 'number') { factor = 2; } let result = ""; for(let i = 1; i <= factor; i++) { result += String(Math.random()); } return "I" + result; } const LogiScriptId = (modelId) => { return "script" + modelId; } const LogiDivId = (logiDashboardId) => { return "logiDiv" + logiDashboardId; } const LogiDashboardId = (name) => { if (embAna_isNullCheck(allDashboardData)) { return null; } let result = allDashboardData.find(f => f.name.toLowerCase() === name.toLowerCase()); if (embAna_isNotNullCheck(result)) { return result.id; } return null; } const embAna_AvantiInDesignMode = () => { return sysproInterop.isInAppBuilder; } const LogiDashboardTheme = () => { return "modern"; } const LogiDashboardEditor = () => { return '"header": false, "breadcrumb": true, "title": true'; } window.logiGetToken = async function logiGetToken() { embAna_ComposerBaseUrl(); var result = await LogiGetAccessToken(); return result; } const embAna_GetAllDashboardsFromComposer = (refresh, call, logiDashboardId, dashboardDivId, modelId) => { refresh = embAna_isNullCheck(refresh) || refresh === true || embAna_isNullCheck(allDashboardData); if (refresh) { allDashboardData = null; $.ajax({ url: embAna_ComposerBaseUrl() + "api/dashboards?fields=name", type: 'GET', headers: {"Authorization": "Bearer " + embAna_logiUserAccessToken} }).done( function(data) { allDashboardData = data.content; if (embAna_isNotNullCheck(call)) { call(logiDashboardId, dashboardDivId, modelId); } }); } else { if (embAna_isNotNullCheck(call)) { call(logiDashboardId, dashboardDivId, modelId); } } } const embAna_GetAllDashboardsFromSEAQRY = (refresh, call, logiDashboardId, dashboardDivId, modelId) => { refresh = embAna_isNullCheck(refresh) || refresh === true || embAna_isNullCheck(allDashboardData); console.log("embAna_GetAllDashboardsFromSEAQRY START"); refresh = embAna_isNullCheck(refresh) || refresh === true || embAna_isNullCheck(allDashboardData) || allDashboardData.length === 0; if (refresh) { allDashboardData = []; let xmlIn = LogiSEAQRYdashboardxml(); sysproInterop.callBusinessObject("query", "SEAQRY", xmlIn, "", (result) => { console.log("embAna_GetAllDashboardsFromSEAQRY (for dashboards) BO call SUCCESS"); parser = new DOMParser(); xmlDoc = parser.parseFromString(result.XmlOut, "text/xml"); let dashBoardElements = xmlDoc.getElementsByTagName("Dashboard"); for (i = 0; i < dashBoardElements.length; i++) { let nameElement = dashBoardElements[i].getElementsByTagName("Name")[0]; let idElement = dashBoardElements[i].getElementsByTagName("Id")[0]; if (embAna_isNotNullCheck(nameElement) && embAna_isNotNullCheck(idElement)) { let dashboardData = { "name": "the_name", "id": "the_id"}; dashboardData.name = nameElement.childNodes[0].nodeValue; dashboardData.id = idElement.childNodes[0].nodeValue; allDashboardData.push(dashboardData); } } if (embAna_isNotNullCheck(call)) { call(refresh, logiDashboardId, dashboardDivId, modelId); } }, function(error) { console.log("embAna_GetAllDashboardsFromSEAQRY busniess call ERROR: " + error); sysproInterop.handleError(error.ErrorMessage, "Loading embedded analytics card."); }, true, true); } else { if (embAna_isNotNullCheck(call)) { call(refresh, logiDashboardId, dashboardDivId, modelId); } } } const embAna_inHomePage = () => { let inHomeMenuPage = false; let currentLayout = ""; currentLayout = sysproInterop.layoutStack[sysproInterop.layoutStack['length'] - 1]; //Todo: Remove the comments on these 2 lines below - WebView Testing //inHomeMenuPage = currentLayout.toUpperCase().includes("IMPMEN"); // inHomeMenuPage = currentLayout.toUpperCase() === "IMPMENLZ"; // return inHomeMenuPage; } const embAna_recentHome = () => { if (embAna_inHomePage()) { return true; } const prevIdx = sysproInterop.layoutStack['length'] > 1 ? sysproInterop.layoutStack['length'] - 2 : 1; return sysproInterop.layoutStack[sysproInterop.layoutStack['length'] - prevIdx].toUpperCase() === "IMPMENLZ"; } const embAna_inModalWindow = () => { try { return sysproInterop.modalWindowHolder.length > 0; } catch(ex) { console.error("embAna_inModalWindow error: " + ex.message); return false; } } sysproInterop.modalWindowHolder const embAna_currentProgram = () => { try { return sysproInterop.layoutStack[sysproInterop.layoutStack['length'] - 1]; } catch(e) { console.error("embAna_currentProgram() error: " + e.message); return ""; } } const embAna_canLoadDashboard = (modelId, dashboardLoaded) => { let index = busyDashboards.indexOf(modelId); if (index > -1) { if (dashboardLoaded) { busyDashboards.splice(index, 1); console.log("$$$ embAna_canLoadDashboard is true by deletion"); return true; } console.log("$$$ embAna_canLoadDashboard is false"); return false; } busyDashboards.push(modelId); console.log("$$$ embAna_canLoadDashboard is true"); return true; } const embAna_RemoveComp = (componentInstanceId) => { try{ if (embAna_isNullCheck(componentInstanceId)) { return; } let theMethod = window["embAna_removeComponent"]; if (embAna_isNotNullCheck(theMethod)) { theMethod(componentInstanceId); } } catch(e){ console.error("$$$embAna_RemoveComp error: " + e.message); } } const embAna_isNewMenuNavigation = () => { console.log("$$$ embAna_isNewMenuNavigation - START"); if (embAna_callStackCount < sysproInterop.layoutStack.length) { console.log("$$$ embAna_isNewMenuNavigation - TRUE"); embAna_callStackCount = sysproInterop.layoutStack.length return true; } console.log("$$$ embAna_isNewMenuNavigation - FALSE"); return false; } const embAna_canRemoveDashboards = () => { console.log("$$$ embAna_canRemoveDashboards - START"); if (embAna_callStackCount < sysproInterop.layoutStack.length) { for (var index = embAna_callStackCount; index < sysproInterop.layoutStack.length; index++) { let programNameStartWith = sysproInterop.layoutStack[index].substring(0, 6).toUpperCase(); if (programNameStartWith === "IMPMEN") { embAna_callStackCount = sysproInterop.layoutStack.length console.log("$$$ embAna_canRemoveDashboards - TRUE"); return true; } } } embAna_callStackCount = sysproInterop.layoutStack.length console.log("$$$ embAna_canRemoveDashboards - FALSE"); return false; } const embAna_RemoveAllComp = () => { try{ console.log("$$$ embAna_RemoveAllComp - START"); embAna_clearFilters(); embAna_clearFilterData(); if (embAna_isNullCheck(logiDashboards)) { return; } let theMethod = window["embAna_removeComponent"]; if (embAna_isNullCheck(theMethod)) { return; } logiDashboards.forEach(logiDashboard => { logiDashboard.active = false; let dashboard = logiDashboard.dashboard; if (embAna_isNullCheck(dashboard)) { return; } let componentInstanceId = dashboard.componentInstanceId; let theMethod = window["embAna_removeComponent"]; if (embAna_isNotNullCheck(theMethod)) { theMethod(componentInstanceId); } }); logiDashboards = []; console.log("$$$ embAna_RemoveAllComp - END"); } catch(e){ console.error("$$$embAna_RemoveComp error: " + e.message); } } const embAna_RemoveDashboards = (force) => { console.log("$$$ embAna_RemoveDashboards - START"); //let canRemove = (embAna_inModalWindow() === false && embAna_isNewMenuNavigation()) //if (canRemove || force) { //if (embAna_inHomePage() || force) { if (force || embAna_canRemoveDashboards()) { embAna_RemoveAllComp(); } console.log("$$$ embAna_RemoveDashboards - END"); } const embAna_AddDashboard = (properties, htmlElement) => { try { console.log("$$$ properties:" + properties); let theMethod = window["embAna_createComponent"]; if (embAna_isNotNullCheck(theMethod)) { theMethod(properties, htmlElement); } } catch(e){ console.error("$$$embAna_AddDashboard error: " + e.message); } } const embAna_LogiDashboardScript = (logiDashboardId, dashboardDivId, modelId) => { if (!logiDashboardId) { console.log("$$$ embAna_LogiDashboardScript: The dashboard id is not set" ); return; } embAna_RemoveDashboards(); embAna_CallSEAQRY(false, embAna_LogiDashboardScriptInt, null, embAna_GetAllDashboardsFromSEAQRY, logiDashboardId, dashboardDivId, modelId); } const embAna_getTheme = () => { try { let docElement = document.body; let theme = docElement.getAttribute("data-theme"); if (embAna_isNotNullCheck(theme)) { if (theme.includes("dark")) { return "dark"; } } } catch(e) { console.error("embAna_getTheme error: " + e.message); return "modern"; } return "modern"; } const embAna_DashboardCanBeRendered = (logiDashboardName, logiDashboardId, dashboardDivId, modelId) => { let canbeRendered = !((embAna_isNullCheck(logiDashboardId) || embAna_isNullCheck(embAna_logiBaseUrl) || embAna_isNullCheck(dashboardDivId) || embAna_isNullCheck(modelId))); if (!canbeRendered) { console.log(`$$$ Dashboard can't be rendered: Dashboard name: ${logiDashboardName}, Dashboard Id: ${logiDashboardId}, SEAUrl: ${embAna_logiBaseUrl}, dashboardDivId: ${dashboardDivId}, modelId: ${modelId}`); } return canbeRendered; } embAna_DashboardCanNOTBeRendered = (logiDashboardName, logiDashboardId, dashboardDivId, modelId) => !(embAna_DashboardCanBeRendered(logiDashboardName, logiDashboardId, dashboardDivId, modelId)); const embAna_LogiDashboardScriptInt = (refresh, logiDashboardName, dashboardDivId, modelId) => { console.log("$$$ embAna_LogiDashboardScriptInt (NOTE: Internal)"); let logiDashboardId = LogiDashboardId(logiDashboardName); let canNOTRenderDashboard = embAna_DashboardCanNOTBeRendered(logiDashboardName, logiDashboardId, dashboardDivId, modelId); if (canNOTRenderDashboard) { let logiDivTemp = document.getElementById(dashboardDivId); $("#" + dashboardDivId).empty(); let hElement = document.createElement("h4"); hElement.innerText = `Dashboard not found: ${logiDashboardName}`; hElement.classList.add("sys-mg-off-t"); hElement.classList.add("sys-mg-b-5"); logiDivTemp.appendChild(hElement); return; } //if (embAna_isNullCheck(logiDashboardId) || embAna_isNullCheck(embAna_logiBaseUrl) || embAna_isNullCheck(dashboardDivId) || embAna_isNullCheck(modelId)) { //return; //} //let canAdd = embAna_canLoadDashboard(modelId); //if (!canAdd) { // return; //} //let existingDashboard = logiDashboards.find(f => f.uuid === embAna_getDashboardUuid(logiDashboardId, modelId)); let existingDashboard = logiDashboards.find(f => f.UniqueIdByModel === embAna_getDashboardUuid(logiDashboardId, modelId) && f.componentInstanceId !== null); let dashboardAlreadyCreated = embAna_isNotNullCheck(existingDashboard); if (!dashboardAlreadyCreated) { existingDashboard = new LogiDashboard(logiDashboardId, modelId, embAna_currentProgram()); logiDashboards.push(existingDashboard); } existingDashboard.active = true; if (embAna_isNotNullCheck(existingDashboard) && embAna_isNotNullCheck(existingDashboard.dashboard)) { embAna_RemoveComp(existingDashboard.dashboard.componentInstanceId); //todo: remove filters? } //if (dashboardAlreadyCreated) { //Do not re-create the dashboard //embAna_ReloadDashboards(modelId); //embAna_AddDashboardFilter(existingDashboard); Filtering not used in this phase based on key fields //return; //} let logiTheme = embAna_getTheme(); let logiDiv = document.getElementById(dashboardDivId); const designerFilterMappings = embAna_GetDesignerFilterMappings(logiDiv); const dashboardFilterMappings = embAna_createMappingFromDesignerObject(designerFilterMappings); //let _deleteScript = document.getElementById(LogiScriptId(modelId)); //if (embAna_isNotNullCheck(_deleteScript)) { // _deleteScript.remove(); //} $("#" + dashboardDivId).empty(); let js = { "dashboardId": logiDashboardId, "theme":logiTheme, }; //embAna_addDashboardFilterMapping(logiDashboardId, dashboardFilterMappings); embAna_addDashboardFilterMapping(existingDashboard, dashboardFilterMappings); const embedSettings = embAna_ApplyEmbedSettings(existingDashboard, embAna_getEmbedSetting()); js = Object.assign(js, embedSettings); console.log(js); embAna_AddDashboard(js, logiDiv); //let jsScript = JSON.stringify(js); //embAna_AddDashboard(jsScript, logiDiv); //jsScript = jsScript.replace("the_dashboard_id", logiDashboardId); //jsScript = jsScript.replace("the_theme_logi", logiTheme); // let theScript = document.createElement('script'); // theScript.id = LogiScriptId(); // theScript.setAttribute('data-name', embAna_LogiEmbedDataName()); // theScript.setAttribute('src', embAna_LogiEmbedJS()); // console.log(jsScript); // theScript.textContent = jsScript; // let logiDiv = $("#" + dashboardDivId); // if (embAna_isNotNullCheck(logiDiv) && embAna_isNotNullCheck(logiDiv[0])) { // existingDashboard.embAna_setScript(jsScript); // logiDiv[0].appendChild(theScript); // } } const embAna_FindCardDivElement = (logiDivElement) => { if (embAna_isNullCheck(logiDivElement)) { return null; } const parentDiv = logiDivElement.closest('div[data-cardtypedetail="LogiDashboard"]'); return parentDiv; } const embAna_FindChildCardConfigElement = (parentElement) => { if (embAna_isNullCheck(parentElement)) { return null; } const firstChildElement = parentElement.querySelector('.card-config'); return firstChildElement; } const embAna_GetCardConfigObject = (cardConfigElement) => { if (embAna_isNullCheck(cardConfigElement)) { return null; } const cardConfigRaw = cardConfigElement.getAttribute('data-card-config'); if (embAna_isNullOrEmptyCheck(cardConfigRaw)) { return null; } return JSON.parse(atob(cardConfigRaw)); } const embAna_GetDesignerFilterMappings = (logiDivElement) => { try { const cardElement = embAna_FindCardDivElement(logiDivElement); if (embAna_isNullCheck(cardElement)) { return null; } const cardConfigElement = embAna_FindChildCardConfigElement(cardElement); const cardConfigObject = embAna_GetCardConfigObject(cardConfigElement); return embAna_DesignerFilterMappingsSetByUser(cardConfigObject); } catch(ex) { console.error("embAna_GetDesignerFilterMappings() function exception: " + ex.message); } } const embAna_DesignerFilterMappingsSetByUser = (cardConfigArray) => { try { if (embAna_InValidArray(cardConfigArray)) { return null; } for (const obj of cardConfigArray) { const isSysproFieldIsSet = embAna_isNotNullOrEmptyCheck(obj.SysproField); const isDashboardFieldIsSet = embAna_isNotNullOrEmptyCheck(obj.DashboardField); if (isSysproFieldIsSet || isDashboardFieldIsSet) { return cardConfigArray; } } return null; } catch(ex) { console.error("embAna_DesignerFilterMappingsSetByUser() function exception: " + ex.message); } } const embAna_ReloadDashboards = () => { console.log("$$$embAna_ReloadDashboards"); if (embAna_isNullCheck(logiDashboards)) { return; } logiDashboards.forEach(logiDashboard => { let dashboardDivId = null; if (embAna_isNotNullCheck(logiDashboard.modelId)) { dashboardDivId = LogiDivId(logiDashboard.modelId); console.log("$$$" + dashboardDivId); } let logiDiv = document.getElementById(dashboardDivId); if (embAna_isNullCheck(logiDiv) || logiDiv.innerHTML.trim().length !== 0) { return; } let _deleteScript = document.getElementById(LogiScriptId(logiDashboard.modelId)); if (embAna_isNotNullCheck(_deleteScript)) { _deleteScript.remove(); } let theScript = document.createElement('script'); theScript.id = LogiScriptId(logiDashboard.modelId); theScript.setAttribute('data-name', embAna_LogiEmbedDataName()); theScript.setAttribute('src', embAna_LogiEmbedJS()); theScript.textContent = logiDashboard.logiScript; if (embAna_isNotNullCheck(logiDiv)) { if (embAna_isNotNullCheck(logiDiv[0])) { logiDiv[0].appendChild(theScript); } else { logiDiv.appendChild(theScript); } } //embAna_canLoadDashboard(logiDashboard.modelId, true); }); } function embAna_AddDashboardFilter(logiDashboard) { if (embAna_isNullCheck(logiDashboard)) { return; } let predictiveSearchElements = document.getElementsByClassName('syspro-browse-button'); if (embAna_isNullCheck(predictiveSearchElements)) { return; } let predictiveSearchElement = predictiveSearchElements[0]; if (embAna_isNullCheck(predictiveSearchElement)) { return; } let sysproKeyField = predictiveSearchElement.getAttribute("data-predictivesearchfield"); if (embAna_isNullCheck(sysproKeyField)) { return; } let keyCodeValue = ""; for (var i = 0; i < embAna_visuals.length; i++) { keyCodeValue = embAna_setEAVisualFilter(embAna_visuals[i], sysproKeyField, embAna_orgVisuals[i]); } embAna_docKeyValue = keyCodeValue; } const embAna_setEAVisualFilter = (visual, sysproKeyField, orgVisual) => { let logiKeyField = sysproKeyField.toLowerCase(); let keyCodeValue = sysproInterop.getGlobalValue(sysproKeyField); if (embAna_isNullCheck(keyCodeValue) || keyCodeValue.trim() === "") { return keyCodeValue; //Todo: Another option here might be to reload the dashboard } if (keyCodeValue === embAna_docKeyValue) { return keyCodeValue; } let visualField = visual.getAllFields().find(f => f.name.toLowerCase() === sysproKeyField.toLowerCase()); if (embAna_isNullCheck(visualField)) { return; //Do not attempt to set filters for fields that does not exist on the visual } let oldFilter = orgVisual.find(x => x.path.name === logiKeyField); if (embAna_isNotNullCheck(oldFilter)) { //visual.filters.remove(oldFilter); Does not work let oldItem = visual.filters.get().find(g => g.path === oldFilter.path.name && g.operation === oldFilter.operation) if (embAna_isNotNullCheck(oldItem)) { visual.filters.remove(oldItem); } let index = orgVisual.indexOf(oldFilter); if (index >= 0) { orgVisual.splice(index, 1); } } var filterby = { path: { name: logiKeyField }, operation: 'EQUALS', value: keyCodeValue }; orgVisual.push(filterby); visual.filters.add(filterby); return keyCodeValue; } const LogiDashboardReady = (e) => { //debugger; //embAna_AddDashboardFilter(e.detail.dashboard); //embAna_applyFilters(); embAna_RemoveFlickerStyle(); } const LogiDashboardLoaded = (e) => { //debugger; embAna_removeDashboardVisuals(e.detail.dashboard); embAna_assignDashboard(e.detail.dashboard); //embAna_addDashboardFilterMapping(e.detail.dashboard.id, mainMapping); $(document).off('click.dropdown.data-api'); try { embAna_setCloseSYSPRO(); embAna_Style(); embAna_HideVisualSaveButtonAsync(); } catch(ex) { console.error("LogiDashboardLoaded function exception: " + ex.message); } } const embAna_Loaded = (e) => { try { embAna_HideVisualSaveButton(); } catch(e) { console.error("$$$ embAna_Loaded error: " + e.message); } } const LogiVisualLoaded = (e) => { embAna_addDashboardVisual(e.detail.visualization); embAna_applyVisualFilterData(e.detail.visualization); //embAna_visuals.push(e.detail.visualization); //embAna_orgVisuals.push([]); } window.removeEventListener('composer-visual-loaded', LogiVisualLoaded); window.addEventListener('composer-visual-loaded', LogiVisualLoaded); window.removeEventListener('composer-dashboard-loaded', LogiDashboardLoaded); window.addEventListener('composer-dashboard-loaded', LogiDashboardLoaded); window.removeEventListener('composer-dashboard-ready', LogiDashboardReady); window.addEventListener('composer-dashboard-ready', LogiDashboardReady); let logiTokenPromise = () => new Promise(function(resolve, reject) { try { let result = {access_token: embAna_logiUserAccessToken, expires_in: 35999, token_type: "Bearer"} resolve(result); } catch(ex) { reject("logiTokenPromise error: " + ex.message) } }); const embAna_ComposerBaseUrl = () => { return embAna_logiBaseUrl; } const embAna_LogiApiTrustedAccessTokenUrl = () => embAna_ComposerBaseUrl() + embAna_logiApiTrustedAccessTokenUrl; const embAna_LogiEmbedJS = () => embAna_ComposerBaseUrl() + embAna_logiEmbedJS; const embAna_LogiEmbedDataName = () => embAna_logiEmbedDataName; const embAna_GetCurrentAvantiOperator = () => sysproInterop.currentUserSession.OperatorInternal; const embAna_GetCurrentLogiUser = () => { return "SysproAdmin"; //Todo: Get this from SYSPRO settings } const GetLogiClient = () => { var result = 'ab0e31c7-07c1-41a6-a2a6-c19b4faeb5e7'; //Local host return result; //Todo: Get this from SYSPRO settings } const GetLogiClientSecret = () => { var result = 'ri2eQhGuFB39gmNx2wduNYGGRwKZi82suVUd'; //Todo: Get this from SYSPRO settings //Local host return result; } async function LogiGetAccessToken(callback) { let result = await logiTokenPromise(); return result; } const LogiAccessTokenValue = () => { var result = LogiGetAccessToken(); return result; } const embAna_Post = async(AuthCreds, ReqUrl, ReqBody) => { return await fetch(ReqUrl, { method: 'POST', headers: { 'Accept': 'application/vnd.composer.v2+json', 'Content-Type': 'application/vnd.composer.v2+json', 'Authorization': `Basic ${AuthCreds}` }, body: JSON.stringify(ReqBody) }).then(x=>x.json()); } const PostLogi = async(AuthCreds, ReqUrl, ReqBody) => { return await fetch(ReqUrl, { method: 'POST', headers: { 'Accept': 'application/vnd.composer.v2+json', 'Content-Type': 'application/vnd.composer.v2+json', 'Authorization': `Basic ${AuthCreds}` }, body: JSON.stringify(ReqBody) }).then(x=>x.json()); } const getToken = (AuthCreds, ComposerUrl, Username, callback) => { AccessToken(ComposerUrl, Username, AuthCreds, (err, result) => { if(result) callback(err, result); else { AccessClient(AuthCreds, ComposerUrl, (err, result) => { if(err) callback(err, result) else { AccessToken(ComposerUrl, Username, (err, result) => { callback(err, result); }); } }); } }); } /********REQUEST TRUSTED ACCESS TOKEN ********/ const AccessToken = (ComposerUrl, Username, AuthCreds, callback) => { var Client = GetLogiClient(); if(embAna_isNullCheck(Client)) callback({ErrorMessage: 'Client Not Found', status : 500}); else { //var BasicAuth = btoa(clientId + ":" + clientSecret); embAna_Post(AuthCreds, `${ComposerUrl}/api/trusted-access/token`, { "username": Username }).then((result) => { if(JSON.stringify(result).indexOf('error')>-1) callback(result, null); else callback(null, result); }); } }; const embAna_TrustedAccess = (req, res, next) => { if(embAna_isNotNullCheck(req.session.AccessResult)) next(); else { var AuthCreds = Buffer.from(`${req.session.Config.ClientCreds.user}:${req.session.Config.ClientCreds.password}`).toString('base64'); getToken(AuthCreds, req.session.Config.ComposerUrl, req.session.Config.LoginAs || 'admin', (err, result) => { if(err) console.log(err); else req.session.AccessResult = result; next(); }); } } const embAna_InitClient = (AuthCreds, ComposerUrl, ClientName, callback) => { Get(`${ComposerUrl}/api/trusted-access/clients`, AuthCreds, 'Basic').then((clients) => { var c = embAna_isNullCheck(clients.content) ? [] : clients.content.filter(c=>c.client_name.indexOf(ClientName) > -1); if(c.length>0) Delete(AuthCreds, `${ComposerUrl}/api/trusted-access/clients/${c[0].client_id}`).then((result) => { callback(null, "finished"); }); else callback(null, clients); }); }; //Added the refresh paramater to cater for token refreshing - possible future development const embAna_CallSEAQRY = (refresh, successCall, errorCall, logiApiCall, logiDashboardId, dashboardDivId, modelId) => { console.log("embAna_CallSEAQRY START"); refresh = embAna_isNullCheck(refresh) || refresh === true || embAna_isNullCheck(allDashboardData); if (refresh) { let xmlIn = LogiSEAQRYxml(); sysproInterop.callBusinessObject("query", "SEAQRY", xmlIn, "", (result) => { console.log("embAna_CallSEAQRY BO call SUCCESS"); parser = new DOMParser(); xmlDoc = parser.parseFromString(result.XmlOut, "text/xml"); let rootElement = xmlDoc.children[0]; let generalElement = embAna_getFirstNodeByName(rootElement, "General"); if (embAna_isNotNullCheck(generalElement)) { let endPointElement = embAna_getFirstNodeByName(generalElement, "Endpoint"); let userTokenElement = embAna_getFirstNodeByName(generalElement, "UserToken"); if (embAna_isNotNullCheck(endPointElement)) { embAna_logiBaseUrl = endPointElement.textContent.trim(); if (!embAna_logiBaseUrl.endsWith("/")) { embAna_logiBaseUrl = embAna_logiBaseUrl + "/"; } } if (embAna_isNotNullCheck(userTokenElement)) { embAna_logiUserAccessToken = userTokenElement.textContent; embAna_addLogiScript(); //embAna_addEmbedManagerPromiseScript(); //embAna_addEmbedManagerScript(); if (embAna_isNotNullCheck(logiApiCall)) { logiApiCall(refresh, successCall, logiDashboardId, dashboardDivId, modelId); } else if (embAna_isNotNullCheck(successCall)) { successCall(refresh, logiDashboardId, dashboardDivId, modelId); } } } }, function(error) { console.log("embAna_CallSEAQRY BO call ERROR: " + error); if (embAna_isNullCheck(embAna_logiBaseUrl)) { embAna_logiBaseUrl = "unknown"; } if (embAna_isNotNullCheck(errorCall)) { errorCall(); } sysproInterop.handleError(error.ErrorMessage, "Loading embedded analytics card."); }, true, true); } else { if (embAna_isNotNullCheck(logiApiCall)) { logiApiCall(refresh, successCall, logiDashboardId, dashboardDivId, modelId); } else if (embAna_isNotNullCheck(successCall)) { successCall(refresh, logiDashboardId, dashboardDivId, modelId); } } } const embAna_CallSEATCF = (type, componentId) => { console.log("embAna_CallSEATCF START"); let xmlIn = LogiSEATCFxml(type, componentId); let paramXml = LogiSEATCFParamxml(); sysproInterop.callBusinessObject("post", "SEATCF", xmlIn, paramXml, (result) => { console.log("embAna_CallSEATCF BO call SUCCESS"); }, function(error) { console.log("embAna_CallSEATCF BO call ERROR: " + error); sysproInterop.handleError(error.ErrorMessage, "Call to SEATCF BO in embAna_CallSEATCF."); }, true, true); } const LogiSEAQRYxml = () => { let avantiOper = embAna_GetCurrentAvantiOperator(); //Todo: This variable must be used below return `User`; } const LogiSEAQRYdashboardxml = () => { return `dashboard`; } const LogiSEATCFxml = (type, componentId) => { return `AddPermissions${type}${componentId}`; } const LogiSEATCFParamxml = () => { return "NN"; } const embAna_getFirstNodeByName = (aNode, nodeName) => { if (embAna_isNullCheck(aNode) || embAna_isNullCheck(nodeName)) { return null; } if (embAna_isNotNullCheck(aNode.tagName) && aNode.tagName.toLowerCase() == nodeName.toLowerCase()) { return aNode; } let result = null; if (aNode.hasChildNodes()) { let total = aNode.childElementCount; let index = 0; while (embAna_isNullCheck(result) && index < total) { let currentNode = aNode.children[index]; result = embAna_getFirstNodeByName(currentNode, nodeName); if (embAna_isNotNullCheck(result)) { return result; } ++index; } } return null; } const embAna_logiMessage = (eventInfo) => { console.log("$$$ embAna_logiMessage - START"); let data = eventInfo.data; if (embAna_isNotNullCheck(data) && (data.Name === "mousedown")) { sysproInterop.lastActivityDateTime = Date.now(); return; } if (embAna_isNotNullCheck(data) && embAna_isNotNullCheck(data.ObjectType)) { console.log("embAna_logiMessage " + data.Id + data.Name + data.Action + data.ObjectType); embAna_CallSEATCF(data.ObjectType.charAt(0).toUpperCase(), data.Id); } } const embAna_ApplySourcesReadAccess = (name, id) => { try { if (embAna_isNullCheck(name) ||embAna_isNullCheck(id)) { return; } const data = { Action: "Updated", ObjectType: "Dashboard", Name: `${name}`, Id: `${id}` }; const eventInfo = { data: { Action: "Updated", ObjectType: "Dashboard", Name: `${name}`, Id: `${id}` } }; embAna_logiMessage(eventInfo); } catch(ex) { console.error("embAna_ApplySourcesReadAccess function: Exeption: " + ex.message); } } const embAna_addEmbedManagerScript = () => { console.log("$$$embAna_addEmbedManagerScript - START"); let existingElement = document.getElementById("embedManagerScript"); if (embAna_isNotNullCheck(existingElement)) { console.log("$$$embAna_addEmbedManagerScript - Script already created"); return; } let scriptElement = document.createElement("script"); scriptElement.type = "text/javascript"; scriptElement.id = "embedManagerScript"; scriptElement.async = false; //scriptElement.setAttribute('data-name', embAna_LogiEmbedDataName()); //scriptElement.setAttribute('src', embAna_LogiEmbedJS()); let scriptCode = `async function embAna_removeComponent(componentInstanceId) { console.log("$$$ embAna_removeComponent - START"); let embedManager = await getEmbedManagerPromise; embedManager.removeComponent(componentInstanceId); console.log("$$$ embAna_removeComponent - Removed " + componentInstanceId); } async function embAna_createComponent(properties, htmlElement) { console.log("$$$ embAna_createComponent - START"); let embedManager = await getEmbedManagerPromise; let newDashboard = await embedManager.createComponent('dashboard', properties); newDashboard.render(htmlElement, {width: '100%', height: '100%'}); } ` try { scriptElement.appendChild(document.createTextNode(scriptCode)); //document.body.appendChild(scriptElement); document.body.insertBefore(scriptElement, document.body.children[2]); console.log("$$$embAna_addEmbedManagerScript - Added 1"); } catch (e) { scriptElement.text = scriptCode; document.body.appendChild(scriptCode); document.body.insertBefore(scriptCode, document.body.children[2]); console.log("$$$embAna_addEmbedManagerScript - Added 2"); } } const embAna_addEmbedManagerPromiseScript = () => { console.log("$$$embAna_addEmbedManagerPromiseScript - START"); let existingElement = document.getElementById("embedManagerPromiseScript"); if (embAna_isNotNullCheck(existingElement)) { console.log("$$$embAna_addEmbedManagerPromiseScript - Script already created"); return; } let scriptElement = document.createElement("script"); scriptElement.type = "text/javascript"; scriptElement.id = "embedManagerPromiseScript"; scriptElement.async = false; //scriptElement.onload = embAna_addEmbedManagerScript; //scriptElement.setAttribute('data-name', embAna_LogiEmbedDataName()); //scriptElement.setAttribute('src', embAna_LogiEmbedJS()); let scriptCode = `const getEmbedManagerPromise = window.initComposerEmbedManager({ getToken: function () { // transform for the embed syntax return getToken().then((result) => { // getToken function uses the Trusted Access API return { access_token: embAna_logiUserAccessToken, expires_in: 7200, }; }); }, }); async function embAna_removeComponent(componentInstanceId) { console.log("$$$ embAna_removeComponent - START"); let embedManager = await getEmbedManagerPromise; embedManager.removeComponent(componentInstanceId); console.log("$$$ embAna_removeComponent - Removed " + componentInstanceId); } async function embAna_createComponent(properties, htmlElement) { console.log("$$$ embAna_createComponent - START"); let embedManager = await getEmbedManagerPromise; let newDashboard = await embedManager.createComponent('dashboard', properties); newDashboard.render(htmlElement, {width: '100%', height: '100%'}); } ` try { scriptElement.appendChild(document.createTextNode(scriptCode)); //document.body.appendChild(scriptElement); document.body.insertBefore(scriptElement, document.body.children[1]); console.log("$$$embAna_addEmbedManagerPromiseScript - Added 1"); } catch (e) { scriptElement.text = scriptCode; //document.body.appendChild(scriptCode); document.body.insertBefore(scriptCode, document.body.children[1]); console.log("$$$embAna_addEmbedManagerPromiseScript - Added 2"); } } const embAna_addLogiScript = () => { //return; console.log("$$$embAna_addLogiScript - START"); let existingElement = document.getElementById("embedLogiScript"); if (embAna_isNotNullCheck(existingElement)) { console.log("$$$embAna_addLogiScript - Script already created"); return; } let scriptElement = document.createElement("script"); let scriptCode = ""; //scriptElement.type = "text/javascript"; scriptElement.id = "embedLogiScript"; scriptElement.setAttribute('data-name', embAna_LogiEmbedDataName()); scriptElement.setAttribute('src', embAna_LogiEmbedJS()); scriptElement.async = false; scriptElement.defer = false; scriptElement.onload = embAna_addEmbedManagerPromiseScript; try { //document.body.appendChild(scriptElement); scriptElement.appendChild(document.createTextNode(scriptCode)); document.body.insertBefore(scriptElement, document.body.firstChild); console.log("$$$embAna_addLogiScript - Added 1"); } catch (e) { scriptElement.text = scriptCode; //document.body.appendChild(scriptCode); document.body.insertBefore(scriptCode, document.body.firstChild); console.log("$$$embAna_addLogiScript - Added 2"); } } var embAna_codeStr; var embAna_codeStrNew; const embAna_setCloseSYSPRO = () => { try { if (embAna_isNotNullCheck(sysproInterop.closeSYSPROFusionInternal)) { console.log("$$$embAna_setCloseSYSPRO - Success - already set"); return; } embAna_codeStr = sysproInterop.closeSYSPROFusion.toString(); embAna_codeStrNew = " try { embAna_RemoveDashboards(true); } catch {} (e === null) ? sysproInterop.closeSYSPROFusionInternal(e) : setTimeout(function() { sysproInterop.closeSYSPROFusionInternal(e); } , 1500); " sysproInterop.closeSYSPROFusionInternal = new Function("e", embAna_codeStr.substring(embAna_codeStr.indexOf("{") + 1, embAna_codeStr.lastIndexOf("}"))); sysproInterop.closeSYSPROFusion = new Function("e", embAna_codeStrNew); console.log("$$$embAna_setCloseSYSPRO - Success"); } catch (e) { console.error("$$$embAna_setCloseSYSPRO - Failed with error: " + e.message); } } const embAna_findElementLogiDivId = (visual) => { if (embAna_isNullCheck(visual) || embAna_isNullCheck(visual.element)) { return null; } let logiDiv = embAna_findElementLogiDiv(visual.element); if (embAna_isNullCheck(logiDiv)) { //This condition should never hold as all Dashboards are rendered within a logiDiv from the Dashboard cards console.warn("embAna_findElementLogiDivId - LogiDiv not found for visual on Dashboard with id: " + embAna_getVisualDashboardId(visual)); return null; } return logiDiv.id.substring(7); } const embAna_findElementLogiDiv = (element) => { if (embAna_isNullCheck(element)) { return null; } let grandparent = element.parentNode.parentNode; while (grandparent) { if (grandparent.tagName === 'DIV' && grandparent.id.startsWith('logiDiv')) { return grandparent; } grandparent = grandparent.parentNode; } return null; } //const embAna_getAttributeValue = (element, attributeName) => { // if (element && element.hasAttribute(attributeName)) { // return element.getAttribute(attributeName); // } else { // return null; // } //} const embAna_getAttributeValue = (element, attributeName) => { return element && element.hasAttribute(attributeName) ? element.getAttribute(attributeName) : null; } const embAna_createMappingFromElement = (element) => { if (!element || !element.attributes) return null; const mappingObject = {}; const attributes = element.attributes; for (let i = 0; i < attributes.length; i++) { const name = attributes[i].name; const value = attributes[i].value; if (name.startsWith('data-appfield')) { const index = name.replace('data-appfield', ''); const dashFieldName = `data-dashfield${index}`; const dashFieldValue = embAna_getAttributeValue(element, dashFieldName); if (value && dashFieldValue) { mappingObject[value] = {dashField: dashFieldValue}; } } } return mappingObject; } const embAna_createMappingFromDesignerObject = (designerObject) => { try { if (embAna_ValidArray(designerObject) === false) return null; const mappingObject = {}; designerObject.forEach((designerMapping) => { if (embAna_isNotNullOrEmptyCheck(designerMapping.SysproField) && embAna_isNotNullOrEmptyCheck(designerMapping.DashboardField)) { mappingObject[designerMapping.SysproField] = {dashField: designerMapping.DashboardField}; } }); return mappingObject; } catch(ex) { console.error("embAna_createMappingFromDesignerObject function exception: " + ex.message); } } //const mainMapping = embAna_createMappingFromElement(document.getElementById("mapping-data")); const embAna_updateMapping = (mappingObject, keyFieldName, keyFieldValue) => { if (!mappingObject || !keyFieldName || !mappingObject[keyFieldName] || !keyFieldValue) { return null; } mappingObject[keyFieldName].keyFieldValue = keyFieldValue; return embAna_getMapping(mappingObject, keyFieldName); } const embAna_getMapping = (mappingObject, keyFieldName) => (mappingObject && keyFieldName) ? mappingObject[keyFieldName] : null; const embAna_getSyproKeyFieldValue = (keyFieldName) => sysproInterop.getGlobalValue(keyFieldName); const emebAna_createFilterObjectEquals = (mappingObject, keyFieldName) => { const mapping = embAna_getMapping(mappingObject, keyFieldName); return (mapping && keyFieldName) ? { path: mapping.dashField, operation: 'EQUALS', value: embAna_getSyproKeyFieldValue(keyFieldName) } : null; } const embAna_dashboardFilterMapping = {}; const embAna_addDashboardFilterMapping = (aLogiDashboard, mapping) => { //embAna_dashboardFilterMapping[dashboardId] = mapping; embAna_dashboardFilterMapping[aLogiDashboard.UniqueIdByModel] = mapping; aLogiDashboard.clearFilterArray(); console.log("embAna_addDashboardFilterMapping: Filters mapping added for " + aLogiDashboard.dashboardId + LogiDashboard.GetName(aLogiDashboard.dashboardId) + mapping); }; //const embAna_getDashboardFilterMapping = (dashboardId) => embAna_dashboardFilterMapping[dashboardId]; const embAna_getDashboardFilterMapping = (aLogiDashboard) => embAna_dashboardFilterMapping[aLogiDashboard.UniqueIdByModel]; const embAna_clearDashboardFilterMapping = () => { for (let dashboardId in embAna_dashboardFilterMapping) { delete embAna_dashboardFilterMapping[dashboardId]; } } const embAna_dashboardVisuals = {}; const embAna_addDashboardVisualOrg = (visual) => { const id = embAna_getVisualDashboardId(visual); const modelId = embAna_findElementLogiDivId(visual); const uuid = id + modelId; if (!embAna_dashboardVisuals[uuid]) { embAna_dashboardVisuals[uuid] = []; } embAna_dashboardVisuals[uuid].push(visual); } const embAna_addDashboardVisual = (visual) => { const id = embAna_getVisualDashboardId(visual); const visualId = embAna_getVisualId(visual); const modelId = embAna_findElementLogiDivId(visual); const uuid = id + modelId; if (!embAna_dashboardVisuals[uuid]) { embAna_dashboardVisuals[uuid] = []; } else { const existingVisualIndex = embAna_dashboardVisuals[uuid].findIndex((item) => embAna_getVisualId(item) === visualId); if (existingVisualIndex !== -1) { embAna_dashboardVisuals[uuid].splice(existingVisualIndex, 1); } } embAna_dashboardVisuals[uuid].push(visual); }; const embAna_removeDashboardVisuals = (dashboard) => { const id = dashboard.id; const modelId = embAna_findElementLogiDivId(dashboard); const uuid = id + modelId; if (!embAna_dashboardVisuals[uuid]) { embAna_dashboardVisuals[uuid] = []; delete embAna_dashboardVisuals[uuid]; } } //const embAna_getDashboardVisuals = (dashboardId) => { // return embAna_dashboardVisuals[dashboardId]; //|| []; //}; const embAna_getDashboardVisuals = (aLogiDashboard) => { return embAna_dashboardVisuals[aLogiDashboard.UniqueIdByModel]; //|| []; }; const embAna_clearDashboardVisuals = () => { for (const key in embAna_dashboardVisuals) { if (embAna_dashboardVisuals.hasOwnProperty(key)) { delete embAna_dashboardVisuals[key]; } } } //const embAna_getFiltersForDashboard = (dashboardId) => { // const dashboardFilterMapping = embAna_getDashboardFilterMapping(dashboardId); // // if (embAna_isNullCheck(dashboardFilterMapping)) { // return []; // } // const filters = []; // Object.keys(dashboardFilterMapping).forEach(key => { // embAna_updateMapping(dashboardFilterMapping, key, embAna_getSyproKeyFieldValue(key)); // filters.push(emebAna_createFilterObjectEquals(dashboardFilterMapping, key)); // }); // console.log("embAna_getFiltersForDashboard: Filters for dashboard " + dashboardId + LogiDashboard.GetName(dashboardId) + filters); // return filters; //} const embAna_getFiltersForDashboard = (aLogiDashboard) => { const dashboardFilterMapping = embAna_getDashboardFilterMapping(aLogiDashboard); if (embAna_isNullCheck(dashboardFilterMapping)) { return []; } const filters = []; Object.keys(dashboardFilterMapping).forEach(key => { embAna_updateMapping(dashboardFilterMapping, key, embAna_getSyproKeyFieldValue(key)); filters.push(emebAna_createFilterObjectEquals(dashboardFilterMapping, key)); }); console.log("embAna_getFiltersForDashboard: Filters for dashboard " + aLogiDashboard.dashboardId + LogiDashboard.GetName(aLogiDashboard.dashboardId) + filters); return filters; } const embAna_getFiltersForVisual = (visual) => embAna_getFiltersForDashboard(LogiDashboard.GetVisualDashboard(visual)); //const embAna_ApplyEmbedSettings = (dashboardId, embedSettings) => { // if (embAna_isNullCheck(dashboardId) || embAna_isNullCheck(embedSettings)) { // return embedSettings; // } // const dashboardFilterMapping = embAna_getDashboardFilterMapping(dashboardId); // return embAna_isNullCheck(dashboardFilterMapping) // ? embedSettings // : embAna_embedSettingsNoFiltering(embedSettings); //} const embAna_ApplyEmbedSettings = (aLogiDashboard, embedSettings) => { if (embAna_isNullCheck(aLogiDashboard) || embAna_isNullCheck(aLogiDashboard.dashboardId) || embAna_isNullCheck(embedSettings)) { return embedSettings; } const dashboardFilterMapping = embAna_getDashboardFilterMapping(aLogiDashboard); return embAna_isNullCheck(dashboardFilterMapping) ? embedSettings : embAna_embedSettingsNoFiltering(embedSettings); } const embAna_embedSettingsNoFiltering = (embedSettings) => { if (embAna_isNullCheck(embedSettings)) { return embedSettings; } try { embedSettings.interactivityOverrides.settings.FILTER = false; //Default value for embedSettings object is true embedSettings.interactivityOverrides.visualSettings.FILTER = false; //Default value for embedSettings object is true } catch(ex) { console.error("embAna_ApplyEmbedSettings() exception: " + ex.message); } finally { return embedSettings; } } const embAna_applyFilters = () => { try { console.log("embAna_applyFilters - START"); if (embAna_ValidArray(logiDashboards) === false) { console.log("embAna_applyFilters: No dashboards set"); return; } logiDashboards.forEach((dashboard) => { if (dashboard.active) { console.log("embAna_applyFilters(): Dashboard is active " + dashboard); //embAna_applyFiltersForDashboard(dashboard.dashboardId); embAna_applyFiltersForDashboard(dashboard); } else { console.log("embAna_applyFilters(): Dashboard is not active " + dashboard); } }); } catch(ex) { console.error("embAna_applyFilters() exception: " + ex.message); } } //const embAna_applyFiltersForDashboard = (dashboardId) => { // let filters = embAna_getFiltersForDashboard(dashboardId); // if (embAna_ValidArray(filters) === false) { // console.log("embAna_applyFiltersForDashboard(): No filters found for dashboard " + dashboardId + LogiDashboard.GetName(dashboardId)); // return; // } // const dashboardVisuals = embAna_getDashboardVisuals(dashboardId); // embAna_applyDashboardVisualsFilters(dashboardVisuals, filters); // filters = null; //} const embAna_applyFiltersForDashboard = (aLogiDashboard) => { let filters = embAna_getFiltersForDashboard(aLogiDashboard); if (embAna_ValidArray(filters) === false) { console.log("embAna_applyFiltersForDashboard(): No filters found for dashboard " + aLogiDashboard.dashboardId + LogiDashboard.GetName(aLogiDashboard.dashboardId)); return; } const dashboardVisuals = embAna_getDashboardVisuals(aLogiDashboard); if (embAna_isNullCheck(dashboardVisuals)) { return; } if (embAna_dashboardFiltersChanged(aLogiDashboard, filters) === false) { return; } embAna_applyDashboardVisualsFilters(dashboardVisuals, filters); filters = null; } const embAna_applyDashboardVisualsFilters = (visuals, filters) => { if (embAna_ValidArray(visuals) === false || embAna_ValidArray(filters) === false) { return; } visuals.forEach((visual) => { embAna_applyVisualFilters(visual, filters); }); } const embAna_applyVisualFilterData = (visual) => { const filters = embAna_getFiltersForVisual(visual); embAna_applyVisualFilters(visual, filters); } const embAna_applyVisualFilters = (visual, filters) => { if (embAna_isNullCheck(visual)) { return; } if (embAna_ValidArray(filters) === false) { return; } visual.resetFilters(); let validFilters = embAna_ValidFilters(visual, filters); if (embAna_ValidArray(validFilters) === false) { return; } visual.filters.add(validFilters); validFilters = null; } const embAna_ValidFilters = (visual, filters) => { try { if (embAna_ValidArray(filters) === false || embAna_isNullCheck(visual)) { console.log("embAna_ValidFilters(): No valid filters - guard clause check"); return null; } const allFields = visual.getAllFields(); if (embAna_ValidArray(allFields) === false) { console.log("embAna_ValidFilters(): No valid filters - array check"); return null; } const validFilters = []; filters.forEach((filter) => { if (embAna_ValidString(filter.value) && allFields.some(field => field.name === filter.path)) { validFilters.push(filter); } }); console.log("embAna_ValidFilters(): Valid filters: " + validFilters); return validFilters; } catch(ex) { console.error("embAna_applyVisualFilters(): " + ex.message); } } const embAna_clearFilterData = () => { try { embAna_clearDashboardVisuals(); embAna_clearDashboardFilterMapping(); } catch(ex) { console.error("embAna_clearFilterData() exception: " + ex.message); } } const embAna_ValidArray = (anArray) => Array.isArray(anArray) && anArray.length > 0; const embAna_InValidArray = (anArray) => embAna_ValidArray(anArray) === false; const embAna_ValidString = (aString) => aString && aString.trim() !== ""; const embAna_clearFilters = () => { try { if (embAna_ValidArray(logiDashboards) === false) { return; } logiDashboards.forEach((dashboard) => { //embAna_clearFiltersForDashboard(dashboard.dashboardId); embAna_clearFiltersForDashboard(dashboard); }); } catch(ex) { console.error("embAna_clearFilters() exception: " + ex.message); } } const embAna_clearFiltersForDashboard = (aLogiDashboard) => { aLogiDashboard.clearFilterArray(); //aLogiDashboard.filterArray = null; let filters = embAna_getFiltersForDashboard(aLogiDashboard); if (embAna_ValidArray(filters) === false) { return; } const dashboardVisuals = embAna_getDashboardVisuals(aLogiDashboard); embAna_clearDashboardVisualsFilters(dashboardVisuals, filters); filters = null; } const embAna_clearDashboardVisualsFilters = (visuals, filters) => { if (embAna_ValidArray(visuals) === false || embAna_ValidArray(filters) === false) { return; } visuals.forEach((visual) => { visual.resetFilters(); }); } const embAna_getURLandToken = () => { try { if (embAna_isNullCheck(sysproInterop) || embAna_isNullCheck(sysproInterop.currentUserSession) || embAna_isNullCheck(sysproInterop.currentUserSession.LogiAnalyticsDashBoardDesignerAddress)){ return {baseUrl: null, accessToken: null, urlIsValid: false, errorMessage: "LogiAnalyticsDashBoardDesignerAddress not set"}; } const url = sysproInterop.currentUserSession.LogiAnalyticsDashBoardDesignerAddress; const parsedUrl = new URL(url); const pathSegments = parsedUrl.pathname.split('/'); pathSegments.pop(); // Remove the last segment of the path (in this case, "admin.html") baseUrl = parsedUrl.origin + pathSegments.join('/') + "/"; const paramString = parsedUrl.search; const urlParams = new URLSearchParams(paramString); const accessToken = urlParams.get("access_token"); return { baseUrl, accessToken, urlIsValid: true, errorMessage: ""}; } catch(ex) { console.error("embAna_getURLandToken() exception: " + ex.message); return {baseUrl: null, accessToken: null, urlIsValid: false, errorMessage: ex.message}; } } const embAna_getValidURLandToken = () => { try { const { baseUrl, accessToken, urlIsValid, errorMessage } = embAna_getURLandToken(); if (urlIsValid === false) { return Promise.reject(new Error(errorMessage)); } } catch(ex) { console.error("embAna_getValidURLandToken() exception: " + ex.message); return Promise.reject(new Error(ex.message)); } } const embApi_GetDashboardId = (dashboardName) => { if (embAna_isNullCheck(dashboardName)) { return null; } const functionName = "embApi_GetDashboardId"; try { const { baseUrl, accessToken, urlIsValid, errorMessage } = embAna_getURLandToken(); if (urlIsValid === false) { return Promise.reject(new Error(errorMessage)); } const urlApiSource = "api/dashboards"; const queryParams = new URLSearchParams({ "fields": "name", "access_token": accessToken }); const url = `${baseUrl}${urlApiSource}?${queryParams.toString()}`; return fetch(url) .then(response => { if (!response.ok) { const errorMessage = `${functionName} HTTP error! Http status code: ${response.status}`; console.error(errorMessage); return Promise.reject(new Error(errorMessage)); } return response.json(); }) .then(data => { if (!data || !data.content || !data.content.length) { return null; } const dashboard = data.content.find(d => d.name === dashboardName); return dashboard ? dashboard.id : null; }) .catch(error => { const errorMessage = `${functionName}: ${error}`; console.error(errorMessage); return Promise.reject(new Error(errorMessage)); }); } catch (error) { const errorMessage = `${functionName}: ${error}`; console.error(errorMessage); return Promise.reject(new Error(errorMessage)); } } const embApi_GetDashboardVisuals = (dashboardId) => { if (embAna_isNullCheck(dashboardId)) { return null; } const functionName = "embApi_GetDashboardVisuals"; try { const { baseUrl, accessToken, urlIsValid, errorMessage } = embAna_getURLandToken(); if (urlIsValid === false) { return Promise.reject(new Error(errorMessage)); } const urlApiSource = "api/dashboards/"; const queryParams = new URLSearchParams({ "access_token": accessToken, }); const url = `${baseUrl}${urlApiSource}${dashboardId}?${queryParams.toString()}`; return fetch(url) .then((response) => { if (!response.ok) { const errorMessage = `${functionName} HTTP error! Http status code: ${response.status}`; console.error(errorMessage); throw new Error(errorMessage); } return response.json(); }) .then((json) => { return embApi_extractVisualIdsFromJson(json); }); } catch (error) { const errorMessage = `${functionName}: ${error}`; console.error(errorMessage); return Promise.reject(new Error(errorMessage)); } } const embApi_extractVisualIdsFromJson = (json) => { if (!json || !json.widgets) { return []; } const widgets = json.widgets; const visualIds = widgets.filter(widget => widget.visualId).map(widget => widget.visualId); return visualIds; } const embApi_GetVisualSource = (visualId) => { if (embAna_isNullCheck(visualId)) { return null; } const functionName = "embApi_GetVisualSource"; try { const { baseUrl, accessToken, urlIsValid, errorMessage } = embAna_getURLandToken(); if (urlIsValid === false) { return Promise.reject(new Error(errorMessage)); } const urlApiSource = "api/visuals/"; const queryParams = new URLSearchParams({ "access_token": accessToken }); const url = `${baseUrl}${urlApiSource}${visualId}?${queryParams.toString()}`; return fetch(url) .then(response => { if (!response.ok) { console.error(`embApi_GetVisualSource HTTP error! status: ${response.status}`); return null; } return response.json(); }) .then(json => { return (!json || !json.source || !json.source.sourceId) ? null : json.source.sourceId; }) .catch(error => { const errorMessage = `${functionName}: ${error}`; console.error(errorMessage); return Promise.reject(new Error(errorMessage)); }); } catch (error) { const errorMessage = `${functionName}: ${error}`; console.error(errorMessage); return Promise.reject(new Error(errorMessage)); } } const embApi_GetVisualSources = (visualIds) => { if (!Array.isArray(visualIds) || visualIds.length === 0) { return Promise.resolve([]); } const functionName = "embApi_GetVisualSource"; const promises = visualIds.map(id => embApi_GetVisualSource(id)); return Promise.all(promises) .then(sourceIds => sourceIds.filter(id => id !== null)) .catch(error => { const errorMessage = `{functionName}: ${error}`; console.error(errorMessage); return Promise.reject(new Error(errorMessage)); }); } const embApi_GetSourceFieldsFilterNames = (sourceId) => { const functionName = "embApi_GetSourceFieldsFilterNames"; if (embAna_isNullCheck(sourceId)) { return null; } const { baseUrl, accessToken, urlIsValid, errorMessage } = embAna_getURLandToken(); if (urlIsValid === false) { return Promise.reject(new Error(errorMessage)); } const urlApiSource = "api/sources/"; const queryParams = new URLSearchParams({ "maxResults": 0, "access_token": accessToken }); const url = `${baseUrl}${urlApiSource}${sourceId}/fields?${queryParams.toString()}`; return fetch(url) .then(response => { if (!response.ok) { const errorMessage = `${functionName}: HTTP error! status: ${response.status}`; console.error(errorMessage); return Promise.reject(new Error(errorMessage)); } return response.json(); }) .then(data => { return embApi_GetSourceFieldNames(data); }) .catch(error => { const errorMessage = `${functionName} catch: ${error}`; console.error(errorMessage); return Promise.reject(new Error(errorMessage)); }); } const embApi_GetSourceFieldNames = (json) => { const functionName = "embApi_GetSourceFieldNames"; try { if (!json || !json.content) { return []; } const content = json.content; const fieldNames = []; for (let i = 0; i < content.length; i++) { const fieldName = content[i].name; if (fieldName) { fieldNames.push(fieldName); } } return fieldNames; } catch (error) { const errorMessage = `${functionName}: ${error}`; console.error(errorMessage); return []; } } const embApi_getUniqueFilterFields = (filterFieldsArrays) => { if (!Array.isArray(filterFieldsArrays) || filterFieldsArrays.some(array => !Array.isArray(array))) { return null; } const filterFields = new Set(); filterFieldsArrays.forEach(array => { if (array.length) { array.forEach(field => { filterFields.add(field); }); } }); return Array.from(filterFields); } const embApi_GetDashboardFilterFields = (dashboardName, successCallback, failedCallback) => { const filtersForJoe = embAna_getFilterFieldsForJoe(); if (embAna_isNotNullCheck(filtersForJoe)) { if (successCallback && typeof successCallback === 'function') { successCallback(filtersForJoe); } return null; } return embApi_GetDashboardId(dashboardName) .then(dashboardId => { //The call to embAna_ApplySourcesReadAccess is temporary and should be removed after the 2023 release. embAna_ApplySourcesReadAccess(dashboardName, dashboardId); return embApi_GetDashboardVisuals(dashboardId); }) .then(visualIds => { return embApi_GetVisualSources(visualIds); }) .then(sourceIds => { if (!sourceIds || !sourceIds.length) { return null; } const promises = sourceIds.map(sourceId => embApi_GetSourceFieldsFilterNames(sourceId)); return Promise.all(promises); }) .then(filterFieldsArrays => { const filterFields = embApi_getUniqueFilterFields(filterFieldsArrays); console.warn(filterFields); if (successCallback && typeof successCallback === 'function') { successCallback(filterFields); } return filterFields; }) .catch(error => { if (failedCallback && typeof failedCallback === 'function') { console.error("embApi_GetDashboardFilterFields() function exception / error: " + error); failedCallback(error); } }); } const embTest_filterSuccess = (filterFields) => { console.warn("filterSuccess " + filterFields); alert("filterSuccess " + filterFields); } const embTest_filterFail = (error) => { console.warn("filterFail " + error); alert("filterFail " + error); } const embAna_dashboardFiltersChanged = (aLogiDashboard, filters) => { if (embAna_isNullCheck(aLogiDashboard)) { return false; } return aLogiDashboard.filtersChanged(filters); } const embAna_compareArrays = (arr1, arr2) => { if ((!arr1 || arr1.length === 0) && (!arr2 || arr2.length === 0)) { return true; } if ((!arr1 || arr1.length === 0) || (!arr2 || arr2.length === 0)) { return false; } // Check if arrays have the same length if (arr1.length !== arr2.length) { return false; } // Sort arrays by stringifying the objects for comparison var sortedArr1 = arr1.map(JSON.stringify).sort(); var sortedArr2 = arr2.map(JSON.stringify).sort(); // Compare the sorted arrays for (var i = 0; i < sortedArr1.length; i++) { if (sortedArr1[i] !== sortedArr2[i]) { return false; } } return true; } //Temparary method to allow Joe to get some filter filed data: const embAna_getFilterFieldsForJoe = () => { const defaultValue = null; let SEAFilterFields = null; try { if (localStorage) { try { SEAFilterFields = JSON.parse(localStorage.getItem("SEAFilterFields")); if (SEAFilterFields === null) { SEAFilterFields = defaultValue; } } catch (ex) { SEAFilterFields = defaultValue; console.error("embAna_getFilterFieldsForJoe function: Exeption (0001): " + ex.message); } } } catch (ex) { SEAFilterFields = defaultValue; console.error("embAna_getFilterFieldsForJoe function: Exeption (0002): " + ex.message); } finally { console.log("embAna_getFilterFieldsForJoe: END: Value of SEAFilterFields: " + SEAFilterFields); return SEAFilterFields; } } const embAna_sysproInteropNotReady = () => embAna_isNullCheck(sysproInterop) || embAna_isNullCheck(sysproInterop.currentUserSession) || embAna_isNullCheck(sysproInterop.currentUserSession.OperatorInternal) || embAna_isNullCheck(sysproInterop.callBusinessObject); const embAna_loadTemplateCard = (modelId, retryCount) => { if (embAna_isNullCheck(retryCount)) { retryCount = 1; } if (embAna_sysproInteropNotReady() && (retryCount <= 20)) { let waitTime = retryCount <= 10 ? 1000 : 2000; setTimeout(() => embAna_loadTemplateCard(modelId, ++retryCount), waitTime); } else { embAna_loadTemplateCardReady(modelId); } }; const embAna_loadTemplateCardReady = (modelId) => { console.log("Dashboard bind function called"); let logiDashboardName = ""; let logiDiv = null; let logiDivId = null; if (embAna_isNotNullCheck(modelId)) { logiDivId = LogiDivId(modelId); logiDiv = document.getElementById(logiDivId); console.log("$$$" + logiDivId); } //let modelId = null; //let scr = document.getElementById("mainDashboardScript"); if (embAna_isNotNullCheck(logiDiv)) { let parent = logiDiv.closest(".card-bindable.sys-pd-off.sys-rd-t"); if (embAna_isNotNullCheck(parent)) { let grandParent = parent.closest(".panel.card.sys-widget.card-widget"); if (embAna_isNotNullCheck(grandParent)) { logiDashboardName = grandParent.getAttribute("data-widget-name"); } } } if (embAna_isNullCheck(modelId) || embAna_isNullCheck(logiDivId)) { console.warn("embAna_loadTemplateCard - modelId and logiDivId is null"); //return; } if (embAna_AvantiInDesignMode()) { //Do not render dashboards when Avanti is in design mode } else { console.log("Before call embAna_LogiDashboardScript - from loadTemplateCard"); embAna_LogiDashboardScript(logiDashboardName, logiDivId, modelId); } try { const cardDiv = document.getElementById(modelId); if (cardDiv && cardDiv.parentNode) { cardDiv.parentNode.style.height = "100%"; } } catch (ex) { console.error("UX_CARD_LogiDashboard height styling error: " + ex.message); } } window.removeEventListener("message", embAna_logiMessage); window.addEventListener("message", embAna_logiMessage); sysproInterop.applyDashboardFilters = embAna_applyFilters; sysproInterop.getDashboardFilterFields = embApi_GetDashboardFilterFields;