@thoughtspot/visual-embed-sdk 1.33.3 → 1.33.5

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 (145) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/config.d.ts.map +1 -1
  3. package/cjs/src/config.js.map +1 -1
  4. package/cjs/src/embed/app.d.ts +20 -6
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js +3 -3
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +10 -0
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/base.d.ts +4 -1
  11. package/cjs/src/embed/base.d.ts.map +1 -1
  12. package/cjs/src/embed/base.js +14 -6
  13. package/cjs/src/embed/base.js.map +1 -1
  14. package/cjs/src/embed/base.spec.js +58 -4
  15. package/cjs/src/embed/base.spec.js.map +1 -1
  16. package/cjs/src/embed/bodyless-conversation.d.ts +17 -0
  17. package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
  18. package/cjs/src/embed/bodyless-conversation.js +13 -0
  19. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  20. package/cjs/src/embed/conversation.d.ts.map +1 -1
  21. package/cjs/src/embed/conversation.js +4 -0
  22. package/cjs/src/embed/conversation.js.map +1 -1
  23. package/cjs/src/embed/conversation.spec.js +13 -0
  24. package/cjs/src/embed/conversation.spec.js.map +1 -1
  25. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  26. package/cjs/src/embed/liveboard.js +1 -2
  27. package/cjs/src/embed/liveboard.js.map +1 -1
  28. package/cjs/src/embed/liveboard.spec.js +2 -2
  29. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  30. package/cjs/src/embed/sage.d.ts.map +1 -1
  31. package/cjs/src/embed/sage.js +0 -1
  32. package/cjs/src/embed/sage.js.map +1 -1
  33. package/cjs/src/embed/search.js +1 -1
  34. package/cjs/src/embed/search.js.map +1 -1
  35. package/cjs/src/embed/search.spec.js +6 -6
  36. package/cjs/src/embed/search.spec.js.map +1 -1
  37. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  38. package/cjs/src/embed/ts-embed.js +13 -2
  39. package/cjs/src/embed/ts-embed.js.map +1 -1
  40. package/cjs/src/embed/ts-embed.spec.js +41 -1
  41. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  42. package/cjs/src/errors.d.ts +1 -0
  43. package/cjs/src/errors.d.ts.map +1 -1
  44. package/cjs/src/errors.js +10 -9
  45. package/cjs/src/errors.js.map +1 -1
  46. package/cjs/src/react/index.spec.js +2 -2
  47. package/cjs/src/react/index.spec.js.map +1 -1
  48. package/cjs/src/types.d.ts +75 -22
  49. package/cjs/src/types.d.ts.map +1 -1
  50. package/cjs/src/types.js +33 -16
  51. package/cjs/src/types.js.map +1 -1
  52. package/dist/{index-Ck3m4Sis.js → index-CAHz286m.js} +1 -1
  53. package/dist/src/config.d.ts.map +1 -1
  54. package/dist/src/embed/app.d.ts +20 -6
  55. package/dist/src/embed/app.d.ts.map +1 -1
  56. package/dist/src/embed/base.d.ts +4 -1
  57. package/dist/src/embed/base.d.ts.map +1 -1
  58. package/dist/src/embed/bodyless-conversation.d.ts +17 -0
  59. package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
  60. package/dist/src/embed/conversation.d.ts.map +1 -1
  61. package/dist/src/embed/liveboard.d.ts.map +1 -1
  62. package/dist/src/embed/sage.d.ts.map +1 -1
  63. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  64. package/dist/src/errors.d.ts +1 -0
  65. package/dist/src/errors.d.ts.map +1 -1
  66. package/dist/src/types.d.ts +75 -22
  67. package/dist/src/types.d.ts.map +1 -1
  68. package/dist/tsembed-react.es.js +188 -91
  69. package/dist/tsembed-react.js +187 -90
  70. package/dist/tsembed.es.js +210 -93
  71. package/dist/tsembed.js +209 -92
  72. package/dist/visual-embed-sdk-react-full.d.ts +116 -29
  73. package/dist/visual-embed-sdk-react.d.ts +116 -29
  74. package/dist/visual-embed-sdk.d.ts +116 -29
  75. package/lib/package.json +1 -1
  76. package/lib/src/config.d.ts.map +1 -1
  77. package/lib/src/config.js.map +1 -1
  78. package/lib/src/embed/app.d.ts +20 -6
  79. package/lib/src/embed/app.d.ts.map +1 -1
  80. package/lib/src/embed/app.js +3 -3
  81. package/lib/src/embed/app.js.map +1 -1
  82. package/lib/src/embed/app.spec.js +10 -0
  83. package/lib/src/embed/app.spec.js.map +1 -1
  84. package/lib/src/embed/base.d.ts +4 -1
  85. package/lib/src/embed/base.d.ts.map +1 -1
  86. package/lib/src/embed/base.js +15 -7
  87. package/lib/src/embed/base.js.map +1 -1
  88. package/lib/src/embed/base.spec.js +58 -4
  89. package/lib/src/embed/base.spec.js.map +1 -1
  90. package/lib/src/embed/bodyless-conversation.d.ts +17 -0
  91. package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
  92. package/lib/src/embed/bodyless-conversation.js +13 -0
  93. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  94. package/lib/src/embed/conversation.d.ts.map +1 -1
  95. package/lib/src/embed/conversation.js +4 -0
  96. package/lib/src/embed/conversation.js.map +1 -1
  97. package/lib/src/embed/conversation.spec.js +13 -0
  98. package/lib/src/embed/conversation.spec.js.map +1 -1
  99. package/lib/src/embed/liveboard.d.ts.map +1 -1
  100. package/lib/src/embed/liveboard.js +1 -2
  101. package/lib/src/embed/liveboard.js.map +1 -1
  102. package/lib/src/embed/liveboard.spec.js +2 -2
  103. package/lib/src/embed/liveboard.spec.js.map +1 -1
  104. package/lib/src/embed/sage.d.ts.map +1 -1
  105. package/lib/src/embed/sage.js +0 -1
  106. package/lib/src/embed/sage.js.map +1 -1
  107. package/lib/src/embed/search.js +1 -1
  108. package/lib/src/embed/search.js.map +1 -1
  109. package/lib/src/embed/search.spec.js +6 -6
  110. package/lib/src/embed/search.spec.js.map +1 -1
  111. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  112. package/lib/src/embed/ts-embed.js +13 -2
  113. package/lib/src/embed/ts-embed.js.map +1 -1
  114. package/lib/src/embed/ts-embed.spec.js +42 -2
  115. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  116. package/lib/src/errors.d.ts +1 -0
  117. package/lib/src/errors.d.ts.map +1 -1
  118. package/lib/src/errors.js +10 -9
  119. package/lib/src/errors.js.map +1 -1
  120. package/lib/src/react/index.spec.js +2 -2
  121. package/lib/src/react/index.spec.js.map +1 -1
  122. package/lib/src/types.d.ts +75 -22
  123. package/lib/src/types.d.ts.map +1 -1
  124. package/lib/src/types.js +33 -16
  125. package/lib/src/types.js.map +1 -1
  126. package/lib/src/visual-embed-sdk.d.ts +116 -29
  127. package/package.json +1 -1
  128. package/src/config.ts +0 -1
  129. package/src/embed/app.spec.ts +15 -0
  130. package/src/embed/app.ts +23 -8
  131. package/src/embed/base.spec.ts +61 -4
  132. package/src/embed/base.ts +21 -7
  133. package/src/embed/bodyless-conversation.ts +17 -0
  134. package/src/embed/conversation.spec.ts +16 -0
  135. package/src/embed/conversation.ts +4 -0
  136. package/src/embed/liveboard.spec.ts +2 -2
  137. package/src/embed/liveboard.ts +1 -2
  138. package/src/embed/sage.ts +0 -1
  139. package/src/embed/search.spec.ts +6 -6
  140. package/src/embed/search.ts +1 -1
  141. package/src/embed/ts-embed.spec.ts +48 -1
  142. package/src/embed/ts-embed.ts +16 -2
  143. package/src/errors.ts +10 -9
  144. package/src/react/index.spec.tsx +2 -2
  145. package/src/types.ts +71 -20
package/src/embed/app.ts CHANGED
@@ -366,7 +366,7 @@ export interface AppViewConfig extends Omit<ViewConfig, 'visibleTabs'> {
366
366
  */
367
367
  dataPanelCustomGroupsAccordionInitialState?: DataPanelCustomColumnGroupsAccordionState;
368
368
  /**
369
- * This flag is used to enable the 2 column layout in liveboard
369
+ * This attribute can be used to enable the two-column layout on an embedded Liveboard
370
370
  * @type {boolean}
371
371
  * @default false
372
372
  * @version SDK: 1.32.0 | ThoughtSpot:10.1.0.cl
@@ -380,17 +380,17 @@ export interface AppViewConfig extends Omit<ViewConfig, 'visibleTabs'> {
380
380
  */
381
381
  enable2ColumnLayout?: boolean;
382
382
  /**
383
- * Flag to use OnBeforeSearchExecute embed event
383
+ * Flag that allows using `EmbedEvent.OnBeforeGetVizDataIntercept`.
384
384
  * @version SDK : 1.29.0 | Thoughtspot : 10.1.0.cl
385
385
  */
386
386
  isOnBeforeGetVizDataInterceptEnabled?: boolean;
387
387
  /**
388
388
  * Flag to use home page search bar mode
389
- * @version SDK : 1.33.0 | Thoughtspot : 10.2.0.cl
389
+ * @version SDK : 1.33.0 | Thoughtspot : 10.3.0.cl
390
390
  */
391
391
  homePageSearchBarMode?: HomePageSearchBarMode;
392
392
  /**
393
- * This flag is used to enable the compact header in liveboard
393
+ * This flag can be used to enable the compact header in Liveboard
394
394
  * @type {boolean}
395
395
  * @default false
396
396
  * @version SDK: 1.35.0 | ThoughtSpot:10.3.0.cl
@@ -404,7 +404,7 @@ export interface AppViewConfig extends Omit<ViewConfig, 'visibleTabs'> {
404
404
  */
405
405
  isLiveboardCompactHeaderEnabled?: boolean;
406
406
  /**
407
- * This flag is used to show/hide verified Icon in liveboard compact header
407
+ * This flag can be used to show or hide the Liveboard verified icon in the compact header.
408
408
  * @type {boolean}
409
409
  * @default true
410
410
  * @version SDK: 1.35.0 | ThoughtSpot:10.4.0.cl
@@ -418,7 +418,7 @@ export interface AppViewConfig extends Omit<ViewConfig, 'visibleTabs'> {
418
418
  */
419
419
  showLiveboardVerifiedBadge?: boolean;
420
420
  /**
421
- * This flag is used to show/hide re-verify banner in liveboard compact header
421
+ * This flag can be used to show or hide the re-verify banner on the Liveboard compact header
422
422
  * @type {boolean}
423
423
  * @default true
424
424
  * @version SDK: 1.35.0 | ThoughtSpot:10.4.0.cl
@@ -431,6 +431,20 @@ export interface AppViewConfig extends Omit<ViewConfig, 'visibleTabs'> {
431
431
  * ```
432
432
  */
433
433
  showLiveboardReverifyBanner?: boolean;
434
+ /**
435
+ * This flag is used to enable unified search experience for full app embed.
436
+ * @type {boolean}
437
+ * @default true
438
+ * @version SDK: 1.34.0 | ThoughtSpot:10.5.0.cl
439
+ * @example
440
+ * ```js
441
+ * const embed = new AppEmbed('#embed-container', {
442
+ * ... // other options
443
+ * isUnifiedSearchExperienceEnabled: true,
444
+ * })
445
+ * ```
446
+ */
447
+ isUnifiedSearchExperienceEnabled?: boolean;
434
448
  }
435
449
 
436
450
  /**
@@ -468,7 +482,7 @@ export class AppEmbed extends V1Embed {
468
482
  hideOrgSwitcher,
469
483
  enableSearchAssist,
470
484
  fullHeight,
471
- dataPanelV2 = true,
485
+ dataPanelV2 = false,
472
486
  hideLiveboardHeader = false,
473
487
  showLiveboardTitle = true,
474
488
  showLiveboardDescription = true,
@@ -487,10 +501,10 @@ export class AppEmbed extends V1Embed {
487
501
  showLiveboardVerifiedBadge = true,
488
502
  showLiveboardReverifyBanner = true,
489
503
  homePageSearchBarMode,
504
+ isUnifiedSearchExperienceEnabled = true,
490
505
  } = this.viewConfig;
491
506
 
492
507
  let params = {};
493
- params[Param.EmbedApp] = true;
494
508
  params[Param.PrimaryNavHidden] = !showPrimaryNavbar;
495
509
  params[Param.HideProfleAndHelp] = !!disableProfileAndHelp;
496
510
  params[Param.HideApplicationSwitcher] = !!hideApplicationSwitcher;
@@ -503,6 +517,7 @@ export class AppEmbed extends V1Embed {
503
517
  params[Param.LiveboardHeaderV2] = isLiveboardCompactHeaderEnabled;
504
518
  params[Param.ShowLiveboardVerifiedBadge] = showLiveboardVerifiedBadge;
505
519
  params[Param.ShowLiveboardReverifyBanner] = showLiveboardReverifyBanner;
520
+ params[Param.IsUnifiedSearchExperienceEnabled] = isUnifiedSearchExperienceEnabled;
506
521
 
507
522
  params = this.getBaseQueryParams(params);
508
523
 
@@ -56,7 +56,7 @@ describe('Base TS Embed', () => {
56
56
  authEE.on(auth.AuthStatus.FAILURE, (reason) => {
57
57
  expect(reason).toEqual(auth.AuthFailureType.NO_COOKIE_ACCESS);
58
58
  expect(window.alert).toBeCalledWith(
59
- 'Third party cookie access is blocked on this browser, please allow third party cookies for this to work properly. \nYou can use `suppressNoCookieAccessAlert` to suppress this message.',
59
+ 'Third-party cookie access is blocked on this browser. Please allow third-party cookies for this to work properly. \nYou can use `suppressNoCookieAccessAlert` to suppress this message.',
60
60
  );
61
61
  done();
62
62
  });
@@ -249,7 +249,7 @@ describe('Base TS Embed', () => {
249
249
  });
250
250
 
251
251
  test('Should add the prefetch iframe when prefetch is called. Should remove it once init is called.', async () => {
252
- const url = 'https://10.87.90.95/';
252
+ const url = 'https://10.87.90.95/?embedApp=true';
253
253
  index.init({
254
254
  thoughtSpotHost: url,
255
255
  authType: index.AuthType.None,
@@ -266,8 +266,8 @@ describe('Base TS Embed', () => {
266
266
 
267
267
  test('Should add the prefetch iframe when prefetch is called with multiple options', async () => {
268
268
  const url = 'https://10.87.90.95/';
269
- const searchUrl = `${url}v2/#/embed/answer`;
270
- const liveboardUrl = url;
269
+ const searchUrl = `${url}v2/?embedApp=true#/embed/answer`;
270
+ const liveboardUrl = `${url}?embedApp=true`;
271
271
  index.prefetch(url, [
272
272
  index.PrefetchFeatures.SearchEmbed,
273
273
  index.PrefetchFeatures.LiveboardEmbed,
@@ -281,6 +281,51 @@ describe('Base TS Embed', () => {
281
281
  expect(secondIframe.src).toBe(liveboardUrl);
282
282
  });
283
283
 
284
+ test('Should add the prefetch iframe with additionalFlags', async () => {
285
+ const url = 'https://10.87.90.95/';
286
+ const searchUrl = `${url}v2/?embedApp=true&flag2=bool&flag3=block&flag1=true#/embed/answer`;
287
+ const liveboardUrl = `${url}?embedApp=true&flag2=bool&flag3=block&flag1=true`;
288
+ base.init({
289
+ thoughtSpotHost: url,
290
+ authType: index.AuthType.None,
291
+ additionalFlags: {
292
+ flag2: 'bar',
293
+ flag3: 'block',
294
+ },
295
+ });
296
+ index.prefetch(url, [
297
+ index.PrefetchFeatures.SearchEmbed,
298
+ index.PrefetchFeatures.LiveboardEmbed,
299
+ ],
300
+ { flag1: true, flag2: 'bool' });
301
+ expect(getAllIframeEl().length).toBe(2);
302
+ const prefetchIframe = document.querySelectorAll<HTMLIFrameElement>('.prefetchIframe');
303
+ expect(prefetchIframe.length).toBe(2);
304
+ const firstIframe = <HTMLIFrameElement>prefetchIframe[0];
305
+ expect(firstIframe.src).toBe(searchUrl);
306
+ const secondIframe = <HTMLIFrameElement>prefetchIframe[1];
307
+ expect(secondIframe.src).toBe(liveboardUrl);
308
+ });
309
+
310
+ test('Should add the prefetch iframe with additionalFlags for prefetch from init', async () => {
311
+ const url = 'https://10.87.90.95/';
312
+ const prefetchUrl = `${url}?embedApp=true&flag2=bar&flag3=block`;
313
+ base.init({
314
+ thoughtSpotHost: url,
315
+ authType: index.AuthType.None,
316
+ additionalFlags: {
317
+ flag2: 'bar',
318
+ flag3: 'block',
319
+ },
320
+ callPrefetch: true,
321
+ });
322
+ expect(getAllIframeEl().length).toBe(1);
323
+ const prefetchIframe = document.querySelectorAll<HTMLIFrameElement>('.prefetchIframe');
324
+ expect(prefetchIframe.length).toBe(1);
325
+ const firstIframe = <HTMLIFrameElement>prefetchIframe[0];
326
+ expect(firstIframe.src).toBe(prefetchUrl);
327
+ });
328
+
284
329
  test('Should not generate a prefetch iframe when url is empty string', async () => {
285
330
  const url = '';
286
331
  index.prefetch(url);
@@ -411,6 +456,18 @@ describe('Base TS Embed', () => {
411
456
  });
412
457
  expect(embedConfigInstance.getEmbedConfig().inPopup).toBe(false);
413
458
  });
459
+ test('@P0 @SCAL-226935 embedConfig should contain correct value of customCSSUrl when added in init ', async () => {
460
+ index.init({
461
+ thoughtSpotHost,
462
+ authType: index.AuthType.None,
463
+ customizations: {
464
+ style: {
465
+ customCSSUrl: 'test.com',
466
+ },
467
+ },
468
+ });
469
+ expect(embedConfigInstance.getEmbedConfig().customizations.style.customCSSUrl).toEqual('test.com');
470
+ });
414
471
  });
415
472
 
416
473
  describe('Base without init', () => {
package/src/embed/base.ts CHANGED
@@ -15,7 +15,7 @@ import { tokenizedFetch } from '../tokenizedFetch';
15
15
  import { EndPoints } from '../utils/authService/authService';
16
16
  import { getThoughtSpotHost } from '../config';
17
17
  import {
18
- AuthType, EmbedConfig, LogLevel, PrefetchFeatures,
18
+ AuthType, EmbedConfig, LogLevel, Param, PrefetchFeatures,
19
19
  } from '../types';
20
20
  import {
21
21
  authenticate,
@@ -33,6 +33,7 @@ import {
33
33
  } from '../auth';
34
34
  import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
35
35
  import { getEmbedConfig, setEmbedConfig } from './embedConfig';
36
+ import { getQueryParamString } from '../utils';
36
37
 
37
38
  const CONFIG_DEFAULTS: Partial<EmbedConfig> = {
38
39
  loginFailedMessage: 'Not logged in',
@@ -88,10 +89,10 @@ export const handleAuth = (): Promise<boolean> => {
88
89
  };
89
90
 
90
91
  const hostUrlToFeatureUrl = {
91
- [PrefetchFeatures.SearchEmbed]: (url: string) => `${url}v2/#/embed/answer`,
92
- [PrefetchFeatures.LiveboardEmbed]: (url: string) => url,
93
- [PrefetchFeatures.FullApp]: (url: string) => url,
94
- [PrefetchFeatures.VizEmbed]: (url: string) => url,
92
+ [PrefetchFeatures.SearchEmbed]: (url: string, flags: string) => `${url}v2/?${flags}#/embed/answer`,
93
+ [PrefetchFeatures.LiveboardEmbed]: (url: string, flags: string) => `${url}?${flags}`,
94
+ [PrefetchFeatures.FullApp]: (url: string, flags: string) => `${url}?${flags}`,
95
+ [PrefetchFeatures.VizEmbed]: (url: string, flags: string) => `${url}?${flags}`,
95
96
  };
96
97
 
97
98
  /**
@@ -100,20 +101,33 @@ const hostUrlToFeatureUrl = {
100
101
  * to your app.
101
102
  * @param url The URL provided for prefetch
102
103
  * @param prefetchFeatures Specify features which needs to be prefetched.
104
+ * @param additionalFlags This can be used to add any URL flag.
103
105
  * @version SDK: 1.4.0 | ThoughtSpot: ts7.sep.cl, 7.2.1
104
106
  * @group Global methods
105
107
  */
106
- export const prefetch = (url?: string, prefetchFeatures?: PrefetchFeatures[]): void => {
108
+ export const prefetch = (
109
+ url?: string,
110
+ prefetchFeatures?: PrefetchFeatures[],
111
+ additionalFlags?: { [key: string]: string | number | boolean },
112
+ ): void => {
107
113
  if (url === '') {
108
114
  // eslint-disable-next-line no-console
109
115
  logger.warn('The prefetch method does not have a valid URL');
110
116
  } else {
111
117
  const features = prefetchFeatures || [PrefetchFeatures.FullApp];
112
118
  let hostUrl = url || getEmbedConfig().thoughtSpotHost;
119
+ const prefetchFlags = {
120
+ [Param.EmbedApp]: true,
121
+ ...getEmbedConfig()?.additionalFlags,
122
+ ...additionalFlags,
123
+ };
113
124
  hostUrl = hostUrl[hostUrl.length - 1] === '/' ? hostUrl : `${hostUrl}/`;
114
125
  Array.from(
115
126
  new Set(features
116
- .map((feature) => hostUrlToFeatureUrl[feature](hostUrl))),
127
+ .map((feature) => hostUrlToFeatureUrl[feature](
128
+ hostUrl,
129
+ getQueryParamString(prefetchFlags),
130
+ ))),
117
131
  )
118
132
  .forEach(
119
133
  (prefetchUrl, index) => {
@@ -4,6 +4,10 @@ import { Conversation as ConversationService } from '../utils/graphql/nlsService
4
4
  import { getEmbedConfig } from './embedConfig';
5
5
  import { getQueryParamString } from '../utils';
6
6
 
7
+ /**
8
+ * Configuration for bodyless conversation options.
9
+ * @group Embed components
10
+ */
7
11
  export interface BodylessConversationViewConfig extends ViewConfig {
8
12
  /**
9
13
  * The ID of the worksheet to use for the conversation.
@@ -60,6 +64,19 @@ class ConversationMessage extends TsEmbed {
60
64
  /**
61
65
  * Create a conversation embed, which can be integrated inside
62
66
  * chatbots or other conversational interfaces.
67
+ * @example
68
+ * ```js
69
+ * import { BodylessConversation } from '@thoughtspot/visual-embed-sdk';
70
+ *
71
+ * const conversation = new BodylessConversation({
72
+ * worksheetId: 'worksheetId',
73
+ * });
74
+ *
75
+ * const { container, error } = await conversation.sendMessage('show me sales by region');
76
+ *
77
+ * // append the container to the DOM
78
+ * document.body.appendChild(container); // or to any other element
79
+ * ```
63
80
  * @group Embed components
64
81
  * @version SDK: 1.33.1 | ThoughtSpot: 10.5.0.cl
65
82
  */
@@ -14,6 +14,7 @@ import {
14
14
  defaultParamsWithoutHiddenActions as defaultParams,
15
15
  expectUrlMatchesWithParams,
16
16
  } from '../test/test-utils';
17
+ import { ERROR_MESSAGE } from '../errors';
17
18
 
18
19
  const thoughtSpotHost = 'tshost';
19
20
 
@@ -43,4 +44,19 @@ describe('ConversationEmbed', () => {
43
44
  `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
44
45
  );
45
46
  });
47
+
48
+ it('should handle error when worksheetId is not provided', async () => {
49
+ const viewConfig: ConversationViewConfig = {
50
+ worksheetId: '',
51
+ searchOptions: {
52
+ searchQuery: 'searchQuery',
53
+ },
54
+ };
55
+ const conversationEmbed = new ConversationEmbed(getRootEl(), viewConfig);
56
+ (conversationEmbed as any).handleError = jest.fn();
57
+ await conversationEmbed.render();
58
+ expect((conversationEmbed as any).handleError).toHaveBeenCalledWith(
59
+ ERROR_MESSAGE.SPOTTER_EMBED_WORKSHEED_ID_NOT_FOUND,
60
+ );
61
+ });
46
62
  });
@@ -1,3 +1,4 @@
1
+ import { ERROR_MESSAGE } from '../errors';
1
2
  import { ViewConfig, Param } from '../types';
2
3
  import { TsEmbed } from './ts-embed';
3
4
  import { getQueryParamString } from '../utils';
@@ -49,6 +50,9 @@ export class ConversationEmbed extends TsEmbed {
49
50
  searchOptions,
50
51
  } = this.viewConfig;
51
52
  const path = 'insights/conv-assist';
53
+ if (!worksheetId) {
54
+ this.handleError(ERROR_MESSAGE.SPOTTER_EMBED_WORKSHEED_ID_NOT_FOUND);
55
+ }
52
56
  const queryParams = this.getBaseQueryParams();
53
57
  queryParams[Param.SpotterEnabled] = true;
54
58
 
@@ -67,7 +67,7 @@ describe('Liveboard/viz embed tests', () => {
67
67
  });
68
68
  });
69
69
 
70
- test('should render liveboard with data panel v2 flag set to true by default', async () => {
70
+ test('should render liveboard with data panel v2 flag set to false by default', async () => {
71
71
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
72
72
  ...defaultViewConfig,
73
73
  liveboardId,
@@ -76,7 +76,7 @@ describe('Liveboard/viz embed tests', () => {
76
76
  await executeAfterWait(() => {
77
77
  expectUrlMatchesWithParams(
78
78
  getIFrameSrc(),
79
- `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}&enableDataPanelV2=true#/embed/viz/${liveboardId}`,
79
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}&enableDataPanelV2=false#/embed/viz/${liveboardId}`,
80
80
  );
81
81
  });
82
82
  });
@@ -363,7 +363,6 @@ export class LiveboardEmbed extends V1Embed {
363
363
  */
364
364
  protected getEmbedParams() {
365
365
  let params = {};
366
- params[Param.EmbedApp] = true;
367
366
  params = this.getBaseQueryParams(params);
368
367
  const {
369
368
  enableVizTransformations,
@@ -383,7 +382,7 @@ export class LiveboardEmbed extends V1Embed {
383
382
  showLiveboardReverifyBanner = true,
384
383
  enableAskSage,
385
384
  enable2ColumnLayout,
386
- dataPanelV2 = true,
385
+ dataPanelV2 = false,
387
386
  enableCustomColumnGroups = false,
388
387
  } = this.viewConfig;
389
388
 
package/src/embed/sage.ts CHANGED
@@ -158,7 +158,6 @@ export class SageEmbed extends V1Embed {
158
158
  } = this.viewConfig;
159
159
 
160
160
  const params = this.getBaseQueryParams();
161
- params[Param.EmbedApp] = true;
162
161
  params[Param.IsSageEmbed] = true;
163
162
  params[Param.DisableWorksheetChange] = !!disableWorksheetChange;
164
163
  params[Param.HideWorksheetSelector] = !!hideWorksheetSelector;
@@ -52,7 +52,7 @@ describe('Search embed tests', () => {
52
52
  await executeAfterWait(() => {
53
53
  expectUrlMatchesWithParams(
54
54
  getIFrameSrc(),
55
- `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&enableDataPanelV2=true&dataSourceMode=expand&useLastSelectedSources=false${prefixParams}#/embed/answer`,
55
+ `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&enableDataPanelV2=false&dataSourceMode=expand&useLastSelectedSources=false${prefixParams}#/embed/answer`,
56
56
  );
57
57
  });
58
58
  });
@@ -438,7 +438,7 @@ describe('Search embed tests', () => {
438
438
  await executeAfterWait(() => {
439
439
  expectUrlMatchesWithParams(
440
440
  getIFrameSrc(),
441
- `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&dataSourceMode=expand&enableDataPanelV2=true&useLastSelectedSources=true${prefixParams}#/embed/saved-answer/${answerId}`,
441
+ `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&dataSourceMode=expand&enableDataPanelV2=false&useLastSelectedSources=true${prefixParams}#/embed/saved-answer/${answerId}`,
442
442
  );
443
443
  });
444
444
  });
@@ -453,7 +453,7 @@ describe('Search embed tests', () => {
453
453
  await executeAfterWait(() => {
454
454
  expectUrlMatchesWithParams(
455
455
  getIFrameSrc(),
456
- `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&dataSources=[%22data-source-1%22]&dataSourceMode=expand&enableDataPanelV2=true&useLastSelectedSources=false${prefixParams}#/embed/saved-answer/${answerId}`,
456
+ `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&dataSources=[%22data-source-1%22]&dataSourceMode=expand&enableDataPanelV2=false&useLastSelectedSources=false${prefixParams}#/embed/saved-answer/${answerId}`,
457
457
  );
458
458
  });
459
459
  });
@@ -468,7 +468,7 @@ describe('Search embed tests', () => {
468
468
  await executeAfterWait(() => {
469
469
  expectUrlMatchesWithParams(
470
470
  getIFrameSrc(),
471
- `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&dataSources=[%22data-source-1%22]&dataSourceMode=expand&enableDataPanelV2=true&useLastSelectedSources=false${prefixParams}#/embed/saved-answer/${answerId}`,
471
+ `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&dataSources=[%22data-source-1%22]&dataSourceMode=expand&enableDataPanelV2=false&useLastSelectedSources=false${prefixParams}#/embed/saved-answer/${answerId}`,
472
472
  );
473
473
  });
474
474
  });
@@ -499,7 +499,7 @@ describe('Search embed tests', () => {
499
499
  await executeAfterWait(() => {
500
500
  expectUrlMatchesWithParams(
501
501
  getIFrameSrc(),
502
- `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&dataSourceMode=expand&enableDataPanelV2=true&useLastSelectedSources=false&hideSearchBar=true${prefixParams}#/embed/saved-answer/${answerId}`,
502
+ `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&dataSourceMode=expand&enableDataPanelV2=false&useLastSelectedSources=false&hideSearchBar=true${prefixParams}#/embed/saved-answer/${answerId}`,
503
503
  );
504
504
  });
505
505
  });
@@ -514,7 +514,7 @@ describe('Search embed tests', () => {
514
514
  await executeAfterWait(() => {
515
515
  expectUrlMatchesWithParams(
516
516
  getIFrameSrc(),
517
- `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&dataSourceMode=expand&enableDataPanelV2=true&useLastSelectedSources=false&dataPanelCustomGroupsAccordionInitialState=EXPAND_FIRST${prefixParams}#/embed/saved-answer/${answerId}`,
517
+ `http://${thoughtSpotHost}/v2/?${defaultParamsWithHiddenActions}&dataSourceMode=expand&enableDataPanelV2=false&useLastSelectedSources=false&dataPanelCustomGroupsAccordionInitialState=EXPAND_FIRST${prefixParams}#/embed/saved-answer/${answerId}`,
518
518
  );
519
519
  });
520
520
  });
@@ -330,7 +330,7 @@ export class SearchEmbed extends TsEmbed {
330
330
  dataSources,
331
331
  excludeRuntimeFiltersfromURL,
332
332
  hideSearchBar,
333
- dataPanelV2 = true,
333
+ dataPanelV2 = false,
334
334
  useLastSelectedSources = false,
335
335
  runtimeParameters,
336
336
  collapseSearchBarInitially = false,
@@ -13,6 +13,7 @@ import {
13
13
  import {
14
14
  Action, HomeLeftNavItem, RuntimeFilter, RuntimeFilterOp, HomepageModule, HostEvent,
15
15
  RuntimeParameter,
16
+ Param,
16
17
  } from '../types';
17
18
  import {
18
19
  executeAfterWait,
@@ -24,10 +25,12 @@ import {
24
25
  defaultParamsForPinboardEmbed,
25
26
  waitFor,
26
27
  expectUrlMatchesWithParams,
28
+ expectUrlToHaveParamsWithValues,
27
29
  mockMessageChannel,
28
30
  createRootEleForEmbed,
29
31
  } from '../test/test-utils';
30
32
  import * as config from '../config';
33
+ import * as embedConfig from './embedConfig';
31
34
  import * as tsEmbedInstance from './ts-embed';
32
35
  import * as mixpanelInstance from '../mixpanel-service';
33
36
  import * as authInstance from '../auth';
@@ -1274,6 +1277,36 @@ describe('Unit test case for ts embed', () => {
1274
1277
  );
1275
1278
  });
1276
1279
 
1280
+ it('should set the additional flags correctly on the iframe src from init and view config', async () => {
1281
+ init({
1282
+ thoughtSpotHost: 'http://tshost',
1283
+ authType: AuthType.None,
1284
+ additionalFlags: {
1285
+ foo: 'bar1',
1286
+ foo2: 'bar2',
1287
+ foo3: false,
1288
+ },
1289
+ });
1290
+ const appEmbed = new AppEmbed(getRootEl(), {
1291
+ frameParams: {
1292
+ width: '100%',
1293
+ height: '100%',
1294
+ },
1295
+ additionalFlags: {
1296
+ foo: 'bar',
1297
+ baz: 1,
1298
+ bool: true,
1299
+ },
1300
+ });
1301
+ await appEmbed.render();
1302
+ console.log('val ', getIFrameSrc());
1303
+ expectUrlMatchesWithParams(
1304
+ getIFrameSrc(),
1305
+ `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&${defaultParamsForPinboardEmbed}`
1306
+ + `&foo=bar&foo2=bar2&foo3=false&baz=1&bool=true${defaultParamsPost}#/home`,
1307
+ );
1308
+ });
1309
+
1277
1310
  it('Sets the showAlerts param', async () => {
1278
1311
  const appEmbed = new AppEmbed(getRootEl(), {
1279
1312
  frameParams: {
@@ -1407,6 +1440,20 @@ describe('Unit test case for ts embed', () => {
1407
1440
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&numberFormatLocale=en-US&dateFormatLocale=en-IN&currencyFormat=USD${defaultParamsPost}#/home`,
1408
1441
  );
1409
1442
  });
1443
+ it('Sets the overrideOrgId param', async () => {
1444
+ const overrideOrgId = 142536;
1445
+ const appEmbed = new AppEmbed(getRootEl(), {
1446
+ frameParams: {
1447
+ width: '100%',
1448
+ height: '100%',
1449
+ },
1450
+ overrideOrgId,
1451
+ });
1452
+ await appEmbed.render();
1453
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
1454
+ orgId: overrideOrgId,
1455
+ });
1456
+ });
1410
1457
  });
1411
1458
 
1412
1459
  describe('When destroyed', () => {
@@ -1615,7 +1662,7 @@ describe('Unit test case for ts embed', () => {
1615
1662
  });
1616
1663
  libEmbed.preRender();
1617
1664
 
1618
- expect(logger.error).toHaveBeenCalledWith('PreRender id is required for preRender');
1665
+ expect(logger.error).toHaveBeenCalledWith('PreRender ID is required for preRender');
1619
1666
  });
1620
1667
 
1621
1668
  it('showPreRender should preRender if not available', async () => {
@@ -7,6 +7,8 @@
7
7
  */
8
8
 
9
9
  import isEqual from 'lodash/isEqual';
10
+ import isEmpty from 'lodash/isEmpty';
11
+ import isObject from 'lodash/isObject';
10
12
  import { logger } from '../utils/logger';
11
13
  import { getAuthenticationToken } from '../authToken';
12
14
  import { AnswerService } from '../utils/graphql/answerService/answerService';
@@ -398,6 +400,7 @@ export class TsEmbed {
398
400
  if (hostAppUrl.includes('localhost') || hostAppUrl.includes('127.0.0.1')) {
399
401
  hostAppUrl = 'local-host';
400
402
  }
403
+ queryParams[Param.EmbedApp] = true;
401
404
  queryParams[Param.HostAppUrl] = encodeURIComponent(hostAppUrl);
402
405
  queryParams[Param.ViewPortHeight] = window.innerHeight;
403
406
  queryParams[Param.ViewPortWidth] = window.innerWidth;
@@ -435,15 +438,23 @@ export class TsEmbed {
435
438
  hiddenTabs,
436
439
  visibleTabs,
437
440
  showAlerts,
438
- additionalFlags,
441
+ additionalFlags: additionalFlagsFromView,
439
442
  locale,
440
443
  customizations,
441
444
  contextMenuTrigger,
442
445
  linkOverride,
443
446
  insertInToSlide,
444
447
  disableRedirectionLinksInNewTab,
448
+ overrideOrgId,
445
449
  } = this.viewConfig;
446
450
 
451
+ const { additionalFlags: additionalFlagsFromInit } = this.embedConfig;
452
+
453
+ const additionalFlags = {
454
+ ...additionalFlagsFromInit,
455
+ ...additionalFlagsFromView,
456
+ };
457
+
447
458
  if (Array.isArray(visibleActions) && Array.isArray(hiddenActions)) {
448
459
  this.handleError('You cannot have both hidden actions and visible actions');
449
460
  return queryParams;
@@ -503,11 +514,14 @@ export class TsEmbed {
503
514
  if (disableRedirectionLinksInNewTab) {
504
515
  queryParams[Param.DisableRedirectionLinksInNewTab] = disableRedirectionLinksInNewTab;
505
516
  }
517
+ if (overrideOrgId !== undefined) {
518
+ queryParams[Param.OverrideOrgId] = overrideOrgId;
519
+ }
506
520
 
507
521
  queryParams[Param.OverrideNativeConsole] = true;
508
522
  queryParams[Param.ClientLogLevel] = this.embedConfig.logLevel;
509
523
 
510
- if (additionalFlags && additionalFlags.constructor.name === 'Object') {
524
+ if (isObject(additionalFlags) && !isEmpty(additionalFlags)) {
511
525
  Object.assign(queryParams, additionalFlags);
512
526
  }
513
527
 
package/src/errors.ts CHANGED
@@ -1,18 +1,19 @@
1
1
  export const ERROR_MESSAGE = {
2
2
  INVALID_THOUGHTSPOT_HOST: 'Error parsing ThoughtSpot host. Please provide a valid URL.',
3
- LIVEBOARD_VIZ_ID_VALIDATION: 'Please select a liveboard to embed.',
4
- TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
5
- SEARCHEMBED_BETA_WRANING_MESSAGE: 'Search Embed is in Beta in this release.',
6
- SAGE_EMBED_BETA_WARNING_MESSAGE: 'Sage Embed is in Beta in this release.',
7
- THIRD_PARTY_COOKIE_BLOCKED_ALERT: 'Third party cookie access is blocked on this browser, please allow third party cookies for this to work properly. \nYou can use `suppressNoCookieAccessAlert` to suppress this message.',
8
- DUPLICATE_TOKEN_ERR: 'Duplicate token, please issue a new token every time getAuthToken callback is called. See https://developers.thoughtspot.com/docs/?pageid=embed-auth#trusted-auth-embed for more details.',
3
+ SPOTTER_EMBED_WORKSHEED_ID_NOT_FOUND: 'Please select a worksheet to get started',
4
+ LIVEBOARD_VIZ_ID_VALIDATION: 'Please select a Liveboard to embed.',
5
+ TRIGGER_TIMED_OUT: 'Trigger timed-out in getting a response',
6
+ SEARCHEMBED_BETA_WRANING_MESSAGE: 'SearchEmbed is in Beta in this release.',
7
+ SAGE_EMBED_BETA_WARNING_MESSAGE: 'SageEmbed is in Beta in this release.',
8
+ THIRD_PARTY_COOKIE_BLOCKED_ALERT: 'Third-party cookie access is blocked on this browser. Please allow third-party cookies for this to work properly. \nYou can use `suppressNoCookieAccessAlert` to suppress this message.',
9
+ DUPLICATE_TOKEN_ERR: 'Duplicate token. Please issue a new token every time getAuthToken callback is called. See https://developers.thoughtspot.com/docs/?pageid=embed-auth#trusted-auth-embed for more details.',
9
10
  SDK_NOT_INITIALIZED: 'SDK not initialized',
10
- SESSION_INFO_FAILED: 'Failed to get session info',
11
+ SESSION_INFO_FAILED: 'Failed to get session information',
11
12
  INVALID_TOKEN_ERROR: 'Received invalid token from getAuthToken callback or authToken endpoint.',
12
13
  MIXPANEL_TOKEN_NOT_FOUND: 'Mixpanel token not found in session info',
13
- PRERENDER_ID_MISSING: 'PreRender id is required for preRender',
14
+ PRERENDER_ID_MISSING: 'PreRender ID is required for preRender',
14
15
  SYNC_STYLE_CALLED_BEFORE_RENDER: 'PreRender should be called before using syncPreRenderStyle',
15
16
  CSP_VIOLATION_ALERT: 'CSP violation detected. Please check the console errors for more details.',
16
- CSP_FRAME_HOST_VIOLATION_LOG_MESSAGE: 'Please setup CSP Correctly for the Application to start working. You can know more about setting CSP Correctly here: https://developers.thoughtspot.com/docs/security-settings#csp-viz-embed-hosts. \n In case you are still facing error, please read: https://developers.thoughtspot.com/docs/security-settings#csp-viz-embed-hosts',
17
+ CSP_FRAME_HOST_VIOLATION_LOG_MESSAGE: 'Please set up CSP correctly for the application to start working. For more information, see https://developers.thoughtspot.com/docs/security-settings#csp-viz-embed-hosts. \n If the issue persists, refer to https://developers.thoughtspot.com/docs/security-settings#csp-viz-embed-hosts',
17
18
  MISSING_REPORTING_OBSERVER: 'ReportingObserver not supported',
18
19
  };
@@ -56,7 +56,7 @@ describe('React Components', () => {
56
56
  ),
57
57
  ).toBe(true);
58
58
  expect(getIFrameSrc(container)).toBe(
59
- `http://${thoughtSpotHost}/?hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22,%22editACopy%22,%22saveAsView%22,%22updateTSL%22,%22editTSL%22,%22onDeleteAnswer%22]&overrideConsoleLogs=true&clientLogLevel=ERROR&enableDataPanelV2=true&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true&collapseSearchBarInitially=true&enableCustomColumnGroups=false&dataPanelCustomGroupsAccordionInitialState=EXPAND_ALL#/embed/answer`,
59
+ `http://${thoughtSpotHost}/?embedApp=true&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22,%22editACopy%22,%22saveAsView%22,%22updateTSL%22,%22editTSL%22,%22onDeleteAnswer%22]&overrideConsoleLogs=true&clientLogLevel=ERROR&enableDataPanelV2=false&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true&collapseSearchBarInitially=true&enableCustomColumnGroups=false&dataPanelCustomGroupsAccordionInitialState=EXPAND_ALL#/embed/answer`,
60
60
  );
61
61
  });
62
62
 
@@ -230,7 +230,7 @@ describe('React Components', () => {
230
230
  ),
231
231
  ).toBe(true);
232
232
  expect(getIFrameSrc(container)).toBe(
233
- `http://${thoughtSpotHost}/?hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22]&overrideConsoleLogs=true&clientLogLevel=ERROR&dataSources=[%22test%22]&searchTokenString=%5Brevenue%5D&executeSearch=true&useLastSelectedSources=false&isSearchEmbed=true#/embed/search-bar-embed`,
233
+ `http://${thoughtSpotHost}/?embedApp=true&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22]&overrideConsoleLogs=true&clientLogLevel=ERROR&dataSources=[%22test%22]&searchTokenString=%5Brevenue%5D&executeSearch=true&useLastSelectedSources=false&isSearchEmbed=true#/embed/search-bar-embed`,
234
234
  );
235
235
  });
236
236
  });