import { useEffect, useState } from "react";
import {
LiveboardEmbed,
useEmbedRef,
} from "@thoughtspot/visual-embed-sdk/react";
ThoughtSpot component pages
app/dashboard/[dashboardId]/page.tsx๐
The first page we will build uses the LiveboardEmbed
component to display any Liveboard, if passed an ID that matches existing content.
As mentioned in the introduction, Next.js uses square brackets in a directory name to denote a variable route. The value placed in the URL after /dashboard/
will be available as the variable dashboardId
in the page.tsx
code.
Note the URL says dashboard, rather than Liveboard. When embedding ThoughtSpot, you can present every aspect of ThoughtSpot as completely customized, matching your own appโs naming and design preferences.
Imports๐
The /app/dashboard/[dashboardId]/page.tsx
file starts with imports: some from React and some from the ThoughtSpot Visual Embed SDK.
LiveboardEmbed
is the component provided by ThoughtSpot to display a Liveboard object.
The React components of the ThoughtSpot Visual Embed SDK wrap around the embedded ThoughtSpot components, which utilize modern iFrame techniques to provide the full ThoughtSpot interface within a page.
Pass Liveboard ID to the component๐
React components have props, which are properties of the component.
The most important prop of the LiveboardEmbed
is the liveboardId
prop that determines which object the component loads from ThoughtSpot.
The page.tsx
we are defining will return a fully configured LiveboardEmbed
component as part of a larger Dashboard
component.
The dashboardId
value needs to pass in from the URL to the Dashboard
component. As mentioned earlier, in this example using Next.js, the directory name with [dashboardId]
provides the value using the variable name within the brackets. Other routing systems will provide their own mechanism for receiving values from a URL.
In the following code, the Props
interface captures the dashboardId
and passes it into the const Dashboard
definition, making the value available within the Dashboard
component via params.dashboardId
.
// Defines the expectation of the dashboardId variable from the URL
interface Props {
params: { dashboardId: string };
}
const Dashboard = ({ params }: Props) => {
...
Set and update state๐
React components are designed to react to changes in state.
By using the useState function imported at the beginning of the code, a dashboardId
state variable is created, with a setDashboardId
update function:
const [dashboardId, setDashboardId] = useState("");
The useEffect Hook is necessary for proper synchronization of elements that are external to the React app. The first usage wraps around calling the setDashboardId
state function.
const Dashboard = ({ params }: Props) => {
const [dashboardId, setDashboardId] = useState("");
// Interactions with systems outside of React app get wrapped in useEffect()
useEffect(() => {
setDashboardId(params.dashboardId);
{
console.log(`Dashboard Id: ${params.dashboardId}`);
setDashboardId(params.dashboardId);
}
}, [params.dashboardId]); // Only runs when dashboardId changes
...
Create the ThoughtSpot embed component๐
The final aspect of establishing proper interaction of the React app and the ThoughtSpot embed component prior to returning the component itself is declaring the embedRef
const:
const embedRef = useEmbedRef<typeof LiveboardEmbed>();
With the embedRef
declared, the LiveboardEmbed
component can be declared along with any necessary props:
...
// Required for referencing the LiveboardEmbed that is created in other code
const embedRef = useEmbedRef<typeof LiveboardEmbed>();
return (
(dashboardId && (
// ThoughtSpot LiveboardEmbed component with config properties. See https://developers.thoughtspot.com/docs/Interface_LiveboardViewConfig
<LiveboardEmbed
className="full-height"
ref={embedRef}
liveboardId={dashboardId}
showLiveboardTitle={true}
showLiveboardDescription={true}
//visibleActions={[]}
/>
)) || <div>No dashboard ID set.</div>
);
};
export default Dashboard;
Note that the return
block above uses a standard conditional rendering pattern involving JavaScriptโs conditional operators, to provide the alternative <div>No dashboard Id set.</div>
if the component was not provided a value for the dashboardId
.
Production code might include additional logical checks to be sure all necessary information has been provided before attempting to render a ThoughtSpot embed component.
Configuration options as component props๐
The Visual Embed SDK defines a large number of properties to configure each component. For example, LiveboardViewConfig for the LiveboardEmbed component.
The properties are sent as an object in the second argument of the component constructor in the JavaScript components:
const liveboardEmbed = new LiveboardEmbed(document.getElementById('ts-embed'), {
frameParams: {
width: '100%',
height: '100%',
},
liveboardId: '<%=liveboardGUID%>',
});
Translating the Visual Embed SDK JavaScript documentation into the form used by the React components is relatively simple.
The React components have the same properties available as props of the component, rather than using a separate config object:
<LiveboardEmbed
className="full-height"
ref={embedRef}
liveboardId={dashboardId}
showLiveboardTitle={true}
showLiveboardDescription={true}
//visibleActions={[]}
/>
The use of props for configuration options and event handlers is the biggest difference between the React components and the JavaScript Visual Embed SDK.