@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
@@ -439,117 +439,111 @@ describe('App embed tests', () => {
439
439
  });
440
440
  });
441
441
 
442
- test('should set isPNGInScheduledEmailsEnabled to true in url', async () => {
443
- const appEmbed = new AppEmbed(getRootEl(), {
444
- ...defaultViewConfig,
445
- isPNGInScheduledEmailsEnabled: true,
446
- } as AppViewConfig);
442
+ test('should set enableHomepageAnnouncement to false in url when not provided in AppViewConfig', async () => {
443
+ const appEmbed = new AppEmbed(getRootEl(), defaultViewConfig);
447
444
  appEmbed.render();
448
445
  await executeAfterWait(() => {
449
446
  expectUrlMatchesWithParams(
450
447
  getIFrameSrc(),
451
- `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isPNGInScheduledEmailsEnabled=true${defaultParamsPost}#/home`,
448
+ `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&enableHomepageAnnouncement=false${defaultParamsPost}#/home`,
452
449
  );
453
450
  });
454
451
  });
455
452
 
456
- test('should set isLinkParametersEnabled to true in url', async () => {
453
+ test('should set isPNGInScheduledEmailsEnabled to true in url', async () => {
457
454
  const appEmbed = new AppEmbed(getRootEl(), {
458
455
  ...defaultViewConfig,
459
- isLinkParametersEnabled: true,
456
+ isPNGInScheduledEmailsEnabled: true,
460
457
  } as AppViewConfig);
461
458
  appEmbed.render();
462
459
  await executeAfterWait(() => {
463
460
  expectUrlMatchesWithParams(
464
461
  getIFrameSrc(),
465
- `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isLinkParametersEnabled=true${defaultParamsPost}#/home`,
462
+ `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isPNGInScheduledEmailsEnabled=true${defaultParamsPost}#/home`,
466
463
  );
467
464
  });
468
465
  });
469
466
 
470
- test('should set isLinkParametersEnabled to false in url', async () => {
467
+ test('should set isWYSIWYGLiveboardPDFEnabled to true in url', async () => {
471
468
  const appEmbed = new AppEmbed(getRootEl(), {
472
469
  ...defaultViewConfig,
473
- isLinkParametersEnabled: false,
470
+ isContinuousLiveboardPDFEnabled: true,
474
471
  } as AppViewConfig);
475
472
  appEmbed.render();
476
473
  await executeAfterWait(() => {
477
474
  expectUrlMatchesWithParams(
478
475
  getIFrameSrc(),
479
- `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isLinkParametersEnabled=false${defaultParamsPost}#/home`,
476
+ `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isWYSIWYGLiveboardPDFEnabled=true${defaultParamsPost}#/home`,
480
477
  );
481
478
  });
482
479
  });
483
480
 
484
- test('should set isLiveboardXLSXCSVDownloadEnabled to true in url', async () => {
481
+ test('should set isLinkParametersEnabled to true in url', async () => {
485
482
  const appEmbed = new AppEmbed(getRootEl(), {
486
483
  ...defaultViewConfig,
487
- isLiveboardXLSXCSVDownloadEnabled: true,
484
+ isLinkParametersEnabled: true,
488
485
  } as AppViewConfig);
489
486
  appEmbed.render();
490
487
  await executeAfterWait(() => {
491
488
  expectUrlMatchesWithParams(
492
489
  getIFrameSrc(),
493
- `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isLiveboardXLSXCSVDownloadEnabled=true${defaultParamsPost}#/home`,
490
+ `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isLinkParametersEnabled=true${defaultParamsPost}#/home`,
494
491
  );
495
492
  });
496
493
  });
497
494
 
498
- test('should set updatedSpotterChatPrompt to true in url', async () => {
495
+ test('should set isLinkParametersEnabled to false in url', async () => {
499
496
  const appEmbed = new AppEmbed(getRootEl(), {
500
497
  ...defaultViewConfig,
501
- updatedSpotterChatPrompt: true,
498
+ isLinkParametersEnabled: false,
502
499
  } as AppViewConfig);
503
500
  appEmbed.render();
504
501
  await executeAfterWait(() => {
505
502
  expectUrlMatchesWithParams(
506
503
  getIFrameSrc(),
507
- `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&updatedSpotterChatPrompt=true${defaultParamsPost}#/home`,
504
+ `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isLinkParametersEnabled=false${defaultParamsPost}#/home`,
508
505
  );
509
506
  });
510
507
  });
511
508
 
512
- test('should set updatedSpotterChatPrompt to false in url', async () => {
509
+ test('should set isLiveboardXLSXCSVDownloadEnabled to true in url', async () => {
513
510
  const appEmbed = new AppEmbed(getRootEl(), {
514
511
  ...defaultViewConfig,
515
- updatedSpotterChatPrompt: false,
512
+ isLiveboardXLSXCSVDownloadEnabled: true,
516
513
  } as AppViewConfig);
517
514
  appEmbed.render();
518
515
  await executeAfterWait(() => {
519
516
  expectUrlMatchesWithParams(
520
517
  getIFrameSrc(),
521
- `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&updatedSpotterChatPrompt=false${defaultParamsPost}#/home`,
518
+ `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&isLiveboardXLSXCSVDownloadEnabled=true${defaultParamsPost}#/home`,
522
519
  );
523
520
  });
524
521
  });
525
522
 
526
- test('should set deprecated standalone enablePastConversationsSidebar in url', async () => {
523
+ test('should set updatedSpotterChatPrompt to true in url', async () => {
527
524
  const appEmbed = new AppEmbed(getRootEl(), {
528
525
  ...defaultViewConfig,
529
- enablePastConversationsSidebar: true,
526
+ updatedSpotterChatPrompt: true,
530
527
  } as AppViewConfig);
531
528
  appEmbed.render();
532
529
  await executeAfterWait(() => {
533
530
  expectUrlMatchesWithParams(
534
531
  getIFrameSrc(),
535
- `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&enablePastConversationsSidebar=true${defaultParamsPost}#/home`,
532
+ `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&updatedSpotterChatPrompt=true${defaultParamsPost}#/home`,
536
533
  );
537
534
  });
538
535
  });
539
536
 
540
- test('should prefer spotterSidebarConfig.enablePastConversationsSidebar over deprecated standalone flag in url', async () => {
537
+ test('should set updatedSpotterChatPrompt to false in url', async () => {
541
538
  const appEmbed = new AppEmbed(getRootEl(), {
542
539
  ...defaultViewConfig,
543
- enablePastConversationsSidebar: false,
544
- spotterSidebarConfig: {
545
- enablePastConversationsSidebar: true,
546
- },
540
+ updatedSpotterChatPrompt: false,
547
541
  } as AppViewConfig);
548
542
  appEmbed.render();
549
543
  await executeAfterWait(() => {
550
544
  expectUrlMatchesWithParams(
551
545
  getIFrameSrc(),
552
- `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&enablePastConversationsSidebar=true${defaultParamsPost}#/home`,
546
+ `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&updatedSpotterChatPrompt=false${defaultParamsPost}#/home`,
553
547
  );
554
548
  });
555
549
  });
@@ -1247,7 +1241,6 @@ describe('App embed tests', () => {
1247
1241
  });
1248
1242
 
1249
1243
  test('should register event handlers to adjust iframe height', async () => {
1250
- jest.spyOn(logger, 'error').mockImplementation(() => {});
1251
1244
  let embedHeightCallback: any = () => { };
1252
1245
  const onSpy = jest.spyOn(AppEmbed.prototype, 'on').mockImplementation((event, callback) => {
1253
1246
  if (event === EmbedEvent.RouteChange) {
@@ -1520,6 +1513,28 @@ describe('App embed tests', () => {
1520
1513
  width: 650,
1521
1514
  });
1522
1515
  });
1516
+ test('should not send correct visible data when RequestFullHeightLazyLoadData is triggered if lazyLoadingForFullHeight is false', async () => {
1517
+ const appEmbed = new AppEmbed(getRootEl(), {
1518
+ ...defaultViewConfig,
1519
+ fullHeight: true,
1520
+ lazyLoadingForFullHeight: false,
1521
+ lazyLoadingMargin: '10px',
1522
+ } as AppViewConfig);
1523
+
1524
+ const mockTrigger = jest.spyOn(appEmbed, 'trigger');
1525
+
1526
+ await appEmbed.render();
1527
+
1528
+ // Trigger the lazy load data calculation
1529
+ (appEmbed as any).sendFullHeightLazyLoadData();
1530
+
1531
+ expect(mockTrigger).not.toHaveBeenCalledWith(HostEvent.VisibleEmbedCoordinates, {
1532
+ top: 0,
1533
+ height: 500,
1534
+ left: 0,
1535
+ width: 650,
1536
+ });
1537
+ });
1523
1538
 
1524
1539
  test('should calculate correct visible data for partially visible full height element', async () => {
1525
1540
  // Mock iframe partially clipped from top and left
@@ -1639,8 +1654,8 @@ describe('App embed tests', () => {
1639
1654
 
1640
1655
  describe('IFrame height management', () => {
1641
1656
  let mockIFrame: HTMLIFrameElement;
1657
+
1642
1658
  beforeEach(() => {
1643
- jest.spyOn(logger, 'error').mockImplementation(() => {});
1644
1659
  mockIFrame = document.createElement('iframe');
1645
1660
  mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
1646
1661
  top: 100,
@@ -1692,16 +1707,13 @@ describe('App embed tests', () => {
1692
1707
  fullHeight: true,
1693
1708
  } as AppViewConfig) as any;
1694
1709
 
1695
- // Set up the mock iframe with a height that differs from defaultHeight by > threshold
1696
- mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
1697
- top: 100, left: 150, bottom: 100, right: 800, width: 650, height: 0,
1698
- });
1710
+ // Set up the mock iframe
1699
1711
  appEmbed.iFrame = mockIFrame;
1700
1712
  document.body.appendChild(mockIFrame);
1701
1713
 
1702
1714
  await appEmbed.render();
1703
1715
  const mockEvent = {
1704
- data: 0, // This will make it use the default height (500); change = |500 - 0| = 500 >= 30
1716
+ data: 0, // This will make it use the default height
1705
1717
  type: EmbedEvent.EmbedHeight,
1706
1718
  };
1707
1719
  appEmbed.updateIFrameHeight(mockEvent);
@@ -1709,61 +1721,6 @@ describe('App embed tests', () => {
1709
1721
  // Should use the default height
1710
1722
  expect(mockIFrame.style.height).toBe('500px');
1711
1723
  });
1712
-
1713
- test('should skip height update when change is below threshold', async () => {
1714
- const appEmbed = new AppEmbed(getRootEl(), {
1715
- ...defaultViewConfig,
1716
- fullHeight: true,
1717
- } as AppViewConfig) as any;
1718
-
1719
- appEmbed.iFrame = mockIFrame;
1720
- document.body.appendChild(mockIFrame);
1721
- await appEmbed.render();
1722
-
1723
- const spySetIFrameHeight = jest.spyOn(appEmbed, 'setIFrameHeight');
1724
-
1725
- // currentHeight is 500; heightToSet will be max(510, 500) = 510; change = 10 < 30
1726
- appEmbed.updateIFrameHeight({ data: 510, type: EmbedEvent.EmbedHeight });
1727
-
1728
- expect(spySetIFrameHeight).not.toHaveBeenCalled();
1729
- });
1730
-
1731
- test('should update height when change meets threshold', async () => {
1732
- const appEmbed = new AppEmbed(getRootEl(), {
1733
- ...defaultViewConfig,
1734
- fullHeight: true,
1735
- } as AppViewConfig) as any;
1736
-
1737
- appEmbed.iFrame = mockIFrame;
1738
- document.body.appendChild(mockIFrame);
1739
- await appEmbed.render();
1740
-
1741
- const spySetIFrameHeight = jest.spyOn(appEmbed, 'setIFrameHeight');
1742
-
1743
- // currentHeight is 500; heightToSet = max(600, 500) = 600; change = 100 >= 30
1744
- appEmbed.updateIFrameHeight({ data: 600, type: EmbedEvent.EmbedHeight });
1745
-
1746
- expect(spySetIFrameHeight).toHaveBeenCalledWith(600);
1747
- });
1748
-
1749
- test('should use defaultHeight when data is below it and check threshold', async () => {
1750
- const appEmbed = new AppEmbed(getRootEl(), {
1751
- ...defaultViewConfig,
1752
- fullHeight: true,
1753
- minimumHeight: 800,
1754
- } as AppViewConfig) as any;
1755
-
1756
- appEmbed.iFrame = mockIFrame;
1757
- document.body.appendChild(mockIFrame);
1758
- await appEmbed.render();
1759
-
1760
- const spySetIFrameHeight = jest.spyOn(appEmbed, 'setIFrameHeight');
1761
-
1762
- // currentHeight is 500; heightToSet = max(100, 800) = 800; change = 300 >= 30
1763
- appEmbed.updateIFrameHeight({ data: 100, type: EmbedEvent.EmbedHeight });
1764
-
1765
- expect(spySetIFrameHeight).toHaveBeenCalledWith(800);
1766
- });
1767
1724
  });
1768
1725
  });
1769
1726
 
@@ -1786,3 +1743,5 @@ describe('App Embed Default Height and Minimum Height Handling', () => {
1786
1743
  expect(appEmbed['defaultHeight']).toBe(700);
1787
1744
  });
1788
1745
  });
1746
+
1747
+
package/src/embed/app.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import { logger } from '../utils/logger';
12
- import { calculateVisibleElementData, getQueryParamString, isUndefined, isValidCssMargin, setParamIfDefined, validateHttpUrl, resolveEnablePastConversationsSidebar } from '../utils';
12
+ import { calculateVisibleElementData, getQueryParamString, isUndefined, isValidCssMargin, setParamIfDefined } from '../utils';
13
13
  import {
14
14
  Param,
15
15
  DOMSelector,
@@ -17,12 +17,11 @@ import {
17
17
  EmbedEvent,
18
18
  MessagePayload,
19
19
  AllEmbedViewConfig,
20
- ErrorDetailsTypes,
21
- EmbedErrorCodes,
20
+ DefaultAppInitData,
22
21
  } from '../types';
23
22
  import { V1Embed } from './ts-embed';
24
23
  import { SpotterChatViewConfig, SpotterSidebarViewConfig } from './conversation';
25
- import { ERROR_MESSAGE } from '../errors';
24
+ import { buildSpotterSidebarAppInitData } from './spotter-utils';
26
25
 
27
26
  /**
28
27
  * Pages within the ThoughtSpot app that can be embedded.
@@ -587,6 +586,25 @@ export interface AppViewConfig extends AllEmbedViewConfig {
587
586
  */
588
587
  isPNGInScheduledEmailsEnabled?: boolean;
589
588
 
589
+ /**
590
+ * Enables the 'what you see is what you get' PDF export for Liveboards. Each tab is rendered on a single page
591
+ * following the exact UI layout, instead of splitting visualizations across multiple A4 pages.
592
+ * This feature is GA from version 26.5.0.cl and is enabled by default on embed deployments.
593
+ *
594
+ * Supported embed types: `AppEmbed`, `LiveboardEmbed`
595
+ * @type {boolean}
596
+ * @version SDK: 1.48.0 | ThoughtSpot: 26.5.0.cl
597
+ * @example
598
+ * ```js
599
+ * // Replace <EmbedComponent> with embed component name. For example, AppEmbed or LiveboardEmbed
600
+ * const embed = new <EmbedComponent>('#tsEmbed', {
601
+ * ... // other embed view config
602
+ * isContinuousLiveboardPDFEnabled: true,
603
+ * })
604
+ * ```
605
+ */
606
+ isContinuousLiveboardPDFEnabled?: boolean;
607
+
590
608
  /**
591
609
  * This flag is used to enable/disable the XLSX/CSV download option for Liveboards
592
610
  *
@@ -760,6 +778,16 @@ export interface AppViewConfig extends AllEmbedViewConfig {
760
778
  enableHomepageAnnouncement?: boolean;
761
779
  }
762
780
 
781
+ /**
782
+ * APP_INIT data shape for AppEmbed.
783
+ * @internal
784
+ */
785
+ export interface AppEmbedAppInitData extends DefaultAppInitData {
786
+ embedParams?: {
787
+ spotterSidebarConfig?: SpotterSidebarViewConfig;
788
+ };
789
+ }
790
+
763
791
  /**
764
792
  * Embeds full ThoughtSpot experience in a host application.
765
793
  * @group Embed components
@@ -783,6 +811,23 @@ export class AppEmbed extends V1Embed {
783
811
  }
784
812
  }
785
813
 
814
+ /**
815
+ * Extends the default APP_INIT payload with `embedParams.spotterSidebarConfig`
816
+ * so the conv-assist app can read sidebar configuration on initialisation.
817
+ *
818
+ * Precedence for `enablePastConversationsSidebar`:
819
+ * `spotterSidebarConfig.enablePastConversationsSidebar` wins over the
820
+ * deprecated top-level `enablePastConversationsSidebar` flag; if the former
821
+ * is absent the latter is used as a fallback.
822
+ *
823
+ * An invalid `spotterDocumentationUrl` triggers a validation error and is
824
+ * excluded from the payload rather than forwarded to the app.
825
+ */
826
+ protected async getAppInitData(): Promise<AppEmbedAppInitData> {
827
+ const defaultAppInitData = await super.getAppInitData();
828
+ return buildSpotterSidebarAppInitData(defaultAppInitData, this.viewConfig, this.handleError.bind(this));
829
+ }
830
+
786
831
  /**
787
832
  * Constructs a map of parameters to be passed on to the
788
833
  * embedded Liveboard or visualization.
@@ -834,11 +879,11 @@ export class AppEmbed extends V1Embed {
834
879
  isCentralizedLiveboardFilterUXEnabled = false,
835
880
  isLinkParametersEnabled,
836
881
  updatedSpotterChatPrompt,
837
- spotterSidebarConfig,
838
882
  spotterChatConfig,
839
883
  minimumHeight,
840
884
  isThisPeriodInDateFiltersEnabled,
841
- enableHomepageAnnouncement,
885
+ enableHomepageAnnouncement = false,
886
+ isContinuousLiveboardPDFEnabled,
842
887
  } = this.viewConfig;
843
888
 
844
889
  let params: any = {};
@@ -867,53 +912,6 @@ export class AppEmbed extends V1Embed {
867
912
  params[Param.UpdatedSpotterChatPrompt] = !!updatedSpotterChatPrompt;
868
913
  }
869
914
 
870
- const resolvedEnablePastConversationsSidebar = resolveEnablePastConversationsSidebar({
871
- spotterSidebarConfigValue: spotterSidebarConfig?.enablePastConversationsSidebar,
872
- standaloneValue: this.viewConfig.enablePastConversationsSidebar,
873
- });
874
- setParamIfDefined(params, Param.EnablePastConversationsSidebar, resolvedEnablePastConversationsSidebar, true);
875
-
876
- // Handle spotterSidebarConfig params
877
- if (spotterSidebarConfig) {
878
- const {
879
- spotterSidebarTitle,
880
- spotterSidebarDefaultExpanded,
881
- spotterChatRenameLabel,
882
- spotterChatDeleteLabel,
883
- spotterDeleteConversationModalTitle,
884
- spotterPastConversationAlertMessage,
885
- spotterDocumentationUrl,
886
- spotterBestPracticesLabel,
887
- spotterConversationsBatchSize,
888
- spotterNewChatButtonTitle,
889
- } = spotterSidebarConfig;
890
-
891
- setParamIfDefined(params, Param.SpotterSidebarDefaultExpanded, spotterSidebarDefaultExpanded, true);
892
- setParamIfDefined(params, Param.SpotterSidebarTitle, spotterSidebarTitle);
893
- setParamIfDefined(params, Param.SpotterChatRenameLabel, spotterChatRenameLabel);
894
- setParamIfDefined(params, Param.SpotterChatDeleteLabel, spotterChatDeleteLabel);
895
- setParamIfDefined(params, Param.SpotterDeleteConversationModalTitle, spotterDeleteConversationModalTitle);
896
- setParamIfDefined(params, Param.SpotterPastConversationAlertMessage, spotterPastConversationAlertMessage);
897
- setParamIfDefined(params, Param.SpotterBestPracticesLabel, spotterBestPracticesLabel);
898
- setParamIfDefined(params, Param.SpotterConversationsBatchSize, spotterConversationsBatchSize);
899
- setParamIfDefined(params, Param.SpotterNewChatButtonTitle, spotterNewChatButtonTitle);
900
-
901
- // URL param with validation
902
- if (spotterDocumentationUrl !== undefined) {
903
- const [isValid, validationError] = validateHttpUrl(spotterDocumentationUrl);
904
- if (isValid) {
905
- params[Param.SpotterDocumentationUrl] = spotterDocumentationUrl;
906
- } else {
907
- this.handleError({
908
- errorType: ErrorDetailsTypes.VALIDATION_ERROR,
909
- message: ERROR_MESSAGE.INVALID_SPOTTER_DOCUMENTATION_URL,
910
- code: EmbedErrorCodes.INVALID_URL,
911
- error: validationError?.message || ERROR_MESSAGE.INVALID_SPOTTER_DOCUMENTATION_URL,
912
- });
913
- }
914
- }
915
- }
916
-
917
915
  // Handle spotterChatConfig params
918
916
  if (spotterChatConfig) {
919
917
  const {
@@ -1017,6 +1015,10 @@ export class AppEmbed extends V1Embed {
1017
1015
  params[Param.EnableHomepageAnnouncement] = enableHomepageAnnouncement;
1018
1016
  }
1019
1017
 
1018
+ if (isContinuousLiveboardPDFEnabled !== undefined) {
1019
+ params[Param.IsWYSIWYGLiveboardPDFEnabled] = isContinuousLiveboardPDFEnabled;
1020
+ }
1021
+
1020
1022
  this.defaultHeight = minimumHeight || this.defaultHeight;
1021
1023
 
1022
1024
  params[Param.DataPanelV2Enabled] = dataPanelV2;
@@ -1085,7 +1087,10 @@ export class AppEmbed extends V1Embed {
1085
1087
 
1086
1088
  private sendFullHeightLazyLoadData = () => {
1087
1089
  const data = calculateVisibleElementData(this.iFrame);
1088
- this.trigger(HostEvent.VisibleEmbedCoordinates, data);
1090
+ // this should be fired only if the lazyLoadingForFullHeight and fullHeight are true
1091
+ if(this.viewConfig.lazyLoadingForFullHeight && this.viewConfig.fullHeight){
1092
+ this.trigger(HostEvent.VisibleEmbedCoordinates, data);
1093
+ }
1089
1094
  }
1090
1095
 
1091
1096
  /**
@@ -1115,22 +1120,13 @@ export class AppEmbed extends V1Embed {
1115
1120
  return url;
1116
1121
  }
1117
1122
 
1118
- private HEIGHT_CHANAGE_THRESHOLD = 30;
1119
1123
  /**
1120
1124
  * Set the iframe height as per the computed height received
1121
1125
  * from the ThoughtSpot app.
1122
1126
  * @param data The event payload
1123
1127
  */
1124
1128
  protected updateIFrameHeight = (data: MessagePayload) => {
1125
- logger.error('Updating iframe height', data);
1126
- const currentHeight = this.iFrame.getBoundingClientRect().height;
1127
- const heightToSet = Math.max(data.data, this.defaultHeight);
1128
- const heightChange = Math.abs(heightToSet - currentHeight);
1129
- if (heightChange < this.HEIGHT_CHANAGE_THRESHOLD) {
1130
- logger.info('Height change is less than the threshold, skipping height update', { heightChange, heightToSet, currentHeight });
1131
- return;
1132
- }
1133
- this.setIFrameHeight(heightToSet);
1129
+ this.setIFrameHeight(Math.max(data.data, this.defaultHeight));
1134
1130
  this.sendFullHeightLazyLoadData();
1135
1131
  };
1136
1132