@thoughtspot/visual-embed-sdk 1.32.0 → 1.33.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/auth.d.ts.map +1 -1
  3. package/cjs/src/auth.js +6 -5
  4. package/cjs/src/auth.js.map +1 -1
  5. package/cjs/src/authToken.d.ts.map +1 -1
  6. package/cjs/src/authToken.js +5 -7
  7. package/cjs/src/authToken.js.map +1 -1
  8. package/cjs/src/embed/app.d.ts +12 -1
  9. package/cjs/src/embed/app.d.ts.map +1 -1
  10. package/cjs/src/embed/app.js +13 -4
  11. package/cjs/src/embed/app.js.map +1 -1
  12. package/cjs/src/embed/app.spec.js +30 -0
  13. package/cjs/src/embed/app.spec.js.map +1 -1
  14. package/cjs/src/embed/base.d.ts.map +1 -1
  15. package/cjs/src/embed/base.js +2 -0
  16. package/cjs/src/embed/base.js.map +1 -1
  17. package/cjs/src/embed/search.d.ts +15 -1
  18. package/cjs/src/embed/search.d.ts.map +1 -1
  19. package/cjs/src/embed/search.js +6 -4
  20. package/cjs/src/embed/search.js.map +1 -1
  21. package/cjs/src/embed/search.spec.js +9 -9
  22. package/cjs/src/embed/search.spec.js.map +1 -1
  23. package/cjs/src/embed/ts-embed.d.ts +1 -1
  24. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  25. package/cjs/src/embed/ts-embed.js +10 -6
  26. package/cjs/src/embed/ts-embed.js.map +1 -1
  27. package/cjs/src/errors.d.ts +11 -0
  28. package/cjs/src/errors.d.ts.map +1 -1
  29. package/cjs/src/errors.js +11 -0
  30. package/cjs/src/errors.js.map +1 -1
  31. package/cjs/src/mixpanel-service.d.ts.map +1 -1
  32. package/cjs/src/mixpanel-service.js +2 -1
  33. package/cjs/src/mixpanel-service.js.map +1 -1
  34. package/cjs/src/react/index.spec.js +1 -1
  35. package/cjs/src/react/index.spec.js.map +1 -1
  36. package/cjs/src/types.d.ts +155 -6
  37. package/cjs/src/types.d.ts.map +1 -1
  38. package/cjs/src/types.js +128 -3
  39. package/cjs/src/types.js.map +1 -1
  40. package/cjs/src/utils/processData.d.ts.map +1 -1
  41. package/cjs/src/utils/processData.js +2 -1
  42. package/cjs/src/utils/processData.js.map +1 -1
  43. package/cjs/src/utils/reporting.d.ts +16 -0
  44. package/cjs/src/utils/reporting.d.ts.map +1 -0
  45. package/cjs/src/utils/reporting.js +68 -0
  46. package/cjs/src/utils/reporting.js.map +1 -0
  47. package/cjs/src/utils/reporting.spec.d.ts +2 -0
  48. package/cjs/src/utils/reporting.spec.d.ts.map +1 -0
  49. package/cjs/src/utils/reporting.spec.js +76 -0
  50. package/cjs/src/utils/reporting.spec.js.map +1 -0
  51. package/dist/src/auth.d.ts.map +1 -1
  52. package/dist/src/authToken.d.ts.map +1 -1
  53. package/dist/src/embed/app.d.ts +12 -1
  54. package/dist/src/embed/app.d.ts.map +1 -1
  55. package/dist/src/embed/base.d.ts.map +1 -1
  56. package/dist/src/embed/search.d.ts +15 -1
  57. package/dist/src/embed/search.d.ts.map +1 -1
  58. package/dist/src/embed/ts-embed.d.ts +1 -1
  59. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  60. package/dist/src/errors.d.ts +11 -0
  61. package/dist/src/errors.d.ts.map +1 -1
  62. package/dist/src/mixpanel-service.d.ts.map +1 -1
  63. package/dist/src/types.d.ts +155 -6
  64. package/dist/src/types.d.ts.map +1 -1
  65. package/dist/src/utils/processData.d.ts.map +1 -1
  66. package/dist/src/utils/reporting.d.ts +16 -0
  67. package/dist/src/utils/reporting.d.ts.map +1 -0
  68. package/dist/src/utils/reporting.spec.d.ts +2 -0
  69. package/dist/src/utils/reporting.spec.d.ts.map +1 -0
  70. package/dist/tsembed-react.es.js +192 -38
  71. package/dist/tsembed-react.js +192 -38
  72. package/dist/tsembed.es.js +239 -39
  73. package/dist/tsembed.js +239 -39
  74. package/dist/visual-embed-sdk-react-full.d.ts +183 -9
  75. package/dist/visual-embed-sdk-react.d.ts +183 -9
  76. package/dist/visual-embed-sdk.d.ts +183 -9
  77. package/lib/package.json +1 -1
  78. package/lib/src/auth.d.ts.map +1 -1
  79. package/lib/src/auth.js +6 -5
  80. package/lib/src/auth.js.map +1 -1
  81. package/lib/src/authToken.d.ts.map +1 -1
  82. package/lib/src/authToken.js +5 -7
  83. package/lib/src/authToken.js.map +1 -1
  84. package/lib/src/embed/app.d.ts +12 -1
  85. package/lib/src/embed/app.d.ts.map +1 -1
  86. package/lib/src/embed/app.js +12 -3
  87. package/lib/src/embed/app.js.map +1 -1
  88. package/lib/src/embed/app.spec.js +31 -1
  89. package/lib/src/embed/app.spec.js.map +1 -1
  90. package/lib/src/embed/base.d.ts.map +1 -1
  91. package/lib/src/embed/base.js +2 -0
  92. package/lib/src/embed/base.js.map +1 -1
  93. package/lib/src/embed/search.d.ts +15 -1
  94. package/lib/src/embed/search.d.ts.map +1 -1
  95. package/lib/src/embed/search.js +6 -4
  96. package/lib/src/embed/search.js.map +1 -1
  97. package/lib/src/embed/search.spec.js +9 -9
  98. package/lib/src/embed/search.spec.js.map +1 -1
  99. package/lib/src/embed/ts-embed.d.ts +1 -1
  100. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  101. package/lib/src/embed/ts-embed.js +10 -6
  102. package/lib/src/embed/ts-embed.js.map +1 -1
  103. package/lib/src/errors.d.ts +11 -0
  104. package/lib/src/errors.d.ts.map +1 -1
  105. package/lib/src/errors.js +11 -0
  106. package/lib/src/errors.js.map +1 -1
  107. package/lib/src/mixpanel-service.d.ts.map +1 -1
  108. package/lib/src/mixpanel-service.js +2 -1
  109. package/lib/src/mixpanel-service.js.map +1 -1
  110. package/lib/src/react/index.spec.js +1 -1
  111. package/lib/src/react/index.spec.js.map +1 -1
  112. package/lib/src/types.d.ts +155 -6
  113. package/lib/src/types.d.ts.map +1 -1
  114. package/lib/src/types.js +128 -3
  115. package/lib/src/types.js.map +1 -1
  116. package/lib/src/utils/processData.d.ts.map +1 -1
  117. package/lib/src/utils/processData.js +2 -1
  118. package/lib/src/utils/processData.js.map +1 -1
  119. package/lib/src/utils/reporting.d.ts +16 -0
  120. package/lib/src/utils/reporting.d.ts.map +1 -0
  121. package/lib/src/utils/reporting.js +62 -0
  122. package/lib/src/utils/reporting.js.map +1 -0
  123. package/lib/src/utils/reporting.spec.d.ts +2 -0
  124. package/lib/src/utils/reporting.spec.d.ts.map +1 -0
  125. package/lib/src/utils/reporting.spec.js +74 -0
  126. package/lib/src/utils/reporting.spec.js.map +1 -0
  127. package/lib/src/visual-embed-sdk.d.ts +183 -9
  128. package/package.json +1 -1
  129. package/src/auth.ts +6 -5
  130. package/src/authToken.ts +5 -9
  131. package/src/embed/app.spec.ts +46 -0
  132. package/src/embed/app.ts +20 -3
  133. package/src/embed/base.ts +3 -1
  134. package/src/embed/search.spec.ts +9 -9
  135. package/src/embed/search.ts +21 -4
  136. package/src/embed/ts-embed.ts +13 -6
  137. package/src/errors.ts +11 -0
  138. package/src/mixpanel-service.ts +2 -1
  139. package/src/react/index.spec.tsx +1 -1
  140. package/src/types.ts +168 -13
  141. package/src/utils/processData.ts +2 -3
  142. package/src/utils/reporting.spec.ts +91 -0
  143. package/src/utils/reporting.ts +71 -0
@@ -88,6 +88,19 @@ export interface SearchViewConfig
88
88
  * ```
89
89
  */
90
90
  collapseDataSources?: boolean;
91
+ /**
92
+ * If set to true, the data panel is collapsed on load,
93
+ * but can be expanded manually.
94
+ * @version: SDK: 1.34.0 | ThoughtSpot: 10.3.0.cl
95
+ * @example
96
+ * ```js
97
+ * const embed = new SearchEmbed('#tsEmbed', {
98
+ * ... // other options
99
+ * collapseDataPanel:true,
100
+ * })
101
+ * ```
102
+ */
103
+ collapseDataPanel?: boolean;
91
104
  /**
92
105
  * Show or hide the data sources panel.
93
106
  * @version: SDK: 1.2.0 | ThoughtSpot: 9.1.0.sw
@@ -216,7 +229,7 @@ export interface SearchViewConfig
216
229
  hideSearchBar?: boolean;
217
230
  /**
218
231
  * Flag to control Data panel experience
219
- * @default false
232
+ * @default true
220
233
  * @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
221
234
  * @example
222
235
  * ```js
@@ -236,6 +249,7 @@ export interface SearchViewConfig
236
249
  * To set the initial state of the search bar in case of saved-answers.
237
250
  * @default false
238
251
  * @version SDK: 1.32.0 | Thoughtspot: 10.0.0.cl
252
+ * @deprecated Use {@link collapseSearchBar} instead
239
253
  */
240
254
  collapseSearchBarInitially?: boolean;
241
255
  /**
@@ -320,7 +334,8 @@ export class SearchEmbed extends TsEmbed {
320
334
  */
321
335
  private getDataSourceMode() {
322
336
  let dataSourceMode = DataSourceVisualMode.Expanded;
323
- if (this.viewConfig.collapseDataSources === true) {
337
+ if (this.viewConfig.collapseDataSources === true
338
+ || this.viewConfig.collapseDataPanel === true) {
324
339
  dataSourceMode = DataSourceVisualMode.Collapsed;
325
340
  }
326
341
  if (this.viewConfig.hideDataSources === true) {
@@ -341,7 +356,7 @@ export class SearchEmbed extends TsEmbed {
341
356
  dataSources,
342
357
  excludeRuntimeFiltersfromURL,
343
358
  hideSearchBar,
344
- dataPanelV2 = false,
359
+ dataPanelV2 = true,
345
360
  useLastSelectedSources = false,
346
361
  runtimeParameters,
347
362
  collapseSearchBarInitially = false,
@@ -351,6 +366,7 @@ export class SearchEmbed extends TsEmbed {
351
366
  dataPanelCustomGroupsAccordionInitialState = DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL,
352
367
  focusSearchBarOnRender = true,
353
368
  excludeRuntimeParametersfromURL,
369
+ collapseSearchBar = true,
354
370
  } = this.viewConfig;
355
371
  const queryParams = this.getBaseQueryParams();
356
372
 
@@ -406,7 +422,8 @@ export class SearchEmbed extends TsEmbed {
406
422
  }
407
423
 
408
424
  queryParams[Param.searchEmbed] = true;
409
- queryParams[Param.CollapseSearchBarInitially] = collapseSearchBarInitially;
425
+ /* eslint-disable-next-line max-len */
426
+ queryParams[Param.CollapseSearchBarInitially] = collapseSearchBarInitially || collapseSearchBar;
410
427
  queryParams[Param.EnableCustomColumnGroups] = enableCustomColumnGroups;
411
428
  if (dataPanelCustomGroupsAccordionInitialState
412
429
  === DataPanelCustomColumnGroupsAccordionState.COLLAPSE_ALL
@@ -59,6 +59,7 @@ import {
59
59
  } from './base';
60
60
  import { AuthFailureType } from '../auth';
61
61
  import { getEmbedConfig } from './embedConfig';
62
+ import { ERROR_MESSAGE } from '../errors';
62
63
 
63
64
  const { version } = pkgInfo;
64
65
 
@@ -347,7 +348,7 @@ export class TsEmbed {
347
348
  data: { authToken },
348
349
  });
349
350
  } catch (e) {
350
- logger.error(`Received invalid token. Error : ${e?.message}`);
351
+ logger.error(`${ERROR_MESSAGE.INVALID_TOKEN_ERROR} Error : ${e?.message}`);
351
352
  processAuthFailure(e, this.isPreRendered ? this.preRenderWrapper : this.el);
352
353
  }
353
354
  } else if (autoLogin) {
@@ -387,7 +388,9 @@ export class TsEmbed {
387
388
  * @param queryParams
388
389
  * @returns queryParams
389
390
  */
390
- protected getBaseQueryParams(queryParams = {}) {
391
+ protected getBaseQueryParams(
392
+ queryParams: Record<any, any> = {},
393
+ ) {
391
394
  let hostAppUrl = window?.location?.host || '';
392
395
 
393
396
  // The below check is needed because TS Cloud firewall, blocks
@@ -438,6 +441,7 @@ export class TsEmbed {
438
441
  contextMenuTrigger,
439
442
  linkOverride,
440
443
  insertInToSlide,
444
+ disableRedirectionLinksInNewTab,
441
445
  } = this.viewConfig;
442
446
 
443
447
  if (Array.isArray(visibleActions) && Array.isArray(hiddenActions)) {
@@ -505,6 +509,9 @@ export class TsEmbed {
505
509
  if (insertInToSlide) {
506
510
  queryParams[Param.ShowInsertToSlide] = insertInToSlide;
507
511
  }
512
+ if (disableRedirectionLinksInNewTab) {
513
+ queryParams[Param.DisableRedirectionLinksInNewTab] = disableRedirectionLinksInNewTab;
514
+ }
508
515
 
509
516
  queryParams[Param.OverrideNativeConsole] = true;
510
517
  queryParams[Param.ClientLogLevel] = this.embedConfig.logLevel;
@@ -557,7 +564,7 @@ export class TsEmbed {
557
564
  iFrame.mozallowfullscreen = true;
558
565
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
559
566
  // @ts-ignore
560
- iFrame.allow = 'clipboard-read; clipboard-write';
567
+ iFrame.allow = 'clipboard-read; clipboard-write fullscreen';
561
568
 
562
569
  const {
563
570
  height: frameHeight,
@@ -1000,7 +1007,7 @@ export class TsEmbed {
1000
1007
  */
1001
1008
  public preRender(showPreRenderByDefault = false): TsEmbed {
1002
1009
  if (!this.viewConfig.preRenderId) {
1003
- logger.error('PreRender id is required for preRender');
1010
+ logger.error(ERROR_MESSAGE.PRERENDER_ID_MISSING);
1004
1011
  return this;
1005
1012
  }
1006
1013
  this.isPreRendered = true;
@@ -1107,7 +1114,7 @@ export class TsEmbed {
1107
1114
  */
1108
1115
  public showPreRender(): void {
1109
1116
  if (!this.viewConfig.preRenderId) {
1110
- logger.error('PreRender id is required for preRender');
1117
+ logger.error(ERROR_MESSAGE.PRERENDER_ID_MISSING);
1111
1118
  return;
1112
1119
  }
1113
1120
  if (!this.isPreRenderAvailable()) {
@@ -1155,7 +1162,7 @@ export class TsEmbed {
1155
1162
  */
1156
1163
  public syncPreRenderStyle(): void {
1157
1164
  if (!this.isPreRenderAvailable() || !this.el) {
1158
- logger.error('PreRender should be called before using syncPreRenderStyle');
1165
+ logger.error(ERROR_MESSAGE.SYNC_STYLE_CALLED_BEFORE_RENDER);
1159
1166
  return;
1160
1167
  }
1161
1168
  const elBoundingClient = this.el.getBoundingClientRect();
package/src/errors.ts CHANGED
@@ -4,4 +4,15 @@ export const ERROR_MESSAGE = {
4
4
  TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
5
5
  SEARCHEMBED_BETA_WRANING_MESSAGE: 'Search Embed is in Beta in this release.',
6
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.',
9
+ SDK_NOT_INITIALIZED: 'SDK not initialized',
10
+ SESSION_INFO_FAILED: 'Failed to get session info',
11
+ INVALID_TOKEN_ERROR: 'Received invalid token from getAuthToken callback or authToken endpoint.',
12
+ MIXPANEL_TOKEN_NOT_FOUND: 'Mixpanel token not found in session info',
13
+ PRERENDER_ID_MISSING: 'PreRender id is required for preRender',
14
+ SYNC_STYLE_CALLED_BEFORE_RENDER: 'PreRender should be called before using syncPreRenderStyle',
15
+ 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
+ MISSING_REPORTING_OBSERVER: 'ReportingObserver not supported',
7
18
  };
@@ -1,6 +1,7 @@
1
1
  import * as mixpanel from 'mixpanel-browser';
2
2
  import { logger } from './utils/logger';
3
3
  import { SessionInfo } from './utils/sessionInfoService';
4
+ import { ERROR_MESSAGE } from './errors';
4
5
 
5
6
  export const EndPoints = {
6
7
  CONFIG: '/callosum/v1/system/config',
@@ -57,7 +58,7 @@ function emptyQueue() {
57
58
  */
58
59
  export function initMixpanel(sessionInfo: SessionInfo): void {
59
60
  if (!sessionInfo || !sessionInfo.mixpanelToken) {
60
- logger.error('Mixpanel token not found in session info');
61
+ logger.error(ERROR_MESSAGE.MIXPANEL_TOKEN_NOT_FOUND);
61
62
  return;
62
63
  }
63
64
  // On a public cluster the user is anonymous, so don't set the identify to
@@ -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=false&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true&collapseSearchBarInitially=false&enableCustomColumnGroups=false&dataPanelCustomGroupsAccordionInitialState=EXPAND_ALL#/embed/answer`,
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`,
60
60
  );
61
61
  });
62
62
 
package/src/types.ts CHANGED
@@ -201,6 +201,10 @@ export enum HomeLeftNavItem {
201
201
  * @version SDK: 1.28.0| ThoughtSpot: 9.12.5.cl
202
202
  */
203
203
  SpotIQAnalysis = 'spotiq-analysis',
204
+ /**
205
+ * @version SDK: 1.34.0| ThoughtSpot: 10.3.0.cl
206
+ */
207
+ LiveboardSchedules = 'liveboard-schedules'
204
208
  }
205
209
  export type DOMSelector = string | HTMLElement;
206
210
 
@@ -588,7 +592,7 @@ export interface EmbedConfig {
588
592
  }
589
593
 
590
594
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
591
- export interface LayoutConfig { }
595
+ export interface LayoutConfig {}
592
596
 
593
597
  /**
594
598
  * Embedded iframe configuration
@@ -1012,6 +1016,30 @@ export interface ViewConfig {
1012
1016
  */
1013
1017
  // eslint-disable-next-line camelcase
1014
1018
  enableV2Shell_experimental?: boolean;
1019
+ /**
1020
+ * To set the initial state of the search bar in case of saved-answers.
1021
+ * @default true
1022
+ * @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
1023
+ * @example
1024
+ * ```js
1025
+ * const embed = new LiveboardEmbed('#embed', {
1026
+ * liveboardId: '123',
1027
+ * collapseSearchBar: true
1028
+ * });
1029
+ */
1030
+ collapseSearchBar?: boolean;
1031
+ /**
1032
+ * This flag can be used to disable links inside the embedded app,
1033
+ * and disables redirection of links in a new tab.
1034
+ * @example
1035
+ * ```js
1036
+ * const embed = new LiveboardEmbed('#embed', {
1037
+ * disableRedirectionLinksInNewTab: true
1038
+ * });
1039
+ * ```
1040
+ * @version SDK: 1.32.1 | ThoughtSpot: 10.3.0.cl
1041
+ */
1042
+ disableRedirectionLinksInNewTab?: boolean;
1015
1043
  }
1016
1044
 
1017
1045
  /**
@@ -2493,13 +2521,15 @@ export enum HostEvent {
2493
2521
  *
2494
2522
  * @example
2495
2523
  * ```js
2496
- * appEmbed.trigger(HostEvent.CreateMonitor)
2524
+ * searchEmbed.trigger(HostEvent.CreateMonitor)
2497
2525
  * ```
2498
2526
  * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
2499
2527
  */
2500
2528
  CreateMonitor = 'createMonitor',
2501
2529
  /**
2502
- * Trigger the **Manage alerts** action on a visualization
2530
+ * Trigger the **Manage alerts** action on a KPI chart
2531
+ * in a visualization or saved Answer.
2532
+ *
2503
2533
  * @param - an object with `vizId` as a key
2504
2534
  * @example
2505
2535
  * ```js
@@ -2507,6 +2537,16 @@ export enum HostEvent {
2507
2537
  * vizId: '730496d6-6903-4601-937e-2c691821af3c'
2508
2538
  * })
2509
2539
  * ```
2540
+ *
2541
+ * @example
2542
+ * ```js
2543
+ * searchEmbed.trigger(HostEvent.ManageMonitor)
2544
+ * ```
2545
+ *
2546
+ * @example
2547
+ * ```js
2548
+ * vizEmbed.trigger(HostEvent.ManageMonitor)
2549
+ * ```
2510
2550
  * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
2511
2551
  */
2512
2552
  ManageMonitor = 'manageMonitor',
@@ -3084,6 +3124,8 @@ export enum Param {
3084
3124
  IsFullAppEmbed = 'isFullAppEmbed',
3085
3125
  IsOnBeforeGetVizDataInterceptEnabled = 'isOnBeforeGetVizDataInterceptEnabled',
3086
3126
  FocusSearchBarOnRender = 'focusSearchBarOnRender',
3127
+ DisableRedirectionLinksInNewTab = 'disableRedirectionLinksInNewTab',
3128
+ HomePageSearchBarMode = 'homePageSearchBarMode',
3087
3129
  }
3088
3130
 
3089
3131
  /**
@@ -3234,6 +3276,7 @@ export enum Action {
3234
3276
  */
3235
3277
  ConfigureFilter = 'configureFilter',
3236
3278
  CollapseDataSources = 'collapseDataSources',
3279
+ CollapseDataPanel = 'collapseDataPanel',
3237
3280
  /**
3238
3281
  * The **Choose sources** button on Search page.
3239
3282
  * Allows selecting data sources for search queries.
@@ -3630,12 +3673,15 @@ export enum Action {
3630
3673
  * The Create alert action on KPI charts.
3631
3674
  * @example
3632
3675
  * ```js
3633
- * disabledActions: [Action.CreateMonitor ]
3676
+ * disabledActions: [Action.CreateMonitor]
3634
3677
  * ```
3635
3678
  * @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
3636
3679
  */
3637
3680
  CreateMonitor = 'createMonitor',
3638
3681
  /**
3682
+ * @deprecated
3683
+ * Reports errors
3684
+ *
3639
3685
  * @example
3640
3686
  * ```js
3641
3687
  * disabledActions: [Action.ReportError]
@@ -3860,35 +3906,84 @@ export enum Action {
3860
3906
  */
3861
3907
  RenameModalTitleDescription = 'renameModalTitleDescription',
3862
3908
  /**
3909
+ *
3910
+ * @example
3911
+ * ```js
3912
+ * disabledActions: [Action.RequestVerification]
3913
+ * ```
3863
3914
  *
3864
3915
  * @version SDK: 1.25.0 | Thoughtspot: 9.6.0.cl
3865
3916
  */
3866
3917
  RequestVerification = 'requestVerification',
3867
3918
  /**
3919
+ *
3920
+ * Allows users to mark a Liveboard as verified.
3921
+ *
3922
+ * @example
3923
+ * ```js
3924
+ * disabledActions: [Action.MarkAsVerified]
3925
+ * ```
3868
3926
  * @version SDK: 1.25.0 | Thoughtspot: 9.6.0.cl
3869
3927
  */
3870
3928
  MarkAsVerified = 'markAsVerified',
3871
3929
  /**
3930
+ * The **Add Tab** action on a Liveboard.
3931
+ * Allows adding a new tab to a Liveboard view.
3932
+ *
3933
+ * @example
3934
+ * ```js
3935
+ * disabledActions: [Action.AddTab]
3936
+ * ```
3872
3937
  * @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
3873
3938
  */
3874
3939
  AddTab = 'addTab',
3875
3940
  /**
3941
+ *
3942
+ * Initiates contextual change analysis on KPI charts.
3943
+ *
3944
+ * @example
3945
+ * ```js
3946
+ * disabledActions: [Action.EnableContextualChangeAnalysis]
3947
+ * ```
3876
3948
  * @version SDK: 1.25.0 | Thoughtspot: 9.6.0.cl
3877
3949
  */
3878
3950
  EnableContextualChangeAnalysis = 'enableContextualChangeAnalysis',
3879
3951
  /**
3952
+ *
3953
+ * @example
3954
+ * ```js
3955
+ * disabledActions: [Action.ShowSageQuery]
3956
+ * ```
3957
+ *
3880
3958
  * @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
3881
3959
  */
3882
3960
  ShowSageQuery = 'showSageQuery',
3883
3961
  /**
3962
+ *
3963
+ * @example
3964
+ * ```js
3965
+ * disabledActions: [Action.EditSageAnswer]
3966
+ * ```
3884
3967
  * @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
3885
3968
  */
3886
3969
  EditSageAnswer = 'editSageAnswer',
3887
3970
  /**
3971
+ *
3972
+ * This action allows users to send feedback on AI-generated Answers.
3973
+ *
3974
+ * @example
3975
+ * ```js
3976
+ * disabledActions: [Action.SageAnswerFeedback]
3977
+ * ```
3888
3978
  * @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
3889
3979
  */
3890
3980
  SageAnswerFeedback = 'sageAnswerFeedback',
3891
3981
  /**
3982
+ *
3983
+ * @example
3984
+ * ```js
3985
+ * disabledActions: [Action.ModifySageAnswer]
3986
+ * ```
3892
3987
  * @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
3893
3988
  */
3894
3989
  ModifySageAnswer = 'modifySageAnswer',
@@ -4018,6 +4113,66 @@ export enum Action {
4018
4113
  * @version SDK: 1.27.10 | Thoughtspot: 9.12.5.cl
4019
4114
  */
4020
4115
  AIHighlights = 'AIHighlights',
4116
+
4117
+ /**
4118
+ * Action ID for edit schedule action on schedule on homepage
4119
+ * @example
4120
+ * ```js
4121
+ * disabledActions: [Action.EditScheduleHomepage]
4122
+ * ```
4123
+ * @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
4124
+ */
4125
+ EditScheduleHomepage = 'editScheduleHomepage',
4126
+
4127
+ /**
4128
+ * Action ID for pause schedule action on schedule on homepage
4129
+ * @example
4130
+ * ```js
4131
+ * disabledActions: [Action.PauseScheduleHomepage]
4132
+ * ```
4133
+ * @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
4134
+ */
4135
+ PauseScheduleHomepage = 'pauseScheduleHomepage',
4136
+
4137
+ /**
4138
+ * Action ID for view schedule run action on schedule on homepage
4139
+ * @example
4140
+ * ```js
4141
+ * disabledActions: [Action.ViewScheduleRunHomepage]
4142
+ * ```
4143
+ * @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
4144
+ */
4145
+ ViewScheduleRunHomepage = 'viewScheduleRunHomepage',
4146
+
4147
+ /**
4148
+ * Action ID for unsubscribe schedule action on schedule on homepage
4149
+ * @example
4150
+ * ```js
4151
+ * disabledActions: [Action.UnsubscribeScheduleHomepage]
4152
+ * ```
4153
+ * @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
4154
+ */
4155
+ UnsubscribeScheduleHomepage = 'unsubscribeScheduleHomepage',
4156
+
4157
+ /**
4158
+ * Action ID for delete schedule action on schedule on homepage
4159
+ * @example
4160
+ * ```js
4161
+ * disabledActions: [Action.DeleteScheduleHomepage]
4162
+ * ```
4163
+ * @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
4164
+ */
4165
+ DeleteScheduleHomepage = 'deleteScheduleHomepage',
4166
+
4167
+ /**
4168
+ * The **Analyze CTA** action on KPI chart.
4169
+ * @example
4170
+ * ```js
4171
+ * disabledActions: [Action.KPIAnalysisCTA]
4172
+ * ```
4173
+ * @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
4174
+ */
4175
+ KPIAnalysisCTA = 'kpiAnalysisCTA',
4021
4176
  }
4022
4177
 
4023
4178
  export interface AnswerServiceType {
@@ -4047,15 +4202,15 @@ export interface ColumnValue {
4047
4202
  [key: string]: any;
4048
4203
  };
4049
4204
  value:
4050
- | string
4051
- | number
4052
- | boolean
4053
- | {
4054
- v: {
4055
- s: number;
4056
- e: number;
4057
- };
4058
- };
4205
+ | string
4206
+ | number
4207
+ | boolean
4208
+ | {
4209
+ v: {
4210
+ s: number;
4211
+ e: number;
4212
+ };
4213
+ };
4059
4214
  }
4060
4215
 
4061
4216
  export interface VizPoint {
@@ -9,6 +9,7 @@ import { AuthFailureType } from '../auth';
9
9
  import { AuthType, CustomActionPayload, EmbedEvent } from '../types';
10
10
  import { AnswerService } from './graphql/answerService/answerService';
11
11
  import { resetCachedAuthToken } from '../authToken';
12
+ import { ERROR_MESSAGE } from '../errors';
12
13
 
13
14
  /**
14
15
  *
@@ -62,9 +63,7 @@ function processNoCookieAccess(e: any, containerEl: Element) {
62
63
  if (!ignoreNoCookieAccess) {
63
64
  if (!suppressNoCookieAccessAlert && !suppressErrorAlerts) {
64
65
  // eslint-disable-next-line no-alert
65
- alert(
66
- '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.',
67
- );
66
+ alert(ERROR_MESSAGE.THIRD_PARTY_COOKIE_BLOCKED_ALERT);
68
67
  }
69
68
  // eslint-disable-next-line no-param-reassign
70
69
  containerEl.innerHTML = loginFailedMessage;
@@ -0,0 +1,91 @@
1
+ import { setEmbedConfig } from '../embed/embedConfig';
2
+ import { registerReportingObserver, getGlobalReportingObserver, resetGlobalReportingObserver } from './reporting';
3
+ import { logger } from './logger';
4
+ import { AuthType } from '../types';
5
+ import { ERROR_MESSAGE } from '../errors';
6
+
7
+ jest.mock('./logger');
8
+
9
+ describe('ReportingObserver', () => {
10
+ let mockReportingObserver: jest.Mock;
11
+
12
+ beforeAll(() => {
13
+ // Mock the ReportingObserver
14
+ mockReportingObserver = jest.fn().mockImplementation((callback: any, options: any) => ({
15
+ observe: jest.fn(),
16
+ disconnect: jest.fn(),
17
+ takeRecords: jest.fn(),
18
+ }));
19
+ (window as any).ReportingObserver = mockReportingObserver;
20
+ });
21
+
22
+ afterEach(() => {
23
+ jest.clearAllMocks();
24
+ resetGlobalReportingObserver();
25
+ });
26
+
27
+ test('should warn if ReportingObserver is not supported', () => {
28
+ (window as any).ReportingObserver = undefined;
29
+ const observer = registerReportingObserver();
30
+ expect(observer).toBeNull();
31
+ expect(logger.warn).toHaveBeenCalledWith('ReportingObserver not supported');
32
+ (window as any).ReportingObserver = mockReportingObserver;
33
+ });
34
+
35
+ test('should return existing globalObserver if override is false', () => {
36
+ const firstObserver = registerReportingObserver();
37
+ const secondObserver = registerReportingObserver();
38
+ expect(firstObserver === secondObserver).toBe(true);
39
+ });
40
+
41
+ test('should override existing globalObserver if override is true', () => {
42
+ const firstObserver = registerReportingObserver();
43
+ const secondObserver = registerReportingObserver(true);
44
+ expect(firstObserver).not.toBe(secondObserver);
45
+ });
46
+
47
+ test('should return globalObserver', () => {
48
+ const observer = registerReportingObserver();
49
+ const globalObserver = getGlobalReportingObserver();
50
+ expect(globalObserver).toBe(observer);
51
+ });
52
+
53
+ test('Should register a global observer with callback', () => {
54
+ let callBackPassed: any;
55
+
56
+ // Mock the ReportingObserver
57
+ const NewMockRO = jest.fn().mockImplementation((callback: any, options: any) => {
58
+ callBackPassed = callback;
59
+ return ({
60
+ observe: jest.fn(),
61
+ disconnect: jest.fn(),
62
+ takeRecords: jest.fn(),
63
+ });
64
+ });
65
+ const currentObserver = (window as any).ReportingObserver;
66
+ (window as any).ReportingObserver = NewMockRO;
67
+
68
+ setEmbedConfig({
69
+ thoughtSpotHost: 'testHost',
70
+ authType: AuthType.None,
71
+ });
72
+
73
+ const mockAlert = jest.fn();
74
+ window.alert = mockAlert;
75
+
76
+ const observer = registerReportingObserver();
77
+ expect(observer).toBeDefined();
78
+ expect(NewMockRO).toHaveBeenCalled();
79
+ expect(callBackPassed).toBeDefined();
80
+
81
+ // call the callback
82
+ callBackPassed([{ type: 'csp-violation', url: 'testHost', body: { effectiveDirective: 'frame-ancestors' } }]);
83
+
84
+ expect(mockAlert).toHaveBeenCalledWith(ERROR_MESSAGE.CSP_VIOLATION_ALERT);
85
+ expect(logger.error).toHaveBeenCalledWith(
86
+ ERROR_MESSAGE.CSP_FRAME_HOST_VIOLATION_LOG_MESSAGE,
87
+ );
88
+
89
+ (window as any).ReportingObserver = currentObserver;
90
+ });
91
+ });
@@ -0,0 +1,71 @@
1
+ import { getEmbedConfig } from '../embed/embedConfig';
2
+ import { logger } from './logger';
3
+ import { ERROR_MESSAGE } from '../errors';
4
+
5
+ enum ReportType {
6
+ CSP_VIOLATION = 'csp-violation',
7
+ DEPRECATION = 'deprecation',
8
+ INTERVENTION = 'intervention',
9
+ }
10
+
11
+ let globalObserver: ReportingObserver | null = null;
12
+
13
+ /**
14
+ * Register a global ReportingObserver to capture all unhandled errors
15
+ * @param overrideExisting boolean to override existing observer
16
+ * @returns ReportingObserver | null
17
+ */
18
+ export function registerReportingObserver(overrideExisting = false): ReportingObserver | null {
19
+ if (!((window as any).ReportingObserver)) {
20
+ logger.warn(ERROR_MESSAGE.MISSING_REPORTING_OBSERVER);
21
+ return null;
22
+ }
23
+
24
+ if (overrideExisting) {
25
+ resetGlobalReportingObserver();
26
+ }
27
+
28
+ if (globalObserver) {
29
+ return globalObserver;
30
+ }
31
+
32
+ const embedConfig = getEmbedConfig();
33
+
34
+ globalObserver = new ReportingObserver((reports) => {
35
+ reports.forEach((report) => {
36
+ const { type, url, body } = report;
37
+ const reportBody = body as any;
38
+
39
+ const isThoughtSpotHost = url
40
+ && url.startsWith(embedConfig.thoughtSpotHost);
41
+
42
+ const isFrameHostError = type === ReportType.CSP_VIOLATION
43
+ && reportBody.effectiveDirective === 'frame-ancestors';
44
+
45
+ if (isThoughtSpotHost && isFrameHostError) {
46
+ if (!embedConfig.suppressErrorAlerts) {
47
+ alert(ERROR_MESSAGE.CSP_VIOLATION_ALERT);
48
+ }
49
+ logger.error(ERROR_MESSAGE.CSP_FRAME_HOST_VIOLATION_LOG_MESSAGE);
50
+ }
51
+ });
52
+ }, { buffered: true });
53
+ globalObserver.observe();
54
+ return globalObserver;
55
+ }
56
+
57
+ /**
58
+ * Get the global ReportingObserver
59
+ * @returns - ReportingObserver | null
60
+ */
61
+ export function getGlobalReportingObserver(): ReportingObserver | null {
62
+ return globalObserver;
63
+ }
64
+
65
+ /**
66
+ * Resets the global ReportingObserver
67
+ */
68
+ export function resetGlobalReportingObserver(): void {
69
+ if (globalObserver) globalObserver.disconnect();
70
+ globalObserver = null;
71
+ }