@thoughtspot/visual-embed-sdk 1.48.0 → 1.49.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 (201) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/css-variables.d.ts +140 -0
  3. package/cjs/src/css-variables.d.ts.map +1 -1
  4. package/cjs/src/embed/app.d.ts +62 -1
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js +57 -6
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +191 -1
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/auto-frame-renderer.js +7 -2
  11. package/cjs/src/embed/auto-frame-renderer.js.map +1 -1
  12. package/cjs/src/embed/auto-frame-renderer.spec.js +385 -6
  13. package/cjs/src/embed/auto-frame-renderer.spec.js.map +1 -1
  14. package/cjs/src/embed/base.d.ts +1 -0
  15. package/cjs/src/embed/base.d.ts.map +1 -1
  16. package/cjs/src/embed/base.js +13 -1
  17. package/cjs/src/embed/base.js.map +1 -1
  18. package/cjs/src/embed/base.spec.js +21 -0
  19. package/cjs/src/embed/base.spec.js.map +1 -1
  20. package/cjs/src/embed/bodyless-conversation.spec.js +86 -0
  21. package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
  22. package/cjs/src/embed/conversation.d.ts +16 -1
  23. package/cjs/src/embed/conversation.d.ts.map +1 -1
  24. package/cjs/src/embed/conversation.js +5 -1
  25. package/cjs/src/embed/conversation.js.map +1 -1
  26. package/cjs/src/embed/conversation.spec.js +26 -0
  27. package/cjs/src/embed/conversation.spec.js.map +1 -1
  28. package/cjs/src/embed/liveboard.d.ts +47 -1
  29. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  30. package/cjs/src/embed/liveboard.js +47 -6
  31. package/cjs/src/embed/liveboard.js.map +1 -1
  32. package/cjs/src/embed/liveboard.spec.js +129 -1
  33. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  34. package/cjs/src/embed/spotter-viz-utils.d.ts +85 -0
  35. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -0
  36. package/cjs/src/embed/spotter-viz-utils.js +17 -0
  37. package/cjs/src/embed/spotter-viz-utils.js.map +1 -0
  38. package/cjs/src/embed/spotter-viz-utils.spec.d.ts +2 -0
  39. package/cjs/src/embed/spotter-viz-utils.spec.d.ts.map +1 -0
  40. package/cjs/src/embed/spotter-viz-utils.spec.js +31 -0
  41. package/cjs/src/embed/spotter-viz-utils.spec.js.map +1 -0
  42. package/cjs/src/embed/ts-embed.d.ts +58 -38
  43. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  44. package/cjs/src/embed/ts-embed.js +245 -149
  45. package/cjs/src/embed/ts-embed.js.map +1 -1
  46. package/cjs/src/embed/ts-embed.spec.js +369 -123
  47. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  48. package/cjs/src/index.d.ts +2 -1
  49. package/cjs/src/index.d.ts.map +1 -1
  50. package/cjs/src/index.js.map +1 -1
  51. package/cjs/src/react/index.d.ts.map +1 -1
  52. package/cjs/src/react/index.js +3 -0
  53. package/cjs/src/react/index.js.map +1 -1
  54. package/cjs/src/types.d.ts +267 -27
  55. package/cjs/src/types.d.ts.map +1 -1
  56. package/cjs/src/types.js +223 -19
  57. package/cjs/src/types.js.map +1 -1
  58. package/cjs/src/utils/authService/tokenizedAuthService.spec.js +6 -7
  59. package/cjs/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
  60. package/cjs/src/utils/logger.js +2 -1
  61. package/cjs/src/utils/logger.js.map +1 -1
  62. package/cjs/src/utils/logger.spec.d.ts +1 -0
  63. package/cjs/src/utils/logger.spec.d.ts.map +1 -1
  64. package/cjs/src/utils/logger.spec.js +10 -9
  65. package/cjs/src/utils/logger.spec.js.map +1 -1
  66. package/cjs/src/utils.d.ts +4 -1
  67. package/cjs/src/utils.d.ts.map +1 -1
  68. package/cjs/src/utils.js +107 -10
  69. package/cjs/src/utils.js.map +1 -1
  70. package/cjs/src/utils.spec.js +163 -4
  71. package/cjs/src/utils.spec.js.map +1 -1
  72. package/dist/{index-Ck-r09gt.js → index-_UGCSSDR.js} +1 -1
  73. package/dist/src/css-variables.d.ts +140 -0
  74. package/dist/src/css-variables.d.ts.map +1 -1
  75. package/dist/src/embed/app.d.ts +62 -1
  76. package/dist/src/embed/app.d.ts.map +1 -1
  77. package/dist/src/embed/base.d.ts +1 -0
  78. package/dist/src/embed/base.d.ts.map +1 -1
  79. package/dist/src/embed/conversation.d.ts +16 -1
  80. package/dist/src/embed/conversation.d.ts.map +1 -1
  81. package/dist/src/embed/liveboard.d.ts +47 -1
  82. package/dist/src/embed/liveboard.d.ts.map +1 -1
  83. package/dist/src/embed/spotter-viz-utils.d.ts +85 -0
  84. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -0
  85. package/dist/src/embed/spotter-viz-utils.spec.d.ts +2 -0
  86. package/dist/src/embed/spotter-viz-utils.spec.d.ts.map +1 -0
  87. package/dist/src/embed/ts-embed.d.ts +58 -38
  88. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  89. package/dist/src/index.d.ts +2 -1
  90. package/dist/src/index.d.ts.map +1 -1
  91. package/dist/src/react/index.d.ts.map +1 -1
  92. package/dist/src/types.d.ts +267 -27
  93. package/dist/src/types.d.ts.map +1 -1
  94. package/dist/src/utils/logger.spec.d.ts +1 -0
  95. package/dist/src/utils/logger.spec.d.ts.map +1 -1
  96. package/dist/src/utils.d.ts +4 -1
  97. package/dist/src/utils.d.ts.map +1 -1
  98. package/dist/tsembed-react.es.js +3708 -3226
  99. package/dist/tsembed-react.js +3358 -2876
  100. package/dist/tsembed.es.js +3713 -3229
  101. package/dist/tsembed.js +3708 -3224
  102. package/dist/visual-embed-sdk-react-full.d.ts +643 -63
  103. package/dist/visual-embed-sdk-react.d.ts +643 -63
  104. package/dist/visual-embed-sdk.d.ts +658 -65
  105. package/lib/package.json +1 -1
  106. package/lib/src/css-variables.d.ts +140 -0
  107. package/lib/src/css-variables.d.ts.map +1 -1
  108. package/lib/src/embed/app.d.ts +62 -1
  109. package/lib/src/embed/app.d.ts.map +1 -1
  110. package/lib/src/embed/app.js +58 -7
  111. package/lib/src/embed/app.js.map +1 -1
  112. package/lib/src/embed/app.spec.js +192 -2
  113. package/lib/src/embed/app.spec.js.map +1 -1
  114. package/lib/src/embed/auto-frame-renderer.js +7 -2
  115. package/lib/src/embed/auto-frame-renderer.js.map +1 -1
  116. package/lib/src/embed/auto-frame-renderer.spec.js +387 -8
  117. package/lib/src/embed/auto-frame-renderer.spec.js.map +1 -1
  118. package/lib/src/embed/base.d.ts +1 -0
  119. package/lib/src/embed/base.d.ts.map +1 -1
  120. package/lib/src/embed/base.js +11 -0
  121. package/lib/src/embed/base.js.map +1 -1
  122. package/lib/src/embed/base.spec.js +22 -1
  123. package/lib/src/embed/base.spec.js.map +1 -1
  124. package/lib/src/embed/bodyless-conversation.spec.js +86 -0
  125. package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
  126. package/lib/src/embed/conversation.d.ts +16 -1
  127. package/lib/src/embed/conversation.d.ts.map +1 -1
  128. package/lib/src/embed/conversation.js +5 -1
  129. package/lib/src/embed/conversation.js.map +1 -1
  130. package/lib/src/embed/conversation.spec.js +27 -1
  131. package/lib/src/embed/conversation.spec.js.map +1 -1
  132. package/lib/src/embed/liveboard.d.ts +47 -1
  133. package/lib/src/embed/liveboard.d.ts.map +1 -1
  134. package/lib/src/embed/liveboard.js +48 -7
  135. package/lib/src/embed/liveboard.js.map +1 -1
  136. package/lib/src/embed/liveboard.spec.js +129 -1
  137. package/lib/src/embed/liveboard.spec.js.map +1 -1
  138. package/lib/src/embed/spotter-viz-utils.d.ts +85 -0
  139. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -0
  140. package/lib/src/embed/spotter-viz-utils.js +13 -0
  141. package/lib/src/embed/spotter-viz-utils.js.map +1 -0
  142. package/lib/src/embed/spotter-viz-utils.spec.d.ts +2 -0
  143. package/lib/src/embed/spotter-viz-utils.spec.d.ts.map +1 -0
  144. package/lib/src/embed/spotter-viz-utils.spec.js +29 -0
  145. package/lib/src/embed/spotter-viz-utils.spec.js.map +1 -0
  146. package/lib/src/embed/ts-embed.d.ts +58 -38
  147. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  148. package/lib/src/embed/ts-embed.js +248 -152
  149. package/lib/src/embed/ts-embed.js.map +1 -1
  150. package/lib/src/embed/ts-embed.spec.js +369 -123
  151. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  152. package/lib/src/index.d.ts +2 -1
  153. package/lib/src/index.d.ts.map +1 -1
  154. package/lib/src/index.js.map +1 -1
  155. package/lib/src/react/index.d.ts.map +1 -1
  156. package/lib/src/react/index.js +3 -0
  157. package/lib/src/react/index.js.map +1 -1
  158. package/lib/src/types.d.ts +267 -27
  159. package/lib/src/types.d.ts.map +1 -1
  160. package/lib/src/types.js +223 -19
  161. package/lib/src/types.js.map +1 -1
  162. package/lib/src/utils/authService/tokenizedAuthService.spec.js +6 -7
  163. package/lib/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
  164. package/lib/src/utils/logger.js +2 -1
  165. package/lib/src/utils/logger.js.map +1 -1
  166. package/lib/src/utils/logger.spec.d.ts +1 -0
  167. package/lib/src/utils/logger.spec.d.ts.map +1 -1
  168. package/lib/src/utils/logger.spec.js +10 -9
  169. package/lib/src/utils/logger.spec.js.map +1 -1
  170. package/lib/src/utils.d.ts +4 -1
  171. package/lib/src/utils.d.ts.map +1 -1
  172. package/lib/src/utils.js +103 -9
  173. package/lib/src/utils.js.map +1 -1
  174. package/lib/src/utils.spec.js +164 -5
  175. package/lib/src/utils.spec.js.map +1 -1
  176. package/lib/src/visual-embed-sdk.d.ts +658 -65
  177. package/package.json +1 -1
  178. package/src/css-variables.ts +175 -1
  179. package/src/embed/app.spec.ts +247 -3
  180. package/src/embed/app.ts +125 -5
  181. package/src/embed/auto-frame-renderer.spec.ts +457 -58
  182. package/src/embed/auto-frame-renderer.ts +7 -2
  183. package/src/embed/base.spec.ts +25 -1
  184. package/src/embed/base.ts +19 -5
  185. package/src/embed/bodyless-conversation.spec.ts +93 -0
  186. package/src/embed/conversation.spec.ts +34 -0
  187. package/src/embed/conversation.ts +22 -1
  188. package/src/embed/liveboard.spec.ts +149 -1
  189. package/src/embed/liveboard.ts +102 -6
  190. package/src/embed/spotter-viz-utils.spec.ts +30 -0
  191. package/src/embed/spotter-viz-utils.ts +94 -0
  192. package/src/embed/ts-embed.spec.ts +532 -234
  193. package/src/embed/ts-embed.ts +383 -257
  194. package/src/index.ts +3 -0
  195. package/src/react/index.tsx +3 -0
  196. package/src/types.ts +284 -23
  197. package/src/utils/authService/tokenizedAuthService.spec.ts +6 -6
  198. package/src/utils/logger.spec.ts +11 -9
  199. package/src/utils/logger.ts +2 -2
  200. package/src/utils.spec.ts +200 -4
  201. package/src/utils.ts +128 -9
@@ -23,14 +23,26 @@ import {
23
23
  ErrorDetailsTypes,
24
24
  EmbedErrorCodes,
25
25
  ContextType,
26
+ DefaultAppInitData,
26
27
  } from '../types';
27
- import { calculateVisibleElementData, getQueryParamString, isUndefined, isValidCssMargin, setParamIfDefined } from '../utils';
28
+ import { calculateVisibleElementData, getEffectiveClippingAncestors, getQueryParamString, getScrollableAncestors, isUndefined, isValidCssMargin, setParamIfDefined } from '../utils';
28
29
  import { getAuthPromise } from './base';
29
30
  import { TsEmbed, V1Embed } from './ts-embed';
30
31
  import { addPreviewStylesIfNotPresent } from '../utils/global-styles';
31
32
  import { TriggerPayload, TriggerResponse } from './hostEventClient/contracts';
32
33
  import { logger } from '../utils/logger';
33
34
  import { SpotterChatViewConfig } from './conversation';
35
+ import { SpotterVizConfig, buildSpotterVizAppInitData } from './spotter-viz-utils';
36
+
37
+ /**
38
+ * APP_INIT data shape for LiveboardEmbed.
39
+ * @internal
40
+ */
41
+ export interface LiveboardEmbedAppInitData extends DefaultAppInitData {
42
+ embedParams?: {
43
+ spotterVizConfig?: SpotterVizConfig;
44
+ };
45
+ }
34
46
 
35
47
 
36
48
  /**
@@ -453,6 +465,16 @@ export interface LiveboardViewConfig extends BaseViewConfig, LiveboardOtherViewC
453
465
  * ```
454
466
  */
455
467
  lazyLoadingForFullHeight?: boolean;
468
+ /**
469
+ * This flag is used to enable container-aware full height lazy loading.
470
+ *
471
+ * Use this when the embed is rendered inside a scrollable or clipping
472
+ * container instead of relying on the browser window as the only viewport.
473
+ *
474
+ * @type {boolean}
475
+ * @default false
476
+ */
477
+ enableScrollableContainerLazyLoading?: boolean;
456
478
  /**
457
479
  * The margin to be used for lazy loading.
458
480
  *
@@ -534,6 +556,29 @@ export interface LiveboardViewConfig extends BaseViewConfig, LiveboardOtherViewC
534
556
  * ```
535
557
  */
536
558
  spotterChatConfig?: SpotterChatViewConfig;
559
+ /**
560
+ * Configuration for the SpotterViz interface shown on the Liveboard.
561
+ * Customize the brand name, description, chat input placeholder,
562
+ * starter prompts, and visibility of starter prompts in the SpotterViz panel.
563
+ *
564
+ * Supported embed types: `AppEmbed`, `LiveboardEmbed`
565
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
566
+ * @example
567
+ * ```js
568
+ * const embed = new LiveboardEmbed('#embed-container', {
569
+ * ... // other options
570
+ * spotterViz: {
571
+ * brandName: 'MyBrand',
572
+ * brandHeadline: 'Hi, there! I\'m',
573
+ * description: 'Ask questions about your data',
574
+ * inputChatPlaceholder: 'Ask a question...',
575
+ * hideStarterPrompts: false,
576
+ * customStarterPrompts: [{ id: '1', displayText: 'Top products', fullPrompt: 'What are the top products by revenue?' }],
577
+ * },
578
+ * })
579
+ * ```
580
+ */
581
+ spotterViz?: SpotterVizConfig;
537
582
  /**
538
583
  * If set to true, enables visualization data caching on the Liveboard.
539
584
  * @type {boolean}
@@ -569,6 +614,10 @@ export class LiveboardEmbed extends V1Embed {
569
614
 
570
615
  private defaultHeight = 500;
571
616
 
617
+ private lazyLoadScrollContainers: HTMLElement[] = [];
618
+
619
+ private lazyLoadResizeObserver: ResizeObserver | undefined;
620
+
572
621
 
573
622
  constructor(domSelector: DOMSelector, viewConfig: LiveboardViewConfig) {
574
623
  viewConfig.embedComponentType = 'LiveboardEmbed';
@@ -586,6 +635,11 @@ export class LiveboardEmbed extends V1Embed {
586
635
  }
587
636
  }
588
637
 
638
+ protected async getAppInitData(): Promise<LiveboardEmbedAppInitData> {
639
+ const defaultAppInitData = await super.getAppInitData();
640
+ return buildSpotterVizAppInitData(defaultAppInitData, this.viewConfig);
641
+ }
642
+
589
643
  /**
590
644
  * Construct a map of params to be passed on to the
591
645
  * embedded Liveboard or visualization.
@@ -735,10 +789,18 @@ export class LiveboardEmbed extends V1Embed {
735
789
  const {
736
790
  hideToolResponseCardBranding,
737
791
  toolResponseCardBrandingLabel,
792
+ spotterFileUploadEnabled,
793
+ spotterFileUploadFileTypes,
738
794
  } = spotterChatConfig;
739
795
 
740
796
  setParamIfDefined(params, Param.HideToolResponseCardBranding, hideToolResponseCardBranding, true);
741
797
  setParamIfDefined(params, Param.ToolResponseCardBrandingLabel, toolResponseCardBrandingLabel);
798
+ if (spotterFileUploadEnabled !== undefined) {
799
+ params[Param.SpotterFileUploadEnabled] = spotterFileUploadEnabled;
800
+ }
801
+ if (spotterFileUploadFileTypes !== undefined) {
802
+ params[Param.SpotterFileUploadFileTypes] = JSON.stringify(spotterFileUploadFileTypes);
803
+ }
742
804
  }
743
805
 
744
806
  if (isLinkParametersEnabled !== undefined) {
@@ -825,7 +887,10 @@ export class LiveboardEmbed extends V1Embed {
825
887
  }
826
888
 
827
889
  private sendFullHeightLazyLoadData = () => {
828
- const data = calculateVisibleElementData(this.iFrame);
890
+ const data = calculateVisibleElementData(
891
+ this.iFrame,
892
+ this.viewConfig.enableScrollableContainerLazyLoading,
893
+ );
829
894
  // this should be fired only if the lazyLoadingForFullHeight and fullHeight are true
830
895
  if(this.viewConfig.lazyLoadingForFullHeight && this.viewConfig.fullHeight){
831
896
  this.trigger(HostEvent.VisibleEmbedCoordinates, data);
@@ -840,7 +905,10 @@ export class LiveboardEmbed extends V1Embed {
840
905
  */
841
906
  private requestVisibleEmbedCoordinatesHandler = (data: MessagePayload, responder: any) => {
842
907
  logger.info('Sending RequestVisibleEmbedCoordinates', data);
843
- const visibleCoordinatesData = calculateVisibleElementData(this.iFrame);
908
+ const visibleCoordinatesData = calculateVisibleElementData(
909
+ this.iFrame,
910
+ this.viewConfig.enableScrollableContainerLazyLoading,
911
+ );
844
912
  responder({ type: EmbedEvent.RequestVisibleEmbedCoordinates, data: visibleCoordinatesData });
845
913
  }
846
914
 
@@ -938,8 +1006,8 @@ export class LiveboardEmbed extends V1Embed {
938
1006
  </div>
939
1007
  `;
940
1008
  const previewDiv = div.firstElementChild as HTMLElement;
941
- this.el.appendChild(previewDiv);
942
- this.el.style.position = 'relative';
1009
+ this.hostElement.appendChild(previewDiv);
1010
+ this.hostElement.style.position = 'relative';
943
1011
  this.on(EmbedEvent.Data, () => {
944
1012
  previewDiv.remove();
945
1013
  });
@@ -961,6 +1029,7 @@ export class LiveboardEmbed extends V1Embed {
961
1029
  };
962
1030
 
963
1031
  protected beforePrerenderVisible(): void {
1032
+ super.beforePrerenderVisible();
964
1033
  const embedObj = this.getPreRenderObj<LiveboardEmbed>();
965
1034
 
966
1035
  this.executeAfterEmbedContainerLoaded(() => {
@@ -1023,17 +1092,44 @@ export class LiveboardEmbed extends V1Embed {
1023
1092
  }
1024
1093
 
1025
1094
  private registerLazyLoadEvents() {
1095
+ if(!this.iFrame) {
1096
+ return;
1097
+ }
1026
1098
  if (this.viewConfig.fullHeight && this.viewConfig.lazyLoadingForFullHeight) {
1099
+ this.unregisterLazyLoadEvents();
1027
1100
  // TODO: Use passive: true, install modernizr to check for passive
1028
1101
  window.addEventListener('resize', this.sendFullHeightLazyLoadData);
1029
1102
  window.addEventListener('scroll', this.sendFullHeightLazyLoadData, true);
1103
+ if (!this.viewConfig.enableScrollableContainerLazyLoading) {
1104
+ return;
1105
+ }
1106
+ this.lazyLoadScrollContainers = getScrollableAncestors(this.iFrame);
1107
+ this.lazyLoadScrollContainers.forEach((scrollContainer) => {
1108
+ scrollContainer.addEventListener('scroll', this.sendFullHeightLazyLoadData);
1109
+ });
1110
+ if (typeof ResizeObserver !== 'undefined') {
1111
+ const resizeTargets = new Set([
1112
+ this.iFrame.parentElement,
1113
+ ...getEffectiveClippingAncestors(this.iFrame),
1114
+ ].filter(Boolean) as HTMLElement[]);
1115
+ this.lazyLoadResizeObserver = new ResizeObserver(this.sendFullHeightLazyLoadData);
1116
+ resizeTargets.forEach((resizeTarget) => {
1117
+ this.lazyLoadResizeObserver.observe(resizeTarget);
1118
+ });
1119
+ }
1030
1120
  }
1031
1121
  }
1032
1122
 
1033
1123
  private unregisterLazyLoadEvents() {
1034
1124
  if (this.viewConfig.fullHeight && this.viewConfig.lazyLoadingForFullHeight) {
1035
1125
  window.removeEventListener('resize', this.sendFullHeightLazyLoadData);
1036
- window.removeEventListener('scroll', this.sendFullHeightLazyLoadData);
1126
+ window.removeEventListener('scroll', this.sendFullHeightLazyLoadData, true);
1127
+ this.lazyLoadResizeObserver?.disconnect();
1128
+ this.lazyLoadResizeObserver = undefined;
1129
+ this.lazyLoadScrollContainers.forEach((scrollContainer) => {
1130
+ scrollContainer.removeEventListener('scroll', this.sendFullHeightLazyLoadData);
1131
+ });
1132
+ this.lazyLoadScrollContainers = [];
1037
1133
  }
1038
1134
  }
1039
1135
 
@@ -0,0 +1,30 @@
1
+ import { buildSpotterVizAppInitData } from './spotter-viz-utils';
2
+
3
+ describe('buildSpotterVizAppInitData', () => {
4
+ const base = { type: 'APP_INIT' } as any;
5
+
6
+ it('returns initData unchanged when spotterViz is not provided', () => {
7
+ const result = buildSpotterVizAppInitData(base, {});
8
+ expect(result).toBe(base);
9
+ });
10
+
11
+ it('nests spotterViz under embedParams.spotterVizConfig', () => {
12
+ const spotterViz = { brandName: 'MyBrand', description: 'Desc', inputChatPlaceholder: 'Ask...' };
13
+ const result = buildSpotterVizAppInitData(base, { spotterViz });
14
+ expect(result.embedParams?.spotterVizConfig).toEqual(spotterViz);
15
+ });
16
+
17
+ it('passes brandHeadline through spotterVizConfig', () => {
18
+ const spotterViz = { brandName: 'MyBrand', brandHeadline: "Hi, there! I'm" };
19
+ const result = buildSpotterVizAppInitData(base, { spotterViz });
20
+ expect(result.embedParams?.spotterVizConfig?.brandHeadline).toBe("Hi, there! I'm");
21
+ });
22
+
23
+ it('preserves existing embedParams when adding spotterVizConfig', () => {
24
+ const existing = { ...base, embedParams: { spotterSidebarConfig: { enablePastConversationsSidebar: true } } };
25
+ const spotterViz = { brandName: 'MyBrand' };
26
+ const result = buildSpotterVizAppInitData(existing, { spotterViz });
27
+ expect(result.embedParams?.spotterVizConfig).toEqual(spotterViz);
28
+ expect(result.embedParams?.spotterSidebarConfig?.enablePastConversationsSidebar).toBe(true);
29
+ });
30
+ });
@@ -0,0 +1,94 @@
1
+ import { DefaultAppInitData } from '../types';
2
+
3
+ /**
4
+ * Defines starter prompts displayed in the SpotterViz interface.
5
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
6
+ * @group Embed components
7
+ */
8
+ export interface SpotterVizStarterPrompt {
9
+ /** Identifier for the prompt. */
10
+ id: string;
11
+ /** Short label shown to the user as a clickable suggestion. */
12
+ displayText: string;
13
+ /** Full prompt text sent to Spotter when the user clicks the suggestion. */
14
+ fullPrompt: string;
15
+ }
16
+
17
+ /**
18
+ * Configuration for the SpotterViz interface shown on the Liveboard.
19
+ * Supported embed types: `AppEmbed`, `LiveboardEmbed`
20
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
21
+ * @group Embed components
22
+ * @example
23
+ * ```js
24
+ * const embed = new AppEmbed('#embed-container', {
25
+ * ... // other options,
26
+ * spotterViz: {
27
+ * brandName: 'MyBrand',
28
+ * brandHeadline: 'Hi, there! I\'m',
29
+ * description: 'Ask questions about your data',
30
+ * inputChatPlaceholder: 'Ask a question...',
31
+ * hideStarterPrompts: false,
32
+ * customStarterPrompts: [
33
+ * { id: '1', displayText: 'Top products', fullPrompt: 'What are the top products by revenue?' }
34
+ * ],
35
+ * },
36
+ * })
37
+ * ```
38
+ */
39
+ export interface SpotterVizConfig {
40
+ /**
41
+ * Rename the default "SpotterViz" label shown in the SpotterViz interface with a custom brand name.
42
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
43
+ * @default ''
44
+ */
45
+ brandName?: string;
46
+ /**
47
+ * Custom headline text shown before the brand name in the SpotterViz interface.
48
+ * Replaces the default greeting prefix (e.g. "Hi, there! I'm").
49
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
50
+ * @default ''
51
+ */
52
+ brandHeadline?: string;
53
+ /**
54
+ * Hides the starter prompts section entirely in the SpotterViz interface.
55
+ * When set to `true`, the starter prompts are not displayed.
56
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
57
+ * @default false
58
+ */
59
+ hideStarterPrompts?: boolean;
60
+ /**
61
+ * Overrides the starter prompts with a custom list.
62
+ * Each entry must match the {@link SpotterVizStarterPrompt} shape.
63
+ * Has no effect when `hideStarterPrompts` is `true`.
64
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
65
+ */
66
+ customStarterPrompts?: SpotterVizStarterPrompt[];
67
+ /**
68
+ * Custom description text shown in the SpotterViz interface.
69
+ * Replaces the default SpotterViz description.
70
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
71
+ */
72
+ description?: string;
73
+ /**
74
+ * Custom placeholder text for the chat input in the SpotterViz interface.
75
+ * Replaces the default chat input placeholder text.
76
+ * @version SDK: 1.50.0 | ThoughtSpot Cloud: 26.7.0.cl
77
+ */
78
+ inputChatPlaceholder?: string;
79
+ }
80
+
81
+ export function buildSpotterVizAppInitData<T extends DefaultAppInitData>(
82
+ initData: T,
83
+ viewConfig: { spotterViz?: SpotterVizConfig },
84
+ ): T & { embedParams?: { spotterVizConfig?: SpotterVizConfig } } {
85
+ const { spotterViz } = viewConfig;
86
+ if (!spotterViz) return initData;
87
+ return {
88
+ ...initData,
89
+ embedParams: {
90
+ ...((initData as T & { embedParams?: Record<string, unknown> }).embedParams || {}),
91
+ spotterVizConfig: spotterViz,
92
+ },
93
+ };
94
+ }