UNPKG

@luzmo/embed

Version:

A modern [Web Component](https://developer.mozilla.org/en-US/docs/Web/Web_Components) for [Luzmo](https://luzmo.com) dashboards in your web application.

1,407 lines (1,377 loc) 124 kB
(function(g,f){if(typeof define=="function"&&define.amd){define(f)}else if(typeof exports=="object" && typeof module<"u"){module.exports=f()}else{var m=f();for(var i in m) g[i]=m[i]}}(typeof globalThis < "u" ? globalThis : typeof self < "u" ? self : this,function(){var exports={};var __exports=exports;var module={exports}; "use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __decorateClass = (decorators, target, key, kind) => { var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; for (var i7 = decorators.length - 1, decorator; i7 >= 0; i7--) if (decorator = decorators[i7]) result = (kind ? decorator(target, key, result) : decorator(result)) || result; if (kind && result) __defProp(target, key, result); return result; }; // libs/embed-libs/embed/src/index.ts var src_exports2 = {}; __export(src_exports2, { LuzmoEmbedDashboard: () => LuzmoEmbedDashboard, LuzmoEmbedVizItem: () => LuzmoEmbedVizItem, LuzmoIQEmbedAnswerComponent: () => LuzmoIQEmbedAnswerComponent, LuzmoIQEmbedChatComponent: () => LuzmoIQEmbedChatComponent, addJSONSchemas: () => addJSONSchemas, fetchJSONSchema: () => fetchJSONSchema, getCachedJSONSchema: () => getCachedJSONSchema, getCachedJSONSchemas: () => getCachedJSONSchemas, getJSONSchemaUrl: () => getJSONSchemaUrl, luzmoRefParserOptions: () => luzmoRefParserOptions, selectedDataUtils: () => selectedDataUtils }); module.exports = __toCommonJS(src_exports2); // libs/embed-libs/shared-embed/src/lib/helpers/error.ts var _handleError = (errorMessage, parameters) => { let message = "The dashboard component encountered an error"; if (typeof parameters?.dashboardId === "string") { message += ` for dashboard with id ${parameters.dashboardId}`; } if (typeof parameters?.dashboardSlug === "string") { message += ` for dashboard with slug ${parameters.dashboardSlug}`; } if (typeof parameters?.container === "string") { message += ` in container ${parameters.container}`; } if (errorMessage) { message += `: ${errorMessage}`; console.warn(message); } }; // libs/embed-libs/shared-embed/src/lib/helpers/browser-check.ts var _browserCheck = (dashboardComponent) => { let hasError = false; let errorMessage = ""; const document_ = document.body || document.documentElement; const style = document_.style; const browserCheck = { svg: !!("createElementNS" in document && document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGRect), flexbox: style.webkitFlexWrap === "" || style.flexWrap === "", postMessage: !!window.postMessage }; const browserCheckKeys = ["svg", "flexbox", "postMessage"]; for (const key of browserCheckKeys) { if (!browserCheck[key]) { hasError = true; dashboardComponent.browserNotSupported = dashboardComponent.browserNotSupported || []; dashboardComponent.browserNotSupported.push(key); errorMessage += `Your browser does not support: ${key} `; } } const ua = window.navigator.userAgent; const msie = ua.includes("MSIE"); const trident = ua.includes("Trident/"); if (msie || trident) { hasError = true; errorMessage = "IE is not supported."; } if (hasError) { _handleError(errorMessage); } }; // libs/embed-libs/shared-embed/src/lib/helpers/default-parameters.ts var DEFAULT_PARAMETERS = { appServer: "https://app.luzmo.com/", apiHost: "https://api.luzmo.com/", dashboardId: null, dashboardSlug: null, container: null, key: null, token: null, language: "auto", editorLanguage: "auto", qeVersion: null, editMode: null, screenMode: null, switchScreenModeOnResize: true, itemId: null, theme: "", mainColor: "", accentColor: "", itemDimensions: { width: "auto", height: "auto" }, loaderBackground: "#f9f9f9", loaderFontColor: "#5a5a5a", loaderSpinnerColor: "rgba(255, 165, 0, 0.7)", loaderSpinnerBackground: "rgba(169, 169, 169, 0.14)", timezoneId: null, contextId: null }; // libs/embed-libs/shared-embed/src/lib/helpers/extents.ts var EXTENTS = [ { mode: "mobile", width: [150, 767] }, { mode: "tablet", width: [768, 1199] }, { mode: "desktop", width: [1200, 1599] }, { mode: "largeScreen", width: [1600, 9999] }, { mode: "fixed", width: [] } ]; // libs/embed-libs/shared-embed/src/lib/helpers/translations.ts var TRANSLATIONS = { initializing: { en: "Initializing...", nl: "Laden...", fr: "Chargement...", de: "Initialisiere...", es: "Inicializando..." }, errorDashboard: { en: "Oops, we could not load this dashboard!", nl: "Oeps, we konden het dashboard niet laden.", fr: "Le chargement a echou\xE9.", de: "Hoppla, wir konnten dieses Dashboard nicht laden!", es: "\xA1Ups! No pudimos cargar este tablero." }, errorItem: { en: "Oops, we could not load this item!", nl: "Oeps, we konden de grafiek niet laden.", fr: "Le chargement a echou\xE9.", de: "Hoppla, wir konnten dieses Diagramm nicht laden!", es: "\xA1Ups! No pudimos cargar este elemento." } }; var translations_default = TRANSLATIONS; // libs/embed-libs/shared-embed/src/lib/helpers/utils.ts var addTrailingSlash = (serverUrl) => { if (!serverUrl) { return ""; } return serverUrl.endsWith("/") ? serverUrl : `${serverUrl}/`; }; var removeTrailingSlash = (serverUrl) => { if (!serverUrl) { return ""; } return serverUrl.endsWith("/") ? serverUrl.slice(0, -1) : serverUrl; }; var formatDashboardList = (dashboards, integrationId, user, dashboardComponent) => { const combineRights = (securable, user2) => { const matchingUser = securable.users.find((u3) => u3.id === user2.id); const securableAccessRights = matchingUser && matchingUser.userAccessRight ? { flagRead: matchingUser.userAccessRight.flagRead, flagUse: matchingUser.userAccessRight.flagUse, flagModify: matchingUser.userAccessRight.flagModify, flagOwn: matchingUser.userAccessRight.flagOwn } : { flagRead: false, flagUse: false, flagModify: false, flagOwn: false }; const groups = securable.groups.filter( (group) => user2.userGroups.includes(group.id) || group.public === true ); const groupsAccess = groups.map((group) => { if (group.groupAccessRight) { return group.groupAccessRight; } }); for (const groupAccess of groupsAccess) { if (!securableAccessRights.flagRead && groupAccess.flagRead) { securableAccessRights.flagRead = groupAccess.flagRead; } if (!securableAccessRights.flagUse && groupAccess.flagUse) { securableAccessRights.flagUse = groupAccess.flagUse; } if (!securableAccessRights.flagModify && groupAccess.flagModify) { securableAccessRights.flagModify = groupAccess.flagModify; } if (!securableAccessRights.flagOwn && groupAccess.flagOwn) { securableAccessRights.flagOwn = groupAccess.flagOwn; } } const integrationsAccess = securable.integrations?.length > 0 ? securable.integrations.map((integration) => { if (integration.integrationAccessRight) { return integration.integrationAccessRight; } }) : []; for (const integrationAccess of integrationsAccess) { if (!securableAccessRights.flagRead && integrationAccess.flagRead) { securableAccessRights.flagRead = integrationAccess.flagRead; } if (!securableAccessRights.flagUse && integrationAccess.flagUse) { securableAccessRights.flagUse = integrationAccess.flagUse; } if (!securableAccessRights.flagModify && integrationAccess.flagModify) { securableAccessRights.flagModify = integrationAccess.flagModify; } } return securableAccessRights; }; const localize = (item, locale) => { if (item === null || item === void 0) { return ""; } if (typeof item !== "object" || Object.keys(item).length === 0) { if (typeof item === "object" && Object.keys(item).length === 0) { return ""; } return item; } let localizedItem; localizedItem = locale && item[locale] ? item[locale] : item[Object.keys(item)[0]]; if (localizedItem === void 0 || localizedItem === null) { localizedItem = ""; } return localizedItem; }; const treatedDashboards = []; for (const dashboard of dashboards) { const treatedDashboard = { accessibleBy: [], accessRights: combineRights(dashboard, user), id: dashboard.id, modifiedAt: dashboard.modified_at, name: localize(dashboard.name, dashboardComponent.language), slug: null, tags: dashboard.tags.map((t4) => t4.tag).sort((t1, t22) => t1.localeCompare(t22)) }; const currentIntegration = dashboard.integrations.find( (i7) => i7.id === integrationId ); if (currentIntegration?.integrationAccessRight?.slug) { treatedDashboard.slug = currentIntegration.integrationAccessRight.slug; } const users = dashboard.users.map((u3) => ({ model: "User", id: u3.id, name: localize(u3.name, user.locale_id) })); const groups = dashboard.groups.map((g2) => ({ model: "Group", id: g2.id, name: localize(g2.name, user.locale_id) || {} })); const integrations = dashboard.integrations.map((i7) => ({ model: "Integration", id: i7.id, name: localize(i7.name, user.locale_id) || {} })); treatedDashboard.accessibleBy = [...users, ...groups, ...integrations]; treatedDashboards.push(treatedDashboard); } return treatedDashboards; }; var VERSION = "0.0.0-unknown-luzmo"; var sanitizeUrl = (url) => { const invalidPrototcolRegex = /^(%20|\s)*(javascript|data)/im; const ctrlCharactersRegex = /[^\u0020-\u007E]/gim; const urlSchemeRegex = /^([^:]+):/gm; const relativeFirstCharacters = /* @__PURE__ */ new Set([".", "/"]); const isRelativeUrlWithoutProtocol = (relativeUrl) => relativeFirstCharacters.has(relativeUrl[0]); if (!url) { return "about:blank"; } const sanitizedUrl = url.replaceAll(ctrlCharactersRegex, "").trim(); if (isRelativeUrlWithoutProtocol(sanitizedUrl)) { return sanitizedUrl; } const urlSchemeParseResults = sanitizedUrl.match(urlSchemeRegex); if (!urlSchemeParseResults) { return sanitizedUrl; } const urlScheme = urlSchemeParseResults[0]; if (invalidPrototcolRegex.test(urlScheme)) { return "about:blank"; } return sanitizedUrl; }; var cloneDeep = (obj) => JSON.parse(JSON.stringify(obj)); var isObject = (o7) => o7 && typeof o7 === "object"; var defaultsDeep = (target, defaults) => { Object.entries(defaults).forEach(([k2, v2]) => { if (k2 in target) { if (target[k2] === void 0) { target[k2] = v2; } else { target[k2] = isObject(v2) ? defaultsDeep( target[k2], v2 ) : target[k2]; } } else { target[k2] = v2; } }); return target; }; var uuidv4 = () => "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replaceAll(/[xy]/g, function(c4) { const r6 = Math.random() * 16 | 0; const v2 = c4 == "x" ? r6 : r6 & 3 | 8; return v2.toString(16); }); // libs/embed-libs/shared-embed/src/lib/helpers/iframe-url.ts var createIframeUrl = (dashboardContent) => { const searchString = []; const { appServer, language, editorLanguage, qeVersion, loaderBackground, loaderSpinnerColor, loaderSpinnerBackground, loaderFontColor, screenMode, key, token, timezoneId, itemEmbedding, itemDimensions, dashboardId, dashboardSlug, itemId, theme, mainColor, accentColor, editMode } = dashboardContent.params; if (language && language !== "auto") { searchString.push(`language=${language}`); } if (editorLanguage && editorLanguage !== "auto") { searchString.push(`editorLanguage=${editorLanguage}`); } if (qeVersion) { searchString.push(`qe_version=${qeVersion}`); } if (loaderBackground) { searchString.push(`ldrbg=${loaderBackground}`); } if (loaderFontColor) { searchString.push(`ldrftclr=${loaderFontColor}`); } if (loaderSpinnerColor) { searchString.push(`ldrspclr=${loaderSpinnerColor}`); } if (loaderSpinnerBackground) { searchString.push(`ldrspbg=${loaderSpinnerBackground}`); } if (theme) { searchString.push(`theme=${theme}`); } if (mainColor) { searchString.push(`mainColor=${mainColor}`); } if (accentColor) { searchString.push(`accentColor=${accentColor}`); } if (screenMode && screenMode !== "auto") { searchString.push(`screenMode=&{screenMode}`); } if (timezoneId) { searchString.push("timezoneId=" + timezoneId); } if (itemEmbedding && itemDimensions && itemDimensions.width) { searchString.push("width=" + itemDimensions.width); } if (itemEmbedding && itemDimensions && itemDimensions.height) { searchString.push("height=" + itemDimensions.height); } if (editMode) { searchString.push("editMode=" + editMode); } const keyTokenUrlAnchor = key && token ? "#" + key + ":" + token : ""; searchString.push("version=" + (dashboardContent.libVersion || VERSION)); const iframeUrl = itemEmbedding ? `${appServer}i/${dashboardId || dashboardSlug}/${itemId}?${encodeURIComponent( searchString.join("&") )}${keyTokenUrlAnchor}` : `${appServer}i/${dashboardId || dashboardSlug}?${encodeURIComponent( searchString.join("&") )}${keyTokenUrlAnchor}`; return sanitizeUrl(iframeUrl); }; // libs/embed-libs/shared-embed/src/lib/helpers/get-loader.ts var getLoader = (dashboardComponent) => { let errorMsg; if (dashboardComponent.params.error || dashboardComponent.browserNotSupported.length > 0) { dashboardComponent.params.error = true; if (dashboardComponent.browserNotSupported) { errorMsg = "Browser is not supported."; } } const loadingMsg = translations_default.initializing[dashboardComponent.params.language] || translations_default.initializing.en; return dashboardComponent.browserNotSupported || dashboardComponent.params.error ? { loadingMsg, errorMsg } : { loadingMsg, errorMsg: "" }; }; // libs/embed-libs/shared-embed/src/lib/helpers/promise-dispatch.ts function resolvePromise(dashboardComponent, requestId, data) { if (dashboardComponent.promises[requestId]) { dashboardComponent.promises[requestId].resolve(data); delete dashboardComponent.promises[requestId]; } } function rejectPromise(dashboardComponent, requestId, data) { if (dashboardComponent.promises[requestId]) { dashboardComponent.promises[requestId].reject(data); delete dashboardComponent.promises[requestId]; } } // libs/embed-libs/shared-embed/src/lib/helpers/styles.ts function containerStyles(dashboardComponent) { const styles = {}; if (dashboardComponent.params.loaderBackground && !dashboardComponent.iframeLoaded) { styles.background = dashboardComponent.params.loaderBackground; } return styles; } function containerLoaderStyles(dashboardComponent) { const height = dashboardComponent.params.itemDimensions?.height || DEFAULT_PARAMETERS.itemDimensions.height; const chartHeightDefined = dashboardComponent.params.itemEmbedding && height !== "auto"; const display = dashboardComponent.iframeLoaded ? "none" : ""; return { display, height: `${chartHeightDefined ? height : dashboardComponent.minHeight}px` }; } function loaderStyles(dashboardComponent) { const background = dashboardComponent.params.loaderBackground || DEFAULT_PARAMETERS.loaderBackground; if (dashboardComponent.params.itemEmbedding) { dashboardComponent.loaderSize = 24; dashboardComponent.borderWidth = 4; dashboardComponent.minHeight = 200; const width = dashboardComponent.params.itemDimensions?.width || DEFAULT_PARAMETERS.itemDimensions.width; const height = dashboardComponent.params.itemDimensions?.height || DEFAULT_PARAMETERS.itemDimensions.height; const chartWidthDefined = width !== "auto"; const chartHeightDefined = height !== "auto"; return { background, width: chartWidthDefined ? `${width}px` : "100%", height: `${chartHeightDefined ? height : "200"}px`, "min-height": chartHeightDefined ? "" : "200px" }; } return { background }; } function plStyles(dashboardComponent) { const { loaderSpinnerColor: defaultSpinnerColor, loaderSpinnerBackground: defaultSpinnerBackground } = DEFAULT_PARAMETERS; const spinnerColorBorder = generateBorderStyle( dashboardComponent.borderWidth, dashboardComponent.params.loaderSpinnerColor || defaultSpinnerColor ); const spinnerBackgroundBorder = generateBorderStyle( dashboardComponent.borderWidth, dashboardComponent.params.loaderSpinnerBackground || defaultSpinnerBackground ); const size = `${dashboardComponent.loaderSize}px`; return { "border-top": spinnerColorBorder, "border-right": spinnerColorBorder, "border-bottom": spinnerBackgroundBorder, "border-left": spinnerBackgroundBorder, width: size, height: size }; } function lcStyles(dashboardComponent) { const height = dashboardComponent.params.itemDimensions?.height || DEFAULT_PARAMETERS.itemDimensions.height; const chartHeightDefined = dashboardComponent.params.itemEmbedding && height !== "auto"; const getPaddingStr = (value) => `${(value - dashboardComponent.loaderSize - 32) / 2}px`; const verticalPadding = dashboardComponent.params.itemId ? chartHeightDefined ? getPaddingStr(Number.parseInt(`${height}`, 10)) : getPaddingStr(dashboardComponent.minHeight) : "128px"; return { padding: `${verticalPadding} 16px` }; } function calculateIframeStyles(dashboardComponent) { const height = dashboardComponent.params.itemDimensions?.height || DEFAULT_PARAMETERS.itemDimensions.height; const width = dashboardComponent.params.itemDimensions?.width || DEFAULT_PARAMETERS.itemDimensions.width; if (dashboardComponent.params.itemEmbedding && height !== "auto") { dashboardComponent.iframeHeight = `${height}px`; } else if (dashboardComponent.params.itemEmbedding) { dashboardComponent.iframeHeight = "200px"; } else if (["editFull", "editLimited"].includes(dashboardComponent.params.editMode)) { dashboardComponent.iframeHeight = "100%"; } else { dashboardComponent.iframeHeight = "400px"; } dashboardComponent.iframeWidth = dashboardComponent.params.itemEmbedding && width !== "auto" ? `${width}px` : "100%"; const styles = { height: dashboardComponent.iframeHeight, width: dashboardComponent.iframeWidth }; if (dashboardComponent.iframeLoaded) { styles.opacity = 1; } else if (dashboardComponent.error) { styles.opacity = 1; styles.width = "100%"; styles.height = "400px"; } else { styles.opacity = 0; } return styles; } function generateBorderStyle(borderWidth, color) { return `${borderWidth}px solid ${color}`; } // libs/embed-libs/shared-embed/src/lib/helpers/update-iframe-url.ts var updateIframeUrl = (iframe, iframeUrl) => { if (iframe?.contentWindow) { iframe.contentWindow.location.replace(iframeUrl); } }; // libs/embed-libs/shared-embed/src/lib/helpers/set-selected-data-utils.ts var selectedDataUtils = { merge(...filters) { return filters.reduce((acc, filter) => { acc.and.push(...filter.and); return acc; }, { and: [] }); }, isIn(slot, values, otherOptions) { return { and: [{ expression: "? in ?", parameters: [ { slot, ...otherOptions }, values ] }] }; }, between(slot, values, otherOptions) { return { and: [{ expression: "? between ?", parameters: [ { slot, ...otherOptions }, [values[0], values[1]] ] }] }; }, range(slot, values, otherOptions) { const expressions = otherOptions?.expressions ?? ["? >= ?", "? < ?"]; return { and: [{ expression: expressions[0], parameters: [ { slot, ...otherOptions }, [values[0]] ] }, { expression: expressions[1], parameters: [ { slot, ...otherOptions }, [values[1]] ] }] }; } }; // libs/embed-libs/shared-embed/src/lib/methods/export-dashboard.ts var exportDashboard = (dashboardComponent, iframe, format) => { const requestId = uuidv4(); if (iframe?.contentWindow) { iframe.contentWindow.postMessage( { action: "exportDashboard", format: format || "png", _version: dashboardComponent.libVersion, requestId }, "*" ); return new Promise((resolve, reject) => { dashboardComponent.promises[requestId] = { resolve, reject }; setTimeout(() => { if (dashboardComponent.promises[requestId]) { const errorMessage = "exportDashboard request timed out."; dashboardComponent.promises[requestId].reject( new Error(errorMessage) ); delete dashboardComponent.promises[requestId]; } }, 12e5); }); } return Promise.reject(new Error("Cannot retrieve contentWindow.")); }; // libs/embed-libs/shared-embed/src/lib/methods/get-accessible-dashboards.ts var getAccessibleDashboards = async (dashboardComponent) => { await dashboardComponent.updateComplete; if ((dashboardComponent.currentAuthKey ?? dashboardComponent.authKey) && (dashboardComponent.currentAuthToken ?? dashboardComponent.authToken)) { const fetchUser = new Promise((resolve, reject) => { void (() => { try { const responsePromise = window.fetch( // With embedMode="webComponent" URLs remove the trailing slash, since the web component expects them to not have it. // Fixes incorrect url with embedMode="webComponent" `${addTrailingSlash(dashboardComponent.params.apiHost)}0.1.0/authorization`, { method: "POST", mode: "cors", cache: "no-cache", headers: { "Content-Type": "application/json" }, redirect: "follow", body: JSON.stringify({ action: "get", version: "0.1.0", key: dashboardComponent.currentAuthKey ?? dashboardComponent.authKey, token: dashboardComponent.currentAuthToken ?? dashboardComponent.authToken, find: { where: { id: dashboardComponent.authKey }, attributes: ["id", "integration_id"], include: [ { model: "User", attributes: ["id", "name", "locale_id"], include: [{ model: "Group" }] } ] } }) } ); responsePromise.then((response) => response.json()).then((data) => { if (!data || !data.rows || data.rows.length === 0 || !data.rows[0].user) { reject("Authorization failed, please check authKey and authToken. If the problem persists, please contact support@luzmo.com."); } else { data.rows[0].user.userGroups = data.rows[0].user.groups.map( (group) => group.id ); delete data.rows[0].user.groups; resolve({ integrationId: data.rows[0].integration_id, user: data.rows[0].user }); } }); } catch (error) { reject(error); } })(); }); return new Promise((resolve, reject) => void (() => { try { fetchUser.then((authorizationData) => { const responsePromise = window.fetch( // With embedMode="webComponent" URLs remove the trailing slash, since the web component expects them to not have it. // Fixes incorrect url with embedMode="webComponent" `${addTrailingSlash(dashboardComponent.params.apiHost)}0.1.0/securable`, { method: "POST", mode: "cors", cache: "no-cache", headers: { "Content-Type": "application/json" }, redirect: "follow", body: JSON.stringify({ action: "get", version: "0.1.0", key: dashboardComponent.currentAuthKey ?? dashboardComponent.authKey, token: dashboardComponent.currentAuthToken ?? dashboardComponent.authToken, find: { where: { type: "dashboard", is_variant: false }, attributes: ["id", "name", "modified_at"], order: [["modified_at", "desc"]], include: [ { model: "Tag", attributes: ["tag"] }, { model: "User", attributes: ["id", "name"] }, { model: "Group", attributes: ["id", "name", "public"] }, { model: "Integration", attributes: ["id", "name"] } ] } }) } ); responsePromise.then((response) => response.json()).then((data) => { const dashboardList = data.rows.length > 0 ? formatDashboardList( data.rows, authorizationData.integrationId, authorizationData.user, dashboardComponent ) : []; resolve(dashboardList); }); }).catch((error) => { reject(error); }); } catch (error) { reject(error); } })()); } throw new Error("No authKey or authToken found in the luzmo-dashboard component."); }; // libs/embed-libs/shared-embed/src/lib/methods/get-data.ts var getData = (dashboardComponent, iframe, itemId) => { if (iframe?.contentWindow) { const requestId = uuidv4(); iframe.contentWindow.postMessage( { action: "getData", id: itemId, _version: dashboardComponent.libVersion, requestId }, "*" ); return new Promise((resolve, reject) => { dashboardComponent.promises[requestId] = { resolve, reject }; setTimeout(() => { if (dashboardComponent.promises[requestId]) { const errorMessage = "getData request timed out."; dashboardComponent.promises[requestId].reject( new Error(errorMessage) ); delete dashboardComponent.promises[requestId]; } }, 2e3); }); } return Promise.reject(new Error("Cannot retrieve contentWindow.")); }; // libs/embed-libs/shared-embed/src/lib/methods/get-filters.ts var getFilters = (dashboardComponent, iframe) => { if (iframe?.contentWindow) { const requestId = uuidv4(); iframe.contentWindow.postMessage( { action: "getFilters", _version: dashboardComponent.libVersion, requestId }, "*" ); return new Promise((resolve, reject) => { dashboardComponent.promises[requestId] = { resolve, reject }; setTimeout(() => { if (dashboardComponent.promises[requestId]) { const errorMessage = "getFilters request timed out."; dashboardComponent.promises[requestId].reject( new Error(errorMessage) ); delete dashboardComponent.promises[requestId]; } }, 2e3); }); } return Promise.reject(new Error("Cannot retrieve contentWindow.")); }; // libs/embed-libs/shared-embed/src/lib/methods/refresh-data.ts var refreshData = (dashboardComponent, iframe, itemId) => { if (iframe) { iframe.contentWindow.postMessage( { action: "refreshData", id: itemId ?? null, _version: dashboardComponent.libVersion }, "*" ); return Promise.resolve(); } return Promise.reject(new Error("Cannot retrieve contentWindow.")); }; // libs/embed-libs/shared-embed/src/lib/methods/reload-dashboard.ts var reloadDashboard = (dashboardComponent, iframe) => { if (iframe) { iframe.contentWindow.postMessage( { action: "reloadDashboard", _version: dashboardComponent.libVersion }, "*" ); return Promise.resolve(); } return Promise.reject(new Error("Cannot retrieve contentWindow.")); }; // libs/embed-libs/shared-embed/src/lib/methods/set-authorization.ts var setAuthorization = (dashboardComponent, iframe, key, token) => { if (iframe) { iframe.contentWindow.postMessage( { action: "setAuthorization", key, token, _version: dashboardComponent.libVersion }, "*" ); return Promise.resolve(); } return Promise.reject(new Error("Cannot retrieve contentWindow.")); }; // libs/embed-libs/shared-embed/src/lib/methods/set-edit-mode.ts var setEditMode = (dashboardComponent, iframe, editMode) => { if (iframe && iframe.contentWindow) { const requestId = uuidv4(); if (dashboardComponent.params.editMode === editMode) { return Promise.reject( new Error("editMode parameter is currently already set to " + editMode) ); } else if (editMode !== "editFull" && editMode !== "editLimited" && editMode !== "view") { return Promise.reject( new Error( "The editMode parameter must be one of the following values: 'editFull', 'editLimited' or 'view'." ) ); } iframe.contentWindow.postMessage( { action: "setEditMode", editMode, _version: dashboardComponent.libVersion, requestId }, "*" ); return new Promise((resolve, reject) => { dashboardComponent.promises[requestId] = { resolve, reject }; }); } return Promise.reject(new Error("Cannot retrieve contentWindow.")); }; // libs/embed-libs/shared-embed/src/lib/methods/set-selected-data.ts var setSelectedData = (dashboardComponent, iframe, itemId, filters) => { if (iframe) { const requestId = uuidv4(); iframe.contentWindow.postMessage( { action: "setSelectedData", itemId, filters, _version: dashboardComponent.libVersion, requestId }, "*" ); return new Promise((resolve, reject) => { dashboardComponent.promises[requestId] = { resolve, reject }; setTimeout(() => { if (dashboardComponent.promises[requestId]) { const errorMessage = "setSelectedData request timed out."; dashboardComponent.promises[requestId].reject( new Error(errorMessage) ); delete dashboardComponent.promises[requestId]; } }, 2e3); }); } return Promise.reject(); }; // libs/embed-libs/shared-embed/src/lib/methods/set-preview.ts var setPreview = (dashboardComponent, iframe, preview) => { if (iframe) { const requestId = uuidv4(); iframe.contentWindow.postMessage( { action: "setPreview", preview, requestId, _version: dashboardComponent.libVersion }, "*" ); return new Promise((resolve, reject) => { dashboardComponent.promises[requestId] = { resolve, reject }; setTimeout(() => { if (dashboardComponent.promises[requestId]) { const errorMessage = "setPreview request timed out."; dashboardComponent.promises[requestId].reject( new Error(errorMessage) ); delete dashboardComponent.promises[requestId]; } }, 2e3); }); } return Promise.reject(new Error("Cannot retrieve contentWindow.")); }; // libs/embed-libs/shared-embed/src/lib/service/calculate-dimensions.ts var _setCalculatedDimensions = (dashboardComponent) => { if (!dashboardComponent.dimensions) { dashboardComponent.params.error = true; _handleError("Got no valid dimensions.", dashboardComponent.params); return; } const dashboardDimensionKeys = Object.keys( dashboardComponent.dimensions ); const availableScreenModeExtents = []; let currentMode; let currentWidth = 0; let currentHeight = 0; if (!dashboardComponent.params.switchScreenModeOnResize && dashboardComponent.currentScreenMode) { dashboardComponent.params.screenMode = dashboardComponent.currentScreenMode; } if (dashboardComponent.dimensions && dashboardDimensionKeys?.[0] === "fixed") { currentMode = "fixed"; currentWidth = dashboardComponent.dimensions.fixed[0]; currentHeight = dashboardComponent.dimensions.fixed[1]; } else { const screenModes = [ "mobile", "tablet", "desktop", "largeScreen" ]; if (dashboardComponent.params.itemEmbedding) { const [firstMatch] = dashboardDimensionKeys; let match = cloneDeep(firstMatch); for (const screenMode of screenModes) { const found = dashboardDimensionKeys.find((key) => key === screenMode); if (found) { match = cloneDeep(found); } else { dashboardComponent.dimensions[screenMode] = dashboardComponent.dimensions[match]; } } } for (const key of dashboardDimensionKeys) { if (screenModes.includes(key)) { const screenMode = EXTENTS.find((extent) => extent.mode === key); availableScreenModeExtents.push({ ...screenMode, height: dashboardComponent.dimensions[key][1] || 50 }); } } if (!availableScreenModeExtents.map((screenModeExtent) => screenModeExtent.mode).includes(dashboardComponent.params.screenMode)) { dashboardComponent.params.screenMode = "auto"; } if (dashboardComponent.params.screenMode === "auto") { availableScreenModeExtents.sort( (a3, b3) => screenModes.indexOf(a3.mode) - screenModes.indexOf(b3.mode) ); for (const screenModeExtent of availableScreenModeExtents) { const [screenModeExtentMinWidth, screenModeExtentMaxWidth] = screenModeExtent.width; if (dashboardComponent.params.itemEmbedding && dashboardComponent.params.itemDimensions && dashboardComponent.params.itemDimensions.width !== "auto" && dashboardComponent.params.itemDimensions.height === "auto") { if (screenModeExtentMinWidth < dashboardComponent.params.itemDimensions.width) { currentMode = screenModeExtent.mode; currentWidth = Number.parseInt( dashboardComponent.params.itemDimensions.width, 10 ); currentHeight = dashboardComponent.dimensions[currentMode][1]; } } else { if (screenModeExtentMinWidth < dashboardComponent.containerWidth) { currentMode = screenModeExtent.mode; if (dashboardComponent.params.itemEmbedding) { currentWidth = dashboardComponent.params.itemDimensions?.width && dashboardComponent.params.itemDimensions?.width !== "auto" ? Number.parseInt( dashboardComponent.params.itemDimensions.width, 10 ) : Math.min( dashboardComponent.containerWidth, screenModeExtentMaxWidth ); currentHeight = dashboardComponent.params.itemDimensions?.height && dashboardComponent.params.itemDimensions?.height !== "auto" ? Number.parseInt( dashboardComponent.params.itemDimensions.height, 10 ) : dashboardComponent.dimensions[currentMode][1]; if (dashboardComponent.params.itemDimensions && dashboardComponent.params.itemDimensions.width !== "auto" && dashboardComponent.params.itemDimensions.height === "auto") { currentWidth = Number.parseInt( dashboardComponent.params.itemDimensions.width, 10 ); currentHeight = dashboardComponent.dimensions[currentMode][1]; } } else { currentWidth = Math.max( Math.min( screenModeExtentMaxWidth, dashboardComponent.containerWidth ), screenModeExtentMinWidth ); currentHeight = screenModeExtent.height; } } } } } else { const { height: chosenModeHeight, width: [chosenModeMinWidth, chosenModeMaxWidth] } = availableScreenModeExtents.find( (d3) => d3.mode === dashboardComponent.params.screenMode ); currentMode = dashboardComponent.params.screenMode; currentWidth = Math.max( Math.min(chosenModeMaxWidth, dashboardComponent.containerWidth), chosenModeMinWidth ); currentHeight = chosenModeHeight; if (dashboardComponent.params.itemEmbedding) { if (dashboardComponent.params.itemDimensions?.width && dashboardComponent.params.itemDimensions?.width !== "auto") { currentWidth = Number.parseInt( dashboardComponent.params.itemDimensions.width, 10 ); } if (dashboardComponent.params.itemDimensions?.height && dashboardComponent.params.itemDimensions?.height !== "auto") { currentHeight = Number.parseInt( dashboardComponent.params.itemDimensions.height, 10 ); } } } if (!currentMode && availableScreenModeExtents.length > 0) { const [lowestModeExtent] = availableScreenModeExtents; currentMode = lowestModeExtent.mode; currentWidth = lowestModeExtent.width[0]; currentHeight = lowestModeExtent.height; } } dashboardComponent.currentScreenMode = currentMode; const style = { height: currentHeight === 0 ? "100%" : `${String(currentHeight)}px`, width: currentWidth === 0 ? "100%" : `${String(currentWidth)}px`, opacity: 1 }; const dashboardEditModes = ["editFull", "editLimited"]; if (dashboardEditModes.includes(dashboardComponent.params.editMode)) { style.height = "100%"; style.width = "100%"; } else if (dashboardComponent.params.itemEmbedding && dashboardComponent.params.itemDimensions) { style.height = dashboardComponent.params.itemDimensions.height === "auto" ? style.height : `${String(dashboardComponent.params.itemDimensions.height).replace( "px", "" )}px`; style.width = dashboardComponent.params.itemDimensions.width === "auto" ? style.width : `${String(dashboardComponent.params.itemDimensions.width).replace( "px", "" )}px`; } else { style.height = currentHeight === 0 ? "100%" : `${String(currentHeight)}px`; style.width = currentWidth === 0 ? "100%" : `${String(currentWidth)}px`; } dashboardComponent.currentScreenMode = currentMode; dashboardComponent.iframeStyle = style; }; // libs/embed-libs/shared-embed/src/lib/service/extend-and-validate.ts var _extendAndValidate = (dashboardContent) => { const defaultKeys = Object.keys( DEFAULT_PARAMETERS ); const errorMessages = []; const requiredStringParams = [ "appServer", "language", "apiHost" ]; const requiredStringOrEmptyParams = [ "key", "token", "screenMode", "timezoneId", "itemId", "container", "loaderBackground", "loaderFontColor", "loaderSpinnerColor", "loaderSpinnerBackground" ]; const objectParams = ["itemDimensions"]; const screenModes = [ "mobile", "tablet", "desktop", "largeScreen", "fixed", "auto" ]; for (const key of defaultKeys) { if (dashboardContent.params[key] === null) { delete dashboardContent.params[key]; } } dashboardContent.params = defaultsDeep( dashboardContent.params, DEFAULT_PARAMETERS ); if ((!dashboardContent.params.dashboardId || typeof dashboardContent.params.dashboardId !== "string") && (!dashboardContent.params.dashboardSlug || typeof dashboardContent.params.dashboardSlug !== "string")) { delete dashboardContent.params.dashboardId; delete dashboardContent.params.dashboardSlug; } for (const key of requiredStringParams) { if (typeof dashboardContent.params[key] !== "string") { delete dashboardContent.params[key]; errorMessages.push(`${key} needs to be of type string.`); } } for (const key of requiredStringOrEmptyParams) { if (typeof dashboardContent.params[key] !== "string" && dashboardContent.params[key] !== null && dashboardContent.params[key] !== void 0) { delete dashboardContent.params[key]; errorMessages.push(`${key} needs to be of type string or empty.`); } } if (dashboardContent.params.screenMode && !screenModes.includes(dashboardContent.params.screenMode)) { const validTypesString = screenModes.map((mode) => `"${mode}"`).join(", "); errorMessages.push( `"screenMode" needs should be one of these types: ${validTypesString}` ); dashboardContent.params.screenMode = "auto"; } if (dashboardContent.params.itemId) { dashboardContent.params.itemEmbedding = true; } for (const key of objectParams) { if (typeof dashboardContent.params[key] !== "object" && dashboardContent.params[key] !== null) { delete dashboardContent.params[key]; errorMessages.push(`${key} needs to be of type object or empty.`); } } if (typeof dashboardContent.params.switchScreenModeOnResize !== "boolean") { errorMessages.push("switchScreenModeOnResize needs to be of type boolean."); dashboardContent.params.switchScreenModeOnResize = true; } if (dashboardContent.params.itemDimensions) { const itemDimensionsKeys = [ "width", "height" ]; for (const key of itemDimensionsKeys) { if (!["string", "number"].includes( typeof dashboardContent.params.itemDimensions[key] ) && dashboardContent.params.itemDimensions[key] !== null) { errorMessages.push( `itemDimensions ${key} needs to be of type string, number or empty.` ); } } } dashboardContent.params = defaultsDeep( dashboardContent.params, DEFAULT_PARAMETERS ); if (dashboardContent.params.screenMode && dashboardContent.params.screenMode !== "auto") { dashboardContent.params.switchScreenModeOnResize = false; } if (dashboardContent.params.itemDimensions.width !== "auto") { dashboardContent.params.itemDimensions.width = Number.parseInt( `${dashboardContent.params.itemDimensions.width}`.replace("px", ""), 10 ) || "auto"; } if (dashboardContent.params.itemDimensions.height !== "auto") { dashboardContent.params.itemDimensions.height = Number.parseInt( `${dashboardContent.params.itemDimensions.height}`.replace("px", ""), 10 ) || "auto"; } dashboardContent.params.itemEmbedding = !!dashboardContent.params.itemId; if (dashboardContent.params.error || errorMessages.length > 0) { _handleError(errorMessages.join("\n"), dashboardContent.params); } }; // libs/embed-libs/shared-embed/src/lib/models/viz-item.model.ts var libraryTypeToWebComponentTypeMapping = { type: "type", slots: "slots", options: "options", appServer: "app-server", apiHost: "api-host", authKey: "auth-key", authToken: "auth-token", contextId: "context-id", canFilter: "can-filter", filters: "filters", dashboardId: "dashboard-id", itemId: "item-id", dashboardContentsVersion: "dashboard-contents-version", libVersion: "lib-version" }; // libs/embed-libs/shared-embed/src/lib/constants/class-constants.ts var luzmoEmbedContainerClass = "luzmo-embed-container"; // libs/embed-libs/shared-embed/src/lib/helpers/remote-federation.ts var remotesMap = { // "remote_app": { url: "http://localhost:4201/remoteEntry.mjs", format: "esm", from: "vite" }, }; var loadJS = async (url, fn) => { const resolvedUrl = typeof url === "function" ? await url() : url; const script = document.createElement("script"); script.type = "text/javascript"; script.addEventListener("load", fn); script.src = resolvedUrl; document.querySelectorAll("head")[0].append(script); }; var wrapShareModule = (remoteFrom) => ({}); async function __federationMethodEnsure(remoteId) { const remote = remotesMap[remoteId]; if (remote.inited) { return remote.lib; } if (remote.format === "var") { return new Promise((resolve) => { const callback = () => { if (!remote.inited) { remote.lib = window[remoteId]; remote.lib.init(wrapShareModule(remote.from)); remote.inited = true; } resolve(remote.lib); }; return loadJS(remote.url, callback); }); } else if (["esm", "systemjs"].includes(remote.format)) { return new Promise((resolve, reject) => { const getUrl = typeof remote.url === "function" ? remote.url : () => Promise.resolve(remote.url); getUrl().then((url) => { import( /* @vite-ignore */ /* webpackIgnore: true */ url ).then((lib) => { if (!remote.inited) { const shareScope = wrapShareModule(remote.from); lib.init(shareScope); remote.lib = lib; remote.lib.init(shareScope); remote.inited = true; } resolve(remote.lib); }).catch(reject); }); }); } } function __federationMethodWrapDefault(module2, need) { if (!(module2 == null ? void 0 : module2.default) && need) { const obj = /* @__PURE__ */ Object.create(null); obj.default = module2; obj.__esModule = true; return obj; } return module2; } async function __federationMethodGetRemote(remoteName, componentName) { return __federationMethodEnsure(remoteName).then((remote) => remote.get(componentName).then((factory) => factory())); } async function loadLibrary(appServer, componentName = "DashboardApp") { const remotesMapIndex = appServer + componentName; if (remotesMap[remotesMapIndex]) { return remotesMap[remotesMapIndex].module; } let url = `${removeTrailingSlash(appServer)}/remoteEntry.mjs`; if (!appServer.startsWith("http://localhost")) { switch (componentName) { case "DashboardApp": case "VizItemApp": { url = `${removeTrailingSlash(appServer)}/dashboard-app/remoteEntry.mjs`; break; } case "IQApp": { url = `${removeTrailingSlash(appServer)}/iq-components/remoteEntry.mjs`; break; } } } remotesMap[remotesMapIndex] = { url, format: "esm", from: "vite", module: void 0 }; const module2 = await __federationMethodGetRemote(remotesMapIndex, `./${componentName}`); const wrappedModule = __federationMethodWrapDefault(module2, true); remotesMap[remotesMapIndex].module = wrappedModule; return wrappedModule; } // node_modules/@lit/reactive-element/css-tag.js var t = globalThis; var e = t.ShadowRoot && (void 0 === t.ShadyCSS || t.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype; var s = Symbol(); var o = /* @__PURE__ */ new WeakMap(); var n = class { constructor(t4, e7, o7) { if (this._$cssResult$ = true, o7 !== s) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); this.cssText = t4, this.t = e7; } get styleSheet() { let t4 = this.o; const s4 = this.t; if (e && void 0 === t4) { const e7 = void 0 !== s4 && 1 === s4.length; e7 && (t4 = o.get(s4)), void 0 === t4 && ((this.o = t4 = new CSSStyleSheet()).replaceSync(this.cssText), e7 && o.set(s4, t4)); } return t4; } toString() { return this.cssText; } }; var r = (t4) => new n("string" == typeof t4 ? t4 : t4 + "", void 0, s); var i = (t4, ...e7) => { const o7 = 1 === t4.length ? t4[0] : e7.reduce((e8, s4, o8) => e8 + ((t5) => { if (true === t5._$cssResult$) return t5.cssText; if ("number" == typeof t5) return t5; throw Error("Value passed to 'css' function must be a 'css' function result: " + t5 + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security."); })(s4) + t4[o8 + 1], t4[0]); return new n(o7, t4, s); }; var S = (s4, o7) => { if (e) s4.adoptedStyleSheets = o7.map((t4) => t4 instanceof CSSStyleSheet ? t4 : t4.styleSheet); else for (const e7 of o7) { const o8 = document.createElement("style"), n6 = t.litNonce; void 0 !== n6 && o8.setAttribute("nonce", n6), o8.textContent = e7.cssText, s4.appendChild(o8); } }; var c = e ? (t4) => t4 : (t4) => t4 instanceof CSSStyleSheet ? ((t5) => { let e7 = ""; for (const s4 of t5.cssRules) e7 += s4.cssText; return r(e7); })(t4) : t4; // node_modules/@lit/reactive-element/reactive-element.js var { is: i2, defineProperty: e2, getOwnPropertyDescriptor: h, getOwnPropertyNames: r2, getOwnPropertySymbols: o2, getPrototypeOf: n2 } = Object; var a = globalThis; var c2 = a.trustedTypes; var l = c2 ? c2.emptyScript : ""; var p = a.reactiveElementPolyfillSupport; var d = (t4, s4) => t4; var u = { toAttribute(t4, s4) { switch (s4) { case Boolean: t4 = t4 ? l : null; break; case Object: case Array: t4 = null == t4 ? t4 : JSON.stringify(t4); } return