@thoughtspot/visual-embed-sdk 1.21.0-alpha.0 → 1.21.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +1 -1
  2. package/dist/src/auth.d.ts +10 -6
  3. package/dist/src/auth.d.ts.map +1 -1
  4. package/dist/src/auth.spec.d.ts +3 -0
  5. package/dist/src/auth.spec.d.ts.map +1 -1
  6. package/dist/src/embed/base.d.ts +3 -1
  7. package/dist/src/embed/base.d.ts.map +1 -1
  8. package/dist/src/embed/liveboard.d.ts +11 -1
  9. package/dist/src/embed/liveboard.d.ts.map +1 -1
  10. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  11. package/dist/src/react/index.d.ts +15 -0
  12. package/dist/src/react/index.d.ts.map +1 -1
  13. package/dist/src/types.d.ts +95 -24
  14. package/dist/src/types.d.ts.map +1 -1
  15. package/dist/tsembed.es.js +17546 -249
  16. package/dist/tsembed.js +17546 -249
  17. package/lib/package.json +1 -1
  18. package/lib/src/auth.d.ts +10 -6
  19. package/lib/src/auth.d.ts.map +1 -1
  20. package/lib/src/auth.js +25 -10
  21. package/lib/src/auth.js.map +1 -1
  22. package/lib/src/auth.spec.d.ts +3 -0
  23. package/lib/src/auth.spec.d.ts.map +1 -1
  24. package/lib/src/auth.spec.js +23 -1
  25. package/lib/src/auth.spec.js.map +1 -1
  26. package/lib/src/embed/base.d.ts +3 -1
  27. package/lib/src/embed/base.d.ts.map +1 -1
  28. package/lib/src/embed/base.js +3 -1
  29. package/lib/src/embed/base.js.map +1 -1
  30. package/lib/src/embed/liveboard.d.ts +11 -1
  31. package/lib/src/embed/liveboard.d.ts.map +1 -1
  32. package/lib/src/embed/liveboard.js +11 -1
  33. package/lib/src/embed/liveboard.js.map +1 -1
  34. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  35. package/lib/src/embed/ts-embed.js +3 -2
  36. package/lib/src/embed/ts-embed.js.map +1 -1
  37. package/lib/src/react/index.d.ts +15 -0
  38. package/lib/src/react/index.d.ts.map +1 -1
  39. package/lib/src/react/index.js +15 -0
  40. package/lib/src/react/index.js.map +1 -1
  41. package/lib/src/types.d.ts +95 -24
  42. package/lib/src/types.d.ts.map +1 -1
  43. package/lib/src/types.js +95 -24
  44. package/lib/src/types.js.map +1 -1
  45. package/lib/src/visual-embed-sdk.d.ts +119 -32
  46. package/package.json +1 -1
  47. package/src/auth.spec.ts +40 -8
  48. package/src/auth.ts +43 -16
  49. package/src/embed/base.ts +4 -2
  50. package/src/embed/liveboard.ts +11 -1
  51. package/src/embed/ts-embed.ts +2 -1
  52. package/src/react/index.tsx +15 -0
  53. package/src/types.ts +95 -24
@@ -187,7 +187,9 @@ declare module '@thoughtspot/visual-embed-sdk/embed/base' {
187
187
  export const prefetch: (url?: string, prefetchFeatures?: PrefetchFeatures[]) => void;
188
188
  /**
189
189
  * Initializes the Visual Embed SDK globally and perform
190
- * authentication if applicable.
190
+ * authentication if applicable. This function needs to be called before any ThoughtSpot
191
+ * component like liveboard etc can be embedded. But need not wait for AuthEvent.SUCCESS
192
+ * to actually embed. That is handled internally.
191
193
  *
192
194
  * @param embedConfig The configuration object containing ThoughtSpot host,
193
195
  * authentication mechanism and so on.
@@ -326,8 +328,18 @@ declare module '@thoughtspot/visual-embed-sdk/embed/liveboard' {
326
328
  activeTabId?: string;
327
329
  }
328
330
  /**
329
- * Embed a ThoughtSpot Liveboard or visualization
331
+ * Embed a ThoughtSpot Liveboard or a Thoughtspot visualization. When rendered it already
332
+ * waits for the authentication to complete, so no need to wait for AuthStatus.SUCCESS.
330
333
  *
334
+ * @example
335
+ * ```js
336
+ * import { .. } from '@thoughtspot/visual-embed-sdk';
337
+ * init({ ... });
338
+ * const embed = new LiveboardEmbed("#container", {
339
+ * liveboardId: <your-id-here>,
340
+ * // .. other params here.
341
+ * })
342
+ * ```
331
343
  * @group Embed components
332
344
  */
333
345
  export class LiveboardEmbed extends V1Embed {
@@ -535,6 +547,12 @@ declare module '@thoughtspot/visual-embed-sdk/auth' {
535
547
  BASIC_LOGIN: string;
536
548
  LOGOUT: string;
537
549
  };
550
+ interface sessionInfoInterface {
551
+ userGUID: any;
552
+ isPublicUser: any;
553
+ mixpanelToken: any;
554
+ [key: string]: any;
555
+ }
538
556
  /**
539
557
  * Enum for auth failure types. This is the parameter passed to the listner
540
558
  * of {@link AuthStatus.FAILURE}.
@@ -647,6 +665,8 @@ declare module '@thoughtspot/visual-embed-sdk/auth' {
647
665
  *
648
666
  */
649
667
  export function notifyLogout(): void;
668
+ export const initSession: (sessionDetails: sessionInfoInterface) => void;
669
+ export const getSessionDetails: (sessionInfoResp: any) => sessionInfoInterface;
650
670
  /**
651
671
  * Return releaseVersion if available
652
672
  */
@@ -657,12 +677,7 @@ declare module '@thoughtspot/visual-embed-sdk/auth' {
657
677
  *
658
678
  * @group Global methods
659
679
  */
660
- export function getSessionInfo(): Promise<any>;
661
- /**
662
- *
663
- * @param sessionDetails
664
- */
665
- export function initSession(sessionDetails: any): void;
680
+ export function getSessionInfo(): Promise<sessionInfoInterface>;
666
681
  export const getAuthenticaionToken: (embedConfig: EmbedConfig) => Promise<any>;
667
682
  /**
668
683
  * Perform token based authentication
@@ -699,6 +714,7 @@ declare module '@thoughtspot/visual-embed-sdk/auth' {
699
714
  * Check if we are authenticated to the ThoughtSpot cluster
700
715
  */
701
716
  export const isAuthenticated: () => boolean;
717
+ export {};
702
718
  }
703
719
 
704
720
  declare module '@thoughtspot/visual-embed-sdk/types' {
@@ -738,16 +754,47 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
738
754
  SAML = "SSO_SAML",
739
755
  /**
740
756
  * SSO using SAML
741
- * Will make the host application redirect to the SAML Idp.
757
+ * Will make the host application redirect to the SAML Idp. Use this
758
+ * when the idp does not allow itself to be embedded.
759
+ *
760
+ * This redirects the host application to the SAML Idp. The host application
761
+ * will be redirected back to the ThoughtSpot app after authentication.
742
762
  *
743
763
  * @example
744
764
  * ```js
745
765
  * init({
746
766
  * // ...
747
767
  * authType: AuthType.SAMLRedirect,
768
+ * });
769
+ * ```
770
+ *
771
+ * This opens the SAML Idp in a popup window. The popup is triggered
772
+ * when the user clicks the trigger button. The popup window will be
773
+ * closed automatically after authentication.
774
+ * @example
775
+ * ```js
776
+ * init({
777
+ * // ...
778
+ * authType: AuthType.SAMLRedirect,
748
779
  * authTriggerText: 'Login with SAML',
749
780
  * authTriggerContainer: '#embed-container',
750
- * });
781
+ * inPopup: true,
782
+ * });
783
+ * ```
784
+ *
785
+ * Can also use event to trigger the popup flow. Works the same
786
+ * as above example.
787
+ * @example
788
+ * ```js
789
+ * const authEE = init({
790
+ * // ...
791
+ * authType: AuthType.SAMLRedirect,
792
+ * inPopup: true,
793
+ * });
794
+ *
795
+ * someButtonOnYourPage.addEventListener('click', () => {
796
+ * authEE.emit(AuthEvent.TRIGGER_SSO_POPUP);
797
+ * });
751
798
  * ```
752
799
  */
753
800
  SAMLRedirect = "SSO_SAML",
@@ -761,6 +808,7 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
761
808
  /**
762
809
  * SSO using OIDC
763
810
  * Will make the host application redirect to the OIDC Idp.
811
+ * See code samples in {@link SAMLRedirect}.
764
812
  */
765
813
  OIDCRedirect = "SSO_OIDC",
766
814
  /**
@@ -1336,18 +1384,17 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
1336
1384
  Load = "load",
1337
1385
  /**
1338
1386
  * Data pertaining to answer or Liveboard is received
1339
- *
1340
- * @returns data - The answer or Liveboard data
1387
+ * @return data - The answer or Liveboard data
1388
+ * @important
1341
1389
  */
1342
1390
  Data = "data",
1343
1391
  /**
1344
- * Search/answer/Liveboard filters have been applied/updated
1345
- *
1392
+ * Search/answer/Liveboard filters have been applied/updated by the user.
1346
1393
  * @hidden
1347
1394
  */
1348
1395
  FiltersChanged = "filtersChanged",
1349
1396
  /**
1350
- * Search query has been updated
1397
+ * Search query has been updated by the user.
1351
1398
  */
1352
1399
  QueryChanged = "queryChanged",
1353
1400
  /**
@@ -1379,17 +1426,29 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
1379
1426
  */
1380
1427
  CustomAction = "customAction",
1381
1428
  /**
1382
- * A double click has been triggered on table/chart
1383
- *
1384
- * @returns ContextMenuInputPoints - data point that is double clicked
1429
+ * Listen to double clicks on a visualization
1430
+ * @return ContextMenuInputPoints - data point that is double clicked
1385
1431
  * @version SDK: 1.5.0 | ThoughtSpot: ts7.oct.cl, 7.2.1
1386
1432
  */
1387
1433
  VizPointDoubleClick = "vizPointDoubleClick",
1388
1434
  /**
1389
- * A click has been triggered on table/chart
1435
+ * Listen to clicks on a visualization in a liveboard or Search result.
1390
1436
  *
1391
- * @returns ContextMenuInputPoints - data point that is clicked
1437
+ * @example
1438
+ * ```js
1439
+ * embed.on(ThoughtSpotEmbed.Event.VizPointClick, (data) => {
1440
+ * console.log(
1441
+ * data.vizId, // viz id
1442
+ * data.clickedPoint.selectedAttributes[0].value,
1443
+ * data.clickedPoint.selectedAttributes[0].column.name,
1444
+ * data.clickedPoint.selectedMeasures[0].value,
1445
+ * data.clickedPoint.selectedMeasures[0].column.name,
1446
+ * )
1447
+ * });
1448
+ * ```
1449
+ * @return {vizId, clickedPoint} - metadata about point that is clicked
1392
1450
  * @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1-sw
1451
+ * @important
1393
1452
  */
1394
1453
  VizPointClick = "vizPointClick",
1395
1454
  /**
@@ -1504,6 +1563,12 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
1504
1563
  * @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1-sw
1505
1564
  */
1506
1565
  Download = "download",
1566
+ /**
1567
+ * Emitted when the download action is triggered on an answer
1568
+ *
1569
+ * @version SDK: 1.21.0 | ThoughtSpot: 9.2.0.cl, 9.4.0-sw
1570
+ */
1571
+ DownloadAsPng = "downloadAsPng",
1507
1572
  /**
1508
1573
  * Emitted when the Download as PDF action is triggered on an answer
1509
1574
  *
@@ -1687,8 +1752,7 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
1687
1752
  */
1688
1753
  CrossFilterChanged = "cross-filter-changed",
1689
1754
  /**
1690
- * Emitted when a user right clicks on chart or table
1691
- *
1755
+ * Emitted when a user right clicks on a visualization (chart or table)
1692
1756
  * @version SDK: 1.21.0 | ThoughtSpot: 9.2.0.cl
1693
1757
  */
1694
1758
  VizPointRightClick = "vizPointRightClick",
@@ -1777,10 +1841,11 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
1777
1841
  * @param - {@link RuntimeFilter}[] an array of {@link RuntimeFilter} Types.
1778
1842
  * @example
1779
1843
  * liveboardEmbed.trigger(HostEvent.UpdateRuntimeFilters, [
1780
- * {columnName: "state",operator: RuntimeFilterOp.EQ,values: ["michigan"]},
1781
- * {columnName: "item type",operator: RuntimeFilterOp.EQ,values:
1782
- * ["Jackets"]} ])
1844
+ * {columnName: "state",operator: RuntimeFilterOp.EQ,values: ["michigan"]},
1845
+ * {columnName: "item type",operator: RuntimeFilterOp.EQ,values: ["Jackets"]}
1846
+ * ])
1783
1847
  * @version SDK: 1.9.0 | ThoughtSpot: 8.1.0.cl, 8.4.1-sw
1848
+ * @important
1784
1849
  */
1785
1850
  UpdateRuntimeFilters = "UpdateRuntimeFilters",
1786
1851
  /**
@@ -2032,9 +2097,14 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
2032
2097
  *
2033
2098
  * @example
2034
2099
  * ```js
2035
- * searchEmbed.trigger(HostEvent.GetTML)
2100
+ * searchEmbed.trigger(HostEvent.GetTML).then((tml) => {
2101
+ * console.log(
2102
+ * tml.search_query // TML representation of the search query
2103
+ * );
2104
+ * })
2036
2105
  * ```
2037
- * @version SDK: 1.18.0 | ThoughtSpot: 8.10.0.cl
2106
+ * @version SDK: 1.18.0 | ThoughtSpot: 8.10.0.cl, 9.0.1-sw
2107
+ * @important
2038
2108
  */
2039
2109
  GetTML = "getTML",
2040
2110
  /**
@@ -2083,12 +2153,29 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
2083
2153
  * '730496d6-6903-4601-937e-2c691821af3c'})
2084
2154
  * vizEmbed.trigger(HostEvent.Download)
2085
2155
  * searchEmbed.trigger(HostEvent.Download)
2156
+ * @deprecated from SDK: 1.21.0 | ThoughtSpot: 9.2.0.cl, 9.4.1-sw, Please use DownloadAsPng
2086
2157
  * @version SDK: 1.19.0 | ThoughtSpot: 9.0.0.cl, 9.0.1-sw
2087
2158
  */
2088
- Download = "download",
2159
+ Download = "downloadAsPng",
2160
+ /**
2161
+ * Triggers the Download action on visualization or search when Displaymode is Chart
2162
+ *
2163
+ * @example
2164
+ * ```js
2165
+ * liveboardEmbed.trigger(HostEvent.DownloadAsPng,
2166
+ * {vizId:'730496d6-6903-4601-937e-2c691821af3c'})
2167
+ * ```
2168
+ * ```js
2169
+ * vizEmbed.trigger(HostEvent.DownloadAsPng)
2170
+ * ```
2171
+ * ```js
2172
+ * searchEmbed.trigger(HostEvent.DownloadAsPng)
2173
+ * ```
2174
+ * @version SDK: 1.21.0 | ThoughtSpot: 9.2.0.cl, 9.4.1-sw
2175
+ */
2176
+ DownloadAsPng = "downloadAsPng",
2089
2177
  /**
2090
- * Triggers the downloadAsCSV action on visualization or search when Displaymode is
2091
- * Table
2178
+ * Triggers the downloadAsCSV action on visualization or search
2092
2179
  *
2093
2180
  * @example
2094
2181
  * liveboardEmbed.trigger(HostEvent.DownloadAsCsv, {vizId:
@@ -2099,8 +2186,7 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
2099
2186
  */
2100
2187
  DownloadAsCsv = "downloadAsCSV",
2101
2188
  /**
2102
- * Triggers the downloadAsXLSX action on visualization or search when Displaymode is
2103
- * Table
2189
+ * Triggers the downloadAsXLSX action on visualization or search
2104
2190
  *
2105
2191
  * @example
2106
2192
  * liveboardEmbed.trigger(HostEvent.DownloadAsXlsx, {vizId:
@@ -2287,6 +2373,7 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
2287
2373
  ReplaySearch = "replaySearch",
2288
2374
  ShowUnderlyingData = "showUnderlyingData",
2289
2375
  Download = "download",
2376
+ DownloadAsPng = "downloadAsPng",
2290
2377
  DownloadAsPdf = "downloadAsPdf",
2291
2378
  DownloadAsCsv = "downloadAsCSV",
2292
2379
  DownloadAsXlsx = "downloadAsXLSX",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thoughtspot/visual-embed-sdk",
3
- "version": "1.21.0-alpha.0",
3
+ "version": "1.21.0-alpha.2",
4
4
  "description": "ThoughtSpot Embed SDK",
5
5
  "module": "lib/src/index.js",
6
6
  "main": "dist/tsembed.js",
package/src/auth.spec.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as authInstance from './auth';
2
2
  import * as authService from './utils/authService';
3
3
  import * as checkReleaseVersionInBetaInstance from './utils';
4
+ import * as mixPanelService from './mixpanel-service';
4
5
  import { AuthType, EmbedEvent } from './types';
5
6
  import { executeAfterWait } from './test/test-utils';
6
7
 
@@ -91,6 +92,9 @@ export const embedConfig: any = {
91
92
 
92
93
  const originalWindow = window;
93
94
  export const mockSessionInfo = {
95
+ userGUID: '1234',
96
+ mixpanelToken: 'abc123',
97
+ isPublicUser: false,
94
98
  sessionId: '6588e7d9-710c-453e-a7b4-535fb3a8cbb2',
95
99
  genNo: 3,
96
100
  acSession: {
@@ -110,6 +114,7 @@ describe('Unit test for auth', () => {
110
114
  });
111
115
 
112
116
  test('when session info giving response', async () => {
117
+ jest.spyOn(mixPanelService, 'initMixpanel').mockImplementation(() => Promise.resolve());
113
118
  authInstance.initSession(mockSessionInfo);
114
119
  const sessionInfo = await authInstance.getSessionInfo();
115
120
  expect(sessionInfo).toStrictEqual(mockSessionInfo);
@@ -138,11 +143,17 @@ describe('Unit test for auth', () => {
138
143
  });
139
144
 
140
145
  test('doTokenAuth: when user is loggedIn', async () => {
141
- jest.spyOn(authService, 'fetchSessionInfoService').mockImplementation(async () => ({
142
- json: () => mockSessionInfo,
143
- status: 200,
144
- }));
145
- await authInstance.doTokenAuth(embedConfig.doTokenAuthSuccess('authToken'));
146
+ jest.spyOn(authService, 'fetchSessionInfoService').mockImplementation(
147
+ async () => ({
148
+ json: () => mockSessionInfo,
149
+ status: 200,
150
+ }),
151
+ );
152
+ jest.spyOn(authInstance, 'getSessionDetails').mockReturnValue(mockSessionInfo);
153
+ jest.spyOn(authInstance, 'initSession').mockReturnValue(null);
154
+ await authInstance.doTokenAuth(
155
+ embedConfig.doTokenAuthSuccess('authToken'),
156
+ );
146
157
  expect(authService.fetchSessionInfoService).toBeCalled();
147
158
  expect(authInstance.loggedInStatus).toBe(true);
148
159
  });
@@ -260,14 +271,24 @@ describe('Unit test for auth', () => {
260
271
  });
261
272
 
262
273
  it('when user is loggedIn', async () => {
263
- spyOn(checkReleaseVersionInBetaInstance, 'checkReleaseVersionInBeta');
264
- jest.spyOn(authService, 'fetchSessionInfoService').mockImplementation(async () => ({
274
+ spyOn(
275
+ checkReleaseVersionInBetaInstance,
276
+ 'checkReleaseVersionInBeta',
277
+ );
278
+ jest.spyOn(authInstance, 'getSessionDetails').mockReturnValue(mockSessionInfo);
279
+ jest.spyOn(authInstance, 'initSession').mockReturnValue(null);
280
+ jest.spyOn(
281
+ authService,
282
+ 'fetchSessionInfoService',
283
+ ).mockImplementation(async () => ({
265
284
  json: () => mockSessionInfo,
266
285
  status: 200,
267
286
  }));
268
287
  await authInstance.doBasicAuth(embedConfig.doBasicAuth);
269
288
  expect(authService.fetchSessionInfoService).toBeCalled();
270
289
  expect(authInstance.loggedInStatus).toBe(true);
290
+ expect(authInstance.getSessionDetails).toBeCalled();
291
+ expect(authInstance.initSession).toBeCalled();
271
292
  });
272
293
 
273
294
  it('when user is not loggedIn', async () => {
@@ -304,6 +325,8 @@ describe('Unit test for auth', () => {
304
325
  json: () => mockSessionInfo,
305
326
  status: 200,
306
327
  }));
328
+ jest.spyOn(authInstance, 'getSessionDetails').mockReturnValue(mockSessionInfo);
329
+ jest.spyOn(authInstance, 'initSession').mockReturnValue(null);
307
330
  await authInstance.doSamlAuth(embedConfig.doSamlAuth);
308
331
  expect(authService.fetchSessionInfoService).toBeCalled();
309
332
  expect(window.location.hash).toBe('');
@@ -340,7 +363,14 @@ describe('Unit test for auth', () => {
340
363
  });
341
364
  spyOn(authInstance, 'samlCompletionPromise');
342
365
  global.window.open = jest.fn();
343
- jest.spyOn(authService, 'fetchSessionInfoService').mockImplementation(() => Promise.reject());
366
+ jest.spyOn(authService, 'fetchSessionInfoService')
367
+ .mockImplementationOnce(() => Promise.reject())
368
+ .mockImplementationOnce(async () => ({
369
+ json: () => mockSessionInfo,
370
+ status: 200,
371
+ }));
372
+ jest.spyOn(authInstance, 'getSessionDetails').mockReturnValue(mockSessionInfo);
373
+ jest.spyOn(authInstance, 'initSession').mockReturnValue(null);
344
374
  expect(await authInstance.samlCompletionPromise).not.toBe(null);
345
375
  expect(
346
376
  await authInstance.doSamlAuth({
@@ -351,6 +381,8 @@ describe('Unit test for auth', () => {
351
381
  window.postMessage({ type: EmbedEvent.SAMLComplete }, '*');
352
382
  await authInstance.samlCompletionPromise;
353
383
  expect(authService.fetchSessionInfoService).toBeCalled();
384
+ expect(authInstance.getSessionDetails).toBeCalled();
385
+ expect(authInstance.initSession).toBeCalled();
354
386
  });
355
387
  });
356
388
 
package/src/auth.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import EventEmitter from 'eventemitter3';
2
+ import _ from 'lodash';
2
3
  import { initMixpanel } from './mixpanel-service';
3
4
  import {
4
5
  AuthType, DOMSelector, EmbedConfig, EmbedEvent, Param,
@@ -20,9 +21,9 @@ export let loggedInStatus = false;
20
21
  export let samlAuthWindow: Window = null;
21
22
  // eslint-disable-next-line import/no-mutable-exports
22
23
  export let samlCompletionPromise: Promise<void> = null;
23
- let sessionInfo: any = null;
24
- let sessionInfoResolver: (value: any) => void = null;
25
- const sessionInfoPromise = new Promise((resolve) => {
24
+ let sessionInfo: sessionInfoInterface = null;
25
+ let sessionInfoResolver: (value: sessionInfoInterface) => void = null;
26
+ const sessionInfoPromise = new Promise((resolve:(value: sessionInfoInterface) => void) => {
26
27
  sessionInfoResolver = resolve;
27
28
  });
28
29
  let releaseVersion = '';
@@ -38,6 +39,13 @@ export const EndPoints = {
38
39
  LOGOUT: '/callosum/v1/session/logout',
39
40
  };
40
41
 
42
+ interface sessionInfoInterface {
43
+ userGUID: any;
44
+ isPublicUser: any;
45
+ mixpanelToken: any;
46
+ [key:string]:any;
47
+ }
48
+
41
49
  /**
42
50
  * Enum for auth failure types. This is the parameter passed to the listner
43
51
  * of {@link AuthStatus.FAILURE}.
@@ -196,6 +204,28 @@ export function notifyLogout(): void {
196
204
  authEE.emit(AuthStatus.LOGOUT);
197
205
  }
198
206
 
207
+ export const initSession = (sessionDetails: sessionInfoInterface) => {
208
+ if (_.isNull(sessionInfo)) {
209
+ sessionInfo = sessionDetails;
210
+ initMixpanel(sessionInfo);
211
+ sessionInfoResolver(sessionInfo);
212
+ }
213
+ };
214
+
215
+ export const getSessionDetails = (sessionInfoResp: any):sessionInfoInterface => {
216
+ const devMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.devSdkKey;
217
+ const prodMixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.prodSdkKey;
218
+ const mixpanelToken = sessionInfoResp.configInfo.mixpanelConfig.production
219
+ ? prodMixpanelToken
220
+ : devMixpanelToken;
221
+ return {
222
+ userGUID: sessionInfoResp.userGUID,
223
+ mixpanelToken,
224
+ isPublicUser: sessionInfoResp.configInfo.isPublicUser,
225
+ ...sessionInfoResp,
226
+ };
227
+ };
228
+
199
229
  /**
200
230
  * Check if we are logged into the ThoughtSpot cluster
201
231
  *
@@ -207,6 +237,9 @@ async function isLoggedIn(thoughtSpotHost: string): Promise<boolean> {
207
237
  try {
208
238
  response = await fetchSessionInfoService(authVerificationUrl);
209
239
  const sessionInfoResp = await response.json();
240
+ const sessionDetails = getSessionDetails(sessionInfoResp);
241
+ // Store user session details from session info
242
+ initSession(sessionDetails);
210
243
  releaseVersion = sessionInfoResp.releaseVersion;
211
244
  } catch (e) {
212
245
  return false;
@@ -227,20 +260,10 @@ export function getReleaseVersion() {
227
260
  *
228
261
  * @group Global methods
229
262
  */
230
- export function getSessionInfo(): Promise<any> {
263
+ export function getSessionInfo(): Promise<sessionInfoInterface> {
231
264
  return sessionInfoPromise;
232
265
  }
233
266
 
234
- /**
235
- *
236
- * @param sessionDetails
237
- */
238
- export function initSession(sessionDetails: any) {
239
- sessionInfo = sessionDetails;
240
- initMixpanel(sessionInfo);
241
- sessionInfoResolver(sessionInfo);
242
- }
243
-
244
267
  const DUPLICATE_TOKEN_ERR = 'Duplicate token, please issue a new token every time getAuthToken callback is called.'
245
268
  + 'See https://developers.thoughtspot.com/docs/?pageid=embed-auth#trusted-auth-embed for more details.';
246
269
  let prevAuthToken: string = null;
@@ -425,8 +448,12 @@ const doSSOAuth = async (embedConfig: EmbedConfig, ssoEndPoint: string): Promise
425
448
 
426
449
  const ssoURL = `${thoughtSpotHost}${ssoEndPoint}`;
427
450
  if (embedConfig.inPopup) {
428
- await samlPopupFlow(ssoURL, embedConfig.authTriggerContainer, embedConfig.authTriggerText);
429
- loggedInStatus = true;
451
+ await samlPopupFlow(
452
+ ssoURL,
453
+ embedConfig.authTriggerContainer,
454
+ embedConfig.authTriggerText,
455
+ );
456
+ loggedInStatus = await isLoggedIn(thoughtSpotHost);
430
457
  return;
431
458
  }
432
459
 
package/src/embed/base.ts CHANGED
@@ -142,7 +142,9 @@ function backwardCompat(embedConfig: EmbedConfig): EmbedConfig {
142
142
 
143
143
  /**
144
144
  * Initializes the Visual Embed SDK globally and perform
145
- * authentication if applicable.
145
+ * authentication if applicable. This function needs to be called before any ThoughtSpot
146
+ * component like liveboard etc can be embedded. But need not wait for AuthEvent.SUCCESS
147
+ * to actually embed. That is handled internally.
146
148
  *
147
149
  * @param embedConfig The configuration object containing ThoughtSpot host,
148
150
  * authentication mechanism and so on.
@@ -232,7 +234,7 @@ export const renderInQueue = (fn: (next?: (val?: any) => void) => Promise<any>):
232
234
  return renderQueue;
233
235
  }
234
236
  // Sending an empty function to keep it consistent with the above usage.
235
- return fn(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
237
+ return fn(() => { }); // eslint-disable-line @typescript-eslint/no-empty-function
236
238
  };
237
239
 
238
240
  // For testing purposes only
@@ -102,8 +102,18 @@ export interface LiveboardViewConfig extends ViewConfig {
102
102
  }
103
103
 
104
104
  /**
105
- * Embed a ThoughtSpot Liveboard or visualization
105
+ * Embed a ThoughtSpot Liveboard or a Thoughtspot visualization. When rendered it already
106
+ * waits for the authentication to complete, so no need to wait for AuthStatus.SUCCESS.
106
107
  *
108
+ * @example
109
+ * ```js
110
+ * import { .. } from '@thoughtspot/visual-embed-sdk';
111
+ * init({ ... });
112
+ * const embed = new LiveboardEmbed("#container", {
113
+ * liveboardId: <your-id-here>,
114
+ * // .. other params here.
115
+ * })
116
+ * ```
107
117
  * @group Embed components
108
118
  */
109
119
  export class LiveboardEmbed extends V1Embed {
@@ -383,7 +383,8 @@ export class TsEmbed {
383
383
  queryParams[Param.ContextMenuTrigger] = false;
384
384
  }
385
385
 
386
- const spriteUrl = customizations?.iconSpriteUrl;
386
+ const spriteUrl = customizations?.iconSpriteUrl
387
+ || this.embedConfig.customizations?.iconSpriteUrl;
387
388
  if (spriteUrl) {
388
389
  queryParams[Param.IconSpriteUrl] = spriteUrl.replace('https://', '');
389
390
  }
@@ -79,6 +79,21 @@ export const AppEmbed = componentFactory<typeof _AppEmbed, AppProps, AppViewConf
79
79
 
80
80
  interface LiveboardProps extends EmbedProps, LiveboardViewConfig {}
81
81
 
82
+ /**
83
+ * React component for Liveboard embed.
84
+ *
85
+ * @example
86
+ * ```tsx
87
+ * function Liveboard() {
88
+ * return <LiveboardEmbed
89
+ * liveboardId="liveboardId"
90
+ * fullHeight={true} {/* default false *\/}
91
+ * onLiveboardRendered={() => console.log('Liveboard rendered')}
92
+ * vizId="vizId" {/* if doing viz embed *\/}
93
+ * />
94
+ * }
95
+ * ```
96
+ */
82
97
  export const LiveboardEmbed = componentFactory<
83
98
  typeof _LiveboardEmbed,
84
99
  LiveboardProps,