@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
JavaScript
(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