@thoughtspot/visual-embed-sdk 1.50.1 → 1.51.0-test

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 (238) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/config.d.ts +1 -0
  3. package/cjs/src/config.d.ts.map +1 -1
  4. package/cjs/src/config.js +2 -1
  5. package/cjs/src/config.js.map +1 -1
  6. package/cjs/src/css-variables.d.ts +63 -0
  7. package/cjs/src/css-variables.d.ts.map +1 -1
  8. package/cjs/src/embed/app.d.ts +148 -25
  9. package/cjs/src/embed/app.d.ts.map +1 -1
  10. package/cjs/src/embed/app.js +74 -37
  11. package/cjs/src/embed/app.js.map +1 -1
  12. package/cjs/src/embed/app.spec.js +571 -150
  13. package/cjs/src/embed/app.spec.js.map +1 -1
  14. package/cjs/src/embed/base.d.ts +1 -1
  15. package/cjs/src/embed/base.js +1 -1
  16. package/cjs/src/embed/conversation.d.ts +375 -2
  17. package/cjs/src/embed/conversation.d.ts.map +1 -1
  18. package/cjs/src/embed/conversation.js +21 -15
  19. package/cjs/src/embed/conversation.js.map +1 -1
  20. package/cjs/src/embed/conversation.spec.js +323 -17
  21. package/cjs/src/embed/conversation.spec.js.map +1 -1
  22. package/cjs/src/embed/events.spec.js +45 -0
  23. package/cjs/src/embed/events.spec.js.map +1 -1
  24. package/cjs/src/embed/host-events.spec.js +81 -0
  25. package/cjs/src/embed/host-events.spec.js.map +1 -1
  26. package/cjs/src/embed/hostEventClient/contracts.d.ts +15 -0
  27. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  28. package/cjs/src/embed/hostEventClient/contracts.js +1 -0
  29. package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
  30. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  31. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  32. package/cjs/src/embed/hostEventClient/host-event-client.js +1 -0
  33. package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
  34. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +27 -0
  35. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  36. package/cjs/src/embed/liveboard.d.ts +76 -14
  37. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  38. package/cjs/src/embed/liveboard.js +50 -9
  39. package/cjs/src/embed/liveboard.js.map +1 -1
  40. package/cjs/src/embed/liveboard.spec.js +432 -4
  41. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  42. package/cjs/src/embed/spotter-utils.d.ts +15 -1
  43. package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
  44. package/cjs/src/embed/spotter-utils.js +28 -1
  45. package/cjs/src/embed/spotter-utils.js.map +1 -1
  46. package/cjs/src/embed/spotter-utils.spec.js +129 -0
  47. package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
  48. package/cjs/src/embed/spotter-viz-utils.d.ts +9 -10
  49. package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
  50. package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
  51. package/cjs/src/embed/ts-embed.d.ts +16 -8
  52. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  53. package/cjs/src/embed/ts-embed.js +82 -30
  54. package/cjs/src/embed/ts-embed.js.map +1 -1
  55. package/cjs/src/embed/ts-embed.spec.js +537 -3
  56. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  57. package/cjs/src/index.d.ts +3 -3
  58. package/cjs/src/index.d.ts.map +1 -1
  59. package/cjs/src/index.js +3 -2
  60. package/cjs/src/index.js.map +1 -1
  61. package/cjs/src/mixpanel-service.d.ts +4 -0
  62. package/cjs/src/mixpanel-service.d.ts.map +1 -1
  63. package/cjs/src/mixpanel-service.js +4 -0
  64. package/cjs/src/mixpanel-service.js.map +1 -1
  65. package/cjs/src/react/all-types-export.d.ts +1 -1
  66. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  67. package/cjs/src/react/all-types-export.js +2 -1
  68. package/cjs/src/react/all-types-export.js.map +1 -1
  69. package/cjs/src/react/all-types-export.parity.spec.d.ts +2 -0
  70. package/cjs/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  71. package/cjs/src/react/all-types-export.parity.spec.js +194 -0
  72. package/cjs/src/react/all-types-export.parity.spec.js.map +1 -0
  73. package/cjs/src/react/index.d.ts +66 -32
  74. package/cjs/src/react/index.d.ts.map +1 -1
  75. package/cjs/src/react/index.js +5 -3
  76. package/cjs/src/react/index.js.map +1 -1
  77. package/cjs/src/react/index.spec.js +101 -0
  78. package/cjs/src/react/index.spec.js.map +1 -1
  79. package/cjs/src/types.d.ts +789 -32
  80. package/cjs/src/types.d.ts.map +1 -1
  81. package/cjs/src/types.js +610 -20
  82. package/cjs/src/types.js.map +1 -1
  83. package/cjs/src/utils.spec.js +4 -0
  84. package/cjs/src/utils.spec.js.map +1 -1
  85. package/dist/{index-fCne7kmU.js → index-Bivg-mDx.js} +1 -1
  86. package/dist/src/config.d.ts +1 -0
  87. package/dist/src/config.d.ts.map +1 -1
  88. package/dist/src/css-variables.d.ts +63 -0
  89. package/dist/src/css-variables.d.ts.map +1 -1
  90. package/dist/src/embed/app.d.ts +148 -25
  91. package/dist/src/embed/app.d.ts.map +1 -1
  92. package/dist/src/embed/base.d.ts +1 -1
  93. package/dist/src/embed/conversation.d.ts +375 -2
  94. package/dist/src/embed/conversation.d.ts.map +1 -1
  95. package/dist/src/embed/hostEventClient/contracts.d.ts +15 -0
  96. package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  97. package/dist/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  98. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  99. package/dist/src/embed/liveboard.d.ts +76 -14
  100. package/dist/src/embed/liveboard.d.ts.map +1 -1
  101. package/dist/src/embed/spotter-utils.d.ts +15 -1
  102. package/dist/src/embed/spotter-utils.d.ts.map +1 -1
  103. package/dist/src/embed/spotter-viz-utils.d.ts +9 -10
  104. package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
  105. package/dist/src/embed/ts-embed.d.ts +16 -8
  106. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  107. package/dist/src/index.d.ts +3 -3
  108. package/dist/src/index.d.ts.map +1 -1
  109. package/dist/src/mixpanel-service.d.ts +4 -0
  110. package/dist/src/mixpanel-service.d.ts.map +1 -1
  111. package/dist/src/react/all-types-export.d.ts +1 -1
  112. package/dist/src/react/all-types-export.d.ts.map +1 -1
  113. package/dist/src/react/all-types-export.parity.spec.d.ts +2 -0
  114. package/dist/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  115. package/dist/src/react/index.d.ts +66 -32
  116. package/dist/src/react/index.d.ts.map +1 -1
  117. package/dist/src/types.d.ts +789 -32
  118. package/dist/src/types.d.ts.map +1 -1
  119. package/dist/tsembed-react.es.js +878 -120
  120. package/dist/tsembed-react.js +877 -119
  121. package/dist/tsembed.es.js +936 -181
  122. package/dist/tsembed.js +938 -183
  123. package/dist/visual-embed-sdk-react-full.d.ts +1553 -128
  124. package/dist/visual-embed-sdk-react.d.ts +1555 -129
  125. package/dist/visual-embed-sdk.d.ts +1499 -100
  126. package/lib/package.json +1 -1
  127. package/lib/src/config.d.ts +1 -0
  128. package/lib/src/config.d.ts.map +1 -1
  129. package/lib/src/config.js +1 -0
  130. package/lib/src/config.js.map +1 -1
  131. package/lib/src/css-variables.d.ts +63 -0
  132. package/lib/src/css-variables.d.ts.map +1 -1
  133. package/lib/src/embed/app.d.ts +148 -25
  134. package/lib/src/embed/app.d.ts.map +1 -1
  135. package/lib/src/embed/app.js +75 -38
  136. package/lib/src/embed/app.js.map +1 -1
  137. package/lib/src/embed/app.spec.js +572 -151
  138. package/lib/src/embed/app.spec.js.map +1 -1
  139. package/lib/src/embed/base.d.ts +1 -1
  140. package/lib/src/embed/base.js +1 -1
  141. package/lib/src/embed/conversation.d.ts +375 -2
  142. package/lib/src/embed/conversation.d.ts.map +1 -1
  143. package/lib/src/embed/conversation.js +23 -17
  144. package/lib/src/embed/conversation.js.map +1 -1
  145. package/lib/src/embed/conversation.spec.js +323 -17
  146. package/lib/src/embed/conversation.spec.js.map +1 -1
  147. package/lib/src/embed/events.spec.js +45 -0
  148. package/lib/src/embed/events.spec.js.map +1 -1
  149. package/lib/src/embed/host-events.spec.js +81 -0
  150. package/lib/src/embed/host-events.spec.js.map +1 -1
  151. package/lib/src/embed/hostEventClient/contracts.d.ts +15 -0
  152. package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  153. package/lib/src/embed/hostEventClient/contracts.js +1 -0
  154. package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
  155. package/lib/src/embed/hostEventClient/host-event-client.d.ts +1 -1
  156. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  157. package/lib/src/embed/hostEventClient/host-event-client.js +1 -0
  158. package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
  159. package/lib/src/embed/hostEventClient/host-event-client.spec.js +27 -0
  160. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  161. package/lib/src/embed/liveboard.d.ts +76 -14
  162. package/lib/src/embed/liveboard.d.ts.map +1 -1
  163. package/lib/src/embed/liveboard.js +50 -9
  164. package/lib/src/embed/liveboard.js.map +1 -1
  165. package/lib/src/embed/liveboard.spec.js +432 -4
  166. package/lib/src/embed/liveboard.spec.js.map +1 -1
  167. package/lib/src/embed/spotter-utils.d.ts +15 -1
  168. package/lib/src/embed/spotter-utils.d.ts.map +1 -1
  169. package/lib/src/embed/spotter-utils.js +25 -0
  170. package/lib/src/embed/spotter-utils.js.map +1 -1
  171. package/lib/src/embed/spotter-utils.spec.js +130 -1
  172. package/lib/src/embed/spotter-utils.spec.js.map +1 -1
  173. package/lib/src/embed/spotter-viz-utils.d.ts +9 -10
  174. package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
  175. package/lib/src/embed/spotter-viz-utils.js.map +1 -1
  176. package/lib/src/embed/ts-embed.d.ts +16 -8
  177. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  178. package/lib/src/embed/ts-embed.js +82 -30
  179. package/lib/src/embed/ts-embed.js.map +1 -1
  180. package/lib/src/embed/ts-embed.spec.js +537 -3
  181. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  182. package/lib/src/index.d.ts +3 -3
  183. package/lib/src/index.d.ts.map +1 -1
  184. package/lib/src/index.js +2 -2
  185. package/lib/src/index.js.map +1 -1
  186. package/lib/src/mixpanel-service.d.ts +4 -0
  187. package/lib/src/mixpanel-service.d.ts.map +1 -1
  188. package/lib/src/mixpanel-service.js +4 -0
  189. package/lib/src/mixpanel-service.js.map +1 -1
  190. package/lib/src/react/all-types-export.d.ts +1 -1
  191. package/lib/src/react/all-types-export.d.ts.map +1 -1
  192. package/lib/src/react/all-types-export.js +1 -1
  193. package/lib/src/react/all-types-export.js.map +1 -1
  194. package/lib/src/react/all-types-export.parity.spec.d.ts +2 -0
  195. package/lib/src/react/all-types-export.parity.spec.d.ts.map +1 -0
  196. package/lib/src/react/all-types-export.parity.spec.js +191 -0
  197. package/lib/src/react/all-types-export.parity.spec.js.map +1 -0
  198. package/lib/src/react/index.d.ts +66 -32
  199. package/lib/src/react/index.d.ts.map +1 -1
  200. package/lib/src/react/index.js +5 -3
  201. package/lib/src/react/index.js.map +1 -1
  202. package/lib/src/react/index.spec.js +102 -1
  203. package/lib/src/react/index.spec.js.map +1 -1
  204. package/lib/src/types.d.ts +789 -32
  205. package/lib/src/types.d.ts.map +1 -1
  206. package/lib/src/types.js +610 -20
  207. package/lib/src/types.js.map +1 -1
  208. package/lib/src/utils.spec.js +4 -0
  209. package/lib/src/utils.spec.js.map +1 -1
  210. package/lib/src/visual-embed-sdk.d.ts +1499 -100
  211. package/package.json +1 -1
  212. package/src/config.ts +1 -0
  213. package/src/css-variables.ts +77 -0
  214. package/src/embed/app.spec.ts +729 -188
  215. package/src/embed/app.ts +240 -75
  216. package/src/embed/base.ts +1 -1
  217. package/src/embed/conversation.spec.ts +379 -20
  218. package/src/embed/conversation.ts +412 -18
  219. package/src/embed/events.spec.ts +56 -0
  220. package/src/embed/host-events.spec.ts +118 -0
  221. package/src/embed/hostEventClient/contracts.ts +16 -0
  222. package/src/embed/hostEventClient/host-event-client.spec.ts +46 -0
  223. package/src/embed/hostEventClient/host-event-client.ts +3 -2
  224. package/src/embed/liveboard.spec.ts +565 -4
  225. package/src/embed/liveboard.ts +150 -29
  226. package/src/embed/spotter-utils.spec.ts +140 -1
  227. package/src/embed/spotter-utils.ts +36 -1
  228. package/src/embed/spotter-viz-utils.ts +9 -10
  229. package/src/embed/ts-embed.spec.ts +699 -3
  230. package/src/embed/ts-embed.ts +99 -35
  231. package/src/index.ts +44 -2
  232. package/src/mixpanel-service.ts +4 -0
  233. package/src/react/all-types-export.parity.spec.ts +208 -0
  234. package/src/react/all-types-export.ts +22 -0
  235. package/src/react/index.spec.tsx +158 -0
  236. package/src/react/index.tsx +70 -33
  237. package/src/types.ts +791 -30
  238. package/src/utils.spec.ts +5 -0
package/src/embed/base.ts CHANGED
@@ -233,7 +233,7 @@ export const getIsInitCalled = (): boolean => !!getValueFromWindow(initFlagKey)?
233
233
  /**
234
234
  * Initializes the Visual Embed SDK globally and perform
235
235
  * authentication if applicable. This function needs to be called before any ThoughtSpot
236
- * component like Liveboard etc can be embedded. But need not wait for AuthEvent.SUCCESS
236
+ * component like Liveboard etc can be embedded. But need not wait for AuthStatus.SUCCESS
237
237
  * to actually embed. That is handled internally.
238
238
  * @param embedConfig The configuration object containing ThoughtSpot host,
239
239
  * authentication mechanism and so on.
@@ -45,6 +45,40 @@ describe('ConversationEmbed', () => {
45
45
  );
46
46
  });
47
47
 
48
+ it('should deep-link to the shared-conversation reader view when sharedConversationId is set', async () => {
49
+ const viewConfig: SpotterEmbedViewConfig = {
50
+ worksheetId: 'worksheetId',
51
+ searchOptions: {
52
+ searchQuery: 'searchQuery',
53
+ },
54
+ sharedConversationId: 'conv-123',
55
+ };
56
+
57
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
58
+ await conversationEmbed.render();
59
+ expectUrlMatchesWithParams(
60
+ getIFrameSrc(),
61
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true#/embed/insights/conv-assist/s/conv-123?worksheet=worksheetId&query=searchQuery`,
62
+ );
63
+ });
64
+
65
+ it('should URL-encode the sharedConversationId in the reader-view path', async () => {
66
+ const viewConfig: SpotterEmbedViewConfig = {
67
+ worksheetId: 'worksheetId',
68
+ searchOptions: {
69
+ searchQuery: 'searchQuery',
70
+ },
71
+ sharedConversationId: 'conv/1',
72
+ };
73
+
74
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
75
+ await conversationEmbed.render();
76
+ expectUrlMatchesWithParams(
77
+ getIFrameSrc(),
78
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true#/embed/insights/conv-assist/s/conv%2F1?worksheet=worksheetId&query=searchQuery`,
79
+ );
80
+ });
81
+
48
82
  it('should render the conversation embed with worksheets disabled', async () => {
49
83
  const viewConfig: SpotterEmbedViewConfig = {
50
84
  worksheetId: 'worksheetId',
@@ -113,26 +147,6 @@ describe('ConversationEmbed', () => {
113
147
  );
114
148
  });
115
149
 
116
- it('should handle error when worksheetId is not provided', async () => {
117
- const viewConfig: SpotterEmbedViewConfig = {
118
- worksheetId: '',
119
- searchOptions: {
120
- searchQuery: 'searchQuery',
121
- },
122
- };
123
- const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
124
- (conversationEmbed as any).handleError = jest.fn();
125
- await conversationEmbed.render();
126
- expect((conversationEmbed as any).handleError).toHaveBeenCalledWith(
127
- {
128
- errorType: ErrorDetailsTypes.VALIDATION_ERROR,
129
- message: ERROR_MESSAGE.SPOTTER_EMBED_WORKSHEED_ID_NOT_FOUND,
130
- code: EmbedErrorCodes.WORKSHEET_ID_NOT_FOUND,
131
- error: ERROR_MESSAGE.SPOTTER_EMBED_WORKSHEED_ID_NOT_FOUND,
132
- },
133
- );
134
- });
135
-
136
150
  it('should render the conversation embed if data panel v2 flag is true', async () => {
137
151
  const viewConfig: SpotterEmbedViewConfig = {
138
152
  worksheetId: 'worksheetId',
@@ -460,6 +474,38 @@ describe('ConversationEmbed', () => {
460
474
  );
461
475
  });
462
476
 
477
+ it('should render the conversation embed with spotter radiance', async () => {
478
+ const viewConfig: SpotterEmbedViewConfig = {
479
+ worksheetId: 'worksheetId',
480
+ searchOptions: {
481
+ searchQuery: 'searchQuery',
482
+ },
483
+ showSpotterRadiance: true,
484
+ };
485
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
486
+ await conversationEmbed.render();
487
+ expectUrlMatchesWithParams(
488
+ getIFrameSrc(),
489
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&showSpotterRadiance=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
490
+ );
491
+ });
492
+
493
+ it('should render the conversation embed with spotter radiance disabled', async () => {
494
+ const viewConfig: SpotterEmbedViewConfig = {
495
+ worksheetId: 'worksheetId',
496
+ searchOptions: {
497
+ searchQuery: 'searchQuery',
498
+ },
499
+ showSpotterRadiance: false,
500
+ };
501
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
502
+ await conversationEmbed.render();
503
+ expectUrlMatchesWithParams(
504
+ getIFrameSrc(),
505
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&showSpotterRadiance=false#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
506
+ );
507
+ });
508
+
463
509
  it('should render the conversation embed with default query mode set to research', async () => {
464
510
  const viewConfig: SpotterEmbedViewConfig = {
465
511
  worksheetId: 'worksheetId',
@@ -491,6 +537,49 @@ describe('ConversationEmbed', () => {
491
537
  );
492
538
  });
493
539
 
540
+ it('should render the conversation embed with spotterAnalystConfig.analystId in the url', async () => {
541
+ const viewConfig: SpotterEmbedViewConfig = {
542
+ worksheetId: 'worksheetId',
543
+ searchOptions: {
544
+ searchQuery: 'searchQuery',
545
+ },
546
+ spotterAnalystConfig: {
547
+ analystId: 'analyst-id-1234',
548
+ },
549
+ };
550
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
551
+ await conversationEmbed.render();
552
+ expectUrlMatchesWithParams(
553
+ getIFrameSrc(),
554
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&analystId=analyst-id-1234#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
555
+ );
556
+ });
557
+
558
+ it('should not add analystId to the url when spotterAnalystConfig is not provided', async () => {
559
+ const viewConfig: SpotterEmbedViewConfig = {
560
+ worksheetId: 'worksheetId',
561
+ searchOptions: {
562
+ searchQuery: 'searchQuery',
563
+ },
564
+ };
565
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
566
+ await conversationEmbed.render();
567
+ expect(getIFrameSrc()).not.toContain('analystId');
568
+ });
569
+
570
+ it('should not add analystId to the url when spotterAnalystConfig is empty', async () => {
571
+ const viewConfig: SpotterEmbedViewConfig = {
572
+ worksheetId: 'worksheetId',
573
+ searchOptions: {
574
+ searchQuery: 'searchQuery',
575
+ },
576
+ spotterAnalystConfig: {},
577
+ };
578
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
579
+ await conversationEmbed.render();
580
+ expect(getIFrameSrc()).not.toContain('analystId');
581
+ });
582
+
494
583
  describe('spotter chat hiddenActions', () => {
495
584
  it.each([
496
585
  ['SpotterChatConnectorResources', Action.SpotterChatConnectorResources],
@@ -502,6 +591,8 @@ describe('ConversationEmbed', () => {
502
591
  ['SpotterAnalystDelete', Action.SpotterAnalystDelete],
503
592
  ['SpotterAnalystMakeACopy', Action.SpotterAnalystMakeACopy],
504
593
  ['SpotterAnalystSidebar', Action.SpotterAnalystSidebar],
594
+ ['SpotterAnalystList', Action.SpotterAnalystList],
595
+ ['SpotterDefaultAnalyst', Action.SpotterDefaultAnalyst],
505
596
  ])('should render with hiddenActions for %s', async (_, action) => {
506
597
  const viewConfig: SpotterEmbedViewConfig = {
507
598
  worksheetId: 'worksheetId',
@@ -546,6 +637,8 @@ describe('ConversationEmbed', () => {
546
637
  ['SpotterAnalystDelete', Action.SpotterAnalystDelete],
547
638
  ['SpotterAnalystMakeACopy', Action.SpotterAnalystMakeACopy],
548
639
  ['SpotterAnalystSidebar', Action.SpotterAnalystSidebar],
640
+ ['SpotterAnalystList', Action.SpotterAnalystList],
641
+ ['SpotterDefaultAnalyst', Action.SpotterDefaultAnalyst],
549
642
  ])('should render with disabledActions for %s', async (_, action) => {
550
643
  const disabledReason = 'testing disabled reason';
551
644
  const viewConfig: SpotterEmbedViewConfig = {
@@ -615,6 +708,24 @@ describe('SpotterEmbed APP_INIT embedParams', () => {
615
708
  });
616
709
  });
617
710
 
711
+ it('should forward spotterChatPinConfig nested in spotterSidebarConfig', async () => {
712
+ const spotterChatPinConfig = {
713
+ enabled: true,
714
+ pinLabel: 'Pin to top',
715
+ unpinLabel: 'Unpin',
716
+ };
717
+ const response = await getAppInitResponse({
718
+ worksheetId: 'ws1',
719
+ spotterSidebarConfig: {
720
+ enablePastConversationsSidebar: true,
721
+ spotterChatPinConfig,
722
+ },
723
+ });
724
+ expect(
725
+ response.data.embedParams.spotterSidebarConfig.spotterChatPinConfig,
726
+ ).toEqual(spotterChatPinConfig);
727
+ });
728
+
618
729
  it('should populate enablePastConversationsSidebar from deprecated standalone flag', async () => {
619
730
  const response = await getAppInitResponse({
620
731
  worksheetId: 'ws1',
@@ -697,5 +808,253 @@ describe('SpotterEmbed APP_INIT embedParams', () => {
697
808
  expect(mockPort.postMessage.mock.calls[0]?.[0].data.embedParams?.spotterSidebarConfig?.spotterDocumentationUrl).toBeUndefined();
698
809
  });
699
810
 
811
+ it('should include spotterShareConversationConfig in embedParams when provided', async () => {
812
+ const response = await getAppInitResponse({
813
+ worksheetId: 'ws1',
814
+ spotterShareConversationConfig: { enableShareConversation: true },
815
+ });
816
+ expect(response.data.embedParams.spotterShareConversationConfig).toEqual({
817
+ enableShareConversation: true,
818
+ });
819
+ });
820
+
821
+ it('should pass spotterShareConversationConfig label overrides through embedParams', async () => {
822
+ const spotterShareConversationConfig = {
823
+ enableShareConversation: true,
824
+ spotterShareLabel: 'Share',
825
+ spotterShareModalTitle: 'Share conversation',
826
+ };
827
+ const response = await getAppInitResponse({
828
+ worksheetId: 'ws1',
829
+ spotterShareConversationConfig,
830
+ });
831
+ expect(response.data.embedParams.spotterShareConversationConfig).toEqual(spotterShareConversationConfig);
832
+ });
833
+
834
+ it('should include spotterShareConversationConfig alongside spotterSidebarConfig', async () => {
835
+ const response = await getAppInitResponse({
836
+ worksheetId: 'ws1',
837
+ spotterSidebarConfig: { enablePastConversationsSidebar: true },
838
+ spotterShareConversationConfig: { enableShareConversation: true },
839
+ });
840
+ expect(response.data.embedParams.spotterSidebarConfig.enablePastConversationsSidebar).toBe(true);
841
+ expect(response.data.embedParams.spotterShareConversationConfig.enableShareConversation).toBe(true);
842
+ });
843
+
844
+ it('should not handle error when neither worksheetId nor dataSources is provided', async () => {
845
+ const viewConfig: SpotterEmbedViewConfig = {
846
+ searchOptions: {
847
+ searchQuery: 'searchQuery',
848
+ },
849
+ };
850
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
851
+ (conversationEmbed as any).handleError = jest.fn();
852
+ await conversationEmbed.render();
853
+ expect((conversationEmbed as any).handleError).not.toHaveBeenCalled();
854
+ });
855
+
856
+ it('should not handle error when dataSources is an empty array and worksheetId is not provided', async () => {
857
+ const viewConfig: SpotterEmbedViewConfig = {
858
+ dataSources: [],
859
+ };
860
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
861
+ (conversationEmbed as any).handleError = jest.fn();
862
+ await conversationEmbed.render();
863
+ expect((conversationEmbed as any).handleError).not.toHaveBeenCalled();
864
+ });
865
+
866
+ it('should render without worksheet and dataSources params when neither is provided', async () => {
867
+ const viewConfig: SpotterEmbedViewConfig = {};
868
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
869
+ await conversationEmbed.render();
870
+ const src = getIFrameSrc();
871
+ expect(src).not.toContain('worksheet=');
872
+ expect(src).not.toContain('dataSources=');
873
+ });
874
+
875
+ it('should not append dataSources to the URL when it is an empty array', async () => {
876
+ const viewConfig: SpotterEmbedViewConfig = {
877
+ worksheetId: 'worksheetId',
878
+ dataSources: [],
879
+ };
880
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
881
+ await conversationEmbed.render();
882
+ expect(getIFrameSrc()).not.toContain('dataSources=');
883
+ });
884
+
885
+ it('should not handle error when dataSources is provided but worksheetId is not', async () => {
886
+ const viewConfig: SpotterEmbedViewConfig = {
887
+ worksheetId: '',
888
+ dataSources: ['ds-1', 'ds-2'],
889
+ };
890
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
891
+ (conversationEmbed as any).handleError = jest.fn();
892
+ await conversationEmbed.render();
893
+ expect((conversationEmbed as any).handleError).not.toHaveBeenCalled();
894
+ });
895
+
896
+ it('should render the conversation embed with dataSources and no worksheetId in the hash params', async () => {
897
+ const viewConfig: SpotterEmbedViewConfig = {
898
+ worksheetId: '',
899
+ dataSources: ['ds-1', 'ds-2'],
900
+ };
901
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
902
+ await conversationEmbed.render();
903
+ expectUrlMatchesWithParams(
904
+ getIFrameSrc(),
905
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true#/embed/insights/conv-assist?dataSources=${encodeURIComponent(JSON.stringify(['ds-1', 'ds-2']))}`,
906
+ );
907
+ });
908
+
909
+ it('should prefer dataSources over worksheetId when both are provided', async () => {
910
+ const viewConfig: SpotterEmbedViewConfig = {
911
+ worksheetId: 'worksheetId',
912
+ dataSources: ['ds-1', 'ds-2'],
913
+ searchOptions: {
914
+ searchQuery: 'searchQuery',
915
+ },
916
+ };
917
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
918
+ await conversationEmbed.render();
919
+ expectUrlMatchesWithParams(
920
+ getIFrameSrc(),
921
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true#/embed/insights/conv-assist?query=searchQuery&dataSources=${encodeURIComponent(JSON.stringify(['ds-1', 'ds-2']))}`,
922
+ );
923
+ });
924
+
925
+ it('should render the conversation embed without searchOptions and worksheetId when neither is set', async () => {
926
+ const viewConfig: SpotterEmbedViewConfig = {
927
+ worksheetId: '',
928
+ dataSources: ['ds-1'],
929
+ };
930
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
931
+ await conversationEmbed.render();
932
+ const src = getIFrameSrc();
933
+ expect(src).not.toContain('worksheet=');
934
+ expect(src).not.toContain('query=');
935
+ });
700
936
  });
701
937
 
938
+
939
+ describe('SpotterEmbed updatedSpotterExperience', () => {
940
+ it('should render the conversation embed with updated spotter experience', async () => {
941
+ const viewConfig: SpotterEmbedViewConfig = {
942
+ worksheetId: 'worksheetId',
943
+ searchOptions: {
944
+ searchQuery: 'searchQuery',
945
+ },
946
+ updatedSpotterExperience: true,
947
+ };
948
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
949
+ await conversationEmbed.render();
950
+ expectUrlMatchesWithParams(
951
+ getIFrameSrc(),
952
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&updatedSpotterExperience=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
953
+ );
954
+ });
955
+
956
+ it('should render the conversation embed with updated spotter experience disabled', async () => {
957
+ const viewConfig: SpotterEmbedViewConfig = {
958
+ worksheetId: 'worksheetId',
959
+ searchOptions: {
960
+ searchQuery: 'searchQuery',
961
+ },
962
+ updatedSpotterExperience: false,
963
+ };
964
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
965
+ await conversationEmbed.render();
966
+ expectUrlMatchesWithParams(
967
+ getIFrameSrc(),
968
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&updatedSpotterExperience=false#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
969
+ );
970
+ });
971
+ });
972
+
973
+ describe('SpotterEmbed APP_INIT starterPrompts', () => {
974
+ const mockEmbedEventPayload = { type: EmbedEvent.APP_INIT, data: {} };
975
+
976
+ async function getAppInitResponse(viewConfig: SpotterEmbedViewConfig) {
977
+ const embed = new SpotterEmbed(getRootEl(), viewConfig);
978
+ embed.render();
979
+ const mockPort: any = { postMessage: jest.fn() };
980
+ await executeAfterWait(() => {
981
+ postMessageToParent(getIFrameEl().contentWindow, mockEmbedEventPayload, mockPort);
982
+ });
983
+ await executeAfterWait(() => {});
984
+ return mockPort.postMessage.mock.calls[0]?.[0];
985
+ }
986
+
987
+ it('should include starterPrompts in embedParams when configured', async () => {
988
+ const response = await getAppInitResponse({
989
+ worksheetId: 'ws1',
990
+ spotterChatConfig: {
991
+ starterPrompts: {
992
+ enable: true,
993
+ quick: {
994
+ label: 'Quick',
995
+ questions: [{ label: 'Q1', prompt: 'P1' }],
996
+ },
997
+ research: { label: 'Research' },
998
+ previewData: { label: 'Explore' },
999
+ },
1000
+ },
1001
+ });
1002
+ expect(response.data.embedParams.starterPrompts).toEqual({
1003
+ enable: true,
1004
+ quick: {
1005
+ label: 'Quick',
1006
+ questions: [{ label: 'Q1', prompt: 'P1' }],
1007
+ },
1008
+ research: { label: 'Research' },
1009
+ previewData: { label: 'Explore' },
1010
+ });
1011
+ });
1012
+
1013
+ it('should forward the config as is, the app enforces the limits', async () => {
1014
+ const starterPrompts = {
1015
+ quick: {
1016
+ label: 'L'.repeat(50),
1017
+ questions: [
1018
+ { label: 'Q'.repeat(100), prompt: 'P'.repeat(400) },
1019
+ { label: 'Q2', prompt: 'P2' },
1020
+ { label: 'Q3', prompt: 'P3' },
1021
+ { label: 'Q4', prompt: 'P4' },
1022
+ { label: 'Q5', prompt: 'P5' },
1023
+ ],
1024
+ },
1025
+ previewData: { label: 'L'.repeat(50) },
1026
+ };
1027
+ const response = await getAppInitResponse({
1028
+ worksheetId: 'ws1',
1029
+ spotterChatConfig: { starterPrompts },
1030
+ });
1031
+ expect(response.data.embedParams.starterPrompts).toEqual(starterPrompts);
1032
+ });
1033
+
1034
+ it('should not include starterPrompts in embedParams when not configured', async () => {
1035
+ const response = await getAppInitResponse({ worksheetId: 'ws1' });
1036
+ expect(response.data.embedParams?.starterPrompts).toBeUndefined();
1037
+ });
1038
+
1039
+ it('exposes per-pill starter-prompt actions with the strings the app gates on', () => {
1040
+ expect(Action.QuickSearchPill).toBe('quickSearchPill');
1041
+ expect(Action.DeepAnalysisPill).toBe('deepAnalysisPill');
1042
+ expect(Action.DataLiteracyPill).toBe('dataLiteracyPill');
1043
+ });
1044
+
1045
+ it('forwards the enable feature flag when disabled', async () => {
1046
+ const response = await getAppInitResponse({
1047
+ worksheetId: 'ws1',
1048
+ spotterChatConfig: {
1049
+ starterPrompts: {
1050
+ enable: false,
1051
+ quick: { questions: [{ label: 'Q1', prompt: 'P1' }] },
1052
+ },
1053
+ },
1054
+ });
1055
+ expect(response.data.embedParams.starterPrompts).toEqual({
1056
+ enable: false,
1057
+ quick: { questions: [{ label: 'Q1', prompt: 'P1' }] },
1058
+ });
1059
+ });
1060
+ });