const embed = new AppEmbed("#embed", {
pageId: Page.Liveboards,
// path: 'pinboard/96a1cf0b-a159-4cc8-8af4-1a297c492ff9', // Alternative direct path rather than pageId
showPrimaryNavbar: false,
frameParams: {
height: '100%',
width: '100%'
}
});
Customize full application embedding
The AppEmbed component embeds the entire ThoughtSpot application within another page.
Choose the page to load🔗
The pageId
parameter of the AppEmbed
parameters object lets you specify the ThoughtSpot page in the Page
enumeration that the AppEmbed component loads to.
Alternatively, you can use the path
parameter to directly specify a page path, to load a specific Liveboard or Answer.
Customize the ThoughtSpot top menu🔗
You cannot change the ThoughtSpot top menu directly, but you can hide and replace it with your own navigation menu (it can even look exactly the same as ThoughtSpot default).
To hide the top menu bar, set the showPrimaryNavbar
parameter of the AppEmbed to false
.
You can replicate the behavior of the hidden menu bar in the embedding web application’s UI.
The AppEmbed
object has a method called navigateToPage()
that will switch the currently loaded page in the ThoughtSpot embedded application. The navigateToPage()
method accepts the values that work for pageId
or path
parameters.
The new navigation menu should call navigateToPage
for the various pages you want to provide access to:
embed.navigateToPage(Page.Answers);
// with noReload option
embed.navigateToPage(Page.Answers, true);
Detect changes in the currently loaded page🔗
Various actions the user takes within the embedded ThoughtSpot application may cause navigation within ThoughtSpot.
The embedding web application can listen for the EmbedEvent.RouteChange
event by attaching an event listener to the AppEmbed
object. The response has a currentPath
property which is the path after the ThoughtSpot domain, for example:
pinboard/96a1cf0b-a159-4cc8-8af4-1a297c492ff9
To parse the currentPath
into varying useful components, this tsAppState
object code can be created in the global scope for use by any other web application code:
// Simple global object to handle details about what is visible in the AppEmbed component at a given moment
let tsAppState = {
currentPath: startPath,
currentDatasources: [], // Can be set later when detected from TML or other events
// return back what is being viewed at the moment, in the form that will translate to the pageId property if captialized, or path property if not
get pageType() {
if (this.currentPath.includes('/saved-answer/')){
return 'answer';
}
else if (this.currentPath.includes('/pinboard/')){
return 'liveboard';
}
/*
* Others are meant to match the exact pageId from SDK
*/
else if(this.currentPath.includes('/answer/')){
return 'Search';
}
else if(this.currentPath.includes('/answers')){
return 'Answers';
}
else if (this.currentPath.includes('/pinboards')){
return 'Liveboards';
}
else if(this.currentPath.includes('/insights')){
return 'SpotIQ';
}
else if(this.currentPath.includes('/monitor')){
return 'Monitor';
}
else if(this.currentPath.includes('/data')){
return 'Data';
}
else {
return 'Home';
}
},
// If viewing an Answer or Liveboard, returns the GUID of that object from the parsed URL
get objectId() {
let pathParts = this.currentPath.split('/');
// '/saved-answer/' is path for Answers (vs. /answer/)
if (this.currentPath.includes('/saved-answer/')){
answerGUID = pathParts[2];
return pathParts[2];
}
// '/pinboard/' is path for saved Liveboards
else if (this.currentPath.includes('/pinboard/')){
let pathParts = this.currentPath.split('/');
// May need adjustment for tabbed views to add in current Tab
liveboardGUID = pathParts[2];
return pathParts[2];
}
else{
return null;
}
}
}
The following example shows the event listener code updating the global tsAppState
object above whenever there is a change within the embedded ThoughtSpot app:
embed.on(EmbedEvent.RouteChange, (response) => {
// console.log("RouteChange fires");
// console.log(response);
// tsAppState object has currentPath property, which allows its other methods to parse out pageId, object type, GUIDs etc.
tsAppState.currentPath = response.data.currentPath;
console.log("TS App page is now: ", tsAppState.currentPath);
// Update elements within your web application based on the new state of ThoughtSpot (adjust menu selections, etc.)
})
Navigate using a custom action🔗
To add a custom action for in-app navigation, follow these steps:
-
Define the navigation path
In this example, the view-report action on a Liveboard page calls the navigateTo
method to open a specific saved Answer page when a user clicks the View report button in the embedded app.
appEmbed.on(EmbedEvent.CustomAction, async (payload: any) => {
if (payload.payload.id === 'view-report') {
appEmbed.navigateToPage(
'saved-answer/3da14030-11e4-42b2-8e56-5ee042a8de9e'
);
}
})
If you want to navigate to a specific application page without initiating a reload, you can set the noReload
attribute to true
as shown here:
appEmbed.on(EmbedEvent.CustomAction, async (payload: any) => {
if (payload.payload.id === 'view-report') {
appEmbed.navigateToPage('saved-answer/3da14030-11e4-42b2-8e56-5ee042a8de9e', true);
}
})
CSS customization and hiding page elements🔗
CSS customization allows overriding the default styles from the ThoughtSpot application, including the application pages.
If there is an element of a page that you dislike and cannot hide with any combination of other options in ThoughtSpot, you can often use CSS customization to target the element and apply either display: none;
, visibility: hidden;
or height: 0px;
and make it functionally disappear to the end user.
Specifying a direct element using the direct CSS selectors vs. the ThoughtSpot provided variables. To discover the appropriate selector, use the Inspect functionality of your browser to bring up the Elements portion of the browser’s Developer Tools, then look at the Styles information.
An example of using direct selectors in a file is available in the complete.css.
.bk-data-scope .left-pane .header-lt {
display: none !important;
visibility: hidden !important;
}
Direct selectors can also be declared using rules in the Visual Embed SDK code. This is useful for real-time testing, particularly in the Visual Embed SDK playground. Note the format for encoding CSS rules into the JavaScript object format used by for rules.