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

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 (184) hide show
  1. package/dist/src/auth.d.ts +75 -5
  2. package/dist/src/auth.d.ts.map +1 -1
  3. package/dist/src/config.d.ts +1 -0
  4. package/dist/src/config.d.ts.map +1 -1
  5. package/dist/src/embed/app.d.ts +19 -7
  6. package/dist/src/embed/app.d.ts.map +1 -1
  7. package/dist/src/embed/base.d.ts +39 -19
  8. package/dist/src/embed/base.d.ts.map +1 -1
  9. package/dist/src/embed/liveboard.d.ts +19 -7
  10. package/dist/src/embed/liveboard.d.ts.map +1 -1
  11. package/dist/src/embed/search-bar.d.ts +7 -1
  12. package/dist/src/embed/search-bar.d.ts.map +1 -1
  13. package/dist/src/embed/search.d.ts +11 -3
  14. package/dist/src/embed/search.d.ts.map +1 -1
  15. package/dist/src/embed/ts-embed.d.ts +76 -5
  16. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  17. package/dist/src/errors.d.ts.map +1 -1
  18. package/dist/src/index.d.ts +3 -3
  19. package/dist/src/index.d.ts.map +1 -1
  20. package/dist/src/mixpanel-service.d.ts +8 -0
  21. package/dist/src/mixpanel-service.d.ts.map +1 -1
  22. package/dist/src/react/index.d.ts.map +1 -1
  23. package/dist/src/react/util.d.ts +4 -0
  24. package/dist/src/react/util.d.ts.map +1 -1
  25. package/dist/src/test/test-utils.d.ts +11 -2
  26. package/dist/src/test/test-utils.d.ts.map +1 -1
  27. package/dist/src/types.d.ts +429 -97
  28. package/dist/src/types.d.ts.map +1 -1
  29. package/dist/src/utils/answerService.d.ts +7 -0
  30. package/dist/src/utils/answerService.d.ts.map +1 -1
  31. package/dist/src/utils/authService.d.ts +30 -0
  32. package/dist/src/utils/authService.d.ts.map +1 -1
  33. package/dist/src/utils/processData.d.ts +12 -0
  34. package/dist/src/utils/processData.d.ts.map +1 -1
  35. package/dist/src/utils/processTrigger.d.ts +7 -0
  36. package/dist/src/utils/processTrigger.d.ts.map +1 -1
  37. package/dist/src/utils.d.ts +12 -0
  38. package/dist/src/utils.d.ts.map +1 -1
  39. package/dist/tsembed.es.js +818 -285
  40. package/dist/tsembed.js +791 -284
  41. package/lib/package.json +4 -3
  42. package/lib/src/auth.d.ts +75 -5
  43. package/lib/src/auth.d.ts.map +1 -1
  44. package/lib/src/auth.js +86 -26
  45. package/lib/src/auth.js.map +1 -1
  46. package/lib/src/auth.spec.js +14 -5
  47. package/lib/src/auth.spec.js.map +1 -1
  48. package/lib/src/config.d.ts +1 -0
  49. package/lib/src/config.d.ts.map +1 -1
  50. package/lib/src/config.js +5 -3
  51. package/lib/src/config.js.map +1 -1
  52. package/lib/src/config.spec.js.map +1 -1
  53. package/lib/src/embed/app.d.ts +19 -7
  54. package/lib/src/embed/app.d.ts.map +1 -1
  55. package/lib/src/embed/app.js +26 -16
  56. package/lib/src/embed/app.js.map +1 -1
  57. package/lib/src/embed/app.spec.js +12 -12
  58. package/lib/src/embed/app.spec.js.map +1 -1
  59. package/lib/src/embed/base.d.ts +39 -19
  60. package/lib/src/embed/base.d.ts.map +1 -1
  61. package/lib/src/embed/base.js +49 -15
  62. package/lib/src/embed/base.js.map +1 -1
  63. package/lib/src/embed/base.spec.js +2 -2
  64. package/lib/src/embed/base.spec.js.map +1 -1
  65. package/lib/src/embed/embed.spec.js +1 -1
  66. package/lib/src/embed/embed.spec.js.map +1 -1
  67. package/lib/src/embed/liveboard.d.ts +19 -7
  68. package/lib/src/embed/liveboard.d.ts.map +1 -1
  69. package/lib/src/embed/liveboard.js +50 -38
  70. package/lib/src/embed/liveboard.js.map +1 -1
  71. package/lib/src/embed/liveboard.spec.js +37 -30
  72. package/lib/src/embed/liveboard.spec.js.map +1 -1
  73. package/lib/src/embed/pinboard.spec.js +14 -26
  74. package/lib/src/embed/pinboard.spec.js.map +1 -1
  75. package/lib/src/embed/search-bar.d.ts +7 -1
  76. package/lib/src/embed/search-bar.d.ts.map +1 -1
  77. package/lib/src/embed/search-bar.js +6 -7
  78. package/lib/src/embed/search-bar.js.map +1 -1
  79. package/lib/src/embed/search.d.ts +11 -3
  80. package/lib/src/embed/search.d.ts.map +1 -1
  81. package/lib/src/embed/search.js +19 -15
  82. package/lib/src/embed/search.js.map +1 -1
  83. package/lib/src/embed/search.spec.js +16 -19
  84. package/lib/src/embed/search.spec.js.map +1 -1
  85. package/lib/src/embed/searchEmbed-basic-auth.spec.js +4 -0
  86. package/lib/src/embed/searchEmbed-basic-auth.spec.js.map +1 -1
  87. package/lib/src/embed/ts-embed.d.ts +76 -5
  88. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  89. package/lib/src/embed/ts-embed.js +150 -72
  90. package/lib/src/embed/ts-embed.js.map +1 -1
  91. package/lib/src/embed/ts-embed.spec.js +23 -24
  92. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  93. package/lib/src/errors.d.ts.map +1 -1
  94. package/lib/src/errors.js.map +1 -1
  95. package/lib/src/index.d.ts +3 -3
  96. package/lib/src/index.d.ts.map +1 -1
  97. package/lib/src/index.js +3 -3
  98. package/lib/src/index.js.map +1 -1
  99. package/lib/src/mixpanel-service.d.ts +8 -0
  100. package/lib/src/mixpanel-service.d.ts.map +1 -1
  101. package/lib/src/mixpanel-service.js +13 -1
  102. package/lib/src/mixpanel-service.js.map +1 -1
  103. package/lib/src/mixpanel-service.spec.js.map +1 -1
  104. package/lib/src/react/index.d.ts.map +1 -1
  105. package/lib/src/react/index.js +4 -6
  106. package/lib/src/react/index.js.map +1 -1
  107. package/lib/src/react/index.spec.js +3 -6
  108. package/lib/src/react/index.spec.js.map +1 -1
  109. package/lib/src/react/util.d.ts +4 -0
  110. package/lib/src/react/util.d.ts.map +1 -1
  111. package/lib/src/react/util.js +4 -0
  112. package/lib/src/react/util.js.map +1 -1
  113. package/lib/src/test/test-utils.d.ts +11 -2
  114. package/lib/src/test/test-utils.d.ts.map +1 -1
  115. package/lib/src/test/test-utils.js +36 -25
  116. package/lib/src/test/test-utils.js.map +1 -1
  117. package/lib/src/types.d.ts +429 -97
  118. package/lib/src/types.d.ts.map +1 -1
  119. package/lib/src/types.js +310 -72
  120. package/lib/src/types.js.map +1 -1
  121. package/lib/src/utils/answerService.d.ts +7 -0
  122. package/lib/src/utils/answerService.d.ts.map +1 -1
  123. package/lib/src/utils/answerService.js +7 -0
  124. package/lib/src/utils/answerService.js.map +1 -1
  125. package/lib/src/utils/answerService.spec.js.map +1 -1
  126. package/lib/src/utils/authService.d.ts +30 -0
  127. package/lib/src/utils/authService.d.ts.map +1 -1
  128. package/lib/src/utils/authService.js +39 -2
  129. package/lib/src/utils/authService.js.map +1 -1
  130. package/lib/src/utils/authService.spec.js.map +1 -1
  131. package/lib/src/utils/processData.d.ts +12 -0
  132. package/lib/src/utils/processData.d.ts.map +1 -1
  133. package/lib/src/utils/processData.js +33 -5
  134. package/lib/src/utils/processData.js.map +1 -1
  135. package/lib/src/utils/processData.spec.js.map +1 -1
  136. package/lib/src/utils/processTrigger.d.ts +7 -0
  137. package/lib/src/utils/processTrigger.d.ts.map +1 -1
  138. package/lib/src/utils/processTrigger.js +17 -3
  139. package/lib/src/utils/processTrigger.js.map +1 -1
  140. package/lib/src/utils/processTrigger.spec.js.map +1 -1
  141. package/lib/src/utils.d.ts +12 -0
  142. package/lib/src/utils.d.ts.map +1 -1
  143. package/lib/src/utils.js +24 -19
  144. package/lib/src/utils.js.map +1 -1
  145. package/lib/src/utils.spec.js.map +1 -1
  146. package/lib/src/visual-embed-sdk.d.ts +664 -141
  147. package/package.json +4 -3
  148. package/src/auth.spec.ts +68 -150
  149. package/src/auth.ts +141 -101
  150. package/src/config.spec.ts +2 -4
  151. package/src/config.ts +5 -3
  152. package/src/embed/app.spec.ts +25 -14
  153. package/src/embed/app.ts +49 -37
  154. package/src/embed/base.spec.ts +6 -12
  155. package/src/embed/base.ts +74 -57
  156. package/src/embed/embed.spec.ts +5 -6
  157. package/src/embed/liveboard.spec.ts +56 -37
  158. package/src/embed/liveboard.ts +67 -65
  159. package/src/embed/pinboard.spec.ts +26 -29
  160. package/src/embed/search-bar.tsx +14 -9
  161. package/src/embed/search.spec.ts +31 -21
  162. package/src/embed/search.ts +28 -22
  163. package/src/embed/searchEmbed-basic-auth.spec.ts +22 -28
  164. package/src/embed/ts-embed.spec.ts +70 -148
  165. package/src/embed/ts-embed.ts +180 -157
  166. package/src/errors.ts +3 -6
  167. package/src/index.ts +23 -7
  168. package/src/mixpanel-service.spec.ts +1 -3
  169. package/src/mixpanel-service.ts +13 -1
  170. package/src/react/index.spec.tsx +11 -20
  171. package/src/react/index.tsx +40 -71
  172. package/src/react/util.ts +8 -4
  173. package/src/test/test-utils.ts +43 -39
  174. package/src/types.ts +427 -97
  175. package/src/utils/answerService.spec.ts +3 -5
  176. package/src/utils/answerService.ts +21 -17
  177. package/src/utils/authService.spec.ts +26 -41
  178. package/src/utils/authService.ts +47 -21
  179. package/src/utils/processData.spec.ts +26 -59
  180. package/src/utils/processData.ts +36 -14
  181. package/src/utils/processTrigger.spec.ts +1 -6
  182. package/src/utils/processTrigger.ts +18 -9
  183. package/src/utils.spec.ts +8 -12
  184. package/src/utils.ts +25 -26
@@ -15,6 +15,8 @@ import {
15
15
  setAttributes,
16
16
  getCustomisations,
17
17
  getDOMNode,
18
+ getFilterQuery,
19
+ getQueryParamString,
18
20
  } from '../utils';
19
21
  import {
20
22
  getThoughtSpotHost,
@@ -38,6 +40,7 @@ import {
38
40
  ViewConfig,
39
41
  FrameParams,
40
42
  ContextMenuTriggerOptions,
43
+ RuntimeFilter,
41
44
  } from '../types';
42
45
  import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
43
46
  import { processEventData } from '../utils/processData';
@@ -64,6 +67,7 @@ const TS_EMBED_ID = '_thoughtspot-embed';
64
67
  * The event id map from v2 event names to v1 event id
65
68
  * v1 events are the classic embed events implemented in Blink v1
66
69
  * We cannot rename v1 event types to maintain backward compatibility
70
+ *
67
71
  * @internal
68
72
  */
69
73
  const V1EventMap = {};
@@ -87,6 +91,8 @@ export class TsEmbed {
87
91
  */
88
92
  private el: Element;
89
93
 
94
+ protected isAppInitialized = false;
95
+
90
96
  /**
91
97
  * A reference to the iframe within which the ThoughtSpot app
92
98
  * will be rendered.
@@ -128,6 +134,7 @@ export class TsEmbed {
128
134
  * Should we encode URL Query Params using base64 encoding which thoughtspot
129
135
  * will generate for embedding. This provides additional security to
130
136
  * thoughtspot clusters against Cross site scripting attacks.
137
+ *
131
138
  * @default false
132
139
  */
133
140
  private shouldEncodeUrlQueryParams = false;
@@ -156,6 +163,7 @@ export class TsEmbed {
156
163
 
157
164
  /**
158
165
  * Handles errors within the SDK
166
+ *
159
167
  * @param error The error message or object
160
168
  */
161
169
  protected handleError(error: string | Record<string, unknown>) {
@@ -169,6 +177,7 @@ export class TsEmbed {
169
177
 
170
178
  /**
171
179
  * Extracts the type field from the event payload
180
+ *
172
181
  * @param event The window message event
173
182
  */
174
183
  private getEventType(event: MessageEvent) {
@@ -178,6 +187,7 @@ export class TsEmbed {
178
187
 
179
188
  /**
180
189
  * Extracts the port field from the event payload
190
+ *
181
191
  * @param event The window message event
182
192
  * @returns
183
193
  */
@@ -191,6 +201,9 @@ export class TsEmbed {
191
201
  /**
192
202
  * fix for ts7.sep.cl
193
203
  * will be removed for ts7.oct.cl
204
+ *
205
+ * @param event
206
+ * @param eventType
194
207
  * @hidden
195
208
  */
196
209
  private formatEventData(event: MessageEvent, eventType: string) {
@@ -218,12 +231,7 @@ export class TsEmbed {
218
231
  if (event.source === this.iFrame.contentWindow) {
219
232
  this.executeCallbacks(
220
233
  eventType,
221
- processEventData(
222
- eventType,
223
- eventData,
224
- this.thoughtSpotHost,
225
- this.el,
226
- ),
234
+ processEventData(eventType, eventData, this.thoughtSpotHost, this.el),
227
235
  eventPort,
228
236
  );
229
237
  }
@@ -232,19 +240,20 @@ export class TsEmbed {
232
240
 
233
241
  /**
234
242
  * Send Custom style as part of payload of APP_INIT
243
+ *
244
+ * @param _
245
+ * @param responder
235
246
  */
236
247
  private appInitCb = async (_: any, responder: any) => {
237
248
  let authToken = '';
238
249
  if (this.embedConfig.authType === AuthType.TrustedAuthTokenCookieless) {
239
250
  authToken = await getAuthenticaionToken(this.embedConfig);
240
251
  }
252
+ this.isAppInitialized = true;
241
253
  responder({
242
254
  type: EmbedEvent.APP_INIT,
243
255
  data: {
244
- customisations: getCustomisations(
245
- this.embedConfig,
246
- this.viewConfig,
247
- ),
256
+ customisations: getCustomisations(this.embedConfig, this.viewConfig),
248
257
  authToken,
249
258
  },
250
259
  });
@@ -252,6 +261,9 @@ export class TsEmbed {
252
261
 
253
262
  /**
254
263
  * Sends updated auth token to the iFrame to avoid user logout
264
+ *
265
+ * @param _
266
+ * @param responder
255
267
  */
256
268
  private updateAuthToken = async (_: any, responder: any) => {
257
269
  const { autoLogin = false, authType } = this.embedConfig; // Set autoLogin default to false
@@ -277,6 +289,8 @@ export class TsEmbed {
277
289
 
278
290
  /**
279
291
  * Constructs the base URL string to load the ThoughtSpot app.
292
+ *
293
+ * @param query
280
294
  */
281
295
  protected getEmbedBasePath(query: string): string {
282
296
  let queryString = query;
@@ -285,31 +299,25 @@ export class TsEmbed {
285
299
  queryString.substr(1),
286
300
  )}`;
287
301
  }
288
- const basePath = [
289
- this.thoughtSpotHost,
290
- this.thoughtSpotV2Base,
291
- queryString,
292
- ]
302
+ const basePath = [this.thoughtSpotHost, this.thoughtSpotV2Base, queryString]
293
303
  .filter((x) => x.length > 0)
294
304
  .join('/');
295
305
 
296
- return `${basePath}#/embed`;
306
+ return `${basePath}#`;
297
307
  }
298
308
 
299
309
  /**
300
310
  * Common query params set for all the embed modes.
311
+ *
312
+ * @param queryParams
301
313
  * @returns queryParams
302
314
  */
303
- protected getBaseQueryParams() {
304
- const queryParams = {};
315
+ protected getBaseQueryParams(queryParams = {}) {
305
316
  let hostAppUrl = window?.location?.host || '';
306
317
 
307
- // The below check is needed because TS Cloud firewall, blocks localhost/127.0.0.1
308
- // in any url param.
309
- if (
310
- hostAppUrl.includes('localhost') ||
311
- hostAppUrl.includes('127.0.0.1')
312
- ) {
318
+ // The below check is needed because TS Cloud firewall, blocks
319
+ // localhost/127.0.0.1 in any url param.
320
+ if (hostAppUrl.includes('localhost') || hostAppUrl.includes('127.0.0.1')) {
313
321
  hostAppUrl = 'local-host';
314
322
  }
315
323
  queryParams[Param.HostAppUrl] = encodeURIComponent(hostAppUrl);
@@ -317,10 +325,7 @@ export class TsEmbed {
317
325
  queryParams[Param.ViewPortWidth] = window.innerWidth;
318
326
  queryParams[Param.Version] = version;
319
327
  queryParams[Param.AuthType] = this.embedConfig.authType;
320
- if (
321
- this.embedConfig.disableLoginRedirect === true ||
322
- this.embedConfig.autoLogin === true
323
- ) {
328
+ if (this.embedConfig.disableLoginRedirect === true || this.embedConfig.autoLogin === true) {
324
329
  queryParams[Param.DisableLoginRedirect] = true;
325
330
  }
326
331
  if (this.embedConfig.authType === AuthType.EmbeddedSSO) {
@@ -345,16 +350,12 @@ export class TsEmbed {
345
350
  } = this.viewConfig;
346
351
 
347
352
  if (Array.isArray(visibleActions) && Array.isArray(hiddenActions)) {
348
- this.handleError(
349
- 'You cannot have both hidden actions and visible actions',
350
- );
353
+ this.handleError('You cannot have both hidden actions and visible actions');
351
354
  return queryParams;
352
355
  }
353
356
 
354
357
  // TODO remove embedConfig.customCssUrl
355
- const cssUrlParam =
356
- customizations?.style?.customCSSUrl ||
357
- this.embedConfig.customCssUrl;
358
+ const cssUrlParam = customizations?.style?.customCSSUrl || this.embedConfig.customCssUrl;
358
359
 
359
360
  if (cssUrlParam) {
360
361
  queryParams[Param.CustomCSSUrl] = cssUrlParam;
@@ -366,31 +367,25 @@ export class TsEmbed {
366
367
  if (disabledActionReason) {
367
368
  queryParams[Param.DisableActionReason] = disabledActionReason;
368
369
  }
369
- queryParams[Param.HideActions] = [
370
- ...this.defaultHiddenActions,
371
- ...(hiddenActions ?? []),
372
- ];
370
+ queryParams[Param.HideActions] = [...this.defaultHiddenActions, ...(hiddenActions ?? [])];
373
371
  if (Array.isArray(visibleActions)) {
374
372
  queryParams[Param.VisibleActions] = visibleActions;
375
373
  }
376
374
 
377
- /** Default behavior for context menu will be left-click
378
- * from version 9.2.0.cl the user have an option to override context menu click
375
+ /**
376
+ * Default behavior for context menu will be left-click
377
+ * from version 9.2.0.cl the user have an option to override context
378
+ * menu click
379
379
  */
380
380
  if (contextMenuTrigger === ContextMenuTriggerOptions.LEFT_CLICK) {
381
381
  queryParams[Param.ContextMenuTrigger] = true;
382
- } else if (
383
- contextMenuTrigger === ContextMenuTriggerOptions.RIGHT_CLICK
384
- ) {
382
+ } else if (contextMenuTrigger === ContextMenuTriggerOptions.RIGHT_CLICK) {
385
383
  queryParams[Param.ContextMenuTrigger] = false;
386
384
  }
387
385
 
388
386
  const spriteUrl = customizations?.iconSpriteUrl;
389
387
  if (spriteUrl) {
390
- queryParams[Param.IconSpriteUrl] = spriteUrl.replace(
391
- 'https://',
392
- '',
393
- );
388
+ queryParams[Param.IconSpriteUrl] = spriteUrl.replace('https://', '');
394
389
  }
395
390
 
396
391
  if (showAlerts !== undefined) {
@@ -414,48 +409,72 @@ export class TsEmbed {
414
409
  /**
415
410
  * Constructs the base URL string to load v1 of the ThoughtSpot app.
416
411
  * This is used for embedding Liveboards, visualizations, and full application.
412
+ *
417
413
  * @param queryString The query string to append to the URL.
418
414
  * @param isAppEmbed A Boolean parameter to specify if you are embedding
419
415
  * the full application.
420
416
  */
421
- protected getV1EmbedBasePath(
422
- queryString: string,
423
- showPrimaryNavbar = false,
424
- disableProfileAndHelp = false,
425
- isAppEmbed = false,
426
- enableSearchAssist = false,
427
- ): string {
428
- const queryStringFrag = queryString ? `&${queryString}` : '';
429
- const primaryNavParam = `&primaryNavHidden=${!showPrimaryNavbar}`;
430
- const disableProfileAndHelpParam = `&profileAndHelpInNavBarHidden=${disableProfileAndHelp}`;
431
- const enableSearchAssistParam = `&${Param.EnableSearchAssist}=${enableSearchAssist}`;
432
- let queryParams = `?embedApp=true${isAppEmbed ? primaryNavParam : ''}${
433
- isAppEmbed ? disableProfileAndHelpParam : ''
434
- }${
435
- enableSearchAssist ? enableSearchAssistParam : ''
436
- }${queryStringFrag}`;
437
- if (this.shouldEncodeUrlQueryParams) {
438
- queryParams = `?base64UrlEncodedFlags=${getEncodedQueryParamsString(
439
- queryParams.substr(1),
440
- )}`;
441
- }
442
- let path = `${this.thoughtSpotHost}/${queryParams}#`;
443
- if (!isAppEmbed) {
444
- path = `${path}/embed`;
445
- }
417
+ protected getV1EmbedBasePath(queryString: string): string {
418
+ const queryParams = this.shouldEncodeUrlQueryParams
419
+ ? `?base64UrlEncodedFlags=${getEncodedQueryParamsString(queryString)}`
420
+ : `?${queryString}`;
421
+ const path = `${this.thoughtSpotHost}/${queryParams}#`;
446
422
  return path;
447
423
  }
448
424
 
425
+ protected getEmbedParams() {
426
+ const queryParams = this.getBaseQueryParams();
427
+ return getQueryParamString(queryParams);
428
+ }
429
+
430
+ protected getRootIframeSrc() {
431
+ const query = this.getEmbedParams();
432
+ return this.getEmbedBasePath(query);
433
+ }
434
+
435
+ protected createIframeEl(frameSrc: string): HTMLIFrameElement {
436
+ const iFrame = document.createElement('iframe');
437
+
438
+ iFrame.src = frameSrc;
439
+ iFrame.id = TS_EMBED_ID;
440
+
441
+ // according to screenfull.js documentation
442
+ // allowFullscreen, webkitallowfullscreen and mozallowfullscreen must be
443
+ // true
444
+ iFrame.allowFullscreen = true;
445
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
446
+ // @ts-ignore
447
+ iFrame.webkitallowfullscreen = true;
448
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
449
+ // @ts-ignore
450
+ iFrame.mozallowfullscreen = true;
451
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
452
+ // @ts-ignore
453
+ iFrame.allow = 'clipboard-read; clipboard-write';
454
+
455
+ const {
456
+ height: frameHeight,
457
+ width: frameWidth, ...restParams
458
+ } = this.viewConfig.frameParams || {};
459
+ const width = getCssDimension(frameWidth || DEFAULT_EMBED_WIDTH);
460
+ const height = getCssDimension(frameHeight || DEFAULT_EMBED_HEIGHT);
461
+ setAttributes(iFrame, restParams);
462
+
463
+ iFrame.style.width = `${width}`;
464
+ iFrame.style.height = `${height}`;
465
+ iFrame.style.border = '0';
466
+ iFrame.name = 'ThoughtSpot Embedded Analytics';
467
+ return iFrame;
468
+ }
469
+
449
470
  /**
450
471
  * Renders the embedded ThoughtSpot app in an iframe and sets up
451
472
  * event listeners.
473
+ *
452
474
  * @param url
453
475
  * @param frameOptions
454
476
  */
455
- protected async renderIFrame(
456
- url: string,
457
- frameOptions: FrameParams = {},
458
- ): Promise<any> {
477
+ protected async renderIFrame(url: string): Promise<any> {
459
478
  if (this.isError) {
460
479
  return null;
461
480
  }
@@ -484,45 +503,8 @@ export class TsEmbed {
484
503
  return;
485
504
  }
486
505
 
487
- uploadMixpanelEvent(
488
- MIXPANEL_EVENT.VISUAL_SDK_RENDER_COMPLETE,
489
- );
490
-
491
- this.iFrame =
492
- this.iFrame || document.createElement('iframe');
493
-
494
- this.iFrame.src = url;
495
- this.iFrame.id = TS_EMBED_ID;
496
-
497
- // according to screenfull.js documentation
498
- // allowFullscreen, webkitallowfullscreen and mozallowfullscreen must be true
499
- this.iFrame.allowFullscreen = true;
500
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
501
- // @ts-ignore
502
- this.iFrame.webkitallowfullscreen = true;
503
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
504
- // @ts-ignore
505
- this.iFrame.mozallowfullscreen = true;
506
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
507
- // @ts-ignore
508
- this.iFrame.allow = 'clipboard-read; clipboard-write';
509
- const {
510
- height: frameHeight,
511
- width: frameWidth,
512
- ...restParams
513
- } = frameOptions;
514
- const width = getCssDimension(
515
- frameWidth || DEFAULT_EMBED_WIDTH,
516
- );
517
- const height = getCssDimension(
518
- frameHeight || DEFAULT_EMBED_HEIGHT,
519
- );
520
- setAttributes(this.iFrame, restParams);
521
-
522
- this.iFrame.style.width = `${width}`;
523
- this.iFrame.style.height = `${height}`;
524
- this.iFrame.style.border = '0';
525
- this.iFrame.name = 'ThoughtSpot Embedded Analytics';
506
+ uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_COMPLETE);
507
+ this.iFrame = this.iFrame || this.createIframeEl(url);
526
508
  this.iFrame.addEventListener('load', () => {
527
509
  nextInQueue();
528
510
  const loadTimestamp = Date.now();
@@ -532,20 +514,15 @@ export class TsEmbed {
532
514
  },
533
515
  type: EmbedEvent.Load,
534
516
  });
535
- uploadMixpanelEvent(
536
- MIXPANEL_EVENT.VISUAL_SDK_IFRAME_LOAD_PERFORMANCE,
537
- {
538
- timeTookToLoad: loadTimestamp - initTimestamp,
539
- },
540
- );
517
+ uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_IFRAME_LOAD_PERFORMANCE, {
518
+ timeTookToLoad: loadTimestamp - initTimestamp,
519
+ });
541
520
  });
542
521
  this.iFrame.addEventListener('error', () => {
543
522
  nextInQueue();
544
523
  });
545
524
  this.insertIntoDOM(this.iFrame);
546
- const prefetchIframe = document.querySelectorAll(
547
- '.prefetchIframe',
548
- );
525
+ const prefetchIframe = document.querySelectorAll('.prefetchIframe');
549
526
  if (prefetchIframe.length) {
550
527
  prefetchIframe.forEach((el) => {
551
528
  el.remove();
@@ -555,10 +532,9 @@ export class TsEmbed {
555
532
  })
556
533
  .catch((error) => {
557
534
  nextInQueue();
558
- uploadMixpanelEvent(
559
- MIXPANEL_EVENT.VISUAL_SDK_RENDER_FAILED,
560
- { error: JSON.stringify(error) },
561
- );
535
+ uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_FAILED, {
536
+ error: JSON.stringify(error),
537
+ });
562
538
  this.insertIntoDOM(this.embedConfig.loginFailedMessage);
563
539
  this.handleError(error);
564
540
  });
@@ -591,6 +567,7 @@ export class TsEmbed {
591
567
 
592
568
  /**
593
569
  * Sets the height of the iframe
570
+ *
594
571
  * @param height The height in pixels
595
572
  */
596
573
  protected setIFrameHeight(height: number): void {
@@ -599,6 +576,7 @@ export class TsEmbed {
599
576
 
600
577
  /**
601
578
  * Executes all registered event handlers for a particular event type
579
+ *
602
580
  * @param eventType The event type
603
581
  * @param data The payload invoked with the event handler
604
582
  * @param eventPort The event Port for a specific MessageChannel
@@ -614,10 +592,12 @@ export class TsEmbed {
614
592
  const dataStatus = data?.status || embedEventStatus.END;
615
593
  callbacks.forEach((callbackObj) => {
616
594
  if (
617
- (callbackObj.options.start &&
618
- dataStatus === embedEventStatus.START) || // When start status is true it trigger only start releated payload
619
- (!callbackObj.options.start &&
620
- dataStatus === embedEventStatus.END) // When start status is false it trigger only end releated payload
595
+ // When start status is true it trigger only start releated
596
+ // payload
597
+ (callbackObj.options.start && dataStatus === embedEventStatus.START)
598
+ // When start status is false it trigger only end releated
599
+ // payload
600
+ || (!callbackObj.options.start && dataStatus === embedEventStatus.END)
621
601
  ) {
622
602
  callbackObj.callback(data, (payload) => {
623
603
  this.triggerEventOnPort(eventPort, payload);
@@ -635,6 +615,7 @@ export class TsEmbed {
635
615
 
636
616
  /**
637
617
  * Gets the v1 event type (if applicable) for the EmbedEvent type
618
+ *
638
619
  * @param eventType The v2 event type
639
620
  * @returns The corresponding v1 event type if one exists
640
621
  * or else the v2 event type itself
@@ -647,6 +628,7 @@ export class TsEmbed {
647
628
  * Calculates the iframe center for the current visible viewPort
648
629
  * of iframe using Scroll position of Host App, offsetTop for iframe
649
630
  * in Host app. ViewPort height of the tab.
631
+ *
650
632
  * @returns iframe Center in visible viewport,
651
633
  * Iframe height,
652
634
  * View port height.
@@ -661,18 +643,11 @@ export class TsEmbed {
661
643
  let iframeOffset;
662
644
 
663
645
  if (iframeScrolled < 0) {
664
- iframeVisibleViewPort =
665
- viewPortHeight - (offsetTopClient - scrollTopClient);
666
- iframeVisibleViewPort = Math.min(
667
- iframeHeight,
668
- iframeVisibleViewPort,
669
- );
646
+ iframeVisibleViewPort = viewPortHeight - (offsetTopClient - scrollTopClient);
647
+ iframeVisibleViewPort = Math.min(iframeHeight, iframeVisibleViewPort);
670
648
  iframeOffset = 0;
671
649
  } else {
672
- iframeVisibleViewPort = Math.min(
673
- iframeHeight - iframeScrolled,
674
- viewPortHeight,
675
- );
650
+ iframeVisibleViewPort = Math.min(iframeHeight - iframeScrolled, viewPortHeight);
676
651
  iframeOffset = iframeScrolled;
677
652
  }
678
653
  const iframeCenter = iframeOffset + iframeVisibleViewPort / 2;
@@ -692,6 +667,20 @@ export class TsEmbed {
692
667
  * @param messageType The message type
693
668
  * @param callback A callback as a function
694
669
  * @param options The message options
670
+ * @example
671
+ * ```js
672
+ * tsEmbed.on(EmbedEvent.Error, (data) => {
673
+ * console.error(data);
674
+ * });
675
+ * ```
676
+ * @example
677
+ * ```js
678
+ * tsEmbed.on(EmbedEvent.Save, (data) => {
679
+ * console.log("Answer save clicked", data);
680
+ * }, {
681
+ * start: true // This will trigger the callback on start of save
682
+ * });
683
+ * ```
695
684
  */
696
685
  public on(
697
686
  messageType: EmbedEvent,
@@ -699,9 +688,7 @@ export class TsEmbed {
699
688
  options: MessageOptions = { start: false },
700
689
  ): typeof TsEmbed.prototype {
701
690
  if (this.isRendered) {
702
- this.handleError(
703
- 'Please register event handlers before calling render',
704
- );
691
+ this.handleError('Please register event handlers before calling render');
705
692
  }
706
693
  const callbacks = this.eventHandlerMap.get(messageType) || [];
707
694
  callbacks.push({ options, callback });
@@ -712,8 +699,11 @@ export class TsEmbed {
712
699
  /**
713
700
  * Triggers an event on specific Port registered against
714
701
  * for the EmbedEvent
702
+ *
715
703
  * @param eventType The message type
716
704
  * @param data The payload to send
705
+ * @param eventPort
706
+ * @param payload
717
707
  */
718
708
  private triggerEventOnPort(eventPort: MessagePort | void, payload: any) {
719
709
  if (eventPort) {
@@ -733,25 +723,20 @@ export class TsEmbed {
733
723
 
734
724
  /**
735
725
  * Triggers an event to the embedded app
726
+ *
736
727
  * @param messageType The event type
737
728
  * @param data The payload to send with the message
738
729
  */
739
730
  public trigger(messageType: HostEvent, data: any = {}): Promise<any> {
740
- uploadMixpanelEvent(
741
- `${MIXPANEL_EVENT.VISUAL_SDK_TRIGGER}-${messageType}`,
742
- );
743
- return processTrigger(
744
- this.iFrame,
745
- messageType,
746
- this.thoughtSpotHost,
747
- data,
748
- );
731
+ uploadMixpanelEvent(`${MIXPANEL_EVENT.VISUAL_SDK_TRIGGER}-${messageType}`);
732
+ return processTrigger(this.iFrame, messageType, this.thoughtSpotHost, data);
749
733
  }
750
734
 
751
735
  /**
752
736
  * Marks the ThoughtSpot object to have been rendered
753
737
  * Needs to be overridden by subclasses to do the actual
754
738
  * rendering of the iframe.
739
+ *
755
740
  * @param args
756
741
  */
757
742
  public render(): TsEmbed {
@@ -764,6 +749,7 @@ export class TsEmbed {
764
749
  * Get the Post Url Params for THOUGHTSPOT from the current
765
750
  * host app URL.
766
751
  * THOUGHTSPOT URL params starts with a prefix "ts-"
752
+ *
767
753
  * @version SDK: 1.14.0 | ThoughtSpot: 8.4.0.cl, 8.4.1-sw
768
754
  */
769
755
  public getThoughtSpotPostUrlParams(): string {
@@ -791,6 +777,7 @@ export class TsEmbed {
791
777
 
792
778
  /**
793
779
  * Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
780
+ *
794
781
  * @version SDK: 1.19.1 | ThoughtSpot: *
795
782
  */
796
783
  public destroy(): void {
@@ -800,12 +787,23 @@ export class TsEmbed {
800
787
  console.log('Error destroying TS Embed', e);
801
788
  }
802
789
  }
790
+
791
+ public getUnderlyingFrameElement(): HTMLIFrameElement {
792
+ return this.iFrame;
793
+ }
794
+
795
+ public async prerenderGeneric(): Promise<any> {
796
+ const prerenderFrameSrc = this.getRootIframeSrc();
797
+ return this.renderIFrame(prerenderFrameSrc);
798
+ }
803
799
  }
804
800
 
805
801
  /**
806
802
  * Base class for embedding v1 experience
807
803
  * Note: The v1 version of ThoughtSpot Blink works on the AngularJS stack
808
804
  * which is currently under migration to v2
805
+ *
806
+ * @inheritdoc
809
807
  */
810
808
  export class V1Embed extends TsEmbed {
811
809
  protected viewConfig: ViewConfig;
@@ -816,14 +814,39 @@ export class V1Embed extends TsEmbed {
816
814
  }
817
815
 
818
816
  /**
819
- * Render the app in an iframe and set up event handlers
817
+ * Render the ap p in an iframe and set up event handlers
818
+ *
820
819
  * @param iframeSrc
821
820
  */
822
821
  protected renderV1Embed(iframeSrc: string): any {
823
- return this.renderIFrame(iframeSrc, this.viewConfig.frameParams);
822
+ return this.renderIFrame(iframeSrc);
823
+ }
824
+
825
+ protected getRootIframeSrc(): string {
826
+ const runtimeFilters = this.viewConfig.runtimeFilters;
827
+ const filterQuery = getFilterQuery(runtimeFilters || []);
828
+ const queryParams = this.getEmbedParams();
829
+ const queryString = [filterQuery, queryParams].filter(Boolean).join('&');
830
+ return this.getV1EmbedBasePath(queryString);
824
831
  }
825
832
 
826
- // @override
833
+ /**
834
+ * @inheritdoc
835
+ * @example
836
+ * ```js
837
+ * tsEmbed.on(EmbedEvent.Error, (data) => {
838
+ * console.error(data);
839
+ * });
840
+ * ```
841
+ * @example
842
+ * ```js
843
+ * tsEmbed.on(EmbedEvent.Save, (data) => {
844
+ * console.log("Answer save clicked", data);
845
+ * }, {
846
+ * start: true // This will trigger the callback on start of save
847
+ * });
848
+ * ```
849
+ */
827
850
  public on(
828
851
  messageType: EmbedEvent,
829
852
  callback: MessageCallback,
package/src/errors.ts CHANGED
@@ -1,9 +1,6 @@
1
1
  export const ERROR_MESSAGE = {
2
- INVALID_THOUGHTSPOT_HOST:
3
- 'Error parsing ThoughtSpot host. Please provide a valid URL.',
4
- LIVEBOARD_VIZ_ID_VALIDATION:
5
- 'Please provide either liveboardId or pinboardId',
2
+ INVALID_THOUGHTSPOT_HOST: 'Error parsing ThoughtSpot host. Please provide a valid URL.',
3
+ LIVEBOARD_VIZ_ID_VALIDATION: 'Please provide either liveboardId or pinboardId',
6
4
  TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
7
- SEARCHEMBED_BETA_WRANING_MESSAGE:
8
- 'Search Embed is in Beta in this release.',
5
+ SEARCHEMBED_BETA_WRANING_MESSAGE: 'Search Embed is in Beta in this release.',
9
6
  };