@thoughtspot/visual-embed-sdk 1.52.2-beta.2 → 1.53.1

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 (281) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/contracts/contracts.spec.js +4 -0
  3. package/cjs/src/contracts/contracts.spec.js.map +1 -1
  4. package/cjs/src/contracts/host-event-contracts.d.ts +10 -0
  5. package/cjs/src/contracts/host-event-contracts.d.ts.map +1 -1
  6. package/cjs/src/css-variables.d.ts +373 -5
  7. package/cjs/src/css-variables.d.ts.map +1 -1
  8. package/cjs/src/embed/app.d.ts +15 -0
  9. package/cjs/src/embed/app.d.ts.map +1 -1
  10. package/cjs/src/embed/app.js +6 -3
  11. package/cjs/src/embed/app.js.map +1 -1
  12. package/cjs/src/embed/app.spec.js +28 -0
  13. package/cjs/src/embed/app.spec.js.map +1 -1
  14. package/cjs/src/embed/auto-frame-renderer.d.ts.map +1 -1
  15. package/cjs/src/embed/auto-frame-renderer.js +244 -4
  16. package/cjs/src/embed/auto-frame-renderer.js.map +1 -1
  17. package/cjs/src/embed/auto-frame-renderer.spec.js +389 -0
  18. package/cjs/src/embed/auto-frame-renderer.spec.js.map +1 -1
  19. package/cjs/src/embed/bodyless-conversation.js +1 -1
  20. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  21. package/cjs/src/embed/conversation.d.ts +29 -0
  22. package/cjs/src/embed/conversation.d.ts.map +1 -1
  23. package/cjs/src/embed/conversation.js +7 -3
  24. package/cjs/src/embed/conversation.js.map +1 -1
  25. package/cjs/src/embed/conversation.spec.js +88 -0
  26. package/cjs/src/embed/conversation.spec.js.map +1 -1
  27. package/cjs/src/embed/host-events.spec.js +32 -0
  28. package/cjs/src/embed/host-events.spec.js.map +1 -1
  29. package/cjs/src/embed/liveboard-override-utils.d.ts +59 -0
  30. package/cjs/src/embed/liveboard-override-utils.d.ts.map +1 -0
  31. package/cjs/src/embed/liveboard-override-utils.js +19 -0
  32. package/cjs/src/embed/liveboard-override-utils.js.map +1 -0
  33. package/cjs/src/embed/liveboard-override-utils.spec.d.ts +2 -0
  34. package/cjs/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
  35. package/cjs/src/embed/liveboard-override-utils.spec.js +34 -0
  36. package/cjs/src/embed/liveboard-override-utils.spec.js.map +1 -0
  37. package/cjs/src/embed/liveboard.d.ts +44 -13
  38. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  39. package/cjs/src/embed/liveboard.js +19 -23
  40. package/cjs/src/embed/liveboard.js.map +1 -1
  41. package/cjs/src/embed/liveboard.spec.js +122 -0
  42. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  43. package/cjs/src/embed/search-bar.js +1 -1
  44. package/cjs/src/embed/search-bar.js.map +1 -1
  45. package/cjs/src/embed/search.js +1 -1
  46. package/cjs/src/embed/search.js.map +1 -1
  47. package/cjs/src/embed/search.spec.js +20 -0
  48. package/cjs/src/embed/search.spec.js.map +1 -1
  49. package/cjs/src/embed/spotter-utils.d.ts +12 -0
  50. package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
  51. package/cjs/src/embed/spotter-utils.js +20 -2
  52. package/cjs/src/embed/spotter-utils.js.map +1 -1
  53. package/cjs/src/embed/spotter-utils.spec.js +19 -0
  54. package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
  55. package/cjs/src/embed/spotter-viz-utils.d.ts +15 -0
  56. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
  57. package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
  58. package/cjs/src/embed/spotter-viz-utils.spec.js +11 -0
  59. package/cjs/src/embed/spotter-viz-utils.spec.js.map +1 -1
  60. package/cjs/src/embed/ts-embed.d.ts +18 -20
  61. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  62. package/cjs/src/embed/ts-embed.js +181 -45
  63. package/cjs/src/embed/ts-embed.js.map +1 -1
  64. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  65. package/cjs/src/embed/ts-embed.spec.js +610 -0
  66. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  67. package/cjs/src/index.d.ts +5 -3
  68. package/cjs/src/index.d.ts.map +1 -1
  69. package/cjs/src/index.js +4 -2
  70. package/cjs/src/index.js.map +1 -1
  71. package/cjs/src/mixpanel-service.d.ts +1 -0
  72. package/cjs/src/mixpanel-service.d.ts.map +1 -1
  73. package/cjs/src/mixpanel-service.js +1 -0
  74. package/cjs/src/mixpanel-service.js.map +1 -1
  75. package/cjs/src/react/all-types-export.d.ts +1 -1
  76. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  77. package/cjs/src/react/all-types-export.js +2 -1
  78. package/cjs/src/react/all-types-export.js.map +1 -1
  79. package/cjs/src/types.d.ts +251 -4
  80. package/cjs/src/types.d.ts.map +1 -1
  81. package/cjs/src/types.js +176 -0
  82. package/cjs/src/types.js.map +1 -1
  83. package/cjs/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  84. package/cjs/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  85. package/cjs/src/utils/graphql/answerService/answer-queries.js +8 -1
  86. package/cjs/src/utils/graphql/answerService/answer-queries.js.map +1 -1
  87. package/cjs/src/utils/graphql/answerService/answerService.d.ts +28 -4
  88. package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  89. package/cjs/src/utils/graphql/answerService/answerService.js +39 -4
  90. package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -1
  91. package/cjs/src/utils/graphql/answerService/answerService.spec.js +124 -0
  92. package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  93. package/cjs/src/utils/runtimeTelemetry.d.ts +11 -0
  94. package/cjs/src/utils/runtimeTelemetry.d.ts.map +1 -0
  95. package/cjs/src/utils/runtimeTelemetry.js +34 -0
  96. package/cjs/src/utils/runtimeTelemetry.js.map +1 -0
  97. package/cjs/src/utils/runtimeTelemetry.spec.d.ts +2 -0
  98. package/cjs/src/utils/runtimeTelemetry.spec.d.ts.map +1 -0
  99. package/cjs/src/utils/runtimeTelemetry.spec.js +124 -0
  100. package/cjs/src/utils/runtimeTelemetry.spec.js.map +1 -0
  101. package/dist/{index-CnHREfvN.js → index-CrBnZBZv.js} +1 -1
  102. package/dist/src/contracts/host-event-contracts.d.ts +10 -0
  103. package/dist/src/contracts/host-event-contracts.d.ts.map +1 -1
  104. package/dist/src/css-variables.d.ts +373 -5
  105. package/dist/src/css-variables.d.ts.map +1 -1
  106. package/dist/src/embed/app.d.ts +15 -0
  107. package/dist/src/embed/app.d.ts.map +1 -1
  108. package/dist/src/embed/auto-frame-renderer.d.ts.map +1 -1
  109. package/dist/src/embed/conversation.d.ts +29 -0
  110. package/dist/src/embed/conversation.d.ts.map +1 -1
  111. package/dist/src/embed/liveboard-override-utils.d.ts +59 -0
  112. package/dist/src/embed/liveboard-override-utils.d.ts.map +1 -0
  113. package/dist/src/embed/liveboard-override-utils.spec.d.ts +2 -0
  114. package/dist/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
  115. package/dist/src/embed/liveboard.d.ts +44 -13
  116. package/dist/src/embed/liveboard.d.ts.map +1 -1
  117. package/dist/src/embed/spotter-utils.d.ts +12 -0
  118. package/dist/src/embed/spotter-utils.d.ts.map +1 -1
  119. package/dist/src/embed/spotter-viz-utils.d.ts +15 -0
  120. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  121. package/dist/src/embed/ts-embed.d.ts +18 -20
  122. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  123. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  124. package/dist/src/index.d.ts +5 -3
  125. package/dist/src/index.d.ts.map +1 -1
  126. package/dist/src/mixpanel-service.d.ts +1 -0
  127. package/dist/src/mixpanel-service.d.ts.map +1 -1
  128. package/dist/src/react/all-types-export.d.ts +1 -1
  129. package/dist/src/react/all-types-export.d.ts.map +1 -1
  130. package/dist/src/types.d.ts +251 -4
  131. package/dist/src/types.d.ts.map +1 -1
  132. package/dist/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  133. package/dist/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  134. package/dist/src/utils/graphql/answerService/answerService.d.ts +28 -4
  135. package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  136. package/dist/src/utils/runtimeTelemetry.d.ts +11 -0
  137. package/dist/src/utils/runtimeTelemetry.d.ts.map +1 -0
  138. package/dist/src/utils/runtimeTelemetry.spec.d.ts +2 -0
  139. package/dist/src/utils/runtimeTelemetry.spec.d.ts.map +1 -0
  140. package/dist/tsembed-react.es.js +500 -85
  141. package/dist/tsembed-react.js +499 -84
  142. package/dist/tsembed.es.js +743 -90
  143. package/dist/tsembed.js +741 -88
  144. package/dist/visual-embed-sdk-react-full.d.ts +788 -44
  145. package/dist/visual-embed-sdk-react.d.ts +783 -44
  146. package/dist/visual-embed-sdk.d.ts +815 -45
  147. package/lib/package.json +1 -1
  148. package/lib/src/contracts/contracts.spec.js +4 -0
  149. package/lib/src/contracts/contracts.spec.js.map +1 -1
  150. package/lib/src/contracts/host-event-contracts.d.ts +10 -0
  151. package/lib/src/contracts/host-event-contracts.d.ts.map +1 -1
  152. package/lib/src/css-variables.d.ts +373 -5
  153. package/lib/src/css-variables.d.ts.map +1 -1
  154. package/lib/src/embed/app.d.ts +15 -0
  155. package/lib/src/embed/app.d.ts.map +1 -1
  156. package/lib/src/embed/app.js +7 -4
  157. package/lib/src/embed/app.js.map +1 -1
  158. package/lib/src/embed/app.spec.js +28 -0
  159. package/lib/src/embed/app.spec.js.map +1 -1
  160. package/lib/src/embed/auto-frame-renderer.d.ts.map +1 -1
  161. package/lib/src/embed/auto-frame-renderer.js +244 -4
  162. package/lib/src/embed/auto-frame-renderer.js.map +1 -1
  163. package/lib/src/embed/auto-frame-renderer.spec.js +389 -0
  164. package/lib/src/embed/auto-frame-renderer.spec.js.map +1 -1
  165. package/lib/src/embed/bodyless-conversation.js +1 -1
  166. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  167. package/lib/src/embed/conversation.d.ts +29 -0
  168. package/lib/src/embed/conversation.d.ts.map +1 -1
  169. package/lib/src/embed/conversation.js +8 -4
  170. package/lib/src/embed/conversation.js.map +1 -1
  171. package/lib/src/embed/conversation.spec.js +89 -1
  172. package/lib/src/embed/conversation.spec.js.map +1 -1
  173. package/lib/src/embed/host-events.spec.js +32 -0
  174. package/lib/src/embed/host-events.spec.js.map +1 -1
  175. package/lib/src/embed/liveboard-override-utils.d.ts +59 -0
  176. package/lib/src/embed/liveboard-override-utils.d.ts.map +1 -0
  177. package/lib/src/embed/liveboard-override-utils.js +15 -0
  178. package/lib/src/embed/liveboard-override-utils.js.map +1 -0
  179. package/lib/src/embed/liveboard-override-utils.spec.d.ts +2 -0
  180. package/lib/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
  181. package/lib/src/embed/liveboard-override-utils.spec.js +32 -0
  182. package/lib/src/embed/liveboard-override-utils.spec.js.map +1 -0
  183. package/lib/src/embed/liveboard.d.ts +44 -13
  184. package/lib/src/embed/liveboard.d.ts.map +1 -1
  185. package/lib/src/embed/liveboard.js +19 -23
  186. package/lib/src/embed/liveboard.js.map +1 -1
  187. package/lib/src/embed/liveboard.spec.js +122 -0
  188. package/lib/src/embed/liveboard.spec.js.map +1 -1
  189. package/lib/src/embed/search-bar.js +1 -1
  190. package/lib/src/embed/search-bar.js.map +1 -1
  191. package/lib/src/embed/search.js +1 -1
  192. package/lib/src/embed/search.js.map +1 -1
  193. package/lib/src/embed/search.spec.js +20 -0
  194. package/lib/src/embed/search.spec.js.map +1 -1
  195. package/lib/src/embed/spotter-utils.d.ts +12 -0
  196. package/lib/src/embed/spotter-utils.d.ts.map +1 -1
  197. package/lib/src/embed/spotter-utils.js +19 -1
  198. package/lib/src/embed/spotter-utils.js.map +1 -1
  199. package/lib/src/embed/spotter-utils.spec.js +19 -0
  200. package/lib/src/embed/spotter-utils.spec.js.map +1 -1
  201. package/lib/src/embed/spotter-viz-utils.d.ts +15 -0
  202. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  203. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  204. package/lib/src/embed/spotter-viz-utils.spec.js +11 -0
  205. package/lib/src/embed/spotter-viz-utils.spec.js.map +1 -1
  206. package/lib/src/embed/ts-embed.d.ts +18 -20
  207. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  208. package/lib/src/embed/ts-embed.js +181 -45
  209. package/lib/src/embed/ts-embed.js.map +1 -1
  210. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  211. package/lib/src/embed/ts-embed.spec.js +611 -1
  212. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  213. package/lib/src/index.d.ts +5 -3
  214. package/lib/src/index.d.ts.map +1 -1
  215. package/lib/src/index.js +3 -2
  216. package/lib/src/index.js.map +1 -1
  217. package/lib/src/mixpanel-service.d.ts +1 -0
  218. package/lib/src/mixpanel-service.d.ts.map +1 -1
  219. package/lib/src/mixpanel-service.js +1 -0
  220. package/lib/src/mixpanel-service.js.map +1 -1
  221. package/lib/src/react/all-types-export.d.ts +1 -1
  222. package/lib/src/react/all-types-export.d.ts.map +1 -1
  223. package/lib/src/react/all-types-export.js +1 -1
  224. package/lib/src/react/all-types-export.js.map +1 -1
  225. package/lib/src/types.d.ts +251 -4
  226. package/lib/src/types.d.ts.map +1 -1
  227. package/lib/src/types.js +176 -0
  228. package/lib/src/types.js.map +1 -1
  229. package/lib/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  230. package/lib/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  231. package/lib/src/utils/graphql/answerService/answer-queries.js +7 -0
  232. package/lib/src/utils/graphql/answerService/answer-queries.js.map +1 -1
  233. package/lib/src/utils/graphql/answerService/answerService.d.ts +28 -4
  234. package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  235. package/lib/src/utils/graphql/answerService/answerService.js +39 -4
  236. package/lib/src/utils/graphql/answerService/answerService.js.map +1 -1
  237. package/lib/src/utils/graphql/answerService/answerService.spec.js +125 -1
  238. package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  239. package/lib/src/utils/runtimeTelemetry.d.ts +11 -0
  240. package/lib/src/utils/runtimeTelemetry.d.ts.map +1 -0
  241. package/lib/src/utils/runtimeTelemetry.js +28 -0
  242. package/lib/src/utils/runtimeTelemetry.js.map +1 -0
  243. package/lib/src/utils/runtimeTelemetry.spec.d.ts +2 -0
  244. package/lib/src/utils/runtimeTelemetry.spec.d.ts.map +1 -0
  245. package/lib/src/utils/runtimeTelemetry.spec.js +122 -0
  246. package/lib/src/utils/runtimeTelemetry.spec.js.map +1 -0
  247. package/lib/src/visual-embed-sdk.d.ts +815 -45
  248. package/package.json +1 -1
  249. package/src/contracts/contracts.spec.ts +4 -0
  250. package/src/contracts/host-event-contracts.ts +13 -0
  251. package/src/css-variables.ts +475 -26
  252. package/src/embed/app.spec.ts +32 -0
  253. package/src/embed/app.ts +29 -4
  254. package/src/embed/auto-frame-renderer.spec.ts +464 -0
  255. package/src/embed/auto-frame-renderer.ts +305 -6
  256. package/src/embed/bodyless-conversation.ts +1 -1
  257. package/src/embed/conversation.spec.ts +118 -1
  258. package/src/embed/conversation.ts +42 -3
  259. package/src/embed/host-events.spec.ts +44 -0
  260. package/src/embed/liveboard-override-utils.spec.ts +38 -0
  261. package/src/embed/liveboard-override-utils.ts +71 -0
  262. package/src/embed/liveboard.spec.ts +138 -0
  263. package/src/embed/liveboard.ts +64 -24
  264. package/src/embed/search-bar.tsx +1 -1
  265. package/src/embed/search.spec.ts +23 -0
  266. package/src/embed/search.ts +1 -1
  267. package/src/embed/spotter-utils.spec.ts +20 -0
  268. package/src/embed/spotter-utils.ts +24 -1
  269. package/src/embed/spotter-viz-utils.spec.ts +11 -0
  270. package/src/embed/spotter-viz-utils.ts +15 -0
  271. package/src/embed/ts-embed.spec.ts +767 -0
  272. package/src/embed/ts-embed.ts +186 -41
  273. package/src/index.ts +18 -1
  274. package/src/mixpanel-service.ts +1 -0
  275. package/src/react/all-types-export.ts +7 -0
  276. package/src/types.ts +254 -5
  277. package/src/utils/graphql/answerService/answer-queries.ts +8 -0
  278. package/src/utils/graphql/answerService/answerService.spec.ts +145 -1
  279. package/src/utils/graphql/answerService/answerService.ts +65 -3
  280. package/src/utils/runtimeTelemetry.spec.ts +148 -0
  281. package/src/utils/runtimeTelemetry.ts +50 -0
@@ -0,0 +1,71 @@
1
+ import type { DefaultAppInitData } from '../types';
2
+
3
+ /**
4
+ * A filter to apply to a Liveboard when it loads.
5
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
6
+ * @group Embed components
7
+ */
8
+ export interface LiveboardFilterQuery {
9
+ /** Name of the Liveboard tab the filter applies to. */
10
+ tabName?: string;
11
+ /** Name of the group within the tab that the filter applies to. */
12
+ groupName?: string;
13
+ /**
14
+ * The filter condition, in search sentence form. For example, `color = red`.
15
+ */
16
+ filterQueryToken: string;
17
+ }
18
+
19
+ /**
20
+ * A Parameter value to apply to a Liveboard when it loads.
21
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
22
+ * @group Embed components
23
+ */
24
+ export interface LiveboardParameterQuery {
25
+ /** Name of the Liveboard tab the Parameter applies to. */
26
+ tabName?: string;
27
+ /** Name of the group within the tab that the Parameter applies to. */
28
+ groupName?: string;
29
+ /** The Parameter assignment. */
30
+ parameterQueryToken: string;
31
+ }
32
+
33
+ /**
34
+ * Filter and Parameter overrides for one data source on the Liveboard.
35
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
36
+ * @group Embed components
37
+ */
38
+ export interface LiveboardDataSourceOverride {
39
+ /** The data source (Model) the overrides apply to. */
40
+ dataSourceIdentifier?: string;
41
+ /** Filters to apply for this data source. */
42
+ filterQuery?: LiveboardFilterQuery[];
43
+ /** Parameter values to apply for this data source. */
44
+ parameterQuery?: LiveboardParameterQuery[];
45
+ }
46
+
47
+ /**
48
+ * Filter and Parameter overrides applied to a Liveboard when it loads.
49
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
50
+ * @group Embed components
51
+ */
52
+ export interface LiveboardOverride {
53
+ /** One entry per data source to override. */
54
+ dataSourceOverride: LiveboardDataSourceOverride[];
55
+ }
56
+
57
+ export function buildLiveboardOverrideAppInitData<T extends DefaultAppInitData>(
58
+ initData: T,
59
+ viewConfig: { liveboardOverride?: LiveboardOverride },
60
+ ): T & { embedParams?: { liveboardOverride?: LiveboardOverride } } {
61
+ const { liveboardOverride } = viewConfig;
62
+ // ThoughtSpot ignores an override with no data source entries; skip it.
63
+ if (!liveboardOverride?.dataSourceOverride?.length) return initData;
64
+ return {
65
+ ...initData,
66
+ embedParams: {
67
+ ...((initData as T & { embedParams?: Record<string, unknown> }).embedParams || {}),
68
+ liveboardOverride,
69
+ },
70
+ };
71
+ }
@@ -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,
@@ -157,6 +158,25 @@ describe('Liveboard/viz embed tests', () => {
157
158
  });
158
159
  });
159
160
 
161
+ test('should hide and disable the Cancel button in the Liveboard edit header', async () => {
162
+ expect(Action.Cancel).toBe('cancel');
163
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
164
+ hiddenActions: [Action.Cancel],
165
+ disabledActions: [Action.Cancel],
166
+ disabledActionReason: 'Save your changes to leave edit mode',
167
+ ...defaultViewConfig,
168
+ liveboardId,
169
+ } as LiveboardViewConfig);
170
+ liveboardEmbed.render();
171
+ await executeAfterWait(() => {
172
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
173
+ hideAction: JSON.stringify([Action.ReportError, Action.Cancel]),
174
+ disableAction: JSON.stringify([Action.Cancel]),
175
+ disableHint: 'Save your changes to leave edit mode',
176
+ });
177
+ });
178
+ });
179
+
160
180
  test('should hide and disable the Spotter button on the Liveboard header', async () => {
161
181
  expect(Action.SpotterOnLiveboard).toBe('spotterOnLiveboard');
162
182
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
@@ -174,6 +194,37 @@ describe('Liveboard/viz embed tests', () => {
174
194
  });
175
195
  });
176
196
 
197
+ test('should set EditLiveboard and EditVisualization independently of each other and of Edit', async () => {
198
+ expect(Action.Edit).toBe('edit');
199
+ expect(Action.EditLiveboard).toBe('editLiveboard');
200
+ expect(Action.EditVisualization).toBe('editVisualization');
201
+
202
+ const liveboardEmbed1 = new LiveboardEmbed(getRootEl(), {
203
+ hiddenActions: [Action.EditVisualization],
204
+ ...defaultViewConfig,
205
+ liveboardId,
206
+ } as LiveboardViewConfig);
207
+ liveboardEmbed1.render();
208
+ await executeAfterWait(() => {
209
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
210
+ hideAction: JSON.stringify([Action.ReportError, Action.EditVisualization]),
211
+ });
212
+ });
213
+
214
+ document.body.innerHTML = getDocumentBody();
215
+ const liveboardEmbed2 = new LiveboardEmbed(getRootEl(), {
216
+ hiddenActions: [Action.EditLiveboard],
217
+ ...defaultViewConfig,
218
+ liveboardId,
219
+ } as LiveboardViewConfig);
220
+ liveboardEmbed2.render();
221
+ await executeAfterWait(() => {
222
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
223
+ hideAction: JSON.stringify([Action.ReportError, Action.EditLiveboard]),
224
+ });
225
+ });
226
+ });
227
+
177
228
  test('should set visible actions', async () => {
178
229
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
179
230
  visibleActions: [Action.DownloadAsCsv, Action.DownloadAsPdf, Action.DownloadAsXlsx],
@@ -1621,6 +1672,58 @@ describe('Liveboard/viz embed tests', () => {
1621
1672
  });
1622
1673
  });
1623
1674
 
1675
+ describe('liveboardOverride in APP_INIT embedParams', () => {
1676
+ const liveboardOverride = {
1677
+ dataSourceOverride: [{
1678
+ dataSourceIdentifier: 'model-guid',
1679
+ filterQuery: [{ tabName: 'Sales', groupName: 'Region', filterQueryToken: 'color = red' }],
1680
+ }],
1681
+ };
1682
+
1683
+ const getAppInitResponse = async (viewConfig: Partial<LiveboardViewConfig>) => {
1684
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1685
+ ...defaultViewConfig,
1686
+ liveboardId,
1687
+ ...viewConfig,
1688
+ } as LiveboardViewConfig);
1689
+
1690
+ mockMessageChannel();
1691
+ await liveboardEmbed.render();
1692
+
1693
+ const mockPort: any = { postMessage: jest.fn() };
1694
+ await executeAfterWait(() => {
1695
+ postMessageToParent(getIFrameEl().contentWindow, { type: EmbedEvent.APP_INIT, data: {} }, mockPort);
1696
+ });
1697
+ let data: any;
1698
+ await executeAfterWait(() => {
1699
+ data = mockPort.postMessage.mock.calls[0][0].data;
1700
+ });
1701
+ return data;
1702
+ };
1703
+
1704
+ test('should include liveboardOverride when provided', async () => {
1705
+ const data = await getAppInitResponse({ liveboardOverride });
1706
+ expect(data.embedParams.liveboardOverride).toEqual(liveboardOverride);
1707
+ });
1708
+
1709
+ test('should not include liveboardOverride when not provided', async () => {
1710
+ const data = await getAppInitResponse({});
1711
+ expect(data.embedParams?.liveboardOverride).toBeUndefined();
1712
+ });
1713
+
1714
+ test('should not include liveboardOverride when dataSourceOverride is empty', async () => {
1715
+ const data = await getAppInitResponse({ liveboardOverride: { dataSourceOverride: [] } });
1716
+ expect(data.embedParams?.liveboardOverride).toBeUndefined();
1717
+ });
1718
+
1719
+ test('should send liveboardOverride alongside spotterVizConfig', async () => {
1720
+ const spotterViz = { brandName: 'MyBrand' };
1721
+ const data = await getAppInitResponse({ liveboardOverride, spotterViz });
1722
+ expect(data.embedParams.liveboardOverride).toEqual(liveboardOverride);
1723
+ expect(data.embedParams.spotterVizConfig).toEqual(spotterViz);
1724
+ });
1725
+ });
1726
+
1624
1727
  test('should include starterPrompts in APP_INIT embedParams', async () => {
1625
1728
  const starterPrompts = {
1626
1729
  enable: true,
@@ -3179,3 +3282,38 @@ describe('LiveboardEmbed updatedSpotterExperience tests', () => {
3179
3282
  });
3180
3283
  });
3181
3284
  });
3285
+
3286
+ describe('LiveboardEmbed spotterExperienceVersion tests', () => {
3287
+ beforeEach(() => {
3288
+ document.body.innerHTML = getDocumentBody();
3289
+ });
3290
+
3291
+ const renderWithConfig = async (config: Partial<LiveboardViewConfig>) => {
3292
+ document.body.innerHTML = getDocumentBody();
3293
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
3294
+ ...defaultViewConfig,
3295
+ liveboardId,
3296
+ ...config,
3297
+ } as LiveboardViewConfig);
3298
+ await liveboardEmbed.render();
3299
+ let src = '';
3300
+ await executeAfterWait(() => {
3301
+ src = getIFrameSrc();
3302
+ });
3303
+ return src;
3304
+ };
3305
+
3306
+ test('should add the spotterExperienceVersion param when spotterExperienceVersion is set', async () => {
3307
+ const src = await renderWithConfig({
3308
+ spotterExperienceVersion: SpotterExperienceVersion.SPOTTER_2026_11,
3309
+ });
3310
+ expect(src).toContain(
3311
+ `spotterExperienceVersion=${SpotterExperienceVersion.SPOTTER_2026_11}`,
3312
+ );
3313
+ });
3314
+
3315
+ test('should not add the spotterExperienceVersion param when spotterExperienceVersion is not set', async () => {
3316
+ const src = await renderWithConfig({});
3317
+ expect(src).not.toContain('spotterExperienceVersion=');
3318
+ });
3319
+ });
@@ -35,8 +35,9 @@ import { addPreviewStylesIfNotPresent } from '../utils/global-styles';
35
35
  import { HostEventRequest, TriggerData, TriggerResponse } from '../contracts/host-event-contracts';
36
36
  import { logger } from '../utils/logger';
37
37
  import { SpotterChatViewConfig, StarterPromptsConfig } from './conversation';
38
- import { buildStarterPromptsAppInitData } from './spotter-utils';
38
+ import { buildStarterPromptsAppInitData, SpotterExperienceVersion } from './spotter-utils';
39
39
  import { SpotterVizConfig, buildSpotterVizAppInitData } from './spotter-viz-utils';
40
+ import { LiveboardOverride, buildLiveboardOverrideAppInitData } from './liveboard-override-utils';
40
41
 
41
42
  // Home unmounts the liveboard container, which is how its state gets cleared.
42
43
  // The settle window gives the container time to do it before we ask for the
@@ -52,6 +53,7 @@ export interface LiveboardEmbedAppInitData extends DefaultAppInitData {
52
53
  embedParams?: {
53
54
  spotterVizConfig?: SpotterVizConfig;
54
55
  starterPrompts?: StarterPromptsConfig;
56
+ liveboardOverride?: LiveboardOverride;
55
57
  };
56
58
  }
57
59
 
@@ -61,7 +63,8 @@ export interface LiveboardEmbedAppInitData extends DefaultAppInitData {
61
63
  * @group Embed components
62
64
  */
63
65
  export interface LiveboardViewConfig
64
- extends BaseViewConfig,
66
+ extends
67
+ BaseViewConfig,
65
68
  FullHeightViewConfig,
66
69
  LiveboardOtherViewConfig,
67
70
  LiveboardAppEmbedViewConfig {
@@ -546,6 +549,46 @@ export interface LiveboardViewConfig
546
549
  * ```
547
550
  */
548
551
  updatedSpotterExperience?: boolean;
552
+ /**
553
+ * Filters and Parameters to apply to the Liveboard when it loads.
554
+ *
555
+ * In an embedded Liveboard, this is the only way to set these overrides.
556
+ * The `filter` and `parameter` URL query params are ignored.
557
+ * Clauses without a query token are dropped.
558
+ *
559
+ * Supported embed types: `LiveboardEmbed`
560
+ * @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
561
+ * @example
562
+ * ```js
563
+ * const embed = new LiveboardEmbed('#tsEmbed', {
564
+ * ... // other embed view config
565
+ * liveboardOverride: {
566
+ * dataSourceOverride: [{
567
+ * dataSourceIdentifier: '<model-guid>',
568
+ * filterQuery: [{
569
+ * tabName: 'Sales',
570
+ * groupName: 'Region',
571
+ * filterQueryToken: 'color = red',
572
+ * }],
573
+ * }],
574
+ * },
575
+ * })
576
+ * ```
577
+ */
578
+ liveboardOverride?: LiveboardOverride;
579
+ /**
580
+ * The Spotter experience version to load for the Spotter surface shown within
581
+ * this embed.
582
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.11.0.cl
583
+ * @example
584
+ * ```js
585
+ * const embed = new LiveboardEmbed('#tsEmbed', {
586
+ * ... // other options
587
+ * spotterExperienceVersion: SpotterExperienceVersion.SPOTTER_2026_11,
588
+ * });
589
+ * ```
590
+ */
591
+ spotterExperienceVersion?: SpotterExperienceVersion;
549
592
  }
550
593
 
551
594
  /**
@@ -600,7 +643,8 @@ export class LiveboardEmbed extends V1Embed {
600
643
  protected async getAppInitData(): Promise<LiveboardEmbedAppInitData> {
601
644
  const defaultAppInitData = await super.getAppInitData();
602
645
  const vizInitData = buildSpotterVizAppInitData(defaultAppInitData, this.viewConfig);
603
- return buildStarterPromptsAppInitData(vizInitData, this.viewConfig);
646
+ const starterPromptsInitData = buildStarterPromptsAppInitData(vizInitData, this.viewConfig);
647
+ return buildLiveboardOverrideAppInitData(starterPromptsInitData, this.viewConfig);
604
648
  }
605
649
 
606
650
  /**
@@ -608,7 +652,7 @@ export class LiveboardEmbed extends V1Embed {
608
652
  * embedded Liveboard or visualization.
609
653
  */
610
654
  protected getEmbedParams() {
611
- const params = this.getEmbedParamsObject();
655
+ const params = this.getUrlQueryParamsObject();
612
656
  const queryParams = getQueryParamString(params, true);
613
657
  return queryParams;
614
658
  }
@@ -661,6 +705,7 @@ export class LiveboardEmbed extends V1Embed {
661
705
  isThisPeriodInDateFiltersEnabled,
662
706
  isContinuousLiveboardPDFEnabled,
663
707
  enableLiveboardDataCache,
708
+ spotterExperienceVersion,
664
709
  } = this.viewConfig;
665
710
 
666
711
  const preventLiveboardFilterRemoval = this.viewConfig.preventLiveboardFilterRemoval
@@ -730,6 +775,10 @@ export class LiveboardEmbed extends V1Embed {
730
775
  params[Param.IsLiveboardStylingAndGroupingEnabled] = isLiveboardStylingAndGroupingEnabled;
731
776
  }
732
777
 
778
+ if (spotterExperienceVersion !== undefined) {
779
+ params[Param.SpotterExperienceVersion] = spotterExperienceVersion;
780
+ }
781
+
733
782
  if (liveboardGutter !== undefined) {
734
783
  params[Param.LiveboardGutter] = liveboardGutter;
735
784
  }
@@ -967,7 +1016,7 @@ export class LiveboardEmbed extends V1Embed {
967
1016
  // instance. React builds a new instance per mount, so an equal config
968
1017
  // is a hide/show, not a hand-over: there is nothing stale to clear.
969
1018
  const previous = this.getPreRenderObj<LiveboardEmbed>();
970
- const showing = this.isSameEmbedConfig(previous)
1019
+ const previousRoute = this.isSameEmbedConfig(previous)
971
1020
  ? undefined
972
1021
  : previous?.currentLiveboardState;
973
1022
 
@@ -976,7 +1025,7 @@ export class LiveboardEmbed extends V1Embed {
976
1025
  // Navigate goes out first, so the container loads with the previous
977
1026
  // config's filters.
978
1027
  await this.preRenderParamsApplied;
979
- if (this.isShowingLiveboardRoute(showing)) {
1028
+ if (this.isAlreadyOnSameRoute(previousRoute)) {
980
1029
  // Navigate to the route we are already on is a no-op, so the
981
1030
  // liveboard keeps its state. Home unmounts the container, which
982
1031
  // clears it.
@@ -1003,18 +1052,9 @@ export class LiveboardEmbed extends V1Embed {
1003
1052
  });
1004
1053
  }
1005
1054
 
1006
- /**
1007
- * Whether `previous` was showing what this instance is about to show.
1008
- *
1009
- * Undefined-valued keys are dropped before comparing. `navigateToLiveboard`
1010
- * assigns `vizId`, `activeTabId` and `personalizedViewId` unconditionally,
1011
- * so an instance that has been shown once carries those keys as `undefined`
1012
- * while a freshly constructed one does not have them at all. `isEqual`
1013
- * counts own keys, so without this the comparison can never be true after
1014
- * the first show — which is the whole case this exists for.
1015
- *
1016
- * Callbacks compare as equal: React passes a fresh closure per render.
1017
- */
1055
+ // definedEntries drops undefined-valued keys: a shown instance carries
1056
+ // vizId/activeTabId/etc as undefined, so a raw isEqual never matches again.
1057
+ // Functions compare equal, since React passes a fresh closure per render.
1018
1058
  private isSameEmbedConfig(previous?: LiveboardEmbed): boolean {
1019
1059
  if (!previous) return false;
1020
1060
  if (previous === this) return true;
@@ -1028,15 +1068,15 @@ export class LiveboardEmbed extends V1Embed {
1028
1068
  // The whole route, not just the liveboard id: the path is built from the
1029
1069
  // viz, tab and view too, so a same-liveboard show onto another tab is a
1030
1070
  // real navigation.
1031
- private isShowingLiveboardRoute(showing?: LiveboardEmbed['currentLiveboardState']): boolean {
1032
- if (!showing?.liveboardId) return false;
1071
+ private isAlreadyOnSameRoute(previousRoute?: LiveboardEmbed['currentLiveboardState']): boolean {
1072
+ if (!previousRoute?.liveboardId) return false;
1033
1073
  const {
1034
1074
  liveboardId, vizId, activeTabId, personalizedViewId,
1035
1075
  } = this.viewConfig;
1036
- return showing.liveboardId === liveboardId
1037
- && showing.vizId === vizId
1038
- && showing.activeTabId === activeTabId
1039
- && showing.personalizedViewId === personalizedViewId;
1076
+ return previousRoute.liveboardId === liveboardId
1077
+ && previousRoute.vizId === vizId
1078
+ && previousRoute.activeTabId === activeTabId
1079
+ && previousRoute.personalizedViewId === personalizedViewId;
1040
1080
  }
1041
1081
 
1042
1082
  protected async handleRenderForPrerender(): Promise<TsEmbed> {
@@ -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) {
@@ -58,6 +58,26 @@ describe('buildSpotterSidebarAppInitData', () => {
58
58
  .toEqual(spotterChatPinConfig);
59
59
  });
60
60
 
61
+ it('lifts enableSpotterInstructionAndMoreSettings to the top level of embedParams', () => {
62
+ const result = buildSpotterSidebarAppInitData(base, {
63
+ spotterSidebarConfig: {
64
+ enablePastConversationsSidebar: true,
65
+ enableSpotterInstructionAndMoreSettings: false,
66
+ },
67
+ }, noopError);
68
+ expect(result.embedParams?.enableSpotterInstructionAndMoreSettings).toBe(false);
69
+ expect(result.embedParams?.spotterSidebarConfig).toEqual({
70
+ enablePastConversationsSidebar: true,
71
+ });
72
+ });
73
+
74
+ it('omits enableSpotterInstructionAndMoreSettings when it is not set', () => {
75
+ const result = buildSpotterSidebarAppInitData(base, {
76
+ spotterSidebarConfig: { enablePastConversationsSidebar: true },
77
+ }, noopError);
78
+ expect(result.embedParams).not.toHaveProperty('enableSpotterInstructionAndMoreSettings');
79
+ });
80
+
61
81
  it('promotes standalone flag into spotterSidebarConfig.enablePastConversationsSidebar', () => {
62
82
  const result = buildSpotterSidebarAppInitData(base, { enablePastConversationsSidebar: true }, noopError);
63
83
  expect(result.embedParams?.spotterSidebarConfig?.enablePastConversationsSidebar).toBe(true);
@@ -36,6 +36,7 @@ export function buildSpotterSidebarAppInitData<T extends DefaultAppInitData>(
36
36
  embedParams?: {
37
37
  spotterSidebarConfig?: SpotterSidebarViewConfig;
38
38
  visualOverridesParams?: VisualizationOverrides | null;
39
+ enableSpotterInstructionAndMoreSettings?: boolean;
39
40
  };
40
41
  } {
41
42
  const { spotterSidebarConfig, enablePastConversationsSidebar, visualOverrides } = viewConfig;
@@ -56,8 +57,15 @@ export function buildSpotterSidebarAppInitData<T extends DefaultAppInitData>(
56
57
  };
57
58
  }
58
59
 
60
+ // The app reads enableSpotterInstructionAndMoreSettings from the top level
61
+ // of embedParams, so lift it out of the sidebar config.
62
+ const {
63
+ enableSpotterInstructionAndMoreSettings,
64
+ ...sidebarConfigRest
65
+ } = spotterSidebarConfig || {};
66
+
59
67
  const resolvedSidebarConfig: SpotterSidebarViewConfig = {
60
- ...spotterSidebarConfig,
68
+ ...sidebarConfigRest,
61
69
  ...(resolvedEnablePastConversations !== undefined && {
62
70
  enablePastConversationsSidebar: resolvedEnablePastConversations,
63
71
  }),
@@ -81,6 +89,9 @@ export function buildSpotterSidebarAppInitData<T extends DefaultAppInitData>(
81
89
  embedParams: {
82
90
  ...((defaultAppInitData as any).embedParams || {}),
83
91
  spotterSidebarConfig: resolvedSidebarConfig,
92
+ ...(enableSpotterInstructionAndMoreSettings !== undefined
93
+ ? { enableSpotterInstructionAndMoreSettings }
94
+ : {}),
84
95
  ...(visualOverrides !== undefined ? { visualOverridesParams: visualOverrides } : {}),
85
96
  },
86
97
  };
@@ -130,3 +141,15 @@ export function buildSpotterAnalystAppInitData<T extends DefaultAppInitData>(
130
141
  },
131
142
  };
132
143
  }
144
+
145
+ /**
146
+ * The Spotter experience version to load in the embedded view.
147
+ * @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.11.0.cl
148
+ * @group Embed components
149
+ */
150
+ export enum SpotterExperienceVersion {
151
+ /**
152
+ * The Spotter experience version introduced in ThoughtSpot 26.11.
153
+ */
154
+ SPOTTER_2026_11 = 'spotter_2026_11',
155
+ }
@@ -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
  /**