UNPKG

@thoughtspot/visual-embed-sdk

Version:
363 lines 15.9 kB
"use strict"; /** * Copyright (c) 2022 * * Embed a ThoughtSpot Liveboard or visualization * https://developers.thoughtspot.com/docs/?pageid=embed-pinboard * https://developers.thoughtspot.com/docs/?pageid=embed-a-viz * @summary Liveboard & visualization embed * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.PinboardEmbed = exports.LiveboardEmbed = void 0; const preview_service_1 = require("../utils/graphql/preview-service"); const errors_1 = require("../errors"); const types_1 = require("../types"); const utils_1 = require("../utils"); const ts_embed_1 = require("./ts-embed"); const global_styles_1 = require("../utils/global-styles"); const logger_1 = require("../utils/logger"); /** * Embed a ThoughtSpot Liveboard or visualization. When rendered it already * waits for the authentication to complete, so you need not wait for * `AuthStatus.SUCCESS`. * @example * ```js * import { .. } from '@thoughtspot/visual-embed-sdk'; * init({ ... }); * const embed = new LiveboardEmbed("#container", { * liveboardId: <your-id-here>, * // .. other params here. * }) * ``` * @group Embed components */ class LiveboardEmbed extends ts_embed_1.V1Embed { constructor(domSelector, viewConfig) { viewConfig.embedComponentType = 'LiveboardEmbed'; super(domSelector, viewConfig); this.defaultHeight = 500; this.sendFullHeightLazyLoadData = () => { const data = (0, utils_1.calculateVisibleElementData)(this.iFrame); this.trigger(types_1.HostEvent.VisibleEmbedCoordinates, data); }; /** * This is a handler for the RequestVisibleEmbedCoordinates event. * It is used to send the visible coordinates data to the host application. * @param data The event payload * @param responder The responder function */ this.requestVisibleEmbedCoordinatesHandler = (data, responder) => { logger_1.logger.info('Sending RequestVisibleEmbedCoordinates', data); const visibleCoordinatesData = (0, utils_1.calculateVisibleElementData)(this.iFrame); responder({ type: types_1.EmbedEvent.RequestVisibleEmbedCoordinates, data: visibleCoordinatesData }); }; /** * Set the iframe height as per the computed height received * from the ThoughtSpot app. * @param data The event payload */ this.updateIFrameHeight = (data) => { this.setIFrameHeight(Math.max(data.data, this.defaultHeight)); this.sendFullHeightLazyLoadData(); }; this.embedIframeCenter = (data, responder) => { const obj = this.getIframeCenter(); responder({ type: types_1.EmbedEvent.EmbedIframeCenter, data: obj }); }; this.setIframeHeightForNonEmbedLiveboard = (data) => { const { height: frameHeight } = this.viewConfig.frameParams || {}; const liveboardRelatedRoutes = [ '/pinboard/', '/insights/pinboard/', '/schedules/', '/embed/viz/', '/embed/insights/viz/', '/liveboard/', '/insights/liveboard/', '/tsl-editor/PINBOARD_ANSWER_BOOK/', '/import-tsl/PINBOARD_ANSWER_BOOK/', ]; if (liveboardRelatedRoutes.some((path) => data.data.currentPath.startsWith(path))) { // Ignore the height reset of the frame, if the navigation is // only within the liveboard page. return; } this.setIFrameHeight(frameHeight || this.defaultHeight); }; /** * @hidden * Internal state to track the current liveboard id. * This is used to navigate to the correct liveboard when the prerender is visible. */ this.currentLiveboardState = { liveboardId: this.viewConfig.liveboardId, vizId: this.viewConfig.vizId, activeTabId: this.viewConfig.activeTabId, }; if (this.viewConfig.fullHeight === true) { if (this.viewConfig.vizId) { logger_1.logger.warn('Full height is currently only supported for Liveboard embeds.' + 'Using full height with vizId might lead to unexpected behavior.'); } this.on(types_1.EmbedEvent.RouteChange, this.setIframeHeightForNonEmbedLiveboard); this.on(types_1.EmbedEvent.EmbedHeight, this.updateIFrameHeight); this.on(types_1.EmbedEvent.EmbedIframeCenter, this.embedIframeCenter); this.on(types_1.EmbedEvent.RequestVisibleEmbedCoordinates, this.requestVisibleEmbedCoordinatesHandler); } } /** * Construct a map of params to be passed on to the * embedded Liveboard or visualization. */ getEmbedParams() { let params = {}; params = this.getBaseQueryParams(params); const { enableVizTransformations, fullHeight, defaultHeight, visibleVizs, liveboardV2, vizId, hideTabPanel, activeTabId, hideLiveboardHeader, showLiveboardDescription, showLiveboardTitle, isLiveboardHeaderSticky = true, isLiveboardCompactHeaderEnabled = false, showLiveboardVerifiedBadge = true, showLiveboardReverifyBanner = true, hideIrrelevantChipsInLiveboardTabs = false, enableAskSage, enable2ColumnLayout, dataPanelV2 = true, enableCustomColumnGroups = false, oAuthPollingInterval, isForceRedirect, dataSourceId, coverAndFilterOptionInPDF = false, liveboardXLSXCSVDownload = false, isLiveboardStylingAndGroupingEnabled, isPNGInScheduledEmailsEnabled = false, showSpotterLimitations, } = this.viewConfig; const preventLiveboardFilterRemoval = this.viewConfig.preventLiveboardFilterRemoval || this.viewConfig.preventPinboardFilterRemoval; if (fullHeight === true) { params[types_1.Param.fullHeight] = true; if (this.viewConfig.lazyLoadingForFullHeight) { params[types_1.Param.IsLazyLoadingForEmbedEnabled] = true; params[types_1.Param.RootMarginForLazyLoad] = this.viewConfig.lazyLoadingMargin; } } if (defaultHeight) { this.defaultHeight = defaultHeight; } if (enableVizTransformations !== undefined) { params[types_1.Param.EnableVizTransformations] = enableVizTransformations.toString(); } if (preventLiveboardFilterRemoval) { params[types_1.Param.preventLiveboardFilterRemoval] = true; } if (visibleVizs) { params[types_1.Param.visibleVizs] = visibleVizs; } params[types_1.Param.livedBoardEmbed] = true; if (vizId) { params[types_1.Param.vizEmbed] = true; } if (liveboardV2 !== undefined) { params[types_1.Param.LiveboardV2Enabled] = liveboardV2; } if (enable2ColumnLayout !== undefined) { params[types_1.Param.Enable2ColumnLayout] = enable2ColumnLayout; } if (hideTabPanel) { params[types_1.Param.HideTabPanel] = hideTabPanel; } if (hideLiveboardHeader) { params[types_1.Param.HideLiveboardHeader] = hideLiveboardHeader; } if (showLiveboardDescription) { params[types_1.Param.ShowLiveboardDescription] = showLiveboardDescription; } if (showLiveboardTitle) { params[types_1.Param.ShowLiveboardTitle] = showLiveboardTitle; } if (enableAskSage) { params[types_1.Param.enableAskSage] = enableAskSage; } if (oAuthPollingInterval !== undefined) { params[types_1.Param.OauthPollingInterval] = oAuthPollingInterval; } if (isForceRedirect) { params[types_1.Param.IsForceRedirect] = isForceRedirect; } if (dataSourceId !== undefined) { params[types_1.Param.DataSourceId] = dataSourceId; } if (isLiveboardStylingAndGroupingEnabled !== undefined) { params[types_1.Param.IsLiveboardStylingAndGroupingEnabled] = isLiveboardStylingAndGroupingEnabled; } if (isPNGInScheduledEmailsEnabled !== undefined) { params[types_1.Param.isPNGInScheduledEmailsEnabled] = isPNGInScheduledEmailsEnabled; } if (showSpotterLimitations !== undefined) { params[types_1.Param.ShowSpotterLimitations] = showSpotterLimitations; } params[types_1.Param.LiveboardHeaderSticky] = isLiveboardHeaderSticky; params[types_1.Param.LiveboardHeaderV2] = isLiveboardCompactHeaderEnabled; params[types_1.Param.ShowLiveboardVerifiedBadge] = showLiveboardVerifiedBadge; params[types_1.Param.ShowLiveboardReverifyBanner] = showLiveboardReverifyBanner; params[types_1.Param.HideIrrelevantFiltersInTab] = hideIrrelevantChipsInLiveboardTabs; params[types_1.Param.DataPanelV2Enabled] = dataPanelV2; params[types_1.Param.EnableCustomColumnGroups] = enableCustomColumnGroups; params[types_1.Param.CoverAndFilterOptionInPDF] = coverAndFilterOptionInPDF; params[types_1.Param.LiveboardXLSXCSVDownload] = !!liveboardXLSXCSVDownload; const queryParams = (0, utils_1.getQueryParamString)(params, true); return queryParams; } getIframeSuffixSrc(liveboardId, vizId, activeTabId) { let suffix = `/embed/viz/${liveboardId}`; if (activeTabId) { suffix = `${suffix}/tab/${activeTabId} `; } if (vizId) { suffix = `${suffix}/${vizId}`; } const tsPostHashParams = this.getThoughtSpotPostUrlParams(); suffix = `${suffix}${tsPostHashParams}`; return suffix; } /** * Construct the URL of the embedded ThoughtSpot Liveboard or visualization * to be loaded within the iFrame. */ getIFrameSrc() { var _a; const { vizId, activeTabId } = this.viewConfig; const liveboardId = (_a = this.viewConfig.liveboardId) !== null && _a !== void 0 ? _a : this.viewConfig.pinboardId; if (!liveboardId) { this.handleError(errors_1.ERROR_MESSAGE.LIVEBOARD_VIZ_ID_VALIDATION); } return `${this.getRootIframeSrc()}${this.getIframeSuffixSrc(liveboardId, vizId, activeTabId)}`; } setActiveTab(data) { if (!this.viewConfig.vizId) { const prefixPath = this.iFrame.src.split('#/')[1].split('/tab')[0]; const path = `${prefixPath}/tab/${data.tabId}`; super.trigger(types_1.HostEvent.Navigate, path); } } async showPreviewLoader() { if (!this.viewConfig.showPreviewLoader || !this.viewConfig.vizId) { return; } try { const preview = await (0, preview_service_1.getPreview)(this.thoughtSpotHost, this.viewConfig.vizId, this.viewConfig.liveboardId); if (!preview.vizContent) { return; } (0, global_styles_1.addPreviewStylesIfNotPresent)(); const div = document.createElement('div'); div.innerHTML = ` <div class=ts-viz-preview-loader> ${preview.vizContent} </div> `; const previewDiv = div.firstElementChild; this.el.appendChild(previewDiv); this.el.style.position = 'relative'; this.on(types_1.EmbedEvent.Data, () => { previewDiv.remove(); }); } catch (error) { console.error('Error fetching preview', error); } } beforePrerenderVisible() { const embedObj = this.getPreRenderObj(); this.executeAfterEmbedContainerLoaded(() => { this.navigateToLiveboard(this.viewConfig.liveboardId, this.viewConfig.vizId, this.viewConfig.activeTabId); if (embedObj) { embedObj.currentLiveboardState = { liveboardId: this.viewConfig.liveboardId, vizId: this.viewConfig.vizId, activeTabId: this.viewConfig.activeTabId, }; } }); } async handleRenderForPrerender() { if ((0, utils_1.isUndefined)(this.viewConfig.liveboardId)) { return this.prerenderGeneric(); } return super.handleRenderForPrerender(); } /** * Triggers an event to the embedded app * @param {HostEvent} messageType The event type * @param {any} data The payload to send with the message * @returns A promise that resolves with the response from the embedded app */ trigger(messageType, data = {}) { const dataWithVizId = data; if (messageType === types_1.HostEvent.SetActiveTab) { this.setActiveTab(data); return Promise.resolve(null); } if (typeof dataWithVizId === 'object' && this.viewConfig.vizId) { dataWithVizId.vizId = this.viewConfig.vizId; } return super.trigger(messageType, dataWithVizId); } /** * Destroys the ThoughtSpot embed, and remove any nodes from the DOM. * @version SDK: 1.39.0 | ThoughtSpot: 10.10.0.cl */ destroy() { super.destroy(); this.unregisterLazyLoadEvents(); } postRender() { this.registerLazyLoadEvents(); } registerLazyLoadEvents() { if (this.viewConfig.fullHeight && this.viewConfig.lazyLoadingForFullHeight) { // TODO: Use passive: true, install modernizr to check for passive window.addEventListener('resize', this.sendFullHeightLazyLoadData); window.addEventListener('scroll', this.sendFullHeightLazyLoadData, true); } } unregisterLazyLoadEvents() { if (this.viewConfig.fullHeight && this.viewConfig.lazyLoadingForFullHeight) { window.removeEventListener('resize', this.sendFullHeightLazyLoadData); window.removeEventListener('scroll', this.sendFullHeightLazyLoadData); } } /** * Render an embedded ThoughtSpot Liveboard or visualization * @param renderOptions An object specifying the Liveboard ID, * visualization ID and the runtime filters. */ async render() { await super.render(); const src = this.getIFrameSrc(); await this.renderV1Embed(src); this.showPreviewLoader(); this.postRender(); return this; } navigateToLiveboard(liveboardId, vizId, activeTabId) { const path = this.getIframeSuffixSrc(liveboardId, vizId, activeTabId); this.viewConfig.liveboardId = liveboardId; this.viewConfig.activeTabId = activeTabId; this.viewConfig.vizId = vizId; if (this.isRendered) { this.trigger(types_1.HostEvent.Navigate, path.substring(1)); } else if (this.viewConfig.preRenderId) { this.preRender(true); } else { this.render(); } } /** * Returns the full url of the Liveboard/visualization which can be used to open * this Liveboard inside the full ThoughtSpot application in a new tab. * @returns url string */ getLiveboardUrl() { let url = `${this.thoughtSpotHost}/#/pinboard/${this.viewConfig.liveboardId}`; if (this.viewConfig.activeTabId) { url = `${url}/tab/${this.viewConfig.activeTabId}`; } if (this.viewConfig.vizId) { url = `${url}/${this.viewConfig.vizId}`; } return url; } } exports.LiveboardEmbed = LiveboardEmbed; /** * @hidden */ class PinboardEmbed extends LiveboardEmbed { } exports.PinboardEmbed = PinboardEmbed; //# sourceMappingURL=liveboard.js.map