@thoughtspot/visual-embed-sdk 1.37.0 → 1.37.1

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 (95) hide show
  1. package/cjs/package.json +2 -2
  2. package/cjs/src/auth.d.ts +9 -4
  3. package/cjs/src/auth.d.ts.map +1 -1
  4. package/cjs/src/auth.js +21 -0
  5. package/cjs/src/auth.js.map +1 -1
  6. package/cjs/src/auth.spec.js +48 -0
  7. package/cjs/src/auth.spec.js.map +1 -1
  8. package/cjs/src/embed/app.d.ts +99 -0
  9. package/cjs/src/embed/app.d.ts.map +1 -1
  10. package/cjs/src/embed/app.js +48 -3
  11. package/cjs/src/embed/app.js.map +1 -1
  12. package/cjs/src/embed/app.spec.js +61 -0
  13. package/cjs/src/embed/app.spec.js.map +1 -1
  14. package/cjs/src/embed/base.d.ts.map +1 -1
  15. package/cjs/src/embed/base.js +7 -0
  16. package/cjs/src/embed/base.js.map +1 -1
  17. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  18. package/cjs/src/embed/ts-embed.js +10 -5
  19. package/cjs/src/embed/ts-embed.js.map +1 -1
  20. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  21. package/cjs/src/embed/ts-embed.spec.js +105 -0
  22. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  23. package/cjs/src/types.d.ts +69 -4
  24. package/cjs/src/types.d.ts.map +1 -1
  25. package/cjs/src/types.js +54 -2
  26. package/cjs/src/types.js.map +1 -1
  27. package/cjs/src/utils/graphql/answerService/answerService.d.ts +35 -15
  28. package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  29. package/cjs/src/utils/graphql/answerService/answerService.js +35 -15
  30. package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -1
  31. package/cjs/src/utils/processData.js +6 -4
  32. package/cjs/src/utils/processData.js.map +1 -1
  33. package/dist/{index-DnIvX1FR.js → index-m9UtENc9.js} +1 -1
  34. package/dist/src/auth.d.ts +9 -4
  35. package/dist/src/auth.d.ts.map +1 -1
  36. package/dist/src/embed/app.d.ts +99 -0
  37. package/dist/src/embed/app.d.ts.map +1 -1
  38. package/dist/src/embed/base.d.ts.map +1 -1
  39. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  40. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  41. package/dist/src/types.d.ts +69 -4
  42. package/dist/src/types.d.ts.map +1 -1
  43. package/dist/src/utils/graphql/answerService/answerService.d.ts +35 -15
  44. package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  45. package/dist/tsembed-react.es.js +183 -31
  46. package/dist/tsembed-react.js +182 -30
  47. package/dist/tsembed.es.js +183 -31
  48. package/dist/tsembed.js +182 -30
  49. package/dist/visual-embed-sdk-react-full.d.ts +212 -23
  50. package/dist/visual-embed-sdk-react.d.ts +212 -23
  51. package/dist/visual-embed-sdk.d.ts +212 -23
  52. package/lib/package.json +2 -2
  53. package/lib/src/auth.d.ts +9 -4
  54. package/lib/src/auth.d.ts.map +1 -1
  55. package/lib/src/auth.js +21 -0
  56. package/lib/src/auth.js.map +1 -1
  57. package/lib/src/auth.spec.js +48 -0
  58. package/lib/src/auth.spec.js.map +1 -1
  59. package/lib/src/embed/app.d.ts +99 -0
  60. package/lib/src/embed/app.d.ts.map +1 -1
  61. package/lib/src/embed/app.js +47 -2
  62. package/lib/src/embed/app.js.map +1 -1
  63. package/lib/src/embed/app.spec.js +62 -1
  64. package/lib/src/embed/app.spec.js.map +1 -1
  65. package/lib/src/embed/base.d.ts.map +1 -1
  66. package/lib/src/embed/base.js +7 -0
  67. package/lib/src/embed/base.js.map +1 -1
  68. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  69. package/lib/src/embed/ts-embed.js +10 -5
  70. package/lib/src/embed/ts-embed.js.map +1 -1
  71. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  72. package/lib/src/embed/ts-embed.spec.js +105 -0
  73. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  74. package/lib/src/types.d.ts +69 -4
  75. package/lib/src/types.d.ts.map +1 -1
  76. package/lib/src/types.js +54 -2
  77. package/lib/src/types.js.map +1 -1
  78. package/lib/src/utils/graphql/answerService/answerService.d.ts +35 -15
  79. package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  80. package/lib/src/utils/graphql/answerService/answerService.js +35 -15
  81. package/lib/src/utils/graphql/answerService/answerService.js.map +1 -1
  82. package/lib/src/utils/processData.js +6 -4
  83. package/lib/src/utils/processData.js.map +1 -1
  84. package/lib/src/visual-embed-sdk.d.ts +212 -23
  85. package/package.json +2 -2
  86. package/src/auth.spec.ts +52 -0
  87. package/src/auth.ts +25 -3
  88. package/src/embed/app.spec.ts +88 -0
  89. package/src/embed/app.ts +133 -0
  90. package/src/embed/base.ts +9 -0
  91. package/src/embed/ts-embed.spec.ts +130 -0
  92. package/src/embed/ts-embed.ts +10 -4
  93. package/src/types.ts +68 -3
  94. package/src/utils/graphql/answerService/answerService.ts +35 -15
  95. package/src/utils/processData.ts +6 -6
package/src/embed/app.ts CHANGED
@@ -83,6 +83,47 @@ export enum HomePageSearchBarMode {
83
83
  AI_ANSWER = 'aiAnswer',
84
84
  NONE = 'none'
85
85
  }
86
+
87
+ /**
88
+ * Define the version of the primary navbar
89
+ * @version SDK: 1.39.0 | Thoughtspot: 10.10.0.cl
90
+ */
91
+ export enum PrimaryNavbarVersion {
92
+ /**
93
+ * Sliding (v3) introduces a new left-side navigation hub featuring a tab switcher,
94
+ * along with updates to the top navigation bar.
95
+ * It serves as the foundational version of the PrimaryNavBar.
96
+  */
97
+ Sliding = 'v3',
98
+ }
99
+
100
+ /**
101
+ * Define the version of the home page
102
+ * @version SDK: 1.39.0 | Thoughtspot: 10.10.0.cl
103
+ */
104
+ export enum HomePage {
105
+ /**
106
+  * Modular (v2) introduces the updated Modular Home Experience.
107
+  * It serves as the foundational version of the home page.
108
+  */
109
+ Modular = 'v2',
110
+ }
111
+
112
+ /**
113
+ * Define the discovery experience
114
+ * @version SDK: 1.39.0 | Thoughtspot: 10.10.0.cl
115
+ */
116
+ export interface DiscoveryExperience {
117
+ /**
118
+ * primaryNavbarVersion determines the version of the navigation version.
119
+ */
120
+ primaryNavbarVersion?: PrimaryNavbarVersion;
121
+ /**
122
+ * homePage determines the version of the home page.
123
+ */
124
+ homePage?: HomePage;
125
+ }
126
+
86
127
  /**
87
128
  * The view configuration for full app embedding.
88
129
  * @group Embed components
@@ -151,6 +192,51 @@ export interface AppViewConfig extends Omit<ViewConfig, 'visibleTabs'> {
151
192
  * ```
152
193
  */
153
194
  enablePendoHelp?: boolean
195
+ /**
196
+ * Control the visibility of the hamburger icon on the top nav bar
197
+ * available when new navigation V3 is enabled.
198
+ *
199
+ * @default false
200
+ * @version SDK: 1.39.0 | Thoughtspot: 10.10.0.cl
201
+ * @example
202
+ * ```js
203
+ * const embed = new AppEmbed('#tsEmbed', {
204
+ * ... // other options
205
+ * hideHamburger : true,
206
+ * })
207
+ * ```
208
+ */
209
+ hideHamburger?: boolean;
210
+ /**
211
+ * Control the visibility of the Eureka search on the top nav bar
212
+ * this will control for both new V2 and new navigation V3.
213
+ *
214
+ * @default true
215
+ * @version SDK: 1.39.0 | Thoughtspot: 10.10.0.cl
216
+ * @example
217
+ * ```js
218
+ * const embed = new AppEmbed('#tsEmbed', {
219
+ * ... // other options
220
+ * hideObjectSearch: false,
221
+ * })
222
+ * ```
223
+ */
224
+ hideObjectSearch?: boolean;
225
+ /**
226
+ * Control the visibility of the notification on the top nav bar V3,
227
+ * available when new navigation V3 is enabled.
228
+ *
229
+ * @default true
230
+ * @version SDK: 1.39.0 | Thoughtspot: 10.10.0.cl
231
+ * @example
232
+ * ```js
233
+ * const embed = new AppEmbed('#tsEmbed', {
234
+ * ... // other options
235
+ * hideNotification: false,
236
+ * })
237
+ * ```
238
+ */
239
+ hideNotification?: boolean;
154
240
  /**
155
241
  * Control the visibility of the application switcher button on the nav-bar.
156
242
  * By default, the application switcher is shown.
@@ -344,6 +430,23 @@ export interface AppViewConfig extends Omit<ViewConfig, 'visibleTabs'> {
344
430
  * ```
345
431
  */
346
432
  modularHomeExperience?: boolean;
433
+ /**
434
+ * To configure the top-left navigation and home page experience
435
+ *
436
+ * @default false
437
+ * @version SDK: 1.39.0 | Thoughtspot: 10.10.0.cl
438
+ * @example
439
+ * ```js
440
+ * const embed = new AppEmbed('#tsEmbed', {
441
+ * ... // other options
442
+ * discoveryExperience : {
443
+ * primaryNavbarVersion: PrimaryNavbarVersion.Sliding,
444
+ * homePage: HompePage.Modular,
445
+ * },
446
+ * })
447
+ * ```
448
+ */
449
+ discoveryExperience?: DiscoveryExperience;
347
450
  /**
348
451
  * Boolean to control if Liveboard header is sticky or not.
349
452
  * @example
@@ -515,6 +618,9 @@ export class AppEmbed extends V1Embed {
515
618
  liveboardV2,
516
619
  showPrimaryNavbar,
517
620
  disableProfileAndHelp,
621
+ hideHamburger,
622
+ hideObjectSearch,
623
+ hideNotification,
518
624
  hideApplicationSwitcher,
519
625
  hideOrgSwitcher,
520
626
  enableSearchAssist,
@@ -541,6 +647,7 @@ export class AppEmbed extends V1Embed {
541
647
  homePageSearchBarMode,
542
648
  isUnifiedSearchExperienceEnabled = true,
543
649
  enablePendoHelp = true,
650
+ discoveryExperience,
544
651
  } = this.viewConfig;
545
652
 
546
653
  let params = {};
@@ -561,6 +668,18 @@ export class AppEmbed extends V1Embed {
561
668
 
562
669
  params = this.getBaseQueryParams(params);
563
670
 
671
+ if (hideObjectSearch) {
672
+ params[Param.HideObjectSearch] = !!hideObjectSearch;
673
+ }
674
+
675
+ if (hideHamburger) {
676
+ params[Param.HideHamburger] = !!hideHamburger;
677
+ }
678
+
679
+ if (hideNotification) {
680
+ params[Param.HideNotification] = !!hideNotification;
681
+ }
682
+
564
683
  if (fullHeight === true) {
565
684
  params[Param.fullHeight] = true;
566
685
  }
@@ -620,6 +739,20 @@ export class AppEmbed extends V1Embed {
620
739
  /* eslint-disable-next-line max-len */
621
740
  params[Param.DataPanelCustomGroupsAccordionInitialState] = DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL;
622
741
  }
742
+
743
+ if (discoveryExperience) {
744
+ // primaryNavbarVersion v3 will enabled the new left navigation
745
+ if (discoveryExperience.primaryNavbarVersion === PrimaryNavbarVersion.Sliding) {
746
+ params[Param.NavigationVersion] = discoveryExperience.primaryNavbarVersion;
747
+ }
748
+
749
+ // homePage v2 will enable the modular home page
750
+ // and it will override the modularHomeExperience value
751
+ if (discoveryExperience.homePage === HomePage.Modular) {
752
+ params[Param.ModularHomeExperienceEnabled] = true;
753
+ }
754
+ }
755
+
623
756
  const queryParams = getQueryParamString(params, true);
624
757
 
625
758
  return queryParams;
package/src/embed/base.ts CHANGED
@@ -137,6 +137,15 @@ export const prefetch = (
137
137
  iFrame.style.width = '0';
138
138
  iFrame.style.height = '0';
139
139
  iFrame.style.border = '0';
140
+
141
+ // Make it 'fixed' to keep it in a different stacking context.
142
+ // This should solve the focus behaviours inside the iframe from
143
+ // interfering with main body.
144
+ iFrame.style.position = 'fixed';
145
+ // Push it out of viewport.
146
+ iFrame.style.top = '100vh';
147
+ iFrame.style.left = '100vw';
148
+
140
149
  iFrame.classList.add('prefetchIframe');
141
150
  iFrame.classList.add(`prefetchIframeNum-${index}`);
142
151
  document.body.appendChild(iFrame);
@@ -60,6 +60,7 @@ import { HiddenActionItemByDefaultForSearchEmbed } from './search';
60
60
  import { processTrigger } from '../utils/processTrigger';
61
61
  import { UIPassthroughEvent } from './hostEventClient/contracts';
62
62
  import * as sessionInfoService from '../utils/sessionInfoService';
63
+ import * as authToken from '../authToken';
63
64
 
64
65
  jest.mock('../utils/processTrigger');
65
66
 
@@ -2578,4 +2579,133 @@ describe('Unit test case for ts embed', () => {
2578
2579
  expect(iframeAfterInit).not.toBe(null);
2579
2580
  });
2580
2581
  });
2582
+
2583
+ describe('AutoLogin behavior in updateAuthToken', () => {
2584
+ const mockPort = { postMessage: jest.fn() };
2585
+ const mockEmbedEventPayload = { type: EmbedEvent.AuthExpire, data: {} };
2586
+
2587
+ beforeEach(() => {
2588
+ jest.clearAllMocks();
2589
+ document.body.innerHTML = getDocumentBody();
2590
+ mockPort.postMessage.mockClear();
2591
+ jest.spyOn(authToken, 'getAuthenticationToken').mockResolvedValue('test-token');
2592
+
2593
+ jest.spyOn(baseInstance, 'handleAuth').mockImplementation(() => Promise.resolve(true));
2594
+ jest.spyOn(baseInstance, 'notifyAuthFailure').mockImplementation(() => {});
2595
+ });
2596
+
2597
+ const renderAndTriggerAuthExpire = async () => {
2598
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
2599
+ await searchEmbed.render();
2600
+ await executeAfterWait(() => {
2601
+ const iframe = getIFrameEl();
2602
+ postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
2603
+ });
2604
+ };
2605
+
2606
+ test('Cookieless with autoLogin undefined should default to true', async () => {
2607
+ init({
2608
+ thoughtSpotHost: 'tshost',
2609
+ authType: AuthType.TrustedAuthTokenCookieless,
2610
+ // autoLogin undefined
2611
+ });
2612
+
2613
+ await renderAndTriggerAuthExpire();
2614
+
2615
+ await executeAfterWait(() => {
2616
+ expect(authToken.getAuthenticationToken).toHaveBeenCalled();
2617
+ expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
2618
+ expect(mockPort.postMessage).toHaveBeenCalledWith({
2619
+ type: EmbedEvent.AuthExpire,
2620
+ data: { authToken: 'test-token' },
2621
+ });
2622
+ });
2623
+ });
2624
+
2625
+ test('Cookieless with autoLogin false should not get auth token', async () => {
2626
+ init({
2627
+ thoughtSpotHost: 'tshost',
2628
+ authType: AuthType.TrustedAuthTokenCookieless,
2629
+ autoLogin: false,
2630
+ });
2631
+
2632
+ await renderAndTriggerAuthExpire();
2633
+
2634
+ await executeAfterWait(() => {
2635
+ expect(authToken.getAuthenticationToken).not.toHaveBeenCalled();
2636
+ expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
2637
+ expect(mockPort.postMessage).not.toHaveBeenCalled();
2638
+ });
2639
+ });
2640
+
2641
+ test('Cookieless with autoLogin true should get auth token', async () => {
2642
+ init({
2643
+ thoughtSpotHost: 'tshost',
2644
+ authType: AuthType.TrustedAuthTokenCookieless,
2645
+ autoLogin: true,
2646
+ });
2647
+
2648
+ await renderAndTriggerAuthExpire();
2649
+
2650
+ await executeAfterWait(() => {
2651
+ expect(authToken.getAuthenticationToken).toHaveBeenCalled();
2652
+ expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
2653
+ expect(mockPort.postMessage).toHaveBeenCalledWith({
2654
+ type: EmbedEvent.AuthExpire,
2655
+ data: { authToken: 'test-token' },
2656
+ });
2657
+ });
2658
+ });
2659
+
2660
+ test('Other authType with autoLogin undefined should default to false', async () => {
2661
+ init({
2662
+ thoughtSpotHost: 'tshost',
2663
+ authType: AuthType.None,
2664
+ // autoLogin undefined
2665
+ });
2666
+
2667
+ await renderAndTriggerAuthExpire();
2668
+
2669
+ await executeAfterWait(() => {
2670
+ expect(authToken.getAuthenticationToken).not.toHaveBeenCalled();
2671
+ expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
2672
+ });
2673
+ });
2674
+
2675
+ test('Other authType with autoLogin true should call handleAuth', async () => {
2676
+ init({
2677
+ thoughtSpotHost: 'tshost',
2678
+ authType: AuthType.None,
2679
+ autoLogin: true,
2680
+ });
2681
+
2682
+ await renderAndTriggerAuthExpire();
2683
+
2684
+ await executeAfterWait(() => {
2685
+ expect(authToken.getAuthenticationToken).not.toHaveBeenCalled();
2686
+ expect(baseInstance.handleAuth).toHaveBeenCalledTimes(2);
2687
+ });
2688
+ });
2689
+
2690
+ test('Other authType with autoLogin false should not call handleAuth', async () => {
2691
+ init({
2692
+ thoughtSpotHost: 'tshost',
2693
+ authType: AuthType.None,
2694
+ autoLogin: false,
2695
+ });
2696
+
2697
+ await renderAndTriggerAuthExpire();
2698
+
2699
+ await executeAfterWait(() => {
2700
+ expect(authToken.getAuthenticationToken).not.toHaveBeenCalled();
2701
+ expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
2702
+ });
2703
+ });
2704
+
2705
+ afterEach(() => {
2706
+ expect(baseInstance.notifyAuthFailure).toHaveBeenCalledWith(
2707
+ authInstance.AuthFailureType.EXPIRY
2708
+ );
2709
+ });
2710
+ });
2581
2711
  });
@@ -409,11 +409,13 @@ export class TsEmbed {
409
409
  * @param responder
410
410
  */
411
411
  private updateAuthToken = async (_: any, responder: any) => {
412
- const { autoLogin = false, authType } = this.embedConfig; // Set autoLogin default to false
413
- if (authType === AuthType.TrustedAuthTokenCookieless) {
414
- let authToken = '';
412
+ const { authType } = this.embedConfig;
413
+ let { autoLogin } = this.embedConfig;
414
+ // Default autoLogin: true for cookieless if undefined/null, otherwise false
415
+ autoLogin = autoLogin ?? (authType === AuthType.TrustedAuthTokenCookieless);
416
+ if (autoLogin && authType === AuthType.TrustedAuthTokenCookieless) {
415
417
  try {
416
- authToken = await getAuthenticationToken(this.embedConfig);
418
+ const authToken = await getAuthenticationToken(this.embedConfig);
417
419
  responder({
418
420
  type: EmbedEvent.AuthExpire,
419
421
  data: { authToken },
@@ -540,6 +542,7 @@ export class TsEmbed {
540
542
  disableRedirectionLinksInNewTab,
541
543
  overrideOrgId,
542
544
  exposeTranslationIDs,
545
+ primaryAction,
543
546
  } = this.viewConfig;
544
547
 
545
548
  const { additionalFlags: additionalFlagsFromInit } = this.embedConfig;
@@ -558,6 +561,9 @@ export class TsEmbed {
558
561
  this.handleError('You cannot have both hidden Tabs and visible Tabs');
559
562
  return queryParams;
560
563
  }
564
+ if (primaryAction) {
565
+ queryParams[Param.PrimaryAction] = primaryAction;
566
+ }
561
567
 
562
568
  if (disabledActions?.length) {
563
569
  queryParams[Param.DisableActions] = disabledActions;
package/src/types.ts CHANGED
@@ -204,7 +204,19 @@ export enum HomeLeftNavItem {
204
204
  /**
205
205
  * @version SDK: 1.34.0| ThoughtSpot: 10.3.0.cl
206
206
  */
207
- LiveboardSchedules = 'liveboard-schedules'
207
+ LiveboardSchedules = 'liveboard-schedules',
208
+ /**
209
+ * Create new options in the insights left navigation,
210
+ * available when new navigation V3 is enabled.
211
+ * @version SDK: 1.39.0 | ThoughtSpot: 10.10.0.cl
212
+ */
213
+ Create = 'create',
214
+ /**
215
+ * Spotter option in the insights left navigation,
216
+ * available when new navigation V3 is enabled.
217
+ * @version SDK: 1.39.0 | ThoughtSpot: 10.10.0.cl
218
+ */
219
+ Spotter = 'spotter',
208
220
  }
209
221
  export type DOMSelector = string | HTMLElement;
210
222
 
@@ -712,6 +724,19 @@ export interface ViewConfig {
712
724
  * ```
713
725
  */
714
726
  disabledActions?: Action[];
727
+ /**
728
+ * The primary action to display on top of the viz for Liveboard and App Embed.
729
+ * Use this to set the primary action.
730
+ * @version SDK: 1.37.0 | ThoughtSpot: 10.9.0.cl
731
+ * @example
732
+ * ```js
733
+ * const embed = new LiveboardEmbed('#embed', {
734
+ * ... // other liveboard view config
735
+ * primaryAction: Action.Download
736
+ * });
737
+ * ```
738
+ */
739
+ primaryAction?: Action | string;
715
740
  /**
716
741
  * The tooltip to display for disabled actions.
717
742
  * @version SDK: 1.6.0 | ThoughtSpot: ts8.nov.cl, 8.4.1.sw
@@ -2654,9 +2679,12 @@ export enum HostEvent {
2654
2679
  * @example
2655
2680
  * ```js
2656
2681
  * searchEmbed.trigger(HostEvent.OpenFilter,
2657
- * { columnId: '<column-GUID>', name: 'column name', type: 'INT64', dataType: 'ATTRIBUTE'})
2682
+ * {column: { columnId: '<column-GUID>', name: 'column name', type: 'INT64', dataType: 'ATTRIBUTE'}})
2683
+ * ```
2684
+ * @example
2685
+ * ```js
2658
2686
  * LiveboardEmbed.trigger(HostEvent.OpenFilter,
2659
- * { columnId: '<column-GUID>'})
2687
+ * { column: {columnId: '<column-GUID>'}})
2660
2688
  * ```
2661
2689
  * @version SDK: 1.21.0 | ThoughtSpot: 9.2.0.cl
2662
2690
  */
@@ -3265,6 +3293,25 @@ export enum HostEvent {
3265
3293
  * }]
3266
3294
  * });
3267
3295
  * ```
3296
+ * If there are multiple columns with the same name, consider
3297
+ * using `WORKSHEET_NAME::COLUMN_NAME` format.
3298
+ *
3299
+ * @example
3300
+ *
3301
+ * ```js
3302
+ * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3303
+ * filters: [{
3304
+ * column: "(Sample) Retail - Apparel::city",
3305
+ * oper: 'IN',
3306
+ * values: ["atlanta"]
3307
+ * },
3308
+ * {
3309
+ * column: "(Sample) Retail - Apparel::Region",
3310
+ * oper: 'IN',
3311
+ * values: ["West","Midwest"]
3312
+ * }]
3313
+ * });
3314
+ * ```
3268
3315
  * @version SDK: 1.23.0 | ThoughtSpot: 9.4.0.cl
3269
3316
  */
3270
3317
  UpdateFilters = 'updateFilters',
@@ -3324,8 +3371,17 @@ export enum HostEvent {
3324
3371
  /**
3325
3372
  * Get the Answer session for a Search or
3326
3373
  * Liveboard visualization.
3374
+ *
3375
+ * Note: This event is not typically used directly. Instead, use the
3376
+ * `getAnswerService()` method on the embed instance to get an AnswerService
3377
+ * object that provides a more convenient interface for working with answers.
3378
+ *
3327
3379
  * @example
3328
3380
  * ```js
3381
+ * // Preferred way to get an AnswerService
3382
+ * const service = await embed.getAnswerService();
3383
+ *
3384
+ * // Alternative direct usage (not recommended)
3329
3385
  * const {session} = await embed.trigger(
3330
3386
  * HostEvent.GetAnswerSession, {
3331
3387
  * vizId: '123', // For Liveboard Visualization.
@@ -3333,6 +3389,10 @@ export enum HostEvent {
3333
3389
  * ```
3334
3390
  * @example
3335
3391
  * ```js
3392
+ * // Preferred way to get an AnswerService
3393
+ * const service = await embed.getAnswerService();
3394
+ *
3395
+ * // Alternative direct usage (not recommended)
3336
3396
  * const {session} = await embed.trigger( HostEvent.GetAnswerSession )
3337
3397
  * ```
3338
3398
  * @version SDK: 1.26.0 | ThoughtSpot: 9.10.0.cl, 10.1.0.sw
@@ -3541,6 +3601,10 @@ export enum Param {
3541
3601
  ShowInsertToSlide = 'insertInToSlide',
3542
3602
  PrimaryNavHidden = 'primaryNavHidden',
3543
3603
  HideProfleAndHelp = 'profileAndHelpInNavBarHidden',
3604
+ NavigationVersion = 'navigationVersion',
3605
+ HideHamburger = 'hideHamburger',
3606
+ HideObjectSearch = 'hideObjectSearch',
3607
+ HideNotification = 'hideNotification',
3544
3608
  HideApplicationSwitcher = 'applicationSwitcherHidden',
3545
3609
  HideOrgSwitcher = 'orgSwitcherHidden',
3546
3610
  IsSageEmbed = 'isSageEmbed',
@@ -3597,6 +3661,7 @@ export enum Param {
3597
3661
  preAuthCache = 'preAuthCache',
3598
3662
  ShowSpotterLimitations = 'showSpotterLimitations',
3599
3663
  CoverAndFilterOptionInPDF = 'coverAndFilterOptionInPDF',
3664
+ PrimaryAction = 'primaryAction',
3600
3665
  }
3601
3666
 
3602
3667
  /**
@@ -26,29 +26,49 @@ export interface UnderlyingDataPoint {
26
26
  }
27
27
 
28
28
  /**
29
- * Class representing the answer service provided with the
30
- * custom action payload. This service could be used to run
31
- * graphql queries in the context of the answer on which the
32
- * custom action was triggered.
29
+ * AnswerService provides a simple way to work with ThoughtSpot Answers.
30
+ *
31
+ * This service allows you to interact with ThoughtSpot Answers programmatically,
32
+ * making it easy to customize visualizations, filter data, and extract insights
33
+ * directly from your application.
34
+ *
35
+ * You can use this service to:
36
+ * - Add or remove columns from Answers (`addColumns`, `removeColumns`, `addColumnsByName`)
37
+ * - Apply filters to Answers (`addFilter`)
38
+ * - Get data from Answers in different formats (JSON, CSV, PNG) (`fetchData`, `fetchCSVBlob`, `fetchPNGBlob`)
39
+ * - Get data for specific points in visualizations (`getUnderlyingDataForPoint`)
40
+ * - Run custom queries (`executeQuery`)
41
+ * - Add visualizations to liveboards (`addDisplayedVizToLiveboard`)
42
+ *
33
43
  * @example
34
44
  * ```js
35
- * embed.on(EmbedEvent.CustomAction, e => {
36
- * const underlying = await e.answerService.getUnderlyingDataForPoint([
37
- * 'col name 1'
38
- * ]);
39
- * const data = await underlying.fetchData(0, 100);
40
- * })
45
+ * // Get the answer service
46
+ * embed.on(EmbedEvent.Data, async (e) => {
47
+ * const service = await embed.getAnswerService();
48
+ *
49
+ * // Add columns to the answer
50
+ * await service.addColumnsByName(["Sales", "Region"]);
51
+ *
52
+ * // Get the data
53
+ * const data = await service.fetchData();
54
+ * console.log(data);
55
+ * });
41
56
  * ```
57
+ *
42
58
  * @example
43
59
  * ```js
44
- * embed.on(EmbedEvent.Data, async (e) => {
45
- * const service = await embed.getAnswerService();
46
- * await service.addColumns([
47
- * "<column guid>"
60
+ * // Get data for a point in a visualization
61
+ * embed.on(EmbedEvent.CustomAction, async (e) => {
62
+ * const underlying = await e.answerService.getUnderlyingDataForPoint([
63
+ * 'Product Name',
64
+ * 'Sales Amount'
48
65
  * ]);
49
- * console.log(await service.fetchData());
66
+ *
67
+ * const data = await underlying.fetchData(0, 100);
68
+ * console.log(data);
50
69
  * });
51
70
  * ```
71
+ *
52
72
  * @version SDK: 1.25.0| ThoughtSpot: 9.10.0.cl
53
73
  * @group Events
54
74
  */
@@ -80,15 +80,15 @@ export function processAuthFailure(e: any, containerEl: Element) {
80
80
  const {
81
81
  loginFailedMessage, authType, disableLoginFailurePage, autoLogin,
82
82
  } = getEmbedConfig();
83
- if (
84
- autoLogin
85
- && (authType === AuthType.TrustedAuthToken
86
- || authType === AuthType.TrustedAuthTokenCookieless)
87
- ) {
83
+
84
+ const isEmbeddedSSO = authType === AuthType.EmbeddedSSO;
85
+ const isTrustedAuth = authType === AuthType.TrustedAuthToken || authType === AuthType.TrustedAuthTokenCookieless;
86
+ const isEmbeddedSSOInfoFailure = isEmbeddedSSO && e?.data?.type === AuthFailureType.UNAUTHENTICATED_FAILURE;
87
+ if (autoLogin && isTrustedAuth) {
88
88
  // eslint-disable-next-line no-param-reassign
89
89
  containerEl.innerHTML = loginFailedMessage;
90
90
  notifyAuthFailure(AuthFailureType.IDLE_SESSION_TIMEOUT);
91
- } else if (authType !== AuthType.None && !disableLoginFailurePage) {
91
+ } else if (authType !== AuthType.None && !disableLoginFailurePage && !isEmbeddedSSOInfoFailure) {
92
92
  // eslint-disable-next-line no-param-reassign
93
93
  containerEl.innerHTML = loginFailedMessage;
94
94
  notifyAuthFailure(AuthFailureType.OTHER);