@thoughtspot/visual-embed-sdk
Version:
ThoughtSpot Embed SDK
1,300 lines (1,296 loc) • 1.04 MB
JavaScript
/* @thoughtspot/visual-embed-sdk version 1.40.0 */
'use client';
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.tsembed = {}));
})(this, (function (exports) { 'use strict';
function _mergeNamespaces(n, m) {
m.forEach(function (e) {
e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
if (k !== 'default' && !(k in n)) {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
});
return Object.freeze(n);
}
// istanbul ignore next
const isObject$1 = (obj) => {
if (typeof obj === "object" && obj !== null) {
if (typeof Object.getPrototypeOf === "function") {
const prototype = Object.getPrototypeOf(obj);
return prototype === Object.prototype || prototype === null;
}
return Object.prototype.toString.call(obj) === "[object Object]";
}
return false;
};
const merge = (...objects) => objects.reduce((result, current) => {
if (Array.isArray(current)) {
throw new TypeError("Arguments provided to ts-deepmerge must be objects, not arrays.");
}
Object.keys(current).forEach((key) => {
if (["__proto__", "constructor", "prototype"].includes(key)) {
return;
}
if (Array.isArray(result[key]) && Array.isArray(current[key])) {
result[key] = merge.options.mergeArrays
? merge.options.uniqueArrayItems
? Array.from(new Set(result[key].concat(current[key])))
: [...result[key], ...current[key]]
: current[key];
}
else if (isObject$1(result[key]) && isObject$1(current[key])) {
result[key] = merge(result[key], current[key]);
}
else {
result[key] =
current[key] === undefined
? merge.options.allowUndefinedOverrides
? current[key]
: result[key]
: current[key];
}
});
return result;
}, {});
const defaultOptions = {
allowUndefinedOverrides: true,
mergeArrays: true,
uniqueArrayItems: true,
};
merge.options = defaultOptions;
merge.withOptions = (options, ...objects) => {
merge.options = Object.assign(Object.assign({}, defaultOptions), options);
const result = merge(...objects);
merge.options = defaultOptions;
return result;
};
/**
* Copyright (c) 2023
*
* Common utility functions for ThoughtSpot Visual Embed SDK
* @summary Utils
* @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
*/
/**
* Construct a runtime filters query string from the given filters.
* Refer to the following docs for more details on runtime filter syntax:
* https://cloud-docs.thoughtspot.com/admin/ts-cloud/apply-runtime-filter.html
* https://cloud-docs.thoughtspot.com/admin/ts-cloud/runtime-filter-operators.html
* @param runtimeFilters
*/
const getFilterQuery = (runtimeFilters) => {
if (runtimeFilters && runtimeFilters.length) {
const filters = runtimeFilters.map((filter, valueIndex) => {
const index = valueIndex + 1;
const filterExpr = [];
filterExpr.push(`col${index}=${encodeURIComponent(filter.columnName)}`);
filterExpr.push(`op${index}=${filter.operator}`);
filterExpr.push(filter.values.map((value) => {
const encodedValue = typeof value === 'bigint' ? value.toString() : value;
return `val${index}=${encodeURIComponent(String(encodedValue))}`;
}).join('&'));
return filterExpr.join('&');
});
return `${filters.join('&')}`;
}
return null;
};
/**
* Construct a runtime parameter override query string from the given option.
* @param runtimeParameters
*/
const getRuntimeParameters = (runtimeParameters) => {
if (runtimeParameters && runtimeParameters.length) {
const params = runtimeParameters.map((param, valueIndex) => {
const index = valueIndex + 1;
const filterExpr = [];
filterExpr.push(`param${index}=${encodeURIComponent(param.name)}`);
filterExpr.push(`paramVal${index}=${encodeURIComponent(param.value)}`);
return filterExpr.join('&');
});
return `${params.join('&')}`;
}
return null;
};
/**
* Convert a value to a string representation to be sent as a query
* parameter to the ThoughtSpot app.
* @param value Any parameter value
*/
const serializeParam = (value) => {
// do not serialize primitive types
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
return value;
}
return JSON.stringify(value);
};
/**
* Convert a value to a string:
* in case of an array, we convert it to CSV.
* in case of any other type, we directly return the value.
* @param value
*/
const paramToString = (value) => (Array.isArray(value) ? value.join(',') : value);
/**
* Return a query param string composed from the given params object
* @param queryParams
* @param shouldSerializeParamValues
*/
const getQueryParamString = (queryParams, shouldSerializeParamValues = false) => {
const qp = [];
const params = Object.keys(queryParams);
params.forEach((key) => {
const val = queryParams[key];
if (val !== undefined) {
const serializedValue = shouldSerializeParamValues
? serializeParam(val)
: paramToString(val);
qp.push(`${key}=${serializedValue}`);
}
});
if (qp.length) {
return qp.join('&');
}
return null;
};
/**
* Get a string representation of a dimension value in CSS
* If numeric, it is considered in pixels.
* @param value
*/
const getCssDimension = (value) => {
if (typeof value === 'number') {
return `${value}px`;
}
return value;
};
const getSSOMarker = (markerId) => {
const encStringToAppend = encodeURIComponent(markerId);
return `tsSSOMarker=${encStringToAppend}`;
};
/**
* Append a string to a URL's hash fragment
* @param url A URL
* @param stringToAppend The string to append to the URL hash
*/
const appendToUrlHash = (url, stringToAppend) => {
let outputUrl = url;
const encStringToAppend = encodeURIComponent(stringToAppend);
const marker = `tsSSOMarker=${encStringToAppend}`;
let splitAdder = '';
if (url.indexOf('#') >= 0) {
// If second half of hash contains a '?' already add a '&' instead of
// '?' which appends to query params.
splitAdder = url.split('#')[1].indexOf('?') >= 0 ? '&' : '?';
}
else {
splitAdder = '#?';
}
outputUrl = `${outputUrl}${splitAdder}${marker}`;
return outputUrl;
};
/**
*
* @param url
* @param stringToAppend
* @param path
*/
function getRedirectUrl(url, stringToAppend, path = '') {
const targetUrl = path ? new URL(path, window.location.origin).href : url;
return appendToUrlHash(targetUrl, stringToAppend);
}
const getEncodedQueryParamsString = (queryString) => {
if (!queryString) {
return queryString;
}
return btoa(queryString).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
};
const getOffsetTop = (element) => {
const rect = element.getBoundingClientRect();
return rect.top + window.scrollY;
};
const embedEventStatus = {
START: 'start',
END: 'end',
};
const setAttributes = (element, attributes) => {
Object.keys(attributes).forEach((key) => {
element.setAttribute(key, attributes[key].toString());
});
};
const isCloudRelease = (version) => version.endsWith('.cl');
/* For Search Embed: ReleaseVersionInBeta */
const checkReleaseVersionInBeta = (releaseVersion, suppressBetaWarning) => {
if (releaseVersion !== '' && !isCloudRelease(releaseVersion)) {
const splittedReleaseVersion = releaseVersion.split('.');
const majorVersion = Number(splittedReleaseVersion[0]);
const isBetaVersion = majorVersion < 8;
return !suppressBetaWarning && isBetaVersion;
}
return false;
};
const getCustomisations = (embedConfig, viewConfig) => {
var _a, _b, _c, _d;
const customizationsFromViewConfig = viewConfig.customizations;
const customizationsFromEmbedConfig = embedConfig.customizations
|| embedConfig.customisations;
const customizations = {
style: {
...customizationsFromEmbedConfig === null || customizationsFromEmbedConfig === void 0 ? void 0 : customizationsFromEmbedConfig.style,
...customizationsFromViewConfig === null || customizationsFromViewConfig === void 0 ? void 0 : customizationsFromViewConfig.style,
customCSS: {
...(_a = customizationsFromEmbedConfig === null || customizationsFromEmbedConfig === void 0 ? void 0 : customizationsFromEmbedConfig.style) === null || _a === void 0 ? void 0 : _a.customCSS,
...(_b = customizationsFromViewConfig === null || customizationsFromViewConfig === void 0 ? void 0 : customizationsFromViewConfig.style) === null || _b === void 0 ? void 0 : _b.customCSS,
},
customCSSUrl: ((_c = customizationsFromViewConfig === null || customizationsFromViewConfig === void 0 ? void 0 : customizationsFromViewConfig.style) === null || _c === void 0 ? void 0 : _c.customCSSUrl)
|| ((_d = customizationsFromEmbedConfig === null || customizationsFromEmbedConfig === void 0 ? void 0 : customizationsFromEmbedConfig.style) === null || _d === void 0 ? void 0 : _d.customCSSUrl),
},
content: {
...customizationsFromEmbedConfig === null || customizationsFromEmbedConfig === void 0 ? void 0 : customizationsFromEmbedConfig.content,
...customizationsFromViewConfig === null || customizationsFromViewConfig === void 0 ? void 0 : customizationsFromViewConfig.content,
},
};
return customizations;
};
const getRuntimeFilters = (runtimefilters) => getFilterQuery(runtimefilters || []);
/**
* Gets a reference to the DOM node given
* a selector.
* @param domSelector
*/
function getDOMNode(domSelector) {
return typeof domSelector === 'string' ? document.querySelector(domSelector) : domSelector;
}
const deepMerge = (target, source) => merge(target, source);
const getOperationNameFromQuery = (query) => {
const regex = /(?:query|mutation)\s+(\w+)/;
const matches = query.match(regex);
return matches === null || matches === void 0 ? void 0 : matches[1];
};
/**
*
* @param obj
*/
function removeTypename(obj) {
if (!obj || typeof obj !== 'object')
return obj;
for (const key in obj) {
if (key === '__typename') {
delete obj[key];
}
else if (typeof obj[key] === 'object') {
removeTypename(obj[key]);
}
}
return obj;
}
/**
* Sets the specified style properties on an HTML element.
* @param {HTMLElement} element - The HTML element to which the styles should be applied.
* @param {Partial<CSSStyleDeclaration>} styleProperties - An object containing style
* property names and their values.
* @example
* // Apply styles to an element
* const element = document.getElementById('myElement');
* const styles = {
* backgroundColor: 'red',
* fontSize: '16px',
* };
* setStyleProperties(element, styles);
*/
const setStyleProperties = (element, styleProperties) => {
if (!(element === null || element === void 0 ? void 0 : element.style))
return;
Object.keys(styleProperties).forEach((styleProperty) => {
const styleKey = styleProperty;
const value = styleProperties[styleKey];
if (value !== undefined) {
element.style[styleKey] = value.toString();
}
});
};
/**
* Removes specified style properties from an HTML element.
* @param {HTMLElement} element - The HTML element from which the styles should be removed.
* @param {string[]} styleProperties - An array of style property names to be removed.
* @example
* // Remove styles from an element
* const element = document.getElementById('myElement');
* element.style.backgroundColor = 'red';
* const propertiesToRemove = ['backgroundColor'];
* removeStyleProperties(element, propertiesToRemove);
*/
const removeStyleProperties = (element, styleProperties) => {
if (!(element === null || element === void 0 ? void 0 : element.style))
return;
styleProperties.forEach((styleProperty) => {
element.style.removeProperty(styleProperty);
});
};
const isUndefined$1 = (value) => value === undefined;
// Return if the value is a string, double or boolean.
const getTypeFromValue = (value) => {
if (typeof value === 'string') {
return ['char', 'string'];
}
if (typeof value === 'number') {
return ['double', 'double'];
}
if (typeof value === 'boolean') {
return ['boolean', 'boolean'];
}
return ['', ''];
};
const sdkWindowKey = '_tsEmbedSDK';
/**
* Stores a value in the global `window` object under the `_tsEmbedSDK` namespace.
* @param key - The key under which the value will be stored.
* @param value - The value to store.
* @param options - Additional options.
* @param options.ignoreIfAlreadyExists - Does not set if value for key is set.
*
* @returns The stored value.
*
* @version SDK: 1.36.2 | ThoughtSpot: *
*/
function storeValueInWindow(key, value, options = {}) {
if (!window[sdkWindowKey]) {
window[sdkWindowKey] = {};
}
if (options.ignoreIfAlreadyExists && key in window[sdkWindowKey]) {
return window[sdkWindowKey][key];
}
window[sdkWindowKey][key] = value;
return value;
}
/**
* Retrieves a stored value from the global `window` object under the `_tsEmbedSDK` namespace.
* @param key - The key whose value needs to be retrieved.
* @returns The stored value or `undefined` if the key is not found.
*/
const getValueFromWindow = (key) => { var _a; return (_a = window === null || window === void 0 ? void 0 : window[sdkWindowKey]) === null || _a === void 0 ? void 0 : _a[key]; };
/**
* Check if the document is currently in fullscreen mode
*/
const isInFullscreen = () => {
return !!(document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement);
};
/**
* Handle Present HostEvent by entering fullscreen mode
* @param iframe The iframe element to make fullscreen
*/
const handlePresentEvent = async (iframe) => {
if (isInFullscreen()) {
return; // Already in fullscreen
}
// Browser-specific methods to enter fullscreen mode
const fullscreenMethods = [
'requestFullscreen',
'webkitRequestFullscreen',
'mozRequestFullScreen',
'msRequestFullscreen' // IE/Edge
];
for (const method of fullscreenMethods) {
if (typeof iframe[method] === 'function') {
try {
const result = iframe[method]();
await Promise.resolve(result);
return;
}
catch (error) {
logger$3.warn(`Failed to enter fullscreen using ${method}:`, error);
}
}
}
logger$3.error('Fullscreen API is not supported by this browser.');
};
/**
* Handle ExitPresentMode EmbedEvent by exiting fullscreen mode
*/
const handleExitPresentMode = async () => {
if (!isInFullscreen()) {
return; // Not in fullscreen
}
const exitFullscreenMethods = [
'exitFullscreen',
'webkitExitFullscreen',
'mozCancelFullScreen',
'msExitFullscreen' // IE/Edge
];
// Try each method until one works
for (const method of exitFullscreenMethods) {
if (typeof document[method] === 'function') {
try {
const result = document[method]();
await Promise.resolve(result);
return;
}
catch (error) {
logger$3.warn(`Failed to exit fullscreen using ${method}:`, error);
}
}
}
logger$3.warn('Exit fullscreen API is not supported by this browser.');
};
const calculateVisibleElementData = (element) => {
const rect = element.getBoundingClientRect();
const windowHeight = window.innerHeight;
const windowWidth = window.innerWidth;
const frameRelativeTop = Math.max(rect.top, 0);
const frameRelativeLeft = Math.max(rect.left, 0);
const frameRelativeBottom = Math.min(windowHeight, rect.bottom);
const frameRelativeRight = Math.min(windowWidth, rect.right);
const data = {
top: Math.max(0, rect.top * -1),
height: Math.max(0, frameRelativeBottom - frameRelativeTop),
left: Math.max(0, rect.left * -1),
width: Math.max(0, frameRelativeRight - frameRelativeLeft),
};
return data;
};
/**
* Copyright (c) 2023
*
* TypeScript type definitions for ThoughtSpot Visual Embed SDK
* @summary Type definitions for Embed SDK
* @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
*/
/**
* The authentication mechanism for allowing access to the
* the embedded app
* @group Authentication / Init
*/
// eslint-disable-next-line no-shadow
exports.AuthType = void 0;
(function (AuthType) {
/**
* No authentication on the SDK. Pass-through to the embedded App. Alias for
* `Passthrough`.
* @example
* ```js
* init({
* // ...
* authType: AuthType.None,
* });
* ```
*/
AuthType["None"] = "None";
/**
* Passthrough SSO to the embedded application within the iframe. Requires least
* configuration, but may not be supported by all IDPs. This will behave like `None`
* if SSO is not configured on ThoughtSpot.
*
* To use this:
* Your SAML or OpenID provider must allow iframe redirects.
* For example, if you are using Okta as IdP, you can enable iframe embedding.
* @example
* ```js
* init({
* // ...
* authType: AuthType.EmbeddedSSO,
* });
* ```
* @version: SDK: 1.15.0 | ThoughtSpot: 8.8.0.cl
*/
AuthType["EmbeddedSSO"] = "EmbeddedSSO";
/**
* SSO using SAML
* @deprecated Use {@link SAMLRedirect} instead
* @hidden
*/
AuthType["SSO"] = "SSO_SAML";
/**
* SSO using SAML
* @deprecated Use {@link SAMLRedirect} instead
* @hidden
*/
AuthType["SAML"] = "SSO_SAML";
/**
* SSO using SAML
* Makes the host application redirect to the SAML IdP. Use this
* if your IdP does not allow itself to be embedded.
*
* This redirects the host application to the SAML IdP. The host application
* will be redirected back to the ThoughtSpot app after authentication.
* @example
* ```js
* init({
* // ...
* authType: AuthType.SAMLRedirect,
* });
* ```
*
* This opens the SAML IdP in a popup window. The popup is triggered
* when the user clicks the trigger button. The popup window will be
* closed automatically after authentication.
* @example
* ```js
* init({
* // ...
* authType: AuthType.SAMLRedirect,
* authTriggerText: 'Login with SAML',
* authTriggerContainer: '#tsEmbed',
* inPopup: true,
* });
* ```
*
* Can also use the event to trigger the popup flow. Works the same
* as the above example.
* @example
* ```js
* const authEE = init({
* // ...
* authType: AuthType.SAMLRedirect,
* inPopup: true,
* });
*
* someButtonOnYourPage.addEventListener('click', () => {
* authEE.emit(AuthEvent.TRIGGER_SSO_POPUP);
* });
* ```
*/
AuthType["SAMLRedirect"] = "SSO_SAML";
/**
* SSO using OIDC
* @hidden
* @deprecated Use {@link OIDCRedirect} instead
*/
AuthType["OIDC"] = "SSO_OIDC";
/**
* SSO using OIDC
* Will make the host application redirect to the OIDC IdP.
* See code samples in {@link SAMLRedirect}.
*/
AuthType["OIDCRedirect"] = "SSO_OIDC";
/**
* Trusted authentication server
* @hidden
* @deprecated Use {@link TrustedAuth} instead
*/
AuthType["AuthServer"] = "AuthServer";
/**
* Trusted authentication server. Use your own authentication server
* which returns a bearer token, generated using the `secret_key` obtained
* from ThoughtSpot.
* @example
* ```js
* init({
* // ...
* authType: AuthType.TrustedAuthToken,
* getAuthToken: () => {
* return fetch('https://my-backend.app/ts-token')
* .then((response) => response.json())
* .then((data) => data.token);
* }
* });
* ```
*/
AuthType["TrustedAuthToken"] = "AuthServer";
/**
* Trusted authentication server Cookieless, Use your own authentication
* server which returns a bearer token, generated using the `secret_key`
* obtained from ThoughtSpot. This uses a cookieless authentication
* approach, recommended to bypass the third-party cookie-blocking restriction
* implemented by some browsers.
* @example
* ```js
* init({
* // ...
* authType: AuthType.TrustedAuthTokenCookieless,
* getAuthToken: () => {
* return fetch('https://my-backend.app/ts-token')
* .then((response) => response.json())
* .then((data) => data.token);
* }
* ```
* @version SDK: 1.22.0| ThoughtSpot: 9.3.0.cl, 9.5.1.sw
*/
AuthType["TrustedAuthTokenCookieless"] = "AuthServerCookieless";
/**
* Use the ThoughtSpot login API to authenticate to the cluster directly.
*
* Warning: This feature is primarily intended for developer testing. It is
* strongly advised not to use this authentication method in production.
*/
AuthType["Basic"] = "Basic";
})(exports.AuthType || (exports.AuthType = {}));
/**
*
* This option does not apply to the classic homepage experience.
* To access the updated modular homepage,
* set `modularHomeExperience` to `true`
* (available as Early Access feature in 9.12.5.cl).
*
*/
exports.HomeLeftNavItem = void 0;
(function (HomeLeftNavItem) {
/**
* @version SDK: 1.28.0| ThoughtSpot: 9.12.5.cl
*/
HomeLeftNavItem["SearchData"] = "search-data";
/**
* @version SDK: 1.28.0| ThoughtSpot: 9.12.5.cl
*/
HomeLeftNavItem["Home"] = "insights-home";
/**
* @version SDK: 1.28.0| ThoughtSpot: 9.12.5.cl
*/
HomeLeftNavItem["Liveboards"] = "liveboards";
/**
* @version SDK: 1.28.0| ThoughtSpot: 9.12.5.cl
*/
HomeLeftNavItem["Answers"] = "answers";
/**
* @version SDK: 1.28.0| ThoughtSpot: 9.12.5.cl
*/
HomeLeftNavItem["MonitorSubscription"] = "monitor-alerts";
/**
* @version SDK: 1.28.0| ThoughtSpot: 9.12.5.cl
*/
HomeLeftNavItem["SpotIQAnalysis"] = "spotiq-analysis";
/**
* @version SDK: 1.34.0| ThoughtSpot: 10.3.0.cl
*/
HomeLeftNavItem["LiveboardSchedules"] = "liveboard-schedules";
/**
* Create new options in the insights left navigation,
* available when new navigation V3 is enabled.
* @version SDK: 1.40.0 | ThoughtSpot: 10.11.0.cl
*/
HomeLeftNavItem["Create"] = "create";
/**
* Spotter option in the insights left navigation,
* available when new navigation V3 is enabled.
* @version SDK: 1.40.0 | ThoughtSpot: 10.11.0.cl
*/
HomeLeftNavItem["Spotter"] = "spotter";
/**
* Favorites option in the insights left navigation,
* available when new navigation V3 is enabled.
* @version SDK: 1.41.0 | ThoughtSpot: 10.12.0.cl
*/
HomeLeftNavItem["Favorites"] = "favorites";
})(exports.HomeLeftNavItem || (exports.HomeLeftNavItem = {}));
/**
* A map of the supported runtime filter operations
*/
// eslint-disable-next-line no-shadow
exports.RuntimeFilterOp = void 0;
(function (RuntimeFilterOp) {
/**
* Equals
*/
RuntimeFilterOp["EQ"] = "EQ";
/**
* Does not equal
*/
RuntimeFilterOp["NE"] = "NE";
/**
* Less than
*/
RuntimeFilterOp["LT"] = "LT";
/**
* Less than or equal to
*/
RuntimeFilterOp["LE"] = "LE";
/**
* Greater than
*/
RuntimeFilterOp["GT"] = "GT";
/**
* Greater than or equal to
*/
RuntimeFilterOp["GE"] = "GE";
/**
* Contains
*/
RuntimeFilterOp["CONTAINS"] = "CONTAINS";
/**
* Begins with
*/
RuntimeFilterOp["BEGINS_WITH"] = "BEGINS_WITH";
/**
* Ends with
*/
RuntimeFilterOp["ENDS_WITH"] = "ENDS_WITH";
/**
* Between, inclusive of higher value
*/
RuntimeFilterOp["BW_INC_MAX"] = "BW_INC_MAX";
/**
* Between, inclusive of lower value
*/
RuntimeFilterOp["BW_INC_MIN"] = "BW_INC_MIN";
/**
* Between, inclusive of both higher and lower value
*/
RuntimeFilterOp["BW_INC"] = "BW_INC";
/**
* Between, non-inclusive
*/
RuntimeFilterOp["BW"] = "BW";
/**
* Is included in this list of values
*/
RuntimeFilterOp["IN"] = "IN";
/**
* Is not included in this list of values
*/
RuntimeFilterOp["NOT_IN"] = "NOT_IN";
})(exports.RuntimeFilterOp || (exports.RuntimeFilterOp = {}));
/**
* Home page module that can be hidden.
* **Note**: This option does not apply to the classic homepage.
* To access the updated modular homepage, set
* `modularHomeExperience` to `true` (available as Early Access feature in 9.12.5.cl).
* @version SDK: 1.28.0 | ThoughtSpot: 9.12.5.cl, 10.1.0.sw
*/
// eslint-disable-next-line no-shadow
exports.HomepageModule = void 0;
(function (HomepageModule) {
/**
* Search bar
*/
HomepageModule["Search"] = "SEARCH";
/**
* kPI watchlist module
*/
HomepageModule["Watchlist"] = "WATCHLIST";
/**
* favorite objects
*/
HomepageModule["Favorite"] = "FAVORITE";
/**
* List of answers and Liveboards
*/
HomepageModule["MyLibrary"] = "MY_LIBRARY";
/**
* Trending list
*/
HomepageModule["Trending"] = "TRENDING";
/**
* Learning videos
*/
HomepageModule["Learning"] = "LEARNING";
})(exports.HomepageModule || (exports.HomepageModule = {}));
/**
* List page columns that can be hidden.
* **Note**: This option is applicable to full app embedding only.
* @version SDK: 1.38.0 | ThoughtSpot: 10.9.0.cl
*/
// eslint-disable-next-line no-shadow
exports.ListPageColumns = void 0;
(function (ListPageColumns) {
/**
* Favourite
*/
ListPageColumns["Favourite"] = "FAVOURITE";
/**
* Tags
*/
ListPageColumns["Tags"] = "TAGS";
/**
* Author
*/
ListPageColumns["Author"] = "AUTHOR";
/**
* Last viewed/Last modified
*/
ListPageColumns["DateSort"] = "DATE_SORT";
/**
* Share
*/
ListPageColumns["Share"] = "SHARE";
})(exports.ListPageColumns || (exports.ListPageColumns = {}));
/**
* Event types emitted by the embedded ThoughtSpot application.
*
* To add an event listener use the corresponding
* {@link LiveboardEmbed.on} or {@link AppEmbed.on} or {@link SearchEmbed.on} method.
* @example
* ```js
* import { EmbedEvent } from '@thoughtspot/visual-embed-sdk';
* // Or
* // const { EmbedEvent } = window.tsembed;
*
* // create the liveboard embed.
*
* liveboardEmbed.on(EmbedEvent.Drilldown, (drilldown) => {
* console.log('Drilldown event', drilldown);
* }));
* ```
*
* If you are using React components for embedding, you can register to any
* events from the `EmbedEvent` list by using the `on<EventName>` convention.
* For example,`onAlert`, `onCopyToClipboard` and so on.
* @example
* ```js
* // ...
* const MyComponent = ({ dataSources }) => {
* const onLoad = () => {
* console.log(EmbedEvent.Load, {});
* };
*
* return (
* <SearchEmbed
* dataSources={dataSources}
* onLoad = {logEvent("Load")}
* />
* );
* };
* ```
* @group Events
*/
// eslint-disable-next-line no-shadow
exports.EmbedEvent = void 0;
(function (EmbedEvent) {
/**
* Rendering has initialized.
* @example
*```js
* liveboardEmbed.on(EmbedEvent.Init, showLoader)
* //show a loader
* function showLoader() {
* document.getElementById("loader");
* }
*```
* @returns timestamp - The timestamp when the event was generated.
*/
EmbedEvent["Init"] = "init";
/**
* Authentication has either succeeded or failed.
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 8.4.1.sw
* @example
*```js
* appEmbed.on(EmbedEvent.AuthInit, payload => {
* console.log('AuthInit', payload);
* })
*```
* @returns isLoggedIn - A Boolean specifying whether authentication was successful.
*/
EmbedEvent["AuthInit"] = "authInit";
/**
* The embed object container has loaded.
* @returns timestamp - The timestamp when the event was generated.
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 8.4.1.sw
* @example
*```js
* liveboardEmbed.on(EmbedEvent.Load, hideLoader)
* //hide loader
* function hideLoader() {
* document.getElementById("loader");
* }
*```
*/
EmbedEvent["Load"] = "load";
/**
* Data pertaining to an Answer or Liveboard is received.
* The event payload includes the raw data of the object.
* @return data - Answer of Liveboard data
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 8.4.1.sw
* @example
*```js
* liveboardEmbed.on(EmbedEvent.Data, payload => {
* console.log('data', payload);
* })
*```
* @important
*/
EmbedEvent["Data"] = "data";
/**
* Search query has been updated by the user.
* @version SDK: 1.4.0 | ThoughtSpot: ts7.sep.cl, 8.4.1.sw
* @example
*```js
* searchEmbed.on(EmbedEvent.QueryChanged, payload => console.log('data', payload))
*```
*/
EmbedEvent["QueryChanged"] = "queryChanged";
/**
* A drill-down operation has been performed.
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 8.4.1.sw
* @returns additionalFilters - Any additional filters applied
* @returns drillDownColumns - The columns on which drill down was performed
* @returns nonFilteredColumns - The columns that were not filtered
* @example
*```js
* searchEmbed.on(EmbedEvent.DrillDown, {
* points: {
* clickedPoint,
* selectedPoints: selectedPoint
* },
* autoDrillDown: true,
* })
*```
* In this example, `VizPointDoubleClick` event is used for
* triggering the `DrillDown` event when an area or specific
* data point on a table or chart is double-clicked.
* @example
*```js
* searchEmbed.on(EmbedEvent.VizPointDoubleClick, (payload) => {
* console.log(payload);
* const clickedPoint = payload.data.clickedPoint;
* const selectedPoint = payload.data.selectedPoints;
* console.log('>>> called', clickedPoint);
* embed.trigger(HostEvent.DrillDown, {
* points: {
* clickedPoint,
* selectedPoints: selectedPoint
* },
* autoDrillDown: true,
* })
* })
*```
*/
EmbedEvent["Drilldown"] = "drillDown";
/**
* One or more data sources have been selected.
* @returns dataSourceIds - the list of data sources
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 8.4.1.sw
* @example
* ```js
* searchEmbed.on(EmbedEvent.DataSourceSelected, payload => {
* console.log('DataSourceSelected', payload);
* })
* ```
*/
EmbedEvent["DataSourceSelected"] = "dataSourceSelected";
/**
* One or more data columns have been selected.
* @returns columnIds - the list of columns
* @version SDK: 1.10.0 | ThoughtSpot: 8.2.0.cl, 8.4.1.sw
* @example
* ```js
* appEmbed.on(EmbedEvent.AddRemoveColumns, payload => {
* console.log('AddRemoveColumns', payload);
* })
* ```
*/
EmbedEvent["AddRemoveColumns"] = "addRemoveColumns";
/**
* A custom action has been triggered.
* @returns actionId - ID of the custom action
* @returns payload {@link CustomActionPayload} - Response payload with the
* Answer or Liveboard data
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 8.4.1.sw
* @example
* ```js
* appEmbed.on(EmbedEvent.customAction, payload => {
* const data = payload.data;
* if (data.id === 'insert Custom Action ID here') {
* console.log('Custom Action event:', data.embedAnswerData);
* }
* })
* ```
*/
EmbedEvent["CustomAction"] = "customAction";
/**
* Listen to double click actions on a visualization.
* @return ContextMenuInputPoints - Data point that is double-clicked
* @version SDK: 1.5.0 | ThoughtSpot: ts7.oct.cl, 7.2.1
* @example
* ```js
* LiveboardEmbed.on(EmbedEvent.VizPointDoubleClick, payload => {
* console.log('VizPointDoubleClick', payload);
* })
* ```
*/
EmbedEvent["VizPointDoubleClick"] = "vizPointDoubleClick";
/**
* Listen to clicks on a visualization in a Liveboard or Search result.
* @return viz, clickedPoint - metadata about the point that is clicked
* @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
* @important
* @example
* ```js
* embed.on(EmbedEvent.VizPointClick, ({data}) => {
* console.log(
* data.vizId, // viz id
* data.clickedPoint.selectedAttributes[0].value,
* data.clickedPoint.selectedAttributes[0].column.name,
* data.clickedPoint.selectedMeasures[0].value,
* data.clickedPoint.selectedMeasures[0].column.name,
* )
* });
* ```
*/
EmbedEvent["VizPointClick"] = "vizPointClick";
/**
* An error has occurred. This event is fired for the following error types:
*
* `API` - API call failure error.
* `FULLSCREEN` - Error when presenting a Liveboard or visualization in full screen
* mode. `SINGLE_VALUE_FILTER` - Error due to multiple values in the single value
* filter. `NON_EXIST_FILTER` - Error due to a non-existent filter.
* `INVALID_DATE_VALUE` - Invalid date value error.
* `INVALID_OPERATOR` - Use of invalid operator during filter application.
*
* For more information, see https://developers.thoughtspot.com/docs/events-app-integration#errorType
* @returns error - An error object or message
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 8.4.1.sw
* @example
* ```js
* // API error
* SearchEmbed.on(EmbedEvent.Error, (error) => {
* console.log(error);
* // { type: "Error", data: { errorType: "API", error: { message: '...', error: '...' } } }
* });
* ```
* @example
* ```js
* // Fullscreen error (Errors during presenting of a liveboard)
* LiveboardEmbed.on(EmbedEvent.Error, (error) => {
* console.log(error);
* // { type: "Error", data: { errorType: "FULLSCREEN", error: {
* // message: "Fullscreen API is not enabled",
* // stack: "..."
* // } }}
* })
* ```
*/
EmbedEvent["Error"] = "Error";
/**
* The embedded object has sent an alert.
* @returns alert - An alert object
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 8.4.1.sw
* @example
* ```js
* searchEmbed.on(EmbedEvent.Alert)
* ```
*/
EmbedEvent["Alert"] = "alert";
/**
* The ThoughtSpot authentication session has expired.
* @version SDK: 1.4.0 | ThoughtSpot: ts7.sep.cl, 8.4.1.sw
* @example
*```js
* appEmbed.on(EmbedEvent.AuthExpire, showAuthExpired)
* //show auth expired banner
* function showAuthExpired() {
* document.getElementById("authExpiredBanner");
* }
*```
*/
EmbedEvent["AuthExpire"] = "ThoughtspotAuthExpired";
/**
* ThoughtSpot failed to validate the auth session.
* @hidden
*/
EmbedEvent["AuthFailure"] = "ThoughtspotAuthFailure";
/**
* ThoughtSpot failed to re validate the auth session.
* @hidden
*/
EmbedEvent["IdleSessionTimeout"] = "IdleSessionTimeout";
/**
* ThoughtSpot failed to validate the auth session.
* @hidden
*/
EmbedEvent["AuthLogout"] = "ThoughtspotAuthLogout";
/**
* The height of the embedded Liveboard or visualization has been computed.
* @returns data - The height of the embedded Liveboard or visualization
* @hidden
*/
EmbedEvent["EmbedHeight"] = "EMBED_HEIGHT";
/**
* The center of visible iframe viewport is calculated.
* @returns data - The center of the visible Iframe viewport.
* @hidden
*/
EmbedEvent["EmbedIframeCenter"] = "EmbedIframeCenter";
/**
* Emitted when the **Get Data** action is initiated.
* Applicable to `SearchBarEmbed` only.
* @version SDK: 1.19.0 | ThoughtSpot: 9.0.0.cl, 9.0.1.sw
* @example
*```js
* searchbarEmbed.on(EmbedEvent.GetDataClick)
* .then(data => {
* console.log('Answer Data:', data);
* })
*```
*/
EmbedEvent["GetDataClick"] = "getDataClick";
/**
* Detects the route change.
* @version SDK: 1.7.0 | ThoughtSpot: 8.0.0.cl, 8.4.1.sw
* @example
*```js
* searchEmbed.on(EmbedEvent.RouteChange, payload =>
* console.log('data', payload))
*```
*/
EmbedEvent["RouteChange"] = "ROUTE_CHANGE";
/**
* The v1 event type for Data
* @hidden
*/
EmbedEvent["V1Data"] = "exportVizDataToParent";
/**
* Emitted when the embed does not have cookie access. This happens
* when Safari and other Web browsers block third-party cookies
* are blocked by default. `NoCookieAccess` can trigger.
* @example
*```js
* appEmbed.on(EmbedEvent.NoCookieAccess)
*```
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 7.2.1.sw
*/
EmbedEvent["NoCookieAccess"] = "noCookieAccess";
/**
* Emitted when SAML is complete
* @private
* @hidden
*/
EmbedEvent["SAMLComplete"] = "samlComplete";
/**
* Emitted when any modal is opened in the app
* @version SDK: 1.6.0 | ThoughtSpot: ts8.nov.cl, 8.4.1.sw
* @example
*```js
* appEmbed.on(EmbedEvent.DialogOpen, payload => {
* console.log('dialog open', payload);
* })
*```
*/
EmbedEvent["DialogOpen"] = "dialog-open";
/**
* Emitted when any modal is closed in the app
* @version SDK: 1.6.0 | ThoughtSpot: ts8.nov.cl, 8.4.1.sw
* @example
*```js
* appEmbed.on(EmbedEvent.DialogClose, payload => {
* console.log('dialog close', payload);
* })
*```
*/
EmbedEvent["DialogClose"] = "dialog-close";
/**
* Emitted when the Liveboard shell loads.
* You can use this event as a hook to trigger
* other events on the rendered Liveboard.
* @version SDK: 1.9.1 | ThoughtSpot: 8.1.0.cl, 8.4.1.sw
* @example
*```js
* liveboardEmbed.on(EmbedEvent.LiveboardRendered, payload => {
console.log('Liveboard is rendered', payload);
})
*```
* The following example shows how to trigger
* `SetVisibleVizs` event using LiveboardRendered embed event:
* @example
*```js
* const embedRef = useEmbedRef();
* const onLiveboardRendered = () => {
* embed.trigger(HostEvent.SetVisibleVizs, ['viz1', 'viz2']);
* };
*```
*/
EmbedEvent["LiveboardRendered"] = "PinboardRendered";
/**
* Emits all events.
* @Version SDK: 1.10.0 | ThoughtSpot: 8.2.0.cl, 8.4.1.sw
* @example
*```js
* appEmbed.on(EmbedEvent.ALL, payload => {
* console.log('Embed Events', payload)
* })
*```
*/
EmbedEvent["ALL"] = "*";
/**
* Emitted when an Answer is saved in the app
* @Version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
* @example
*```js
* //Emit when action starts
* searchEmbed.on(EmbedEvent.Save, payload => {
* console.log('Save', payload)
* }, {
* start: true
* })
* //emit when action ends
* searchEmbed.on(EmbedEvent.Save, payload => {
* console.log('Save', payload)
* })
*```
*/
EmbedEvent["Save"] = "save";
/**
* Emitted when the download action is triggered on an Answer.
*
* **Note**: This event is deprecated in v1.21.0.
* To fire an event when a download action is initiated on a chart or table,
* use `EmbedEvent.DownloadAsPng`, `EmbedEvent.DownloadAsPDF`,
* `EmbedEvent.DownloadAsCSV`, or `EmbedEvent.DownloadAsXLSX`
* @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
* @example
*```js
* liveboardEmbed.on(EmbedEvent.Download, {
* vizId: '730496d6-6903-4601-937e-2c691821af3c'
* })
*```
*/
EmbedEvent["Download"] = "download";
/**
* Emitted when the download action is triggered on an Answer.
* @version SDK: 1.21.0 | ThoughtSpot: 9.2.0.cl, 9.4.0.sw
* @example
*```js
* //emit when action starts
* searchEmbed.on(EmbedEvent.DownloadAsPng, payload => {
* console.log('download PNG', payload)}, {start: true })
* //emit when action ends
* searchEmbed.on(EmbedEvent.DownloadAsPng, payload => {
* console.log('download PNG', payload)})
*```
*/
EmbedEvent["DownloadAsPng"] = "downloadAsPng";
/**
* Emitted when the Download as PDF action is triggered on an Answer
* @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
* @example
*```js
* //emit when action starts
* searchEmbed.on(EmbedEvent.DownloadAsPdf, payload => {
* console.log('download PDF', payload)}, {start: true })
* //emit when action ends
* searchEmbed.on(EmbedEvent.DownloadAsPdf, payload => {
* console.log('download PDF', payload)})
*```
*/
EmbedEvent["DownloadAsPdf"] = "downloadAsPdf";
/**
* Emitted when the Download as CSV action is triggered on an Answer.
* @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
* @example
*```js
* //emit when action starts
* searchEmbed.on(EmbedEvent.DownloadAsCSV, payload => {
* console.log('download CSV', payload)}, {start: true })
* //emit when action ends
* searchEmbed.on(EmbedEvent.DownloadAsCSV, payload => {
* console.log('download CSV', payload)})
*```
*/
EmbedEvent["DownloadAsCsv"] = "downloadAsCsv";
/**
* Emitted when the Download as XLSX action is triggered on an Answer.
* @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
* @example
*```js
* //emit when action starts
* searchEmbed.on(EmbedEvent.DownloadAsXlsx, payload => {
* console.log('download Xlsx', payload)}, { start: true })
* //