@thoughtspot/visual-embed-sdk 1.46.5-beta.1 → 1.46.5

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 (180) hide show
  1. package/cjs/package.json +4 -4
  2. package/cjs/src/css-variables.d.ts +36 -0
  3. package/cjs/src/css-variables.d.ts.map +1 -1
  4. package/cjs/src/embed/app.d.ts +41 -2
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js +26 -46
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +36 -69
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/conversation.d.ts +23 -1
  11. package/cjs/src/embed/conversation.d.ts.map +1 -1
  12. package/cjs/src/embed/conversation.js +18 -33
  13. package/cjs/src/embed/conversation.js.map +1 -1
  14. package/cjs/src/embed/conversation.spec.js +129 -97
  15. package/cjs/src/embed/conversation.spec.js.map +1 -1
  16. package/cjs/src/embed/hostEventClient/contracts.d.ts +31 -0
  17. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  18. package/cjs/src/embed/hostEventClient/contracts.js +2 -0
  19. package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
  20. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +18 -0
  21. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  22. package/cjs/src/embed/hostEventClient/host-event-client.js +69 -9
  23. package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
  24. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +185 -19
  25. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  26. package/cjs/src/embed/hostEventClient/utils.d.ts +22 -0
  27. package/cjs/src/embed/hostEventClient/utils.d.ts.map +1 -0
  28. package/cjs/src/embed/hostEventClient/utils.js +51 -0
  29. package/cjs/src/embed/hostEventClient/utils.js.map +1 -0
  30. package/cjs/src/embed/hostEventClient/utils.spec.d.ts +2 -0
  31. package/cjs/src/embed/hostEventClient/utils.spec.d.ts.map +1 -0
  32. package/cjs/src/embed/hostEventClient/utils.spec.js +115 -0
  33. package/cjs/src/embed/hostEventClient/utils.spec.js.map +1 -0
  34. package/cjs/src/embed/liveboard.d.ts +18 -1
  35. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  36. package/cjs/src/embed/liveboard.js +9 -11
  37. package/cjs/src/embed/liveboard.js.map +1 -1
  38. package/cjs/src/embed/liveboard.spec.js +29 -71
  39. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  40. package/cjs/src/embed/spotter-utils.d.ts +20 -0
  41. package/cjs/src/embed/spotter-utils.d.ts.map +1 -0
  42. package/cjs/src/embed/spotter-utils.js +52 -0
  43. package/cjs/src/embed/spotter-utils.js.map +1 -0
  44. package/cjs/src/embed/spotter-utils.spec.d.ts +2 -0
  45. package/cjs/src/embed/spotter-utils.spec.d.ts.map +1 -0
  46. package/cjs/src/embed/spotter-utils.spec.js +54 -0
  47. package/cjs/src/embed/spotter-utils.spec.js.map +1 -0
  48. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  49. package/cjs/src/embed/ts-embed.js +13 -1
  50. package/cjs/src/embed/ts-embed.js.map +1 -1
  51. package/cjs/src/errors.d.ts +2 -0
  52. package/cjs/src/errors.d.ts.map +1 -1
  53. package/cjs/src/errors.js +2 -0
  54. package/cjs/src/errors.js.map +1 -1
  55. package/cjs/src/types.d.ts +102 -1
  56. package/cjs/src/types.d.ts.map +1 -1
  57. package/cjs/src/types.js +101 -0
  58. package/cjs/src/types.js.map +1 -1
  59. package/cjs/src/utils.d.ts +0 -9
  60. package/cjs/src/utils.d.ts.map +1 -1
  61. package/cjs/src/utils.js +1 -10
  62. package/cjs/src/utils.js.map +1 -1
  63. package/dist/index-ChNydfIz.js +7371 -0
  64. package/dist/index-DGV_zh53.js +7371 -0
  65. package/dist/src/css-variables.d.ts +36 -0
  66. package/dist/src/css-variables.d.ts.map +1 -1
  67. package/dist/src/embed/app.d.ts +41 -2
  68. package/dist/src/embed/app.d.ts.map +1 -1
  69. package/dist/src/embed/conversation.d.ts +23 -1
  70. package/dist/src/embed/conversation.d.ts.map +1 -1
  71. package/dist/src/embed/hostEventClient/contracts.d.ts +31 -0
  72. package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  73. package/dist/src/embed/hostEventClient/host-event-client.d.ts +18 -0
  74. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  75. package/dist/src/embed/hostEventClient/utils.d.ts +22 -0
  76. package/dist/src/embed/hostEventClient/utils.d.ts.map +1 -0
  77. package/dist/src/embed/hostEventClient/utils.spec.d.ts +2 -0
  78. package/dist/src/embed/hostEventClient/utils.spec.d.ts.map +1 -0
  79. package/dist/src/embed/liveboard.d.ts +18 -1
  80. package/dist/src/embed/liveboard.d.ts.map +1 -1
  81. package/dist/src/embed/spotter-utils.d.ts +20 -0
  82. package/dist/src/embed/spotter-utils.d.ts.map +1 -0
  83. package/dist/src/embed/spotter-utils.spec.d.ts +2 -0
  84. package/dist/src/embed/spotter-utils.spec.d.ts.map +1 -0
  85. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  86. package/dist/src/errors.d.ts +2 -0
  87. package/dist/src/errors.d.ts.map +1 -1
  88. package/dist/src/types.d.ts +102 -1
  89. package/dist/src/types.d.ts.map +1 -1
  90. package/dist/src/utils.d.ts +0 -9
  91. package/dist/src/utils.d.ts.map +1 -1
  92. package/dist/tsembed-react.es.js +324 -110
  93. package/dist/tsembed-react.js +323 -109
  94. package/dist/tsembed.es.js +324 -110
  95. package/dist/tsembed.js +323 -109
  96. package/dist/visual-embed-sdk-react-full.d.ts +266 -3
  97. package/dist/visual-embed-sdk-react.d.ts +266 -3
  98. package/dist/visual-embed-sdk.d.ts +266 -3
  99. package/lib/package.json +4 -4
  100. package/lib/src/css-variables.d.ts +36 -0
  101. package/lib/src/css-variables.d.ts.map +1 -1
  102. package/lib/src/embed/app.d.ts +41 -2
  103. package/lib/src/embed/app.d.ts.map +1 -1
  104. package/lib/src/embed/app.js +28 -48
  105. package/lib/src/embed/app.js.map +1 -1
  106. package/lib/src/embed/app.spec.js +36 -69
  107. package/lib/src/embed/app.spec.js.map +1 -1
  108. package/lib/src/embed/conversation.d.ts +23 -1
  109. package/lib/src/embed/conversation.d.ts.map +1 -1
  110. package/lib/src/embed/conversation.js +19 -34
  111. package/lib/src/embed/conversation.js.map +1 -1
  112. package/lib/src/embed/conversation.spec.js +131 -99
  113. package/lib/src/embed/conversation.spec.js.map +1 -1
  114. package/lib/src/embed/hostEventClient/contracts.d.ts +31 -0
  115. package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  116. package/lib/src/embed/hostEventClient/contracts.js +2 -0
  117. package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
  118. package/lib/src/embed/hostEventClient/host-event-client.d.ts +18 -0
  119. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  120. package/lib/src/embed/hostEventClient/host-event-client.js +69 -9
  121. package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
  122. package/lib/src/embed/hostEventClient/host-event-client.spec.js +185 -19
  123. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  124. package/lib/src/embed/hostEventClient/utils.d.ts +22 -0
  125. package/lib/src/embed/hostEventClient/utils.d.ts.map +1 -0
  126. package/lib/src/embed/hostEventClient/utils.js +43 -0
  127. package/lib/src/embed/hostEventClient/utils.js.map +1 -0
  128. package/lib/src/embed/hostEventClient/utils.spec.d.ts +2 -0
  129. package/lib/src/embed/hostEventClient/utils.spec.d.ts.map +1 -0
  130. package/lib/src/embed/hostEventClient/utils.spec.js +113 -0
  131. package/lib/src/embed/hostEventClient/utils.spec.js.map +1 -0
  132. package/lib/src/embed/liveboard.d.ts +18 -1
  133. package/lib/src/embed/liveboard.d.ts.map +1 -1
  134. package/lib/src/embed/liveboard.js +9 -11
  135. package/lib/src/embed/liveboard.js.map +1 -1
  136. package/lib/src/embed/liveboard.spec.js +29 -71
  137. package/lib/src/embed/liveboard.spec.js.map +1 -1
  138. package/lib/src/embed/spotter-utils.d.ts +20 -0
  139. package/lib/src/embed/spotter-utils.d.ts.map +1 -0
  140. package/lib/src/embed/spotter-utils.js +47 -0
  141. package/lib/src/embed/spotter-utils.js.map +1 -0
  142. package/lib/src/embed/spotter-utils.spec.d.ts +2 -0
  143. package/lib/src/embed/spotter-utils.spec.d.ts.map +1 -0
  144. package/lib/src/embed/spotter-utils.spec.js +52 -0
  145. package/lib/src/embed/spotter-utils.spec.js.map +1 -0
  146. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  147. package/lib/src/embed/ts-embed.js +13 -1
  148. package/lib/src/embed/ts-embed.js.map +1 -1
  149. package/lib/src/errors.d.ts +2 -0
  150. package/lib/src/errors.d.ts.map +1 -1
  151. package/lib/src/errors.js +2 -0
  152. package/lib/src/errors.js.map +1 -1
  153. package/lib/src/types.d.ts +102 -1
  154. package/lib/src/types.d.ts.map +1 -1
  155. package/lib/src/types.js +101 -0
  156. package/lib/src/types.js.map +1 -1
  157. package/lib/src/utils.d.ts +0 -9
  158. package/lib/src/utils.d.ts.map +1 -1
  159. package/lib/src/utils.js +0 -8
  160. package/lib/src/utils.js.map +1 -1
  161. package/lib/src/visual-embed-sdk.d.ts +266 -3
  162. package/package.json +4 -4
  163. package/src/css-variables.ts +45 -0
  164. package/src/embed/app.spec.ts +51 -92
  165. package/src/embed/app.ts +60 -64
  166. package/src/embed/conversation.spec.ts +150 -119
  167. package/src/embed/conversation.ts +30 -54
  168. package/src/embed/hostEventClient/contracts.ts +31 -0
  169. package/src/embed/hostEventClient/host-event-client.spec.ts +260 -19
  170. package/src/embed/hostEventClient/host-event-client.ts +87 -11
  171. package/src/embed/hostEventClient/utils.spec.ts +137 -0
  172. package/src/embed/hostEventClient/utils.ts +61 -0
  173. package/src/embed/liveboard.spec.ts +38 -93
  174. package/src/embed/liveboard.ts +28 -10
  175. package/src/embed/spotter-utils.spec.ts +56 -0
  176. package/src/embed/spotter-utils.ts +65 -0
  177. package/src/embed/ts-embed.ts +15 -1
  178. package/src/errors.ts +2 -0
  179. package/src/types.ts +104 -0
  180. package/src/utils.ts +0 -14
@@ -2,13 +2,16 @@ import { SpotterEmbed, SpotterEmbedViewConfig, ConversationEmbed } from './conve
2
2
  import { TsEmbed } from './ts-embed';
3
3
  import * as authInstance from '../auth';
4
4
  import { Action, init } from '../index';
5
- import { AuthType, Param, RuntimeFilterOp, ErrorDetailsTypes, EmbedErrorCodes } from '../types';
5
+ import { AuthType, Param, RuntimeFilterOp, ErrorDetailsTypes, EmbedErrorCodes, EmbedEvent } from '../types';
6
6
  import {
7
7
  getDocumentBody,
8
8
  getIFrameSrc,
9
+ getIFrameEl,
9
10
  getRootEl,
10
11
  defaultParamsWithoutHiddenActions as defaultParams,
11
12
  expectUrlMatchesWithParams,
13
+ postMessageToParent,
14
+ executeAfterWait,
12
15
  } from '../test/test-utils';
13
16
  import { ERROR_MESSAGE } from '../errors';
14
17
 
@@ -289,81 +292,6 @@ describe('ConversationEmbed', () => {
289
292
  );
290
293
  });
291
294
 
292
- it('should render the conversation embed with past conversations sidebar enabled', async () => {
293
- const viewConfig: SpotterEmbedViewConfig = {
294
- worksheetId: 'worksheetId',
295
- searchOptions: {
296
- searchQuery: 'searchQuery',
297
- },
298
- spotterSidebarConfig: {
299
- enablePastConversationsSidebar: true,
300
- },
301
- };
302
-
303
- const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
304
- await conversationEmbed.render();
305
- expectUrlMatchesWithParams(
306
- getIFrameSrc(),
307
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&enablePastConversationsSidebar=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
308
- );
309
- });
310
-
311
- it('should render the conversation embed with past conversations sidebar disabled', async () => {
312
- const viewConfig: SpotterEmbedViewConfig = {
313
- worksheetId: 'worksheetId',
314
- searchOptions: {
315
- searchQuery: 'searchQuery',
316
- },
317
- spotterSidebarConfig: {
318
- enablePastConversationsSidebar: false,
319
- },
320
- };
321
-
322
- const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
323
- await conversationEmbed.render();
324
- expectUrlMatchesWithParams(
325
- getIFrameSrc(),
326
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&enablePastConversationsSidebar=false#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
327
- );
328
- });
329
-
330
- it('should render the conversation embed with deprecated standalone enablePastConversationsSidebar flag', async () => {
331
- const viewConfig: SpotterEmbedViewConfig = {
332
- worksheetId: 'worksheetId',
333
- searchOptions: {
334
- searchQuery: 'searchQuery',
335
- },
336
- enablePastConversationsSidebar: true,
337
- };
338
-
339
- const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
340
- await conversationEmbed.render();
341
- expectUrlMatchesWithParams(
342
- getIFrameSrc(),
343
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&enablePastConversationsSidebar=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
344
- );
345
- });
346
-
347
- it('should prefer spotterSidebarConfig.enablePastConversationsSidebar over deprecated standalone flag', async () => {
348
- const viewConfig: SpotterEmbedViewConfig = {
349
- worksheetId: 'worksheetId',
350
- searchOptions: {
351
- searchQuery: 'searchQuery',
352
- },
353
- enablePastConversationsSidebar: false,
354
- spotterSidebarConfig: {
355
- enablePastConversationsSidebar: true,
356
- },
357
- };
358
-
359
- const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
360
- await conversationEmbed.render();
361
- expectUrlMatchesWithParams(
362
- getIFrameSrc(),
363
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&enablePastConversationsSidebar=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
364
- );
365
- });
366
-
367
295
  it('should render the conversation embed with all boolean flags set', async () => {
368
296
  const viewConfig: SpotterEmbedViewConfig = {
369
297
  worksheetId: 'worksheetId',
@@ -375,16 +303,13 @@ describe('ConversationEmbed', () => {
375
303
  dataPanelV2: true,
376
304
  showSpotterLimitations: true,
377
305
  hideSampleQuestions: true,
378
- spotterSidebarConfig: {
379
- enablePastConversationsSidebar: true,
380
- },
381
306
  };
382
307
 
383
308
  const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
384
309
  await conversationEmbed.render();
385
310
  expectUrlMatchesWithParams(
386
311
  getIFrameSrc(),
387
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&disableSourceSelection=true&hideSourceSelection=true&enableDataPanelV2=true&showSpotterLimitations=true&hideSampleQuestions=true&enablePastConversationsSidebar=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
312
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&disableSourceSelection=true&hideSourceSelection=true&enableDataPanelV2=true&showSpotterLimitations=true&hideSampleQuestions=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
388
313
  );
389
314
  });
390
315
 
@@ -484,73 +409,179 @@ describe('ConversationEmbed', () => {
484
409
  );
485
410
  });
486
411
 
487
- describe('spotter sidebar config params', () => {
412
+ describe('spotter chat hiddenActions', () => {
488
413
  it.each([
489
- ['enablePastConversationsSidebar', true, 'enablePastConversationsSidebar=true'],
490
- ['spotterSidebarTitle', 'My Conversations', 'spotterSidebarTitle=My%20Conversations'],
491
- ['spotterSidebarDefaultExpanded', true, 'spotterSidebarDefaultExpanded=true'],
492
- ['spotterChatRenameLabel', 'Edit Name', 'spotterChatRenameLabel=Edit%20Name'],
493
- ['spotterChatDeleteLabel', 'Remove', 'spotterChatDeleteLabel=Remove'],
494
- ['spotterDeleteConversationModalTitle', 'Remove Conversation', 'spotterDeleteConversationModalTitle=Remove%20Conversation'],
495
- ['spotterPastConversationAlertMessage', 'Viewing past conversation', 'spotterPastConversationAlertMessage=Viewing%20past%20conversation'],
496
- ['spotterBestPracticesLabel', 'Help Tips', 'spotterBestPracticesLabel=Help%20Tips'],
497
- ['spotterConversationsBatchSize', 50, 'spotterConversationsBatchSize=50'],
498
- ['spotterNewChatButtonTitle', 'Start New Conversation', 'spotterNewChatButtonTitle=Start%20New%20Conversation'],
499
- ['spotterDocumentationUrl', 'https://docs.example.com/spotter', 'spotterDocumentationUrl=https%3A%2F%2Fdocs.example.com%2Fspotter'],
500
- ])('should render with spotterSidebarConfig.%s', async (configKey, configValue, expectedParam) => {
414
+ ['SpotterChatConnectorResources', Action.SpotterChatConnectorResources],
415
+ ['SpotterChatConnectors', Action.SpotterChatConnectors],
416
+ ['SpotterChatModeSwitcher', Action.SpotterChatModeSwitcher],
417
+ ])('should render with hiddenActions for %s', async (_, action) => {
501
418
  const viewConfig: SpotterEmbedViewConfig = {
502
419
  worksheetId: 'worksheetId',
503
- spotterSidebarConfig: {
504
- [configKey]: configValue,
505
- },
420
+ searchOptions: { searchQuery: 'searchQuery' },
421
+ hiddenActions: [action],
422
+ };
423
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
424
+ await conversationEmbed.render();
425
+ expectUrlMatchesWithParams(
426
+ getIFrameSrc(),
427
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&hideAction=[%22${Action.ReportError}%22,%22${action}%22]&isSpotterExperienceEnabled=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
428
+ );
429
+ });
430
+
431
+ it('should render with multiple spotter chat actions hidden together', async () => {
432
+ const viewConfig: SpotterEmbedViewConfig = {
433
+ worksheetId: 'worksheetId',
434
+ searchOptions: { searchQuery: 'searchQuery' },
435
+ hiddenActions: [
436
+ Action.SpotterChatConnectorResources,
437
+ Action.SpotterChatConnectors,
438
+ Action.SpotterChatModeSwitcher,
439
+ ],
506
440
  };
507
441
  const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
508
442
  await conversationEmbed.render();
509
443
  expectUrlMatchesWithParams(
510
444
  getIFrameSrc(),
511
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&${expectedParam}#/embed/insights/conv-assist?worksheet=worksheetId&query=`,
445
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&hideAction=[%22${Action.ReportError}%22,%22${Action.SpotterChatConnectorResources}%22,%22${Action.SpotterChatConnectors}%22,%22${Action.SpotterChatModeSwitcher}%22]&isSpotterExperienceEnabled=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
512
446
  );
513
447
  });
448
+ });
514
449
 
450
+ describe('spotter chat disabledActions', () => {
515
451
  it.each([
516
- ['invalid URL format', 'invalid-url'],
517
- ['invalid protocol (ftp)', 'ftp://docs.example.com/spotter'],
518
- ])('should handle error for spotterSidebarConfig.spotterDocumentationUrl with %s', async (_, invalidUrl) => {
452
+ ['SpotterChatConnectorResources', Action.SpotterChatConnectorResources],
453
+ ['SpotterChatConnectors', Action.SpotterChatConnectors],
454
+ ['SpotterChatModeSwitcher', Action.SpotterChatModeSwitcher],
455
+ ])('should render with disabledActions for %s', async (_, action) => {
456
+ const disabledReason = 'testing disabled reason';
519
457
  const viewConfig: SpotterEmbedViewConfig = {
520
458
  worksheetId: 'worksheetId',
521
- spotterSidebarConfig: {
522
- spotterDocumentationUrl: invalidUrl,
523
- },
459
+ searchOptions: { searchQuery: 'searchQuery' },
460
+ disabledActions: [action],
461
+ disabledActionReason: disabledReason,
524
462
  };
525
463
  const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
526
- (conversationEmbed as any).handleError = jest.fn();
527
464
  await conversationEmbed.render();
528
- expect((conversationEmbed as any).handleError).toHaveBeenCalledWith(
529
- expect.objectContaining({
530
- errorType: ErrorDetailsTypes.VALIDATION_ERROR,
531
- message: ERROR_MESSAGE.INVALID_SPOTTER_DOCUMENTATION_URL,
532
- code: EmbedErrorCodes.INVALID_URL,
533
- }),
465
+ expectUrlMatchesWithParams(
466
+ getIFrameSrc(),
467
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&${Param.DisableActions}=[%22${action}%22]&${Param.DisableActionReason}=${disabledReason}&isSpotterExperienceEnabled=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
534
468
  );
535
469
  });
536
470
 
537
- it('should render with multiple spotterSidebarConfig options', async () => {
471
+ it('should render with multiple spotter chat actions disabled together', async () => {
472
+ const disabledReason = 'not available';
538
473
  const viewConfig: SpotterEmbedViewConfig = {
539
474
  worksheetId: 'worksheetId',
540
- spotterSidebarConfig: {
541
- enablePastConversationsSidebar: true,
542
- spotterSidebarTitle: 'Chats',
543
- spotterSidebarDefaultExpanded: true,
544
- spotterNewChatButtonTitle: 'New',
545
- spotterConversationsBatchSize: 25,
546
- },
475
+ searchOptions: { searchQuery: 'searchQuery' },
476
+ disabledActions: [
477
+ Action.SpotterChatConnectorResources,
478
+ Action.SpotterChatConnectors,
479
+ Action.SpotterChatModeSwitcher,
480
+ ],
481
+ disabledActionReason: disabledReason,
547
482
  };
548
483
  const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
549
484
  await conversationEmbed.render();
550
485
  expectUrlMatchesWithParams(
551
486
  getIFrameSrc(),
552
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&enablePastConversationsSidebar=true&spotterSidebarDefaultExpanded=true&spotterSidebarTitle=Chats&spotterConversationsBatchSize=25&spotterNewChatButtonTitle=New#/embed/insights/conv-assist?worksheet=worksheetId&query=`,
487
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&${Param.DisableActions}=[%22${Action.SpotterChatConnectorResources}%22,%22${Action.SpotterChatConnectors}%22,%22${Action.SpotterChatModeSwitcher}%22]&${Param.DisableActionReason}=${disabledReason}&isSpotterExperienceEnabled=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
553
488
  );
554
489
  });
555
490
  });
491
+
556
492
  });
493
+
494
+ describe('SpotterEmbed APP_INIT embedParams', () => {
495
+ const mockEmbedEventPayload = { type: EmbedEvent.APP_INIT, data: {} };
496
+
497
+ async function getAppInitResponse(viewConfig: SpotterEmbedViewConfig) {
498
+ const embed = new SpotterEmbed(getRootEl(), viewConfig);
499
+ embed.render();
500
+ const mockPort: any = { postMessage: jest.fn() };
501
+ await executeAfterWait(() => {
502
+ postMessageToParent(getIFrameEl().contentWindow, mockEmbedEventPayload, mockPort);
503
+ });
504
+ await executeAfterWait(() => {});
505
+ return mockPort.postMessage.mock.calls[0]?.[0];
506
+ }
507
+
508
+ it('should include spotterSidebarConfig in embedParams when spotterSidebarConfig is provided', async () => {
509
+ const response = await getAppInitResponse({
510
+ worksheetId: 'ws1',
511
+ spotterSidebarConfig: {
512
+ enablePastConversationsSidebar: true,
513
+ spotterSidebarTitle: 'My Conversations',
514
+ spotterSidebarDefaultExpanded: true,
515
+ },
516
+ });
517
+ expect(response.data.embedParams.spotterSidebarConfig).toEqual({
518
+ enablePastConversationsSidebar: true,
519
+ spotterSidebarTitle: 'My Conversations',
520
+ spotterSidebarDefaultExpanded: true,
521
+ });
522
+ });
523
+
524
+ it('should populate enablePastConversationsSidebar from deprecated standalone flag', async () => {
525
+ const response = await getAppInitResponse({
526
+ worksheetId: 'ws1',
527
+ enablePastConversationsSidebar: true,
528
+ });
529
+ expect(response.data.embedParams.spotterSidebarConfig).toEqual({
530
+ enablePastConversationsSidebar: true,
531
+ });
532
+ });
533
+
534
+ it('should use spotterSidebarConfig.enablePastConversationsSidebar over deprecated standalone flag', async () => {
535
+ const response = await getAppInitResponse({
536
+ worksheetId: 'ws1',
537
+ enablePastConversationsSidebar: false,
538
+ spotterSidebarConfig: {
539
+ enablePastConversationsSidebar: true,
540
+ spotterSidebarTitle: 'Chats',
541
+ },
542
+ });
543
+ expect(response.data.embedParams.spotterSidebarConfig.enablePastConversationsSidebar).toBe(true);
544
+ expect(response.data.embedParams.spotterSidebarConfig.spotterSidebarTitle).toBe('Chats');
545
+ });
546
+
547
+ it('should fall back to deprecated standalone flag when spotterSidebarConfig omits enablePastConversationsSidebar', async () => {
548
+ const response = await getAppInitResponse({
549
+ worksheetId: 'ws1',
550
+ enablePastConversationsSidebar: true,
551
+ spotterSidebarConfig: {
552
+ spotterSidebarTitle: 'My Chats',
553
+ },
554
+ });
555
+ expect(response.data.embedParams.spotterSidebarConfig.enablePastConversationsSidebar).toBe(true);
556
+ expect(response.data.embedParams.spotterSidebarConfig.spotterSidebarTitle).toBe('My Chats');
557
+ });
558
+
559
+ it('should not include embedParams when neither spotterSidebarConfig nor standalone flag is set', async () => {
560
+ const response = await getAppInitResponse({ worksheetId: 'ws1' });
561
+ expect(response.data.embedParams).toBeUndefined();
562
+ });
563
+
564
+ it('should call handleError and exclude spotterDocumentationUrl from embedParams when URL is invalid', async () => {
565
+ const embed = new SpotterEmbed(getRootEl(), {
566
+ worksheetId: 'ws1',
567
+ spotterSidebarConfig: { spotterDocumentationUrl: 'invalid-url' },
568
+ });
569
+ (embed as any).handleError = jest.fn();
570
+ embed.render();
571
+ const mockPort: any = { postMessage: jest.fn() };
572
+ await executeAfterWait(() => {
573
+ postMessageToParent(getIFrameEl().contentWindow, mockEmbedEventPayload, mockPort);
574
+ });
575
+ await executeAfterWait(() => {});
576
+ expect((embed as any).handleError).toHaveBeenCalledWith(
577
+ expect.objectContaining({
578
+ errorType: ErrorDetailsTypes.VALIDATION_ERROR,
579
+ message: ERROR_MESSAGE.INVALID_SPOTTER_DOCUMENTATION_URL,
580
+ code: EmbedErrorCodes.INVALID_URL,
581
+ }),
582
+ );
583
+ expect(mockPort.postMessage.mock.calls[0]?.[0].data.embedParams?.spotterSidebarConfig?.spotterDocumentationUrl).toBeUndefined();
584
+ });
585
+
586
+ });
587
+
@@ -1,8 +1,9 @@
1
1
  import isUndefined from 'lodash/isUndefined';
2
2
  import { ERROR_MESSAGE } from '../errors';
3
- import { Param, BaseViewConfig, RuntimeFilter, RuntimeParameter, ErrorDetailsTypes, EmbedErrorCodes } from '../types';
3
+ import { Param, BaseViewConfig, RuntimeFilter, RuntimeParameter, ErrorDetailsTypes, EmbedErrorCodes, DefaultAppInitData } from '../types';
4
4
  import { TsEmbed } from './ts-embed';
5
- import { getQueryParamString, getFilterQuery, getRuntimeParameters, validateHttpUrl, setParamIfDefined, resolveEnablePastConversationsSidebar } from '../utils';
5
+ import { buildSpotterSidebarAppInitData } from './spotter-utils';
6
+ import { getQueryParamString, getFilterQuery, getRuntimeParameters, setParamIfDefined } from '../utils';
6
7
 
7
8
  /**
8
9
  * Configuration for search options
@@ -343,6 +344,16 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
343
344
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
344
345
  export interface ConversationViewConfig extends SpotterEmbedViewConfig {}
345
346
 
347
+ /**
348
+ * APP_INIT data shape for SpotterEmbed.
349
+ * @internal
350
+ */
351
+ export interface SpotterAppInitData extends DefaultAppInitData {
352
+ embedParams?: {
353
+ spotterSidebarConfig?: SpotterSidebarViewConfig;
354
+ };
355
+ }
356
+
346
357
  /**
347
358
  * Embed ThoughtSpot AI Conversation.
348
359
  * @version SDK: 1.37.0 | ThoughtSpot: 10.9.0.cl
@@ -369,6 +380,23 @@ export class SpotterEmbed extends TsEmbed {
369
380
  super(container, viewConfig);
370
381
  }
371
382
 
383
+ /**
384
+ * Extends the default APP_INIT payload with `embedParams.spotterSidebarConfig`
385
+ * so the conv-assist app can read sidebar configuration on initialisation.
386
+ *
387
+ * Precedence for `enablePastConversationsSidebar`:
388
+ * `spotterSidebarConfig.enablePastConversationsSidebar` wins over the
389
+ * deprecated top-level `enablePastConversationsSidebar` flag; if the former
390
+ * is absent the latter is used as a fallback.
391
+ *
392
+ * An invalid `spotterDocumentationUrl` triggers a validation error and is
393
+ * excluded from the payload rather than forwarded to the app.
394
+ */
395
+ protected async getAppInitData(): Promise<SpotterAppInitData> {
396
+ const defaultAppInitData = await super.getAppInitData();
397
+ return buildSpotterSidebarAppInitData(defaultAppInitData, this.viewConfig, this.handleError.bind(this));
398
+ }
399
+
372
400
  protected getEmbedParamsObject() {
373
401
  const {
374
402
  worksheetId,
@@ -383,29 +411,9 @@ export class SpotterEmbed extends TsEmbed {
383
411
  runtimeParameters,
384
412
  excludeRuntimeParametersfromURL,
385
413
  updatedSpotterChatPrompt,
386
- spotterSidebarConfig,
387
414
  spotterChatConfig,
388
415
  } = this.viewConfig;
389
416
 
390
- // Extract sidebar config properties
391
- const {
392
- enablePastConversationsSidebar: sidebarEnablePastConversationsSidebar,
393
- spotterSidebarTitle,
394
- spotterSidebarDefaultExpanded,
395
- spotterChatRenameLabel,
396
- spotterChatDeleteLabel,
397
- spotterDeleteConversationModalTitle,
398
- spotterPastConversationAlertMessage,
399
- spotterDocumentationUrl,
400
- spotterBestPracticesLabel,
401
- spotterConversationsBatchSize,
402
- spotterNewChatButtonTitle,
403
- } = spotterSidebarConfig || {};
404
- const resolvedEnablePastConversationsSidebar = resolveEnablePastConversationsSidebar({
405
- spotterSidebarConfigValue: sidebarEnablePastConversationsSidebar,
406
- standaloneValue: this.viewConfig.enablePastConversationsSidebar,
407
- });
408
-
409
417
  if (!worksheetId) {
410
418
  this.handleError({
411
419
  errorType: ErrorDetailsTypes.VALIDATION_ERROR,
@@ -424,38 +432,6 @@ export class SpotterEmbed extends TsEmbed {
424
432
  setParamIfDefined(queryParams, Param.ShowSpotterLimitations, showSpotterLimitations, true);
425
433
  setParamIfDefined(queryParams, Param.HideSampleQuestions, hideSampleQuestions, true);
426
434
  setParamIfDefined(queryParams, Param.UpdatedSpotterChatPrompt, updatedSpotterChatPrompt, true);
427
- setParamIfDefined(
428
- queryParams,
429
- Param.EnablePastConversationsSidebar,
430
- resolvedEnablePastConversationsSidebar,
431
- true,
432
- );
433
- setParamIfDefined(queryParams, Param.SpotterSidebarDefaultExpanded, spotterSidebarDefaultExpanded, true);
434
-
435
- // String params
436
- setParamIfDefined(queryParams, Param.SpotterSidebarTitle, spotterSidebarTitle);
437
- setParamIfDefined(queryParams, Param.SpotterChatRenameLabel, spotterChatRenameLabel);
438
- setParamIfDefined(queryParams, Param.SpotterChatDeleteLabel, spotterChatDeleteLabel);
439
- setParamIfDefined(queryParams, Param.SpotterDeleteConversationModalTitle, spotterDeleteConversationModalTitle);
440
- setParamIfDefined(queryParams, Param.SpotterPastConversationAlertMessage, spotterPastConversationAlertMessage);
441
- setParamIfDefined(queryParams, Param.SpotterBestPracticesLabel, spotterBestPracticesLabel);
442
- setParamIfDefined(queryParams, Param.SpotterConversationsBatchSize, spotterConversationsBatchSize);
443
- setParamIfDefined(queryParams, Param.SpotterNewChatButtonTitle, spotterNewChatButtonTitle);
444
-
445
- // URL param with validation
446
- if (spotterDocumentationUrl !== undefined) {
447
- const [isValid, validationError] = validateHttpUrl(spotterDocumentationUrl);
448
- if (isValid) {
449
- queryParams[Param.SpotterDocumentationUrl] = spotterDocumentationUrl;
450
- } else {
451
- this.handleError({
452
- errorType: ErrorDetailsTypes.VALIDATION_ERROR,
453
- message: ERROR_MESSAGE.INVALID_SPOTTER_DOCUMENTATION_URL,
454
- code: EmbedErrorCodes.INVALID_URL,
455
- error: validationError?.message || ERROR_MESSAGE.INVALID_SPOTTER_DOCUMENTATION_URL,
456
- });
457
- }
458
- }
459
435
 
460
436
  // Handle spotterChatConfig params
461
437
  if (spotterChatConfig) {
@@ -15,6 +15,8 @@ export enum UIPassthroughEvent {
15
15
  GetAnswerConfig = 'getAnswerPageConfig',
16
16
  GetLiveboardConfig = 'getPinboardPageConfig',
17
17
  GetUnsavedAnswerTML = 'getUnsavedAnswerTML',
18
+ UpdateFilters = 'updateFilters',
19
+ Drilldown = 'drillDown',
18
20
  GetAnswerSession = 'getAnswerSession',
19
21
  GetFilters = 'getFilters',
20
22
  GetIframeUrl = 'getIframeUrl',
@@ -138,6 +140,35 @@ export type UIPassthroughContractBase = {
138
140
  v2Content: string;
139
141
  };
140
142
  };
143
+ [UIPassthroughEvent.UpdateFilters]: {
144
+ request: {
145
+ filter?: {
146
+ column: string;
147
+ oper: string;
148
+ values: string[];
149
+ type?: string;
150
+ };
151
+ filters?: {
152
+ column: string;
153
+ oper: string;
154
+ values: string[];
155
+ type?: string;
156
+ }[];
157
+ };
158
+ response: unknown;
159
+ };
160
+ [UIPassthroughEvent.Drilldown]: {
161
+ request: {
162
+ points: {
163
+ selectedPoints?: string[];
164
+ clickedPoint?: string;
165
+ };
166
+ columnGuid?: string;
167
+ autoDrillDown?: boolean;
168
+ vizId?: string;
169
+ };
170
+ response: unknown;
171
+ };
141
172
  };
142
173
 
143
174
  // UI Passthrough Request and Response