@thoughtspot/visual-embed-sdk 1.52.2-beta.1 → 1.53.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 (237) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/css-variables.d.ts +373 -5
  3. package/cjs/src/css-variables.d.ts.map +1 -1
  4. package/cjs/src/embed/app.d.ts +14 -0
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js +6 -3
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +28 -0
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/auto-frame-renderer.d.ts.map +1 -1
  11. package/cjs/src/embed/auto-frame-renderer.js +244 -4
  12. package/cjs/src/embed/auto-frame-renderer.js.map +1 -1
  13. package/cjs/src/embed/auto-frame-renderer.spec.js +389 -0
  14. package/cjs/src/embed/auto-frame-renderer.spec.js.map +1 -1
  15. package/cjs/src/embed/bodyless-conversation.js +1 -1
  16. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  17. package/cjs/src/embed/conversation.d.ts +15 -0
  18. package/cjs/src/embed/conversation.d.ts.map +1 -1
  19. package/cjs/src/embed/conversation.js +7 -3
  20. package/cjs/src/embed/conversation.js.map +1 -1
  21. package/cjs/src/embed/conversation.spec.js +66 -0
  22. package/cjs/src/embed/conversation.spec.js.map +1 -1
  23. package/cjs/src/embed/liveboard-override-utils.d.ts +59 -0
  24. package/cjs/src/embed/liveboard-override-utils.d.ts.map +1 -0
  25. package/cjs/src/embed/liveboard-override-utils.js +19 -0
  26. package/cjs/src/embed/liveboard-override-utils.js.map +1 -0
  27. package/cjs/src/embed/liveboard-override-utils.spec.d.ts +2 -0
  28. package/cjs/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
  29. package/cjs/src/embed/liveboard-override-utils.spec.js +34 -0
  30. package/cjs/src/embed/liveboard-override-utils.spec.js.map +1 -0
  31. package/cjs/src/embed/liveboard.d.ts +43 -1
  32. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  33. package/cjs/src/embed/liveboard.js +11 -18
  34. package/cjs/src/embed/liveboard.js.map +1 -1
  35. package/cjs/src/embed/liveboard.spec.js +104 -54
  36. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  37. package/cjs/src/embed/search-bar.js +1 -1
  38. package/cjs/src/embed/search-bar.js.map +1 -1
  39. package/cjs/src/embed/search.js +1 -1
  40. package/cjs/src/embed/search.js.map +1 -1
  41. package/cjs/src/embed/search.spec.js +20 -0
  42. package/cjs/src/embed/search.spec.js.map +1 -1
  43. package/cjs/src/embed/spotter-utils.d.ts +11 -0
  44. package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
  45. package/cjs/src/embed/spotter-utils.js +13 -1
  46. package/cjs/src/embed/spotter-utils.js.map +1 -1
  47. package/cjs/src/embed/spotter-viz-utils.d.ts +15 -0
  48. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
  49. package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
  50. package/cjs/src/embed/spotter-viz-utils.spec.js +11 -0
  51. package/cjs/src/embed/spotter-viz-utils.spec.js.map +1 -1
  52. package/cjs/src/embed/ts-embed.d.ts +27 -34
  53. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  54. package/cjs/src/embed/ts-embed.js +224 -102
  55. package/cjs/src/embed/ts-embed.js.map +1 -1
  56. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  57. package/cjs/src/embed/ts-embed.spec.js +543 -171
  58. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  59. package/cjs/src/index.d.ts +4 -2
  60. package/cjs/src/index.d.ts.map +1 -1
  61. package/cjs/src/index.js +4 -2
  62. package/cjs/src/index.js.map +1 -1
  63. package/cjs/src/mixpanel-service.d.ts +1 -0
  64. package/cjs/src/mixpanel-service.d.ts.map +1 -1
  65. package/cjs/src/mixpanel-service.js +1 -0
  66. package/cjs/src/mixpanel-service.js.map +1 -1
  67. package/cjs/src/react/all-types-export.d.ts +1 -1
  68. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  69. package/cjs/src/react/all-types-export.js +2 -1
  70. package/cjs/src/react/all-types-export.js.map +1 -1
  71. package/cjs/src/types.d.ts +182 -2
  72. package/cjs/src/types.d.ts.map +1 -1
  73. package/cjs/src/types.js +109 -0
  74. package/cjs/src/types.js.map +1 -1
  75. package/cjs/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  76. package/cjs/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  77. package/cjs/src/utils/graphql/answerService/answer-queries.js +8 -1
  78. package/cjs/src/utils/graphql/answerService/answer-queries.js.map +1 -1
  79. package/cjs/src/utils/graphql/answerService/answerService.d.ts +28 -4
  80. package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  81. package/cjs/src/utils/graphql/answerService/answerService.js +39 -4
  82. package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -1
  83. package/cjs/src/utils/graphql/answerService/answerService.spec.js +124 -0
  84. package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  85. package/dist/{index-Bt56pC82.js → index-CyDR8j_0.js} +1 -1
  86. package/dist/src/css-variables.d.ts +373 -5
  87. package/dist/src/css-variables.d.ts.map +1 -1
  88. package/dist/src/embed/app.d.ts +14 -0
  89. package/dist/src/embed/app.d.ts.map +1 -1
  90. package/dist/src/embed/auto-frame-renderer.d.ts.map +1 -1
  91. package/dist/src/embed/conversation.d.ts +15 -0
  92. package/dist/src/embed/conversation.d.ts.map +1 -1
  93. package/dist/src/embed/liveboard-override-utils.d.ts +59 -0
  94. package/dist/src/embed/liveboard-override-utils.d.ts.map +1 -0
  95. package/dist/src/embed/liveboard-override-utils.spec.d.ts +2 -0
  96. package/dist/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
  97. package/dist/src/embed/liveboard.d.ts +43 -1
  98. package/dist/src/embed/liveboard.d.ts.map +1 -1
  99. package/dist/src/embed/spotter-utils.d.ts +11 -0
  100. package/dist/src/embed/spotter-utils.d.ts.map +1 -1
  101. package/dist/src/embed/spotter-viz-utils.d.ts +15 -0
  102. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  103. package/dist/src/embed/ts-embed.d.ts +27 -34
  104. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  105. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  106. package/dist/src/index.d.ts +4 -2
  107. package/dist/src/index.d.ts.map +1 -1
  108. package/dist/src/mixpanel-service.d.ts +1 -0
  109. package/dist/src/mixpanel-service.d.ts.map +1 -1
  110. package/dist/src/react/all-types-export.d.ts +1 -1
  111. package/dist/src/react/all-types-export.d.ts.map +1 -1
  112. package/dist/src/types.d.ts +182 -2
  113. package/dist/src/types.d.ts.map +1 -1
  114. package/dist/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  115. package/dist/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  116. package/dist/src/utils/graphql/answerService/answerService.d.ts +28 -4
  117. package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  118. package/dist/tsembed-react.es.js +437 -175
  119. package/dist/tsembed-react.js +436 -174
  120. package/dist/tsembed.es.js +680 -180
  121. package/dist/tsembed.js +678 -178
  122. package/dist/visual-embed-sdk-react-full.d.ts +702 -44
  123. package/dist/visual-embed-sdk-react.d.ts +697 -44
  124. package/dist/visual-embed-sdk.d.ts +729 -45
  125. package/lib/package.json +1 -1
  126. package/lib/src/css-variables.d.ts +373 -5
  127. package/lib/src/css-variables.d.ts.map +1 -1
  128. package/lib/src/embed/app.d.ts +14 -0
  129. package/lib/src/embed/app.d.ts.map +1 -1
  130. package/lib/src/embed/app.js +7 -4
  131. package/lib/src/embed/app.js.map +1 -1
  132. package/lib/src/embed/app.spec.js +28 -0
  133. package/lib/src/embed/app.spec.js.map +1 -1
  134. package/lib/src/embed/auto-frame-renderer.d.ts.map +1 -1
  135. package/lib/src/embed/auto-frame-renderer.js +244 -4
  136. package/lib/src/embed/auto-frame-renderer.js.map +1 -1
  137. package/lib/src/embed/auto-frame-renderer.spec.js +389 -0
  138. package/lib/src/embed/auto-frame-renderer.spec.js.map +1 -1
  139. package/lib/src/embed/bodyless-conversation.js +1 -1
  140. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  141. package/lib/src/embed/conversation.d.ts +15 -0
  142. package/lib/src/embed/conversation.d.ts.map +1 -1
  143. package/lib/src/embed/conversation.js +8 -4
  144. package/lib/src/embed/conversation.js.map +1 -1
  145. package/lib/src/embed/conversation.spec.js +67 -1
  146. package/lib/src/embed/conversation.spec.js.map +1 -1
  147. package/lib/src/embed/liveboard-override-utils.d.ts +59 -0
  148. package/lib/src/embed/liveboard-override-utils.d.ts.map +1 -0
  149. package/lib/src/embed/liveboard-override-utils.js +15 -0
  150. package/lib/src/embed/liveboard-override-utils.js.map +1 -0
  151. package/lib/src/embed/liveboard-override-utils.spec.d.ts +2 -0
  152. package/lib/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
  153. package/lib/src/embed/liveboard-override-utils.spec.js +32 -0
  154. package/lib/src/embed/liveboard-override-utils.spec.js.map +1 -0
  155. package/lib/src/embed/liveboard.d.ts +43 -1
  156. package/lib/src/embed/liveboard.d.ts.map +1 -1
  157. package/lib/src/embed/liveboard.js +11 -17
  158. package/lib/src/embed/liveboard.js.map +1 -1
  159. package/lib/src/embed/liveboard.spec.js +104 -54
  160. package/lib/src/embed/liveboard.spec.js.map +1 -1
  161. package/lib/src/embed/search-bar.js +1 -1
  162. package/lib/src/embed/search-bar.js.map +1 -1
  163. package/lib/src/embed/search.js +1 -1
  164. package/lib/src/embed/search.js.map +1 -1
  165. package/lib/src/embed/search.spec.js +20 -0
  166. package/lib/src/embed/search.spec.js.map +1 -1
  167. package/lib/src/embed/spotter-utils.d.ts +11 -0
  168. package/lib/src/embed/spotter-utils.d.ts.map +1 -1
  169. package/lib/src/embed/spotter-utils.js +12 -0
  170. package/lib/src/embed/spotter-utils.js.map +1 -1
  171. package/lib/src/embed/spotter-viz-utils.d.ts +15 -0
  172. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  173. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  174. package/lib/src/embed/spotter-viz-utils.spec.js +11 -0
  175. package/lib/src/embed/spotter-viz-utils.spec.js.map +1 -1
  176. package/lib/src/embed/ts-embed.d.ts +27 -34
  177. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  178. package/lib/src/embed/ts-embed.js +224 -102
  179. package/lib/src/embed/ts-embed.js.map +1 -1
  180. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  181. package/lib/src/embed/ts-embed.spec.js +544 -172
  182. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  183. package/lib/src/index.d.ts +4 -2
  184. package/lib/src/index.d.ts.map +1 -1
  185. package/lib/src/index.js +3 -2
  186. package/lib/src/index.js.map +1 -1
  187. package/lib/src/mixpanel-service.d.ts +1 -0
  188. package/lib/src/mixpanel-service.d.ts.map +1 -1
  189. package/lib/src/mixpanel-service.js +1 -0
  190. package/lib/src/mixpanel-service.js.map +1 -1
  191. package/lib/src/react/all-types-export.d.ts +1 -1
  192. package/lib/src/react/all-types-export.d.ts.map +1 -1
  193. package/lib/src/react/all-types-export.js +1 -1
  194. package/lib/src/react/all-types-export.js.map +1 -1
  195. package/lib/src/types.d.ts +182 -2
  196. package/lib/src/types.d.ts.map +1 -1
  197. package/lib/src/types.js +109 -0
  198. package/lib/src/types.js.map +1 -1
  199. package/lib/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  200. package/lib/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  201. package/lib/src/utils/graphql/answerService/answer-queries.js +7 -0
  202. package/lib/src/utils/graphql/answerService/answer-queries.js.map +1 -1
  203. package/lib/src/utils/graphql/answerService/answerService.d.ts +28 -4
  204. package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  205. package/lib/src/utils/graphql/answerService/answerService.js +39 -4
  206. package/lib/src/utils/graphql/answerService/answerService.js.map +1 -1
  207. package/lib/src/utils/graphql/answerService/answerService.spec.js +125 -1
  208. package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  209. package/lib/src/visual-embed-sdk.d.ts +729 -45
  210. package/package.json +1 -1
  211. package/src/css-variables.ts +475 -26
  212. package/src/embed/app.spec.ts +32 -0
  213. package/src/embed/app.ts +28 -4
  214. package/src/embed/auto-frame-renderer.spec.ts +464 -0
  215. package/src/embed/auto-frame-renderer.ts +305 -6
  216. package/src/embed/bodyless-conversation.ts +1 -1
  217. package/src/embed/conversation.spec.ts +94 -1
  218. package/src/embed/conversation.ts +28 -3
  219. package/src/embed/liveboard-override-utils.spec.ts +38 -0
  220. package/src/embed/liveboard-override-utils.ts +71 -0
  221. package/src/embed/liveboard.spec.ts +119 -62
  222. package/src/embed/liveboard.ts +56 -21
  223. package/src/embed/search-bar.tsx +1 -1
  224. package/src/embed/search.spec.ts +23 -0
  225. package/src/embed/search.ts +1 -1
  226. package/src/embed/spotter-utils.ts +12 -0
  227. package/src/embed/spotter-viz-utils.spec.ts +11 -0
  228. package/src/embed/spotter-viz-utils.ts +15 -0
  229. package/src/embed/ts-embed.spec.ts +684 -213
  230. package/src/embed/ts-embed.ts +227 -97
  231. package/src/index.ts +16 -1
  232. package/src/mixpanel-service.ts +1 -0
  233. package/src/react/all-types-export.ts +6 -0
  234. package/src/types.ts +186 -5
  235. package/src/utils/graphql/answerService/answer-queries.ts +8 -0
  236. package/src/utils/graphql/answerService/answerService.spec.ts +145 -1
  237. package/src/utils/graphql/answerService/answerService.ts +65 -3
@@ -1,4 +1,5 @@
1
1
  import { LiveboardViewConfig, LiveboardEmbed } from './liveboard';
2
+ import { SpotterExperienceVersion } from './spotter-utils';
2
3
  import { init, UIPassthroughEvent } from '../index';
3
4
  import {
4
5
  Action,
@@ -174,6 +175,37 @@ describe('Liveboard/viz embed tests', () => {
174
175
  });
175
176
  });
176
177
 
178
+ test('should set EditLiveboard and EditVisualization independently of each other and of Edit', async () => {
179
+ expect(Action.Edit).toBe('edit');
180
+ expect(Action.EditLiveboard).toBe('editLiveboard');
181
+ expect(Action.EditVisualization).toBe('editVisualization');
182
+
183
+ const liveboardEmbed1 = new LiveboardEmbed(getRootEl(), {
184
+ hiddenActions: [Action.EditVisualization],
185
+ ...defaultViewConfig,
186
+ liveboardId,
187
+ } as LiveboardViewConfig);
188
+ liveboardEmbed1.render();
189
+ await executeAfterWait(() => {
190
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
191
+ hideAction: JSON.stringify([Action.ReportError, Action.EditVisualization]),
192
+ });
193
+ });
194
+
195
+ document.body.innerHTML = getDocumentBody();
196
+ const liveboardEmbed2 = new LiveboardEmbed(getRootEl(), {
197
+ hiddenActions: [Action.EditLiveboard],
198
+ ...defaultViewConfig,
199
+ liveboardId,
200
+ } as LiveboardViewConfig);
201
+ liveboardEmbed2.render();
202
+ await executeAfterWait(() => {
203
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
204
+ hideAction: JSON.stringify([Action.ReportError, Action.EditLiveboard]),
205
+ });
206
+ });
207
+ });
208
+
177
209
  test('should set visible actions', async () => {
178
210
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
179
211
  visibleActions: [Action.DownloadAsCsv, Action.DownloadAsPdf, Action.DownloadAsXlsx],
@@ -1621,6 +1653,58 @@ describe('Liveboard/viz embed tests', () => {
1621
1653
  });
1622
1654
  });
1623
1655
 
1656
+ describe('liveboardOverride in APP_INIT embedParams', () => {
1657
+ const liveboardOverride = {
1658
+ dataSourceOverride: [{
1659
+ dataSourceIdentifier: 'model-guid',
1660
+ filterQuery: [{ tabName: 'Sales', groupName: 'Region', filterQueryToken: 'color = red' }],
1661
+ }],
1662
+ };
1663
+
1664
+ const getAppInitResponse = async (viewConfig: Partial<LiveboardViewConfig>) => {
1665
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1666
+ ...defaultViewConfig,
1667
+ liveboardId,
1668
+ ...viewConfig,
1669
+ } as LiveboardViewConfig);
1670
+
1671
+ mockMessageChannel();
1672
+ await liveboardEmbed.render();
1673
+
1674
+ const mockPort: any = { postMessage: jest.fn() };
1675
+ await executeAfterWait(() => {
1676
+ postMessageToParent(getIFrameEl().contentWindow, { type: EmbedEvent.APP_INIT, data: {} }, mockPort);
1677
+ });
1678
+ let data: any;
1679
+ await executeAfterWait(() => {
1680
+ data = mockPort.postMessage.mock.calls[0][0].data;
1681
+ });
1682
+ return data;
1683
+ };
1684
+
1685
+ test('should include liveboardOverride when provided', async () => {
1686
+ const data = await getAppInitResponse({ liveboardOverride });
1687
+ expect(data.embedParams.liveboardOverride).toEqual(liveboardOverride);
1688
+ });
1689
+
1690
+ test('should not include liveboardOverride when not provided', async () => {
1691
+ const data = await getAppInitResponse({});
1692
+ expect(data.embedParams?.liveboardOverride).toBeUndefined();
1693
+ });
1694
+
1695
+ test('should not include liveboardOverride when dataSourceOverride is empty', async () => {
1696
+ const data = await getAppInitResponse({ liveboardOverride: { dataSourceOverride: [] } });
1697
+ expect(data.embedParams?.liveboardOverride).toBeUndefined();
1698
+ });
1699
+
1700
+ test('should send liveboardOverride alongside spotterVizConfig', async () => {
1701
+ const spotterViz = { brandName: 'MyBrand' };
1702
+ const data = await getAppInitResponse({ liveboardOverride, spotterViz });
1703
+ expect(data.embedParams.liveboardOverride).toEqual(liveboardOverride);
1704
+ expect(data.embedParams.spotterVizConfig).toEqual(spotterViz);
1705
+ });
1706
+ });
1707
+
1624
1708
  test('should include starterPrompts in APP_INIT embedParams', async () => {
1625
1709
  const starterPrompts = {
1626
1710
  enable: true,
@@ -2748,68 +2832,6 @@ describe('Liveboard/viz embed tests', () => {
2748
2832
  expect(navigateToLiveboardSpy).toHaveBeenCalled();
2749
2833
  });
2750
2834
 
2751
- test('should not route via home when a new instance shows an equal config', async () => {
2752
- const viewConfig = {
2753
- liveboardId,
2754
- vizId,
2755
- activeTabId,
2756
- ...defaultViewConfig,
2757
- };
2758
- const previous = new LiveboardEmbed(getRootEl(), { ...viewConfig, beforeRender: () => {} } as any);
2759
- const liveboardEmbed = new LiveboardEmbed(getRootEl(), { ...viewConfig, beforeRender: () => {} } as any);
2760
-
2761
- // React constructs a new embed on every mount.
2762
- jest.spyOn(liveboardEmbed as any, 'getPreRenderObj').mockReturnValue(previous);
2763
- const triggerSpy = jest
2764
- .spyOn(liveboardEmbed, 'trigger')
2765
- .mockImplementation(() => Promise.resolve(undefined as any));
2766
- const navigateToLiveboardSpy = jest
2767
- .spyOn(liveboardEmbed, 'navigateToLiveboard')
2768
- .mockImplementation(() => Promise.resolve(undefined));
2769
-
2770
- liveboardEmbed.isEmbedContainerLoaded = false;
2771
- liveboardEmbed['beforePrerenderVisible']();
2772
- liveboardEmbed.isEmbedContainerLoaded = true;
2773
- liveboardEmbed['executeEmbedContainerReadyCallbacks']();
2774
- await waitForPreRenderNavigate();
2775
-
2776
- expect(triggerSpy).not.toHaveBeenCalledWith(HostEvent.Navigate, 'home');
2777
- expect(navigateToLiveboardSpy).toHaveBeenCalled();
2778
- });
2779
-
2780
- test('should route via home when a new instance shows the same route with other filters', async () => {
2781
- const viewConfig = {
2782
- liveboardId,
2783
- vizId,
2784
- activeTabId,
2785
- ...defaultViewConfig,
2786
- };
2787
- const previous = new LiveboardEmbed(getRootEl(), {
2788
- ...viewConfig,
2789
- runtimeFilters: [{ columnName: 'region', operator: RuntimeFilterOp.EQ, values: ['east'] }],
2790
- });
2791
- const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2792
- ...viewConfig,
2793
- runtimeFilters: [{ columnName: 'region', operator: RuntimeFilterOp.EQ, values: ['west'] }],
2794
- });
2795
-
2796
- jest.spyOn(liveboardEmbed as any, 'getPreRenderObj').mockReturnValue(previous);
2797
- const triggerSpy = jest
2798
- .spyOn(liveboardEmbed, 'trigger')
2799
- .mockImplementation(() => Promise.resolve(undefined as any));
2800
- jest
2801
- .spyOn(liveboardEmbed, 'navigateToLiveboard')
2802
- .mockImplementation(() => Promise.resolve(undefined));
2803
-
2804
- liveboardEmbed.isEmbedContainerLoaded = false;
2805
- liveboardEmbed['beforePrerenderVisible']();
2806
- liveboardEmbed.isEmbedContainerLoaded = true;
2807
- liveboardEmbed['executeEmbedContainerReadyCallbacks']();
2808
- await waitForHomeHopNavigate();
2809
-
2810
- expect(triggerSpy).toHaveBeenCalledWith(HostEvent.Navigate, 'home');
2811
- });
2812
-
2813
2835
  test('should not route via home when the pre-render is on another liveboard', async () => {
2814
2836
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
2815
2837
  liveboardId,
@@ -3149,3 +3171,38 @@ describe('LiveboardEmbed updatedSpotterExperience tests', () => {
3149
3171
  });
3150
3172
  });
3151
3173
  });
3174
+
3175
+ describe('LiveboardEmbed spotterExperienceVersion tests', () => {
3176
+ beforeEach(() => {
3177
+ document.body.innerHTML = getDocumentBody();
3178
+ });
3179
+
3180
+ const renderWithConfig = async (config: Partial<LiveboardViewConfig>) => {
3181
+ document.body.innerHTML = getDocumentBody();
3182
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
3183
+ ...defaultViewConfig,
3184
+ liveboardId,
3185
+ ...config,
3186
+ } as LiveboardViewConfig);
3187
+ await liveboardEmbed.render();
3188
+ let src = '';
3189
+ await executeAfterWait(() => {
3190
+ src = getIFrameSrc();
3191
+ });
3192
+ return src;
3193
+ };
3194
+
3195
+ test('should add the spotterExperienceVersion param when spotterExperienceVersion is set', async () => {
3196
+ const src = await renderWithConfig({
3197
+ spotterExperienceVersion: SpotterExperienceVersion.SPOTTER_2026_11,
3198
+ });
3199
+ expect(src).toContain(
3200
+ `spotterExperienceVersion=${SpotterExperienceVersion.SPOTTER_2026_11}`,
3201
+ );
3202
+ });
3203
+
3204
+ test('should not add the spotterExperienceVersion param when spotterExperienceVersion is not set', async () => {
3205
+ const src = await renderWithConfig({});
3206
+ expect(src).not.toContain('spotterExperienceVersion=');
3207
+ });
3208
+ });
@@ -8,7 +8,6 @@
8
8
  * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
9
9
  */
10
10
 
11
- import isEqualWith from 'lodash/isEqualWith';
12
11
  import { getPreview } from '../utils/graphql/preview-service';
13
12
  import { ERROR_MESSAGE } from '../errors';
14
13
  import {
@@ -35,8 +34,9 @@ import { addPreviewStylesIfNotPresent } from '../utils/global-styles';
35
34
  import { HostEventRequest, TriggerData, TriggerResponse } from '../contracts/host-event-contracts';
36
35
  import { logger } from '../utils/logger';
37
36
  import { SpotterChatViewConfig, StarterPromptsConfig } from './conversation';
38
- import { buildStarterPromptsAppInitData } from './spotter-utils';
37
+ import { buildStarterPromptsAppInitData, SpotterExperienceVersion } from './spotter-utils';
39
38
  import { SpotterVizConfig, buildSpotterVizAppInitData } from './spotter-viz-utils';
39
+ import { LiveboardOverride, buildLiveboardOverrideAppInitData } from './liveboard-override-utils';
40
40
 
41
41
  // Home unmounts the liveboard container, which is how its state gets cleared.
42
42
  // The settle window gives the container time to do it before we ask for the
@@ -52,6 +52,7 @@ export interface LiveboardEmbedAppInitData extends DefaultAppInitData {
52
52
  embedParams?: {
53
53
  spotterVizConfig?: SpotterVizConfig;
54
54
  starterPrompts?: StarterPromptsConfig;
55
+ liveboardOverride?: LiveboardOverride;
55
56
  };
56
57
  }
57
58
 
@@ -61,7 +62,8 @@ export interface LiveboardEmbedAppInitData extends DefaultAppInitData {
61
62
  * @group Embed components
62
63
  */
63
64
  export interface LiveboardViewConfig
64
- extends BaseViewConfig,
65
+ extends
66
+ BaseViewConfig,
65
67
  FullHeightViewConfig,
66
68
  LiveboardOtherViewConfig,
67
69
  LiveboardAppEmbedViewConfig {
@@ -546,6 +548,46 @@ export interface LiveboardViewConfig
546
548
  * ```
547
549
  */
548
550
  updatedSpotterExperience?: boolean;
551
+ /**
552
+ * Filters and Parameters to apply to the Liveboard when it loads.
553
+ *
554
+ * In an embedded Liveboard, this is the only way to set these overrides.
555
+ * The `filter` and `parameter` URL query params are ignored.
556
+ * Clauses without a query token are dropped.
557
+ *
558
+ * Supported embed types: `LiveboardEmbed`
559
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
560
+ * @example
561
+ * ```js
562
+ * const embed = new LiveboardEmbed('#tsEmbed', {
563
+ * ... // other embed view config
564
+ * liveboardOverride: {
565
+ * dataSourceOverride: [{
566
+ * dataSourceIdentifier: '<model-guid>',
567
+ * filterQuery: [{
568
+ * tabName: 'Sales',
569
+ * groupName: 'Region',
570
+ * filterQueryToken: 'color = red',
571
+ * }],
572
+ * }],
573
+ * },
574
+ * })
575
+ * ```
576
+ */
577
+ liveboardOverride?: LiveboardOverride;
578
+ /**
579
+ * The Spotter experience version to load for the Spotter surface shown within
580
+ * this embed.
581
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.11.0.cl
582
+ * @example
583
+ * ```js
584
+ * const embed = new LiveboardEmbed('#tsEmbed', {
585
+ * ... // other options
586
+ * spotterExperienceVersion: SpotterExperienceVersion.SPOTTER_2026_11,
587
+ * });
588
+ * ```
589
+ */
590
+ spotterExperienceVersion?: SpotterExperienceVersion;
549
591
  }
550
592
 
551
593
  /**
@@ -592,7 +634,8 @@ export class LiveboardEmbed extends V1Embed {
592
634
  protected async getAppInitData(): Promise<LiveboardEmbedAppInitData> {
593
635
  const defaultAppInitData = await super.getAppInitData();
594
636
  const vizInitData = buildSpotterVizAppInitData(defaultAppInitData, this.viewConfig);
595
- return buildStarterPromptsAppInitData(vizInitData, this.viewConfig);
637
+ const starterPromptsInitData = buildStarterPromptsAppInitData(vizInitData, this.viewConfig);
638
+ return buildLiveboardOverrideAppInitData(starterPromptsInitData, this.viewConfig);
596
639
  }
597
640
 
598
641
  /**
@@ -600,7 +643,7 @@ export class LiveboardEmbed extends V1Embed {
600
643
  * embedded Liveboard or visualization.
601
644
  */
602
645
  protected getEmbedParams() {
603
- const params = this.getEmbedParamsObject();
646
+ const params = this.getUrlQueryParamsObject();
604
647
  const queryParams = getQueryParamString(params, true);
605
648
  return queryParams;
606
649
  }
@@ -653,6 +696,7 @@ export class LiveboardEmbed extends V1Embed {
653
696
  isThisPeriodInDateFiltersEnabled,
654
697
  isContinuousLiveboardPDFEnabled,
655
698
  enableLiveboardDataCache,
699
+ spotterExperienceVersion,
656
700
  } = this.viewConfig;
657
701
 
658
702
  const preventLiveboardFilterRemoval = this.viewConfig.preventLiveboardFilterRemoval
@@ -722,6 +766,10 @@ export class LiveboardEmbed extends V1Embed {
722
766
  params[Param.IsLiveboardStylingAndGroupingEnabled] = isLiveboardStylingAndGroupingEnabled;
723
767
  }
724
768
 
769
+ if (spotterExperienceVersion !== undefined) {
770
+ params[Param.SpotterExperienceVersion] = spotterExperienceVersion;
771
+ }
772
+
725
773
  if (liveboardGutter !== undefined) {
726
774
  params[Param.LiveboardGutter] = liveboardGutter;
727
775
  }
@@ -956,12 +1004,10 @@ export class LiveboardEmbed extends V1Embed {
956
1004
  super.beforePrerenderVisible();
957
1005
 
958
1006
  // Captured before showPreRender() hands the wrapper over to this
959
- // instance. React builds a new instance per mount, so an equal config
960
- // is a hide/show, not a hand-over: there is nothing stale to clear.
1007
+ // instance. Itself means a hide/show, not a hand-over, so there is
1008
+ // nothing stale to clear.
961
1009
  const previous = this.getPreRenderObj<LiveboardEmbed>();
962
- const showing = this.isSameEmbedConfig(previous)
963
- ? undefined
964
- : previous?.currentLiveboardState;
1010
+ const showing = previous === this ? undefined : previous?.currentLiveboardState;
965
1011
 
966
1012
  this.executeAfterEmbedContainerLoaded(async () => {
967
1013
  // Without this the params callback suspends on its await and
@@ -995,17 +1041,6 @@ export class LiveboardEmbed extends V1Embed {
995
1041
  });
996
1042
  }
997
1043
 
998
- // Callbacks are compared as equal: React passes a fresh closure per render.
999
- private isSameEmbedConfig(previous?: LiveboardEmbed): boolean {
1000
- if (!previous) return false;
1001
- if (previous === this) return true;
1002
- return isEqualWith(
1003
- previous.viewConfig,
1004
- this.viewConfig,
1005
- (a, b) => (typeof a === 'function' && typeof b === 'function' ? true : undefined),
1006
- );
1007
- }
1008
-
1009
1044
  // The whole route, not just the liveboard id: the path is built from the
1010
1045
  // viz, tab and view too, so a same-liveboard show onto another tab is a
1011
1046
  // real navigation.
@@ -163,7 +163,7 @@ export class SearchBarEmbed extends TsEmbed {
163
163
  * @param dataSources A list of data source GUIDs
164
164
  */
165
165
  private getIFrameSrc() {
166
- const queryParams = this.getEmbedParamsObject();
166
+ const queryParams = this.getUrlQueryParamsObject();
167
167
  const path = 'search-bar-embed';
168
168
 
169
169
  let query = '';
@@ -854,6 +854,29 @@ test('should pass forceTable parameter when forceTable is true', async () => {
854
854
  });
855
855
 
856
856
  describe('SearchBarEmbed tests', () => {
857
+ test('should keep view config off the URL when excludeConfigFromURL is set', async () => {
858
+ const searchBarEmbed = new SearchBarEmbed(getRootEl() as any, {
859
+ ...defaultViewConfig,
860
+ dataSources: ['source-1', 'source-2'],
861
+ additionalFlags: { excludeConfigFromURL: true },
862
+ } as any);
863
+ searchBarEmbed.render();
864
+ await executeAfterWait(() => {
865
+ const iframeSrc = getIFrameSrc();
866
+
867
+ // Bootstrap params stay: the handshake, the embed marker that
868
+ // picks the app shell, and the data sources it boots against.
869
+ expect(iframeSrc).toContain('hostAppUrl=');
870
+ expect(iframeSrc).toContain('isSearchEmbed=true');
871
+ expect(iframeSrc).toContain('dataSources');
872
+
873
+ // The rest of the view config goes over
874
+ // HostEvent.UpdateEmbedParams.
875
+ expect(iframeSrc).not.toContain('hideAction');
876
+ expect(iframeSrc).not.toContain('useLastSelectedDataSource');
877
+ });
878
+ });
879
+
857
880
  test('should pass dataSources parameter when dataSources array is provided', async () => {
858
881
  const searchBarEmbed = new SearchBarEmbed(getRootEl() as any, {
859
882
  ...defaultViewConfig,
@@ -546,7 +546,7 @@ export class SearchEmbed extends TsEmbed {
546
546
  excludeRuntimeParametersfromURL,
547
547
  excludeRuntimeFiltersfromURL,
548
548
  } = this.viewConfig;
549
- const queryParams = this.getEmbedParamsObject();
549
+ const queryParams = this.getUrlQueryParamsObject();
550
550
  let query = '';
551
551
  const queryParamsString = getQueryParamString(queryParams, true);
552
552
  if (queryParamsString) {
@@ -130,3 +130,15 @@ export function buildSpotterAnalystAppInitData<T extends DefaultAppInitData>(
130
130
  },
131
131
  };
132
132
  }
133
+
134
+ /**
135
+ * The Spotter experience version to load in the embedded view.
136
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.11.0.cl
137
+ * @group Embed components
138
+ */
139
+ export enum SpotterExperienceVersion {
140
+ /**
141
+ * The Spotter experience version introduced in ThoughtSpot 26.11.
142
+ */
143
+ SPOTTER_2026_11 = 'spotter_2026_11',
144
+ }
@@ -37,6 +37,17 @@ describe('buildSpotterVizAppInitData', () => {
37
37
  expect(result.embedParams?.spotterVizConfig?.insightTileLoaderText).toBe('Generating insight');
38
38
  });
39
39
 
40
+ it('passes fileUploadEnabled and fileUploadFileTypes through spotterVizConfig', () => {
41
+ const spotterViz = {
42
+ brandName: 'MyBrand',
43
+ fileUploadEnabled: false,
44
+ fileUploadFileTypes: ['csv', '.pdf'],
45
+ };
46
+ const result = buildSpotterVizAppInitData(base, { spotterViz });
47
+ expect(result.embedParams?.spotterVizConfig?.fileUploadEnabled).toBe(false);
48
+ expect(result.embedParams?.spotterVizConfig?.fileUploadFileTypes).toEqual(['csv', '.pdf']);
49
+ });
50
+
40
51
  it('preserves existing embedParams when adding spotterVizConfig', () => {
41
52
  const existing = { ...base, embedParams: { spotterSidebarConfig: { enablePastConversationsSidebar: true } } };
42
53
  const spotterViz = { brandName: 'MyBrand' };
@@ -127,6 +127,21 @@ export interface SpotterVizConfig {
127
127
  * @version SDK: 1.51.0 | ThoughtSpot Cloud: 26.7.0.cl
128
128
  */
129
129
  insightTileLoaderText?: string;
130
+ /**
131
+ * Set to `false` to hide the file upload feature in the SpotterViz chat
132
+ * input on a cluster where the feature is available.
133
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
134
+ * @default true
135
+ */
136
+ fileUploadEnabled?: boolean;
137
+ /**
138
+ * Restricts the allowed file types for SpotterViz file upload to a
139
+ * subset of the types SpotterViz supports, e.g. `['csv', 'pdf']`.
140
+ * Entries are file extensions (with or without the leading dot); types
141
+ * SpotterViz does not support are ignored, as are empty lists.
142
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
143
+ */
144
+ fileUploadFileTypes?: string[];
130
145
  }
131
146
 
132
147
  /**