UNPKG

@thoughtspot/visual-embed-sdk

Version:
451 lines 16.7 kB
/** * Copyright (c) 2022 * * Base classes * @summary Base classes * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com> */ import { TriggerPayload, TriggerResponse, UIPassthroughArrayResponse, UIPassthroughEvent, UIPassthroughRequest } from './hostEventClient/contracts'; import { AnswerService } from '../utils/graphql/answerService/answerService'; import { DOMSelector, HostEvent, EmbedEvent, MessageCallback, EmbedConfig, MessageOptions, DefaultAppInitData, AllEmbedViewConfig as ViewConfig } from '../types'; import { HostEventClient } from './hostEventClient/host-event-client'; /** * Global prefix for all Thoughtspot postHash Params. */ export declare const THOUGHTSPOT_PARAM_PREFIX = "ts-"; /** * Base class for embedding v2 experience * Note: the v2 version of ThoughtSpot Blink is built on the new stack: * React+GraphQL */ export declare class TsEmbed { /** * The DOM node which was inserted by the SDK to either * render the iframe or display an error message. * This is useful for removing the DOM node when the * embed instance is destroyed. */ protected insertedDomEl: Node; /** * The DOM node where the ThoughtSpot app is to be embedded. */ protected el: HTMLElement; /** * The key to store the embed instance in the DOM node */ protected embedNodeKey: string; protected isAppInitialized: boolean; /** * A reference to the iframe within which the ThoughtSpot app * will be rendered. */ protected iFrame: HTMLIFrameElement; /** * Setter for the iframe element * @param {HTMLIFrameElement} iFrame HTMLIFrameElement */ protected setIframeElement(iFrame: HTMLIFrameElement): void; protected viewConfig: ViewConfig & { visibleTabs?: string[]; hiddenTabs?: string[]; showAlerts?: boolean; }; protected embedConfig: EmbedConfig; /** * The ThoughtSpot hostname or IP address */ protected thoughtSpotHost: string; protected thoughtSpotV2Base: string; /** * A map of event handlers for particular message types triggered * by the embedded app; multiple event handlers can be registered * against a particular message type. */ private eventHandlerMap; /** * A flag that is set to true post render. */ protected isRendered: boolean; /** * A flag to mark if an error has occurred. */ private isError; /** * A flag that is set to true post preRender. */ private isPreRendered; /** * Should we encode URL Query Params using base64 encoding which thoughtspot * will generate for embedding. This provides additional security to * thoughtspot clusters against Cross site scripting attacks. * @default false */ private shouldEncodeUrlQueryParams; private defaultHiddenActions; private resizeObserver; protected hostEventClient: HostEventClient; protected isReadyForRenderPromise: Promise<void>; /** * Handler for fullscreen change events */ private fullscreenChangeHandler; constructor(domSelector: DOMSelector, viewConfig?: ViewConfig); /** * Throws error encountered during initialization. */ private throwInitError; /** * Handles errors within the SDK * @param error The error message or object */ protected handleError(error: string | Record<string, unknown>): void; /** * Extracts the type field from the event payload * @param event The window message event */ private getEventType; /** * Extracts the port field from the event payload * @param event The window message event * @returns */ private getEventPort; /** * Checks if preauth cache is enabled * from the view config and embed config * @returns boolean */ private isPreAuthCacheEnabled; /** * Checks if current embed is FullAppEmbed with visible primary navbar * @returns boolean */ private isFullAppEmbedWithVisiblePrimaryNavbar; /** * fix for ts7.sep.cl * will be removed for ts7.oct.cl * @param event * @param eventType * @hidden */ private formatEventData; private subscribedListeners; /** * Adds a global event listener to window for "message" events. * ThoughtSpot detects if a particular event is targeted to this * embed instance through an identifier contained in the payload, * and executes the registered callbacks accordingly. */ private subscribeToEvents; private unsubscribeToEvents; protected getAuthTokenForCookielessInit(): Promise<string>; protected getDefaultAppInitData(): Promise<DefaultAppInitData>; protected getAppInitData(): Promise<DefaultAppInitData>; /** * Send Custom style as part of payload of APP_INIT * @param _ * @param responder */ private appInitCb; /** * Sends updated auth token to the iFrame to avoid user logout * @param _ * @param responder */ private updateAuthToken; /** * Auto Login and send updated authToken to the iFrame to avoid user session logout * @param _ * @param responder */ private idleSessionTimeout; /** * Register APP_INIT event and sendback init payload */ private registerAppInit; /** * Constructs the base URL string to load the ThoughtSpot app. * @param query */ protected getEmbedBasePath(query: string): string; /** * Common query params set for all the embed modes. * @param queryParams * @returns queryParams */ protected getBaseQueryParams(queryParams?: Record<any, any>): Record<any, any>; /** * Constructs the base URL string to load v1 of the ThoughtSpot app. * This is used for embedding Liveboards, visualizations, and full application. * @param queryString The query string to append to the URL. * @param isAppEmbed A Boolean parameter to specify if you are embedding * the full application. */ protected getV1EmbedBasePath(queryString: string): string; protected getEmbedParams(): string; protected getRootIframeSrc(): string; protected createIframeEl(frameSrc: string): HTMLIFrameElement; protected handleInsertionIntoDOM(child: string | Node): void; /** * Renders the embedded ThoughtSpot app in an iframe and sets up * event listeners. * @param url - The URL of the embedded ThoughtSpot app. */ protected renderIFrame(url: string): Promise<any>; protected createPreRenderWrapper(): HTMLDivElement; protected preRenderWrapper: HTMLElement; protected preRenderChild: HTMLElement; protected connectPreRendered(): boolean; protected isPreRenderAvailable(): boolean; protected createPreRenderChild(child: string | Node): HTMLElement; protected insertIntoDOMForPreRender(child: string | Node): void; private showPreRenderByDefault; protected insertIntoDOM(child: string | Node): void; /** * Sets the height of the iframe * @param height The height in pixels */ protected setIFrameHeight(height: number | string): void; /** * Executes all registered event handlers for a particular event type * @param eventType The event type * @param data The payload invoked with the event handler * @param eventPort The event Port for a specific MessageChannel */ protected executeCallbacks(eventType: EmbedEvent, data: any, eventPort?: MessagePort | void): void; /** * Returns the ThoughtSpot hostname or IP address. */ protected getThoughtSpotHost(): string; /** * Gets the v1 event type (if applicable) for the EmbedEvent type * @param eventType The v2 event type * @returns The corresponding v1 event type if one exists * or else the v2 event type itself */ protected getCompatibleEventType(eventType: EmbedEvent): EmbedEvent; /** * Calculates the iframe center for the current visible viewPort * of iframe using Scroll position of Host App, offsetTop for iframe * in Host app. ViewPort height of the tab. * @returns iframe Center in visible viewport, * Iframe height, * View port height. */ protected getIframeCenter(): { iframeCenter: number; iframeScrolled: number; iframeHeight: number; viewPortHeight: number; iframeVisibleViewPort: number; }; /** * Registers an event listener to trigger an alert when the ThoughtSpot app * sends an event of a particular message type to the host application. * @param messageType The message type * @param callback A callback as a function * @param options The message options * @param isSelf * @param isRegisteredBySDK * @example * ```js * tsEmbed.on(EmbedEvent.Error, (data) => { * console.error(data); * }); * ``` * @example * ```js * tsEmbed.on(EmbedEvent.Save, (data) => { * console.log("Answer save clicked", data); * }, { * start: true // This will trigger the callback on start of save * }); * ``` */ on(messageType: EmbedEvent, callback: MessageCallback, options?: MessageOptions, isRegisteredBySDK?: boolean): typeof TsEmbed.prototype; /** * Removes an event listener for a particular event type. * @param messageType The message type * @param callback The callback to remove * @example * ```js * const errorHandler = (data) => { console.error(data); }; * tsEmbed.on(EmbedEvent.Error, errorHandler); * tsEmbed.off(EmbedEvent.Error, errorHandler); * ``` */ off(messageType: EmbedEvent, callback: MessageCallback): typeof TsEmbed.prototype; /** * Triggers an event on specific Port registered against * for the EmbedEvent * @param eventType The message type * @param data The payload to send * @param eventPort * @param payload */ private triggerEventOnPort; /** * @hidden * Internal state to track if the embed container is loaded. * This is used to trigger events after the embed container is loaded. */ isEmbedContainerLoaded: boolean; /** * @hidden * Internal state to track the callbacks to be executed after the embed container * is loaded. * This is used to trigger events after the embed container is loaded. */ private embedContainerReadyCallbacks; protected getPreRenderObj<T extends TsEmbed>(): T; private checkEmbedContainerLoaded; private executeEmbedContainerReadyCallbacks; /** * Executes a callback after the embed container is loaded. * @param callback The callback to execute */ protected executeAfterEmbedContainerLoaded(callback: () => void): void; protected createEmbedContainerHandler: (source: EmbedEvent.AuthInit | EmbedEvent.EmbedListenerReady) => () => void; /** * 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<HostEventT extends HostEvent, PayloadT>(messageType: HostEventT, data?: TriggerPayload<PayloadT, HostEventT>): Promise<TriggerResponse<PayloadT, HostEventT>>; /** * Triggers an event to the embedded app, skipping the UI flow. * @param {UIPassthroughEvent} apiName - The name of the API to be triggered. * @param {UIPassthroughRequest} parameters - The parameters to be passed to the API. * @returns {Promise<UIPassthroughRequest>} - A promise that resolves with the response * from the embedded app. */ triggerUIPassThrough<UIPassthroughEventT extends UIPassthroughEvent>(apiName: UIPassthroughEventT, parameters: UIPassthroughRequest<UIPassthroughEventT>): Promise<UIPassthroughArrayResponse<UIPassthroughEventT>>; /** * Marks the ThoughtSpot object to have been rendered * Needs to be overridden by subclasses to do the actual * rendering of the iframe. * @param args */ render(): Promise<TsEmbed>; getIframeSrc(): string; protected handleRenderForPrerender(): Promise<TsEmbed>; /** * Creates the preRender shell * @param showPreRenderByDefault - Show the preRender after render, hidden by default */ preRender(showPreRenderByDefault?: boolean, replaceExistingPreRender?: boolean): Promise<TsEmbed>; /** * Get the Post Url Params for THOUGHTSPOT from the current * host app URL. * THOUGHTSPOT URL params starts with a prefix "ts-" * @version SDK: 1.14.0 | ThoughtSpot: 8.4.0.cl, 8.4.1-sw */ getThoughtSpotPostUrlParams(additionalParams?: { [key: string]: string | number; }): string; /** * Destroys the ThoughtSpot embed, and remove any nodes from the DOM. * @version SDK: 1.19.1 | ThoughtSpot: * */ destroy(): void; getUnderlyingFrameElement(): HTMLIFrameElement; /** * Prerenders a generic instance of the TS component. * This means without the path but with the flags already applied. * This is useful for prerendering the component in the background. * @version SDK: 1.22.0 * @returns */ prerenderGeneric(): Promise<any>; protected beforePrerenderVisible(): void; private validatePreRenderViewConfig; /** * Displays the PreRender component. * If the component is not preRendered, it attempts to create and render it. * Also, synchronizes the style of the PreRender component with the embedding * element. */ showPreRender(): Promise<TsEmbed>; /** * Synchronizes the style properties of the PreRender component with the embedding * element. This function adjusts the position, width, and height of the PreRender * component * to match the dimensions and position of the embedding element. * @throws {Error} Throws an error if the embedding element (passed as domSelector) * is not defined or not found. */ syncPreRenderStyle(): void; /** * Hides the PreRender component if it is available. * If the component is not preRendered, it issues a warning. */ hidePreRender(): void; /** * Retrieves unique HTML element IDs for PreRender-related elements. * These IDs are constructed based on the provided 'preRenderId' from 'viewConfig'. * @returns {object} An object containing the IDs for the PreRender elements. * @property {string} wrapper - The HTML element ID for the PreRender wrapper. * @property {string} child - The HTML element ID for the PreRender child. */ getPreRenderIds(): { wrapper: string; child: string; }; /** * Returns the answerService which can be used to make arbitrary graphql calls on top * session. * @param vizId [Optional] to get for a specific viz in case of a Liveboard. * @version SDK: 1.25.0 / ThoughtSpot 9.10.0 */ getAnswerService(vizId?: string): Promise<AnswerService>; /** * Set up fullscreen change detection to automatically trigger ExitPresentMode * when user exits fullscreen mode */ private setupFullscreenChangeHandler; /** * Remove fullscreen change handler */ private removeFullscreenChangeHandler; } /** * Base class for embedding v1 experience * Note: The v1 version of ThoughtSpot Blink works on the AngularJS stack * which is currently under migration to v2 * @inheritdoc */ export declare class V1Embed extends TsEmbed { protected viewConfig: ViewConfig; constructor(domSelector: DOMSelector, viewConfig: ViewConfig); /** * Render the app in an iframe and set up event handlers * @param iframeSrc */ protected renderV1Embed(iframeSrc: string): Promise<any>; protected getRootIframeSrc(): string; /** * @inheritdoc * @example * ```js * tsEmbed.on(EmbedEvent.Error, (data) => { * console.error(data); * }); * ``` * @example * ```js * tsEmbed.on(EmbedEvent.Save, (data) => { * console.log("Answer save clicked", data); * }, { * start: true // This will trigger the callback on start of save * }); * ``` */ on(messageType: EmbedEvent, callback: MessageCallback, options?: MessageOptions): typeof TsEmbed.prototype; /** * Only for testing purposes. * @hidden */ test__executeCallbacks: (eventType: EmbedEvent, data: any, eventPort?: void | MessagePort) => void; } //# sourceMappingURL=ts-embed.d.ts.map