UNPKG

@thoughtspot/visual-embed-sdk

Version:
297 lines 9.54 kB
import React, { useRef } from 'react'; import useDeepCompareEffect from 'use-deep-compare-effect'; import { deepMerge } from '../utils'; import { SearchBarEmbed as _SearchBarEmbed } from '../embed/search-bar'; import { SageEmbed as _SageEmbed } from '../embed/sage'; import { SearchEmbed as _SearchEmbed } from '../embed/search'; import { AppEmbed as _AppEmbed } from '../embed/app'; import { LiveboardEmbed as _LiveboardEmbed } from '../embed/liveboard'; import { getViewPropsAndListeners } from './util'; import { ConversationEmbed as _ConversationEmbed } from '../embed/conversation'; import { init } from '../embed/base'; const componentFactory = (EmbedConstructor, // isPreRenderedComponent: Specifies whether the component being returned is // intended for preRendering. If set to true, the component will call the // Embed.preRender() method instead of the usual render method, and it will // not be destroyed when the component is unmounted. isPreRenderedComponent = false) => React.forwardRef((props, forwardedRef) => { const ref = React.useRef(null); const { className, style, ...embedProps } = props; const { viewConfig, listeners } = getViewPropsAndListeners(embedProps); const handleDestroy = (tsEmbed) => { // do not destroy if it is a preRender component if (isPreRenderedComponent) return; // if component is connected to a preRendered component if (props.preRenderId) { tsEmbed.hidePreRender(); return; } tsEmbed.destroy(); }; const handlePreRenderRendering = (tsEmbed) => { tsEmbed.preRender(); }; const handleDefaultRendering = (tsEmbed) => { // if component is connected to a preRendered component if (props.preRenderId) { tsEmbed.showPreRender(); return; } tsEmbed.render(); }; const handleRendering = (tsEmbed) => { if (isPreRenderedComponent) { handlePreRenderRendering(tsEmbed); return; } handleDefaultRendering(tsEmbed); }; useDeepCompareEffect(() => { const tsEmbed = new EmbedConstructor(ref.current, deepMerge({ insertAsSibling: viewConfig.insertAsSibling, frameParams: { class: viewConfig.insertAsSibling ? className || '' : '', }, }, viewConfig)); Object.keys(listeners).forEach((eventName) => { tsEmbed.on(eventName, listeners[eventName]); }); handleRendering(tsEmbed); if (forwardedRef) { // eslint-disable-next-line no-param-reassign forwardedRef.current = tsEmbed; } return () => { handleDestroy(tsEmbed); }; }, [viewConfig, listeners]); return viewConfig.insertAsSibling ? (React.createElement("span", { "data-testid": "tsEmbed", ref: ref, style: { position: 'absolute' } })) : (React.createElement("div", { "data-testid": "tsEmbed", ref: ref, style: style, className: `ts-embed-container ${className}` })); }); /** * React component for Search Embed. * @example * ```tsx * function Search() { * return <SearchEmbed * dataSource="dataSourceId" * searchOptions={{ searchTokenString: "[revenue]" }} * /> * } * ``` */ export const SearchEmbed = componentFactory(_SearchEmbed); export const PreRenderedSearchEmbed = componentFactory(_SearchEmbed, true); /** * React component for Full app Embed. * @example * ```tsx * function Search() { * return <AppEmbed * showPrimaryNavbar={false} * pageId={Page.Liveboards} * onError={(error) => console.error(error)} * /> * } * ``` */ export const AppEmbed = componentFactory(_AppEmbed); /** * React component for PreRendered Liveboard embed. * * PreRenderedAppEmbed will preRender the SearchBarEmbed and will be hidden by * default. * * AppEmbed with preRenderId passed will call showPreRender on the embed. * @example * ```tsx * function LandingPageComponent() { * return <PreRenderedAppEmbed preRenderId="someId" showPrimaryNavbar={false} /> * } * ``` * function MyComponent() { * return <AppEmbed preRenderId="someId" showPrimaryNavbar={false} /> * } * ``` */ export const PreRenderedAppEmbed = componentFactory(_AppEmbed, true); /** * React component for Liveboard embed. * @example * ```tsx * function Liveboard() { * return <LiveboardEmbed * liveboardId="liveboardId" * fullHeight={true} {/* default false *\/} * onLiveboardRendered={() => console.log('Liveboard rendered')} * vizId="vizId" {/* if doing viz embed *\/} * /> * } * ``` */ export const LiveboardEmbed = componentFactory(_LiveboardEmbed); export const PinboardEmbed = LiveboardEmbed; /** * React component for PreRendered Liveboard embed. * * PreRenderedLiveboardEmbed will preRender the liveboard and will be hidden by default. * * LiveboardEmbed with preRenderId passed will call showPreRender on the embed. * * If LiveboardEmbed is rendered before PreRenderedLiveboardEmbed is rendered it * tries to preRender the LiveboardEmbed, so it is recommended to use pass the * liveboardId to both the components. * @example * ```tsx * function LandingPageComponent() { * return <PreRenderedLiveboardEmbed preRenderId="someId" liveboardId="libId" /> * } * ``` * function MyComponent() { * return <LiveboardEmbed preRenderId="someId" liveboardId="libId" /> * } * ``` */ export const PreRenderedLiveboardEmbed = componentFactory(_LiveboardEmbed, true); export const PreRenderedPinboardEmbed = PreRenderedLiveboardEmbed; /** * React component for Search bar embed. * @example * ```tsx * function SearchBar() { * return <SearchBarEmbed * dataSource="dataSourceId" * searchOptions={{ searchTokenString: "[revenue]" }} * /> * } * ``` */ export const SearchBarEmbed = componentFactory(_SearchBarEmbed); /** * React component for PreRendered Liveboard embed. * * PreRenderedSearchBarEmbed will preRender the SearchBarEmbed and will be hidden by * default. * * SearchBarEmbed with preRenderId passed will call showPreRender on the embed. * @example * ```tsx * function LandingPageComponent() { * return <PreRenderedSearchBarEmbed preRenderId="someId" dataSource="dataSourceId" /> * } * ``` * function MyComponent() { * return <SearchBarEmbed preRenderId="someId" dataSource="dataSourceId" /> * } * ``` */ export const PreRenderedSearchBarEmbed = componentFactory(_SearchBarEmbed, true); /** * React component for LLM based search Sage embed. * @example * ```tsx * function Sage() { * return <SageEmbed * showObjectResults={true} * ... other view config props or event listeners. * /> * } * ``` */ export const SageEmbed = componentFactory(_SageEmbed); /** * React component for PreRendered Liveboard embed. * * PreRenderedSageEmbed will preRender the SearchBarEmbed and will be hidden by * default. * * SageEmbed with preRenderId passed will call showPreRender on the embed. * @example * ```tsx * function LandingPageComponent() { * return <PreRenderedSageEmbed preRenderId="someId" showObjectResults={true} /> * } * ``` * function MyComponent() { * return <SageEmbed preRenderId="someId" showObjectResults={true} /> * } * ``` */ export const PreRenderedSageEmbed = componentFactory(_SageEmbed, true); /** * React component for LLM based conversation BI. * @example * ```tsx * function Sage() { * return <ConversationEmbed * worksheetId="<worksheet-id-here>" * searchOptions={{ * searchQuery: "<search query to start with>" * }} * ... other view config props or event listeners. * /> * } * ``` */ export const ConversationEmbed = componentFactory(_ConversationEmbed); /** * React component for PreRendered Conversation embed. * * PreRenderedConversationEmbed will preRender the ConversationEmbed and will be hidden by * default. * * SageEmbed with preRenderId passed will call showPreRender on the embed. * @example * ```tsx * function LandingPageComponent() { * return <PreRenderedConversationEmbed preRenderId="someId" worksheetId={"id-"} /> * } * ``` * function MyComponent() { * return <ConversationEmbed preRenderId="someId" worksheetId="id" /> * } * ``` */ export const PreRenderedConversationEmbed = componentFactory(_ConversationEmbed, true); /** * Get a reference to the embed component to trigger events on the component. * @example * ``` * function Component() { * const ref = useEmbedRef(); * useEffect(() => { * ref.current.trigger( * EmbedEvent.UpdateRuntimeFilter, * [{ columnName: 'name', operator: 'EQ', values: ['value']}]); * }, []) * return <LiveboardEmbed ref={ref} liveboardId={<id>} /> * } * ``` * @returns {React.MutableRefObject<T extends TsEmbed>} ref */ export function useEmbedRef() { return React.useRef(null); } /** * * @param config - EmbedConfig * @returns AuthEventEmitter * @example * ``` * function Component() { * const authEE = useInit({ ...initConfig }); * return <LiveboardEmbed ref={ref} liveboardId={<id>} /> * } * ``` * @version SDK: 1.36.2 | ThoughtSpot: * */ export function useInit(config) { const ref = useRef(null); useDeepCompareEffect(() => { const authEE = init(config); ref.current = authEE; }, [config]); return ref; } export { Page, RuntimeFilterOp, EmbedEvent, HostEvent, Action, HomeLeftNavItem, HomepageModule, LogLevel, getSessionInfo, } from '../index'; //# sourceMappingURL=index.js.map