@thoughtspot/visual-embed-sdk 1.41.1 → 1.42.1-alpha.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 (216) hide show
  1. package/cjs/package.json +9 -9
  2. package/cjs/src/api-intercept.d.ts +25 -0
  3. package/cjs/src/api-intercept.d.ts.map +1 -0
  4. package/cjs/src/api-intercept.js +115 -0
  5. package/cjs/src/api-intercept.js.map +1 -0
  6. package/cjs/src/css-variables.d.ts +52 -14
  7. package/cjs/src/css-variables.d.ts.map +1 -1
  8. package/cjs/src/embed/app.d.ts.map +1 -1
  9. package/cjs/src/embed/app.js +7 -2
  10. package/cjs/src/embed/app.js.map +1 -1
  11. package/cjs/src/embed/app.spec.js +20 -0
  12. package/cjs/src/embed/app.spec.js.map +1 -1
  13. package/cjs/src/embed/bodyless-conversation.d.ts +1 -0
  14. package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
  15. package/cjs/src/embed/bodyless-conversation.js +7 -3
  16. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  17. package/cjs/src/embed/conversation.d.ts +1 -0
  18. package/cjs/src/embed/conversation.d.ts.map +1 -1
  19. package/cjs/src/embed/conversation.js +7 -2
  20. package/cjs/src/embed/conversation.js.map +1 -1
  21. package/cjs/src/embed/hostEventClient/contracts.d.ts +11 -1
  22. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  23. package/cjs/src/embed/hostEventClient/contracts.js +1 -0
  24. package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
  25. package/cjs/src/embed/liveboard.d.ts +1 -0
  26. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  27. package/cjs/src/embed/liveboard.js +10 -2
  28. package/cjs/src/embed/liveboard.js.map +1 -1
  29. package/cjs/src/embed/liveboard.spec.js +35 -0
  30. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  31. package/cjs/src/embed/sage.d.ts +1 -0
  32. package/cjs/src/embed/sage.d.ts.map +1 -1
  33. package/cjs/src/embed/sage.js +10 -6
  34. package/cjs/src/embed/sage.js.map +1 -1
  35. package/cjs/src/embed/search-bar.d.ts +1 -0
  36. package/cjs/src/embed/search-bar.d.ts.map +1 -1
  37. package/cjs/src/embed/search-bar.js +11 -7
  38. package/cjs/src/embed/search-bar.js.map +1 -1
  39. package/cjs/src/embed/search.d.ts +1 -0
  40. package/cjs/src/embed/search.d.ts.map +1 -1
  41. package/cjs/src/embed/search.js +10 -9
  42. package/cjs/src/embed/search.js.map +1 -1
  43. package/cjs/src/embed/ts-embed.d.ts +21 -4
  44. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  45. package/cjs/src/embed/ts-embed.js +115 -34
  46. package/cjs/src/embed/ts-embed.js.map +1 -1
  47. package/cjs/src/embed/ts-embed.spec.js +83 -0
  48. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  49. package/cjs/src/errors.d.ts +1 -0
  50. package/cjs/src/errors.d.ts.map +1 -1
  51. package/cjs/src/errors.js +1 -0
  52. package/cjs/src/errors.js.map +1 -1
  53. package/cjs/src/index.d.ts +2 -2
  54. package/cjs/src/index.d.ts.map +1 -1
  55. package/cjs/src/index.js +2 -1
  56. package/cjs/src/index.js.map +1 -1
  57. package/cjs/src/react/all-types-export.d.ts +1 -1
  58. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  59. package/cjs/src/react/all-types-export.js +2 -1
  60. package/cjs/src/react/all-types-export.js.map +1 -1
  61. package/cjs/src/react/all-types-export.spec.js +1 -1
  62. package/cjs/src/react/all-types-export.spec.js.map +1 -1
  63. package/cjs/src/react/util.js.map +1 -1
  64. package/cjs/src/react/util.spec.d.ts +2 -0
  65. package/cjs/src/react/util.spec.d.ts.map +1 -0
  66. package/cjs/src/react/util.spec.js +78 -0
  67. package/cjs/src/react/util.spec.js.map +1 -0
  68. package/cjs/src/types.d.ts +135 -8
  69. package/cjs/src/types.d.ts.map +1 -1
  70. package/cjs/src/types.js +73 -4
  71. package/cjs/src/types.js.map +1 -1
  72. package/cjs/src/utils/processData.d.ts +1 -1
  73. package/cjs/src/utils/processData.d.ts.map +1 -1
  74. package/cjs/src/utils/processData.js +8 -8
  75. package/cjs/src/utils/processData.js.map +1 -1
  76. package/dist/index-BEzW4MDA.js +7371 -0
  77. package/dist/{index-DQueHwfQ.js → index-DvNA626T.js} +1 -1
  78. package/dist/src/api-intercept.d.ts +25 -0
  79. package/dist/src/api-intercept.d.ts.map +1 -0
  80. package/dist/src/css-variables.d.ts +52 -14
  81. package/dist/src/css-variables.d.ts.map +1 -1
  82. package/dist/src/embed/app.d.ts.map +1 -1
  83. package/dist/src/embed/bodyless-conversation.d.ts +1 -0
  84. package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
  85. package/dist/src/embed/conversation.d.ts +1 -0
  86. package/dist/src/embed/conversation.d.ts.map +1 -1
  87. package/dist/src/embed/hostEventClient/contracts.d.ts +11 -1
  88. package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  89. package/dist/src/embed/liveboard.d.ts +1 -0
  90. package/dist/src/embed/liveboard.d.ts.map +1 -1
  91. package/dist/src/embed/sage.d.ts +1 -0
  92. package/dist/src/embed/sage.d.ts.map +1 -1
  93. package/dist/src/embed/search-bar.d.ts +1 -0
  94. package/dist/src/embed/search-bar.d.ts.map +1 -1
  95. package/dist/src/embed/search.d.ts +1 -0
  96. package/dist/src/embed/search.d.ts.map +1 -1
  97. package/dist/src/embed/ts-embed.d.ts +21 -4
  98. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  99. package/dist/src/errors.d.ts +1 -0
  100. package/dist/src/errors.d.ts.map +1 -1
  101. package/dist/src/index.d.ts +2 -2
  102. package/dist/src/index.d.ts.map +1 -1
  103. package/dist/src/react/all-types-export.d.ts +1 -1
  104. package/dist/src/react/all-types-export.d.ts.map +1 -1
  105. package/dist/src/react/util.spec.d.ts +2 -0
  106. package/dist/src/react/util.spec.d.ts.map +1 -0
  107. package/dist/src/types.d.ts +135 -8
  108. package/dist/src/types.d.ts.map +1 -1
  109. package/dist/src/utils/processData.d.ts +1 -1
  110. package/dist/src/utils/processData.d.ts.map +1 -1
  111. package/dist/tsembed-react.es.js +370 -90
  112. package/dist/tsembed-react.js +369 -89
  113. package/dist/tsembed.es.js +371 -91
  114. package/dist/tsembed.js +369 -89
  115. package/dist/visual-embed-sdk-react-full.d.ts +9431 -9915
  116. package/dist/visual-embed-sdk-react.d.ts +9301 -9922
  117. package/dist/visual-embed-sdk.d.ts +9470 -9532
  118. package/lib/package.json +9 -9
  119. package/lib/src/api-intercept.d.ts +25 -0
  120. package/lib/src/api-intercept.d.ts.map +1 -0
  121. package/lib/src/api-intercept.js +108 -0
  122. package/lib/src/api-intercept.js.map +1 -0
  123. package/lib/src/css-variables.d.ts +52 -14
  124. package/lib/src/css-variables.d.ts.map +1 -1
  125. package/lib/src/embed/app.d.ts.map +1 -1
  126. package/lib/src/embed/app.js +7 -2
  127. package/lib/src/embed/app.js.map +1 -1
  128. package/lib/src/embed/app.spec.js +20 -0
  129. package/lib/src/embed/app.spec.js.map +1 -1
  130. package/lib/src/embed/bodyless-conversation.d.ts +1 -0
  131. package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
  132. package/lib/src/embed/bodyless-conversation.js +7 -3
  133. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  134. package/lib/src/embed/conversation.d.ts +1 -0
  135. package/lib/src/embed/conversation.d.ts.map +1 -1
  136. package/lib/src/embed/conversation.js +7 -2
  137. package/lib/src/embed/conversation.js.map +1 -1
  138. package/lib/src/embed/hostEventClient/contracts.d.ts +11 -1
  139. package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  140. package/lib/src/embed/hostEventClient/contracts.js +1 -0
  141. package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
  142. package/lib/src/embed/liveboard.d.ts +1 -0
  143. package/lib/src/embed/liveboard.d.ts.map +1 -1
  144. package/lib/src/embed/liveboard.js +10 -2
  145. package/lib/src/embed/liveboard.js.map +1 -1
  146. package/lib/src/embed/liveboard.spec.js +35 -0
  147. package/lib/src/embed/liveboard.spec.js.map +1 -1
  148. package/lib/src/embed/sage.d.ts +1 -0
  149. package/lib/src/embed/sage.d.ts.map +1 -1
  150. package/lib/src/embed/sage.js +10 -6
  151. package/lib/src/embed/sage.js.map +1 -1
  152. package/lib/src/embed/search-bar.d.ts +1 -0
  153. package/lib/src/embed/search-bar.d.ts.map +1 -1
  154. package/lib/src/embed/search-bar.js +11 -7
  155. package/lib/src/embed/search-bar.js.map +1 -1
  156. package/lib/src/embed/search.d.ts +1 -0
  157. package/lib/src/embed/search.d.ts.map +1 -1
  158. package/lib/src/embed/search.js +10 -9
  159. package/lib/src/embed/search.js.map +1 -1
  160. package/lib/src/embed/ts-embed.d.ts +21 -4
  161. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  162. package/lib/src/embed/ts-embed.js +115 -34
  163. package/lib/src/embed/ts-embed.js.map +1 -1
  164. package/lib/src/embed/ts-embed.spec.js +83 -0
  165. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  166. package/lib/src/errors.d.ts +1 -0
  167. package/lib/src/errors.d.ts.map +1 -1
  168. package/lib/src/errors.js +1 -0
  169. package/lib/src/errors.js.map +1 -1
  170. package/lib/src/index.d.ts +2 -2
  171. package/lib/src/index.d.ts.map +1 -1
  172. package/lib/src/index.js +2 -2
  173. package/lib/src/index.js.map +1 -1
  174. package/lib/src/react/all-types-export.d.ts +1 -1
  175. package/lib/src/react/all-types-export.d.ts.map +1 -1
  176. package/lib/src/react/all-types-export.js +1 -1
  177. package/lib/src/react/all-types-export.js.map +1 -1
  178. package/lib/src/react/all-types-export.spec.js +1 -1
  179. package/lib/src/react/all-types-export.spec.js.map +1 -1
  180. package/lib/src/react/util.js.map +1 -1
  181. package/lib/src/react/util.spec.d.ts +2 -0
  182. package/lib/src/react/util.spec.d.ts.map +1 -0
  183. package/lib/src/react/util.spec.js +76 -0
  184. package/lib/src/react/util.spec.js.map +1 -0
  185. package/lib/src/types.d.ts +135 -8
  186. package/lib/src/types.d.ts.map +1 -1
  187. package/lib/src/types.js +72 -3
  188. package/lib/src/types.js.map +1 -1
  189. package/lib/src/utils/processData.d.ts +1 -1
  190. package/lib/src/utils/processData.d.ts.map +1 -1
  191. package/lib/src/utils/processData.js +8 -8
  192. package/lib/src/utils/processData.js.map +1 -1
  193. package/package.json +9 -9
  194. package/src/api-intercept.ts +134 -0
  195. package/src/css-variables.ts +53 -16
  196. package/src/embed/app.spec.ts +28 -0
  197. package/src/embed/app.ts +9 -1
  198. package/src/embed/bodyless-conversation.ts +8 -3
  199. package/src/embed/conversation.ts +17 -2
  200. package/src/embed/hostEventClient/contracts.ts +10 -0
  201. package/src/embed/liveboard.spec.ts +44 -0
  202. package/src/embed/liveboard.ts +12 -1
  203. package/src/embed/sage.ts +14 -9
  204. package/src/embed/search-bar.tsx +14 -7
  205. package/src/embed/search.ts +21 -8
  206. package/src/embed/ts-embed.spec.ts +116 -5
  207. package/src/embed/ts-embed.ts +152 -50
  208. package/src/errors.ts +1 -0
  209. package/src/index.ts +2 -0
  210. package/src/react/all-types-export.spec.ts +1 -1
  211. package/src/react/all-types-export.ts +1 -0
  212. package/src/react/util.spec.tsx +88 -0
  213. package/src/react/util.ts +3 -3
  214. package/src/types.ts +195 -64
  215. package/src/utils/processData.ts +11 -11
  216. package/lib/src/visual-embed-sdk.d.ts +0 -9779
@@ -7,6 +7,7 @@ export enum UIPassthroughEvent {
7
7
  GetAvailableUIPassthroughs = 'getAvailableUiPassthroughs',
8
8
  GetAnswerConfig = 'getAnswerPageConfig',
9
9
  GetLiveboardConfig = 'getPinboardPageConfig',
10
+ GetUnsavedAnswerTML = 'getUnsavedAnswerTML',
10
11
  }
11
12
 
12
13
  // UI Passthrough Contract
@@ -63,6 +64,15 @@ export type UIPassthroughContractBase = {
63
64
  request: any;
64
65
  response: any;
65
66
  };
67
+ [UIPassthroughEvent.GetUnsavedAnswerTML]: {
68
+ request: {
69
+ sessionId?: string;
70
+ vizId?: string;
71
+ };
72
+ response: {
73
+ tml: string;
74
+ };
75
+ };
66
76
  };
67
77
 
68
78
  // UI Passthrough Request and Response
@@ -183,6 +183,36 @@ describe('Liveboard/viz embed tests', () => {
183
183
  });
184
184
  });
185
185
 
186
+ test('should set isLinkParametersEnabled to true in url', async () => {
187
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
188
+ isLinkParametersEnabled: true,
189
+ ...defaultViewConfig,
190
+ liveboardId,
191
+ } as LiveboardViewConfig);
192
+ liveboardEmbed.render();
193
+ await executeAfterWait(() => {
194
+ expectUrlMatchesWithParams(
195
+ getIFrameSrc(),
196
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLinkParametersEnabled=true${prefixParams}#/embed/viz/${liveboardId}`,
197
+ );
198
+ });
199
+ });
200
+
201
+ test('should set isLinkParametersEnabled to false in url', async () => {
202
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
203
+ isLinkParametersEnabled: false,
204
+ ...defaultViewConfig,
205
+ liveboardId,
206
+ } as LiveboardViewConfig);
207
+ liveboardEmbed.render();
208
+ await executeAfterWait(() => {
209
+ expectUrlMatchesWithParams(
210
+ getIFrameSrc(),
211
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLinkParametersEnabled=false${prefixParams}#/embed/viz/${liveboardId}`,
212
+ );
213
+ });
214
+ });
215
+
186
216
  test('should set visible actions as empty array', async () => {
187
217
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
188
218
  visibleActions: [],
@@ -657,6 +687,7 @@ describe('Liveboard/viz embed tests', () => {
657
687
  test('navigateToLiveboard should trigger the navigate event with the correct path', async (done) => {
658
688
  mockMessageChannel();
659
689
  // mock getSessionInfo
690
+
660
691
  mockGetSessionInfo();
661
692
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
662
693
  ...defaultViewConfig,
@@ -684,6 +715,13 @@ describe('Liveboard/viz embed tests', () => {
684
715
  mockMessageChannel();
685
716
 
686
717
  // mock getSessionInfo
718
+ jest.spyOn(SessionInfoService, 'getSessionInfo').mockResolvedValue({
719
+ releaseVersion: '1.0.0',
720
+ userGUID: '1234567890',
721
+ currentOrgId: 1,
722
+ privileges: [],
723
+ mixpanelToken: '1234567890',
724
+ });
687
725
  mockGetSessionInfo();
688
726
 
689
727
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
@@ -779,6 +817,12 @@ describe('Liveboard/viz embed tests', () => {
779
817
  });
780
818
 
781
819
  describe('PreRender flow for liveboard embed', () => {
820
+ beforeAll(() => {
821
+ init({
822
+ thoughtSpotHost: "http://tshost",
823
+ authType: AuthType.None,
824
+ });
825
+ });
782
826
  test('it should preRender generic with liveboard id is not passed', async (done) => {
783
827
  const consoleSpy = jest.spyOn(console, 'error');
784
828
  const libEmbed = new LiveboardEmbed(getRootEl(), {
@@ -440,6 +440,12 @@ export class LiveboardEmbed extends V1Embed {
440
440
  * embedded Liveboard or visualization.
441
441
  */
442
442
  protected getEmbedParams() {
443
+ const params = this.getEmbedParamsObject();
444
+ const queryParams = getQueryParamString(params, true);
445
+ return queryParams;
446
+ }
447
+
448
+ protected getEmbedParamsObject() {
443
449
  let params: any = {};
444
450
  params = this.getBaseQueryParams(params);
445
451
  const {
@@ -471,6 +477,7 @@ export class LiveboardEmbed extends V1Embed {
471
477
  isLiveboardStylingAndGroupingEnabled,
472
478
  isPNGInScheduledEmailsEnabled = false,
473
479
  showSpotterLimitations,
480
+ isLinkParametersEnabled,
474
481
  } = this.viewConfig;
475
482
 
476
483
  const preventLiveboardFilterRemoval = this.viewConfig.preventLiveboardFilterRemoval
@@ -546,6 +553,10 @@ export class LiveboardEmbed extends V1Embed {
546
553
  params[Param.ShowSpotterLimitations] = showSpotterLimitations;
547
554
  }
548
555
 
556
+ if (isLinkParametersEnabled !== undefined) {
557
+ params[Param.isLinkParametersEnabled] = isLinkParametersEnabled;
558
+ }
559
+
549
560
  params[Param.LiveboardHeaderSticky] = isLiveboardHeaderSticky;
550
561
  params[Param.LiveboardHeaderV2] = isLiveboardCompactHeaderEnabled;
551
562
  params[Param.ShowLiveboardVerifiedBadge] = showLiveboardVerifiedBadge;
@@ -557,7 +568,7 @@ export class LiveboardEmbed extends V1Embed {
557
568
  params[Param.LiveboardXLSXCSVDownload] = !!liveboardXLSXCSVDownload;
558
569
  const queryParams = getQueryParamString(params, true);
559
570
 
560
- return queryParams;
571
+ return params;
561
572
  }
562
573
 
563
574
  private getIframeSuffixSrc(liveboardId: string, vizId: string, activeTabId: string) {
package/src/embed/sage.ts CHANGED
@@ -153,12 +153,7 @@ export class SageEmbed extends V1Embed {
153
153
  super(domSelector, viewConfig);
154
154
  }
155
155
 
156
- /**
157
- * Constructs a map of parameters to be passed on to the
158
- * embedded Eureka or Sage search page.
159
- * @returns {string} query string
160
- */
161
- protected getEmbedParams(): string {
156
+ protected getEmbedParamsObject() {
162
157
  const {
163
158
  disableWorksheetChange,
164
159
  hideWorksheetSelector,
@@ -184,6 +179,16 @@ export class SageEmbed extends V1Embed {
184
179
  params[Param.IsProductTour] = !!isProductTour;
185
180
  params[Param.HideSageAnswerHeader] = !!hideSageAnswerHeader;
186
181
 
182
+ return params;
183
+ }
184
+
185
+ /**
186
+ * Constructs a map of parameters to be passed on to the
187
+ * embedded Eureka or Sage search page.
188
+ * @returns {string} query string
189
+ */
190
+ protected getEmbedParams(): string {
191
+ const params = this.getEmbedParamsObject();
187
192
  return getQueryParamString(params, true);
188
193
  }
189
194
 
@@ -194,15 +199,15 @@ export class SageEmbed extends V1Embed {
194
199
  */
195
200
  public getIFrameSrc(): string {
196
201
  const path = 'eureka';
197
- const postHashObj = {};
202
+ const postHashObj: Record<string, any> = {};
198
203
  const tsPostHashParams = this.getThoughtSpotPostUrlParams();
199
204
  const {
200
205
  dataSource, searchOptions,
201
206
  } = this.viewConfig;
202
207
 
203
- if (dataSource) postHashObj[Param.WorksheetId] = dataSource;
208
+ if (dataSource) (postHashObj as any)[Param.WorksheetId] = dataSource;
204
209
  if (searchOptions?.searchQuery && searchOptions.executeSearch) {
205
- postHashObj[Param.executeSearch] = true;
210
+ (postHashObj as any)[Param.executeSearch] = true;
206
211
  }
207
212
 
208
213
  let sagePostHashParams = new URLSearchParams(postHashObj).toString();
@@ -118,12 +118,7 @@ export class SearchBarEmbed extends TsEmbed {
118
118
  this.viewConfig = viewConfig;
119
119
  }
120
120
 
121
- /**
122
- * Construct the URL of the embedded ThoughtSpot search to be
123
- * loaded in the iframe
124
- * @param dataSources A list of data source GUIDs
125
- */
126
- private getIFrameSrc() {
121
+ protected getEmbedParamsObject() {
127
122
  const {
128
123
  searchOptions,
129
124
  dataSource,
@@ -131,7 +126,6 @@ export class SearchBarEmbed extends TsEmbed {
131
126
  useLastSelectedSources = false,
132
127
  excludeSearchTokenStringFromURL,
133
128
  } = this.viewConfig;
134
- const path = 'search-bar-embed';
135
129
  const queryParams = this.getBaseQueryParams();
136
130
 
137
131
  queryParams[Param.HideActions] = [...(queryParams[Param.HideActions] ?? [])];
@@ -159,6 +153,19 @@ export class SearchBarEmbed extends TsEmbed {
159
153
  queryParams[Param.UseLastSelectedDataSource] = false;
160
154
  }
161
155
  queryParams[Param.searchEmbed] = true;
156
+
157
+ return queryParams;
158
+ }
159
+
160
+ /**
161
+ * Construct the URL of the embedded ThoughtSpot search to be
162
+ * loaded in the iframe
163
+ * @param dataSources A list of data source GUIDs
164
+ */
165
+ private getIFrameSrc() {
166
+ const queryParams = this.getEmbedParamsObject();
167
+ const path = 'search-bar-embed';
168
+
162
169
  let query = '';
163
170
  const queryParamsString = getQueryParamString(queryParams, true);
164
171
  if (queryParamsString) {
@@ -26,6 +26,7 @@ import { ERROR_MESSAGE } from '../errors';
26
26
  import { getAuthPromise } from './base';
27
27
  import { getReleaseVersion } from '../auth';
28
28
  import { getEmbedConfig } from './embedConfig';
29
+ import { getInterceptInitData } from '../api-intercept';
29
30
 
30
31
  /**
31
32
  * Configuration for search options.
@@ -331,7 +332,7 @@ export const HiddenActionItemByDefaultForSearchEmbed = [
331
332
  ];
332
333
 
333
334
  export interface SearchAppInitData extends DefaultAppInitData {
334
- searchOptions?: SearchOptions;
335
+ searchOptions?: SearchOptions;
335
336
  }
336
337
 
337
338
  /**
@@ -381,7 +382,7 @@ export class SearchEmbed extends TsEmbed {
381
382
  return { ...defaultAppInitData, ...this.getSearchInitData() };
382
383
  }
383
384
 
384
- protected getEmbedParams(): string {
385
+ protected getEmbedParamsObject() {
385
386
  const {
386
387
  hideResults,
387
388
  enableSearchAssist,
@@ -398,7 +399,7 @@ export class SearchEmbed extends TsEmbed {
398
399
  collapseSearchBarInitially = false,
399
400
  enableCustomColumnGroups = false,
400
401
  isOnBeforeGetVizDataInterceptEnabled = false,
401
- /* eslint-disable-next-line max-len */
402
+
402
403
  dataPanelCustomGroupsAccordionInitialState = DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL,
403
404
  focusSearchBarOnRender = true,
404
405
  excludeRuntimeParametersfromURL,
@@ -442,8 +443,9 @@ export class SearchEmbed extends TsEmbed {
442
443
  queryParams[Param.HideSearchBar] = true;
443
444
  }
444
445
 
445
- if (isOnBeforeGetVizDataInterceptEnabled) {
446
- /* eslint-disable-next-line max-len */
446
+ const { enableApiIntercept } = getInterceptInitData(this.embedConfig, this.viewConfig);
447
+ if (isOnBeforeGetVizDataInterceptEnabled && !enableApiIntercept) {
448
+
447
449
  queryParams[Param.IsOnBeforeGetVizDataInterceptEnabled] = isOnBeforeGetVizDataInterceptEnabled;
448
450
  }
449
451
 
@@ -460,7 +462,7 @@ export class SearchEmbed extends TsEmbed {
460
462
  }
461
463
 
462
464
  queryParams[Param.searchEmbed] = true;
463
- /* eslint-disable-next-line max-len */
465
+
464
466
  queryParams[Param.CollapseSearchBarInitially] = collapseSearchBarInitially || collapseSearchBar;
465
467
  queryParams[Param.EnableCustomColumnGroups] = enableCustomColumnGroups;
466
468
  if (dataPanelCustomGroupsAccordionInitialState
@@ -468,12 +470,23 @@ export class SearchEmbed extends TsEmbed {
468
470
  || dataPanelCustomGroupsAccordionInitialState
469
471
  === DataPanelCustomColumnGroupsAccordionState.EXPAND_FIRST
470
472
  ) {
471
- /* eslint-disable-next-line max-len */
473
+
472
474
  queryParams[Param.DataPanelCustomGroupsAccordionInitialState] = dataPanelCustomGroupsAccordionInitialState;
473
475
  } else {
474
- /* eslint-disable-next-line max-len */
476
+
475
477
  queryParams[Param.DataPanelCustomGroupsAccordionInitialState] = DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL;
476
478
  }
479
+ return queryParams;
480
+ }
481
+
482
+ protected getEmbedParams() {
483
+ const {
484
+ runtimeParameters,
485
+ runtimeFilters,
486
+ excludeRuntimeParametersfromURL,
487
+ excludeRuntimeFiltersfromURL,
488
+ } = this.viewConfig;
489
+ const queryParams = this.getEmbedParamsObject();
477
490
  let query = '';
478
491
  const queryParamsString = getQueryParamString(queryParams, true);
479
492
  if (queryParamsString) {
@@ -1045,7 +1045,7 @@ describe('Unit test case for ts embed', () => {
1045
1045
  type: EmbedEvent.APP_INIT,
1046
1046
  data: {},
1047
1047
  };
1048
-
1048
+
1049
1049
  // Create a SearchEmbed with valid custom actions to test
1050
1050
  // CustomActionsValidationResult
1051
1051
  const searchEmbed = new SearchEmbed(getRootEl(), {
@@ -1067,7 +1067,7 @@ describe('Unit test case for ts embed', () => {
1067
1067
  }
1068
1068
  ]
1069
1069
  });
1070
-
1070
+
1071
1071
  searchEmbed.render();
1072
1072
  const mockPort: any = {
1073
1073
  postMessage: jest.fn(),
@@ -1116,7 +1116,7 @@ describe('Unit test case for ts embed', () => {
1116
1116
  customVariablesForThirdPartyTools: {},
1117
1117
  },
1118
1118
  });
1119
-
1119
+
1120
1120
  // Verify that CustomActionsValidationResult structure is
1121
1121
  // correct
1122
1122
  const appInitData = mockPort.postMessage.mock.calls[0][0].data;
@@ -1137,7 +1137,7 @@ describe('Unit test case for ts embed', () => {
1137
1137
  })
1138
1138
  ])
1139
1139
  );
1140
-
1140
+
1141
1141
  // Verify actions are sorted by name (alphabetically)
1142
1142
  expect(appInitData.customActions[0].name).toBe('Another Valid Action');
1143
1143
  expect(appInitData.customActions[1].name).toBe('Valid Action');
@@ -2488,7 +2488,7 @@ describe('Unit test case for ts embed', () => {
2488
2488
  });
2489
2489
 
2490
2490
  afterAll((): void => {
2491
- window.location = location;
2491
+ (window.location as any) = location;
2492
2492
  });
2493
2493
 
2494
2494
  it('get url params for TS', () => {
@@ -3345,4 +3345,115 @@ describe('Unit test case for ts embed', () => {
3345
3345
  expect(searchEmbed.isEmbedContainerLoaded).toBe(true);
3346
3346
  });
3347
3347
  });
3348
+
3349
+ describe('Online event listener registration after auth failure', () => {
3350
+ beforeAll(() => {
3351
+ init({
3352
+ thoughtSpotHost: 'tshost',
3353
+ authType: AuthType.None,
3354
+ loginFailedMessage: 'Not logged in',
3355
+ });
3356
+ });
3357
+
3358
+ test('should register online event listener when authentication fails', async () => {
3359
+ const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
3360
+ jest.spyOn(baseInstance, 'getAuthPromise').mockRejectedValueOnce(
3361
+ new Error('Auth failed'),
3362
+ );
3363
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3364
+ addEventListenerSpy.mockClear();
3365
+ await searchEmbed.render();
3366
+ await executeAfterWait(() => {
3367
+ expect(getRootEl().innerHTML).toContain('Not logged in');
3368
+ const onlineListenerCalls = addEventListenerSpy.mock.calls.filter(
3369
+ (call) => call[0] === 'online',
3370
+ );
3371
+ expect(onlineListenerCalls).toHaveLength(1);
3372
+ const offlineListenerCalls = addEventListenerSpy.mock.calls.filter(
3373
+ (call) => call[0] === 'offline',
3374
+ );
3375
+ expect(offlineListenerCalls).toHaveLength(1);
3376
+ const messageListenerCalls = addEventListenerSpy.mock.calls.filter(
3377
+ (call) => call[0] === 'message',
3378
+ );
3379
+ expect(messageListenerCalls).toHaveLength(0);
3380
+ });
3381
+
3382
+ addEventListenerSpy.mockRestore();
3383
+ });
3384
+
3385
+ test('should attempt to trigger reload when online event occurs after auth failure', async () => {
3386
+ jest.spyOn(baseInstance, 'getAuthPromise').mockRejectedValueOnce(
3387
+ new Error('Auth failed'),
3388
+ );
3389
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3390
+ const triggerSpy = jest.spyOn(searchEmbed, 'trigger').mockResolvedValue(null);
3391
+ await searchEmbed.render();
3392
+
3393
+ await executeAfterWait(() => {
3394
+ expect(getRootEl().innerHTML).toContain('Not logged in');
3395
+ triggerSpy.mockClear();
3396
+ const onlineEvent = new Event('online');
3397
+ window.dispatchEvent(onlineEvent);
3398
+ expect(triggerSpy).toHaveBeenCalledWith(HostEvent.Reload);
3399
+ });
3400
+
3401
+ triggerSpy.mockReset();
3402
+ });
3403
+
3404
+ test('should handle online event gracefully when no iframe exists', async () => {
3405
+ jest.spyOn(baseInstance, 'getAuthPromise').mockRejectedValueOnce(
3406
+ new Error('Auth failed'),
3407
+ );
3408
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3409
+ const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
3410
+ await searchEmbed.render();
3411
+ await executeAfterWait(() => {
3412
+ expect(getRootEl().innerHTML).toContain('Not logged in');
3413
+ const onlineEvent = new Event('online');
3414
+ expect(() => {
3415
+ window.dispatchEvent(onlineEvent);
3416
+ }).not.toThrow();
3417
+ });
3418
+
3419
+ errorSpy.mockReset();
3420
+ });
3421
+
3422
+ test('should register all event listeners when authentication succeeds', async () => {
3423
+ const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
3424
+ jest.spyOn(baseInstance, 'getAuthPromise').mockResolvedValueOnce(true);
3425
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3426
+ addEventListenerSpy.mockClear();
3427
+ await searchEmbed.render();
3428
+ await executeAfterWait(() => {
3429
+ const onlineListenerCalls = addEventListenerSpy.mock.calls.filter(
3430
+ (call) => call[0] === 'online',
3431
+ );
3432
+ expect(onlineListenerCalls).toHaveLength(1);
3433
+ const offlineListenerCalls = addEventListenerSpy.mock.calls.filter(
3434
+ (call) => call[0] === 'offline',
3435
+ );
3436
+ expect(offlineListenerCalls).toHaveLength(1);
3437
+ const messageListenerCalls = addEventListenerSpy.mock.calls.filter(
3438
+ (call) => call[0] === 'message',
3439
+ );
3440
+ expect(messageListenerCalls).toHaveLength(1);
3441
+ });
3442
+
3443
+ addEventListenerSpy.mockRestore();
3444
+ });
3445
+ test('should successfully trigger reload when online event occurs after auth success', async () => {
3446
+ jest.spyOn(baseInstance, 'getAuthPromise').mockResolvedValueOnce(true);
3447
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
3448
+ const triggerSpy = jest.spyOn(searchEmbed, 'trigger').mockResolvedValue({} as any);
3449
+ await searchEmbed.render();
3450
+ await executeAfterWait(() => {
3451
+ triggerSpy.mockClear();
3452
+ const onlineEvent = new Event('online');
3453
+ window.dispatchEvent(onlineEvent);
3454
+ expect(triggerSpy).toHaveBeenCalledWith(HostEvent.Reload);
3455
+ });
3456
+ triggerSpy.mockReset();
3457
+ });
3458
+ });
3348
3459
  });