@thoughtspot/visual-embed-sdk 1.45.2 → 1.45.3

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 (140) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/css-variables.d.ts +48 -0
  3. package/cjs/src/css-variables.d.ts.map +1 -1
  4. package/cjs/src/embed/app.d.ts +37 -0
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js +37 -1
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +24 -0
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/conversation.d.ts +127 -9
  11. package/cjs/src/embed/conversation.d.ts.map +1 -1
  12. package/cjs/src/embed/conversation.js +41 -18
  13. package/cjs/src/embed/conversation.js.map +1 -1
  14. package/cjs/src/embed/conversation.spec.js +96 -3
  15. package/cjs/src/embed/conversation.spec.js.map +1 -1
  16. package/cjs/src/embed/liveboard.d.ts +38 -1
  17. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  18. package/cjs/src/embed/liveboard.js +38 -10
  19. package/cjs/src/embed/liveboard.js.map +1 -1
  20. package/cjs/src/embed/liveboard.spec.js +179 -7
  21. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  22. package/cjs/src/errors.d.ts +1 -0
  23. package/cjs/src/errors.d.ts.map +1 -1
  24. package/cjs/src/errors.js +1 -0
  25. package/cjs/src/errors.js.map +1 -1
  26. package/cjs/src/index.d.ts +3 -3
  27. package/cjs/src/index.d.ts.map +1 -1
  28. package/cjs/src/index.js.map +1 -1
  29. package/cjs/src/types.d.ts +192 -40
  30. package/cjs/src/types.d.ts.map +1 -1
  31. package/cjs/src/types.js +184 -19
  32. package/cjs/src/types.js.map +1 -1
  33. package/cjs/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  34. package/cjs/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  35. package/cjs/src/utils/graphql/answerService/answer-queries.js +23 -1
  36. package/cjs/src/utils/graphql/answerService/answer-queries.js.map +1 -1
  37. package/cjs/src/utils/graphql/answerService/answerService.d.ts +2 -1
  38. package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  39. package/cjs/src/utils/graphql/answerService/answerService.js +9 -1
  40. package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -1
  41. package/cjs/src/utils/graphql/answerService/answerService.spec.js +73 -0
  42. package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  43. package/cjs/src/utils.d.ts +15 -0
  44. package/cjs/src/utils.d.ts.map +1 -1
  45. package/cjs/src/utils.js +33 -1
  46. package/cjs/src/utils.js.map +1 -1
  47. package/cjs/src/utils.spec.js +49 -0
  48. package/cjs/src/utils.spec.js.map +1 -1
  49. package/dist/{index-BdkKLLo1.js → index-BuwECGdm.js} +1 -1
  50. package/dist/src/css-variables.d.ts +48 -0
  51. package/dist/src/css-variables.d.ts.map +1 -1
  52. package/dist/src/embed/app.d.ts +37 -0
  53. package/dist/src/embed/app.d.ts.map +1 -1
  54. package/dist/src/embed/conversation.d.ts +127 -9
  55. package/dist/src/embed/conversation.d.ts.map +1 -1
  56. package/dist/src/embed/liveboard.d.ts +38 -1
  57. package/dist/src/embed/liveboard.d.ts.map +1 -1
  58. package/dist/src/errors.d.ts +1 -0
  59. package/dist/src/errors.d.ts.map +1 -1
  60. package/dist/src/index.d.ts +3 -3
  61. package/dist/src/index.d.ts.map +1 -1
  62. package/dist/src/types.d.ts +192 -40
  63. package/dist/src/types.d.ts.map +1 -1
  64. package/dist/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  65. package/dist/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  66. package/dist/src/utils/graphql/answerService/answerService.d.ts +2 -1
  67. package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  68. package/dist/src/utils.d.ts +15 -0
  69. package/dist/src/utils.d.ts.map +1 -1
  70. package/dist/tsembed-react.es.js +364 -52
  71. package/dist/tsembed-react.js +363 -51
  72. package/dist/tsembed.es.js +364 -52
  73. package/dist/tsembed.js +363 -51
  74. package/dist/visual-embed-sdk-react-full.d.ts +696 -342
  75. package/dist/visual-embed-sdk-react.d.ts +685 -331
  76. package/dist/visual-embed-sdk.d.ts +757 -379
  77. package/lib/package.json +1 -1
  78. package/lib/src/css-variables.d.ts +48 -0
  79. package/lib/src/css-variables.d.ts.map +1 -1
  80. package/lib/src/embed/app.d.ts +37 -0
  81. package/lib/src/embed/app.d.ts.map +1 -1
  82. package/lib/src/embed/app.js +39 -3
  83. package/lib/src/embed/app.js.map +1 -1
  84. package/lib/src/embed/app.spec.js +24 -0
  85. package/lib/src/embed/app.spec.js.map +1 -1
  86. package/lib/src/embed/conversation.d.ts +127 -9
  87. package/lib/src/embed/conversation.d.ts.map +1 -1
  88. package/lib/src/embed/conversation.js +42 -19
  89. package/lib/src/embed/conversation.js.map +1 -1
  90. package/lib/src/embed/conversation.spec.js +96 -3
  91. package/lib/src/embed/conversation.spec.js.map +1 -1
  92. package/lib/src/embed/liveboard.d.ts +38 -1
  93. package/lib/src/embed/liveboard.d.ts.map +1 -1
  94. package/lib/src/embed/liveboard.js +39 -11
  95. package/lib/src/embed/liveboard.js.map +1 -1
  96. package/lib/src/embed/liveboard.spec.js +179 -7
  97. package/lib/src/embed/liveboard.spec.js.map +1 -1
  98. package/lib/src/errors.d.ts +1 -0
  99. package/lib/src/errors.d.ts.map +1 -1
  100. package/lib/src/errors.js +1 -0
  101. package/lib/src/errors.js.map +1 -1
  102. package/lib/src/index.d.ts +3 -3
  103. package/lib/src/index.d.ts.map +1 -1
  104. package/lib/src/index.js.map +1 -1
  105. package/lib/src/types.d.ts +192 -40
  106. package/lib/src/types.d.ts.map +1 -1
  107. package/lib/src/types.js +184 -19
  108. package/lib/src/types.js.map +1 -1
  109. package/lib/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
  110. package/lib/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
  111. package/lib/src/utils/graphql/answerService/answer-queries.js +22 -0
  112. package/lib/src/utils/graphql/answerService/answer-queries.js.map +1 -1
  113. package/lib/src/utils/graphql/answerService/answerService.d.ts +2 -1
  114. package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  115. package/lib/src/utils/graphql/answerService/answerService.js +9 -1
  116. package/lib/src/utils/graphql/answerService/answerService.js.map +1 -1
  117. package/lib/src/utils/graphql/answerService/answerService.spec.js +73 -0
  118. package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  119. package/lib/src/utils.d.ts +15 -0
  120. package/lib/src/utils.d.ts.map +1 -1
  121. package/lib/src/utils.js +30 -0
  122. package/lib/src/utils.js.map +1 -1
  123. package/lib/src/utils.spec.js +50 -1
  124. package/lib/src/utils.spec.js.map +1 -1
  125. package/package.json +1 -1
  126. package/src/css-variables.ts +60 -0
  127. package/src/embed/app.spec.ts +32 -0
  128. package/src/embed/app.ts +97 -1
  129. package/src/embed/conversation.spec.ts +117 -3
  130. package/src/embed/conversation.ts +188 -29
  131. package/src/embed/liveboard.spec.ts +264 -10
  132. package/src/embed/liveboard.ts +100 -11
  133. package/src/errors.ts +1 -0
  134. package/src/index.ts +5 -1
  135. package/src/types.ts +193 -40
  136. package/src/utils/graphql/answerService/answer-queries.ts +23 -0
  137. package/src/utils/graphql/answerService/answerService.spec.ts +87 -0
  138. package/src/utils/graphql/answerService/answerService.ts +13 -1
  139. package/src/utils.spec.ts +56 -0
  140. package/src/utils.ts +36 -0
@@ -855,6 +855,187 @@ describe('Liveboard/viz embed tests', () => {
855
855
  });
856
856
  });
857
857
 
858
+ describe('personalizedViewId functionality', () => {
859
+ const personalizedViewId = 'view-456-guid';
860
+
861
+ test('should render liveboard with personalizedViewId', async () => {
862
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
863
+ ...defaultViewConfig,
864
+ liveboardId,
865
+ personalizedViewId,
866
+ } as LiveboardViewConfig);
867
+ liveboardEmbed.render();
868
+ await executeAfterWait(() => {
869
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), { view: personalizedViewId });
870
+ });
871
+ });
872
+
873
+ test('should render liveboard with personalizedViewId and activeTabId together', async () => {
874
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
875
+ ...defaultViewConfig,
876
+ liveboardId,
877
+ personalizedViewId,
878
+ activeTabId,
879
+ } as LiveboardViewConfig);
880
+ liveboardEmbed.render();
881
+ await executeAfterWait(() => {
882
+ // URL should be: #/embed/viz/{id}/tab/{tabId}?view={viewId}
883
+ expect(getIFrameSrc()).toMatch(
884
+ new RegExp(
885
+ `#/embed/viz/${liveboardId}/tab/${activeTabId}\\?view=${personalizedViewId}`,
886
+ ),
887
+ );
888
+ });
889
+ });
890
+
891
+ test('should render liveboard with personalizedViewId and vizId together', async () => {
892
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
893
+ ...defaultViewConfig,
894
+ liveboardId,
895
+ personalizedViewId,
896
+ vizId,
897
+ } as LiveboardViewConfig);
898
+ liveboardEmbed.render();
899
+ await executeAfterWait(() => {
900
+ // URL should be: #/embed/viz/{id}/{vizId}?view={viewId}
901
+ expect(getIFrameSrc()).toMatch(
902
+ new RegExp(`#/embed/viz/${liveboardId}/${vizId}\\?view=${personalizedViewId}`),
903
+ );
904
+ });
905
+ });
906
+
907
+ test('should render liveboard with personalizedViewId, activeTabId, and vizId together', async () => {
908
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
909
+ ...defaultViewConfig,
910
+ liveboardId,
911
+ personalizedViewId,
912
+ activeTabId,
913
+ vizId,
914
+ } as LiveboardViewConfig);
915
+ liveboardEmbed.render();
916
+ await executeAfterWait(() => {
917
+ // URL should be: #/embed/viz/{id}/tab/{tabId}/{vizId}?view={viewId}
918
+ expect(getIFrameSrc()).toMatch(
919
+ new RegExp(
920
+ `#/embed/viz/${liveboardId}/tab/${activeTabId}/${vizId}\\?view=${personalizedViewId}`,
921
+ ),
922
+ );
923
+ });
924
+ });
925
+
926
+ test('should not include view param when personalizedViewId is not provided', async () => {
927
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
928
+ ...defaultViewConfig,
929
+ liveboardId,
930
+ } as LiveboardViewConfig);
931
+ liveboardEmbed.render();
932
+ await executeAfterWait(() => {
933
+ expect(getIFrameSrc()).not.toContain('view=');
934
+ });
935
+ });
936
+
937
+ test('should include personalizedViewId in getLiveboardUrl', async () => {
938
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
939
+ ...defaultViewConfig,
940
+ liveboardId,
941
+ personalizedViewId,
942
+ } as LiveboardViewConfig);
943
+ await liveboardEmbed.render();
944
+ expect(liveboardEmbed.getLiveboardUrl()).toBe(
945
+ `http://${thoughtSpotHost}/#/pinboard/${liveboardId}?view=${personalizedViewId}`,
946
+ );
947
+ });
948
+
949
+ test('should include personalizedViewId with activeTabId in getLiveboardUrl', async () => {
950
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
951
+ ...defaultViewConfig,
952
+ liveboardId,
953
+ personalizedViewId,
954
+ activeTabId,
955
+ } as LiveboardViewConfig);
956
+ await liveboardEmbed.render();
957
+ expect(liveboardEmbed.getLiveboardUrl()).toBe(
958
+ `http://${thoughtSpotHost}/#/pinboard/${liveboardId}/tab/${activeTabId}?view=${personalizedViewId}`,
959
+ );
960
+ });
961
+
962
+ test('personalizedViewId should work with runtime filters', async () => {
963
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
964
+ ...defaultViewConfig,
965
+ liveboardId,
966
+ personalizedViewId,
967
+ runtimeFilters: [
968
+ {
969
+ columnName: 'sales',
970
+ operator: RuntimeFilterOp.EQ,
971
+ values: [1000],
972
+ },
973
+ ],
974
+ excludeRuntimeFiltersfromURL: false,
975
+ } as LiveboardViewConfig);
976
+ liveboardEmbed.render();
977
+ await executeAfterWait(() => {
978
+ expectUrlToHaveParamsWithValues(getIFrameSrc(), {
979
+ view: personalizedViewId,
980
+ col1: 'sales',
981
+ op1: 'EQ',
982
+ val1: '1000',
983
+ });
984
+ });
985
+ });
986
+
987
+ describe('backward compatibility with liveboardId?view= workaround', () => {
988
+ const workaroundViewId = 'workaround-view-id';
989
+ const liveboardIdWithView = `${liveboardId}?view=${workaroundViewId}`;
990
+
991
+ test('should extract view from workaround and add at end of URL', async () => {
992
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
993
+ ...defaultViewConfig,
994
+ liveboardId: liveboardIdWithView,
995
+ } as LiveboardViewConfig);
996
+ liveboardEmbed.render();
997
+ await executeAfterWait(() => {
998
+ // URL: #/embed/viz/{cleanId}?view={workaroundViewId}
999
+ expect(getIFrameSrc()).toMatch(
1000
+ new RegExp(`#/embed/viz/${liveboardId}\\?view=${workaroundViewId}`),
1001
+ );
1002
+ });
1003
+ });
1004
+
1005
+ test('should extract view and place after tab when activeTabId is provided', async () => {
1006
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1007
+ ...defaultViewConfig,
1008
+ liveboardId: liveboardIdWithView,
1009
+ activeTabId,
1010
+ } as LiveboardViewConfig);
1011
+ liveboardEmbed.render();
1012
+ await executeAfterWait(() => {
1013
+ // URL: #/embed/viz/{id}/tab/{tabId}?view={viewId} (view at END, not middle)
1014
+ expect(getIFrameSrc()).toMatch(
1015
+ new RegExp(
1016
+ `#/embed/viz/${liveboardId}/tab/${activeTabId}\\?view=${workaroundViewId}`,
1017
+ ),
1018
+ );
1019
+ });
1020
+ });
1021
+
1022
+ test('should use personalizedViewId over workaround when both provided', async () => {
1023
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1024
+ ...defaultViewConfig,
1025
+ liveboardId: liveboardIdWithView,
1026
+ personalizedViewId,
1027
+ } as LiveboardViewConfig);
1028
+ liveboardEmbed.render();
1029
+ await executeAfterWait(() => {
1030
+ // personalizedViewId wins, workaround stripped
1031
+ expect(getIFrameSrc()).toMatch(
1032
+ new RegExp(`#/embed/viz/${liveboardId}\\?view=${personalizedViewId}`),
1033
+ );
1034
+ });
1035
+ });
1036
+ });
1037
+ });
1038
+
858
1039
  test('navigateToLiveboard should trigger the navigate event with the correct path', async () => {
859
1040
  mockMessageChannel();
860
1041
  // mock getSessionInfo
@@ -979,6 +1160,40 @@ describe('Liveboard/viz embed tests', () => {
979
1160
  });
980
1161
  });
981
1162
 
1163
+ test('should set hideToolResponseCardBranding parameter in url params via spotterChatConfig', async () => {
1164
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1165
+ ...defaultViewConfig,
1166
+ liveboardId,
1167
+ spotterChatConfig: {
1168
+ hideToolResponseCardBranding: true,
1169
+ },
1170
+ } as LiveboardViewConfig);
1171
+ await liveboardEmbed.render();
1172
+ await executeAfterWait(() => {
1173
+ expectUrlMatchesWithParams(
1174
+ getIFrameSrc(),
1175
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}&hideToolResponseCardBranding=true#/embed/viz/${liveboardId}`,
1176
+ );
1177
+ });
1178
+ });
1179
+
1180
+ test('should set toolResponseCardBrandingLabel parameter in url params via spotterChatConfig', async () => {
1181
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1182
+ ...defaultViewConfig,
1183
+ liveboardId,
1184
+ spotterChatConfig: {
1185
+ toolResponseCardBrandingLabel: 'MyBrand',
1186
+ },
1187
+ } as LiveboardViewConfig);
1188
+ await liveboardEmbed.render();
1189
+ await executeAfterWait(() => {
1190
+ expectUrlMatchesWithParams(
1191
+ getIFrameSrc(),
1192
+ `http://${thoughtSpotHost}/?embedApp=true${defaultParams}${prefixParams}&toolResponseCardBrandingLabel=MyBrand#/embed/viz/${liveboardId}`,
1193
+ );
1194
+ });
1195
+ });
1196
+
982
1197
  test('SetActiveTab Hostevent should not trigger the navigate event with the correct path, for vizEmbed', async () => {
983
1198
  const mockProcessTrigger = jest.spyOn(tsEmbed.TsEmbed.prototype, 'trigger');
984
1199
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
@@ -1137,7 +1352,12 @@ describe('Liveboard/viz embed tests', () => {
1137
1352
  ) as HTMLIFrameElement;
1138
1353
 
1139
1354
  // should render the generic link
1140
- expect(navigateToLiveboardSpy).toHaveBeenCalledWith(testLiveboardId, 'testVizId', 'testActiveTabId');
1355
+ expect(navigateToLiveboardSpy).toHaveBeenCalledWith(
1356
+ testLiveboardId,
1357
+ 'testVizId',
1358
+ 'testActiveTabId',
1359
+ undefined,
1360
+ );
1141
1361
  expect(iFrame.src).toMatch(/http:\/\/tshost\/.*&isLiveboardEmbed=true.*#$/);
1142
1362
 
1143
1363
  expect(consoleSpy).toHaveBeenCalledTimes(0);
@@ -1195,7 +1415,12 @@ describe('Liveboard/viz embed tests', () => {
1195
1415
  libEmbed.getPreRenderIds().child,
1196
1416
  ) as HTMLIFrameElement;
1197
1417
  // should render the generic link
1198
- expect(navigateToLiveboardSpy).toHaveBeenCalledWith(testLiveboardId, 'testVizId', 'testActiveTabId');
1418
+ expect(navigateToLiveboardSpy).toHaveBeenCalledWith(
1419
+ testLiveboardId,
1420
+ 'testVizId',
1421
+ 'testActiveTabId',
1422
+ undefined,
1423
+ );
1199
1424
  expect(iFrame.src).toMatch(/http:\/\/tshost\/.*&isLiveboardEmbed=true.*#$/);
1200
1425
  expect(consoleSpy).toHaveBeenCalledTimes(0);
1201
1426
  }, 1005);
@@ -1528,9 +1753,13 @@ describe('Liveboard/viz embed tests', () => {
1528
1753
  mockProcessTrigger.mockResolvedValue({ session: 'test' });
1529
1754
  await executeAfterWait(async () => {
1530
1755
  await liveboardEmbed.trigger(HostEvent.Save);
1531
- expect(mockProcessTrigger).toHaveBeenCalledWith(HostEvent.Save, {
1532
- vizId: 'testViz',
1533
- }, undefined);
1756
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
1757
+ HostEvent.Save,
1758
+ {
1759
+ vizId: 'testViz',
1760
+ },
1761
+ undefined,
1762
+ );
1534
1763
  });
1535
1764
  });
1536
1765
  });
@@ -1564,7 +1793,12 @@ describe('Liveboard/viz embed tests', () => {
1564
1793
  liveboardEmbed['executeEmbedContainerReadyCallbacks']();
1565
1794
 
1566
1795
  // Now navigateToLiveboard should be called
1567
- expect(navigateToLiveboardSpy).toHaveBeenCalledWith(liveboardId, vizId, activeTabId);
1796
+ expect(navigateToLiveboardSpy).toHaveBeenCalledWith(
1797
+ liveboardId,
1798
+ vizId,
1799
+ activeTabId,
1800
+ undefined,
1801
+ );
1568
1802
  });
1569
1803
 
1570
1804
  test('should update currentLiveboardState for prerender object when embed container loads', async () => {
@@ -1617,7 +1851,12 @@ describe('Liveboard/viz embed tests', () => {
1617
1851
  liveboardEmbed['beforePrerenderVisible']();
1618
1852
 
1619
1853
  // navigateToLiveboard should be called immediately
1620
- expect(navigateToLiveboardSpy).toHaveBeenCalledWith(liveboardId, vizId, activeTabId);
1854
+ expect(navigateToLiveboardSpy).toHaveBeenCalledWith(
1855
+ liveboardId,
1856
+ vizId,
1857
+ activeTabId,
1858
+ undefined,
1859
+ );
1621
1860
  });
1622
1861
 
1623
1862
  test('should handle beforePrerenderVisible without prerender object', async () => {
@@ -1642,7 +1881,12 @@ describe('Liveboard/viz embed tests', () => {
1642
1881
  liveboardEmbed['executeEmbedContainerReadyCallbacks']();
1643
1882
 
1644
1883
  // navigateToLiveboard should still be called
1645
- expect(navigateToLiveboardSpy).toHaveBeenCalledWith(liveboardId, vizId, activeTabId);
1884
+ expect(navigateToLiveboardSpy).toHaveBeenCalledWith(
1885
+ liveboardId,
1886
+ vizId,
1887
+ activeTabId,
1888
+ undefined,
1889
+ );
1646
1890
  });
1647
1891
 
1648
1892
  test('should work with all liveboard parameters', async () => {
@@ -1666,7 +1910,12 @@ describe('Liveboard/viz embed tests', () => {
1666
1910
  liveboardEmbed['beforePrerenderVisible']();
1667
1911
 
1668
1912
  // Check that all parameters are passed correctly
1669
- expect(navigateToLiveboardSpy).toHaveBeenCalledWith(customLiveboardId, customVizId, customActiveTabId);
1913
+ expect(navigateToLiveboardSpy).toHaveBeenCalledWith(
1914
+ customLiveboardId,
1915
+ customVizId,
1916
+ customActiveTabId,
1917
+ undefined,
1918
+ );
1670
1919
  });
1671
1920
 
1672
1921
  test('should work with minimal liveboard parameters', async () => {
@@ -1684,7 +1933,12 @@ describe('Liveboard/viz embed tests', () => {
1684
1933
  liveboardEmbed['beforePrerenderVisible']();
1685
1934
 
1686
1935
  // Check that undefined parameters are passed correctly
1687
- expect(navigateToLiveboardSpy).toHaveBeenCalledWith(liveboardId, undefined, undefined);
1936
+ expect(navigateToLiveboardSpy).toHaveBeenCalledWith(
1937
+ liveboardId,
1938
+ undefined,
1939
+ undefined,
1940
+ undefined,
1941
+ );
1688
1942
  });
1689
1943
  });
1690
1944
 
@@ -24,12 +24,13 @@ import {
24
24
  EmbedErrorCodes,
25
25
  ContextType,
26
26
  } from '../types';
27
- import { calculateVisibleElementData, getQueryParamString, isUndefined, isValidCssMargin } from '../utils';
27
+ import { calculateVisibleElementData, getQueryParamString, isUndefined, isValidCssMargin, setParamIfDefined } from '../utils';
28
28
  import { getAuthPromise } from './base';
29
29
  import { TsEmbed, V1Embed } from './ts-embed';
30
30
  import { addPreviewStylesIfNotPresent } from '../utils/global-styles';
31
31
  import { TriggerPayload, TriggerResponse } from './hostEventClient/contracts';
32
32
  import { logger } from '../utils/logger';
33
+ import { SpotterChatViewConfig } from './conversation';
33
34
 
34
35
 
35
36
  /**
@@ -209,6 +210,23 @@ export interface LiveboardViewConfig extends BaseViewConfig, LiveboardOtherViewC
209
210
  * @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1-sw
210
211
  */
211
212
  activeTabId?: string;
213
+ /**
214
+ * The GUID of a saved personalized view to load.
215
+ * A personalized view is a saved configuration of a Liveboard
216
+ * that includes specific filter selections.
217
+ *
218
+ * Supported embed types: `LiveboardEmbed`
219
+ * @example
220
+ * ```js
221
+ * const embed = new LiveboardEmbed('#tsEmbed', {
222
+ * liveboardId: 'liveboard-guid',
223
+ * personalizedViewId: 'view-guid',
224
+ * activeTabId: 'tab-guid',
225
+ * })
226
+ * ```
227
+ * @version SDK: 1.46.0 | ThoughtSpot: 26.4.0.cl
228
+ */
229
+ personalizedViewId?: string;
212
230
  /**
213
231
  * Show or hide the tab panel of the embedded Liveboard.
214
232
  *
@@ -464,6 +482,24 @@ export interface LiveboardViewConfig extends BaseViewConfig, LiveboardOtherViewC
464
482
  * @version SDK: 1.45.0 | ThoughtSpot: 26.2.0.cl
465
483
  */
466
484
  updatedSpotterChatPrompt?: boolean;
485
+ /**
486
+ * Configuration for customizing Spotter chat UI
487
+ * branding in tool response cards.
488
+ *
489
+ * Supported embed types: `LiveboardEmbed`
490
+ * @example
491
+ * ```js
492
+ * const embed = new LiveboardEmbed('#tsEmbed', {
493
+ * ... //other embed view config
494
+ * spotterChatConfig: {
495
+ * hideToolResponseCardBranding: true,
496
+ * toolResponseCardBrandingLabel: 'MyBrand',
497
+ * },
498
+ * })
499
+ * ```
500
+ * @version SDK: 1.46.0 | ThoughtSpot: 26.4.0.cl
501
+ */
502
+ spotterChatConfig?: SpotterChatViewConfig;
467
503
  }
468
504
 
469
505
  /**
@@ -553,6 +589,7 @@ export class LiveboardEmbed extends V1Embed {
553
589
  isCentralizedLiveboardFilterUXEnabled = false,
554
590
  isLinkParametersEnabled,
555
591
  updatedSpotterChatPrompt,
592
+ spotterChatConfig,
556
593
  isThisPeriodInDateFiltersEnabled,
557
594
  } = this.viewConfig;
558
595
 
@@ -619,7 +656,6 @@ export class LiveboardEmbed extends V1Embed {
619
656
  params[Param.DataSourceId] = dataSourceId;
620
657
  }
621
658
 
622
-
623
659
  if (isLiveboardStylingAndGroupingEnabled !== undefined) {
624
660
  params[Param.IsLiveboardStylingAndGroupingEnabled] = isLiveboardStylingAndGroupingEnabled;
625
661
  }
@@ -640,6 +676,17 @@ export class LiveboardEmbed extends V1Embed {
640
676
  params[Param.ShowSpotterLimitations] = showSpotterLimitations;
641
677
  }
642
678
 
679
+ // Handle spotterChatConfig params
680
+ if (spotterChatConfig) {
681
+ const {
682
+ hideToolResponseCardBranding,
683
+ toolResponseCardBrandingLabel,
684
+ } = spotterChatConfig;
685
+
686
+ setParamIfDefined(params, Param.HideToolResponseCardBranding, hideToolResponseCardBranding, true);
687
+ setParamIfDefined(params, Param.ToolResponseCardBrandingLabel, toolResponseCardBrandingLabel);
688
+ }
689
+
643
690
  if (isLinkParametersEnabled !== undefined) {
644
691
  params[Param.isLinkParametersEnabled] = isLinkParametersEnabled;
645
692
  }
@@ -671,15 +718,39 @@ export class LiveboardEmbed extends V1Embed {
671
718
  return params;
672
719
  }
673
720
 
674
- private getIframeSuffixSrc(liveboardId: string, vizId: string, activeTabId: string) {
675
- let suffix = `/embed/viz/${liveboardId}`;
721
+ private getIframeSuffixSrc(
722
+ liveboardId: string,
723
+ vizId: string,
724
+ activeTabId: string,
725
+ personalizedViewId?: string,
726
+ ) {
727
+ // Extract view from liveboardId if passed along with it (legacy approach)
728
+ // View must be appended as query param at the end, not embedded in path
729
+ let liveboardGuid = liveboardId;
730
+ let legacyViewId: string | undefined;
731
+
732
+ if (liveboardId?.includes('?')) {
733
+ const [id, query] = liveboardId.split('?');
734
+ liveboardGuid = id;
735
+ const params = new URLSearchParams(query);
736
+ legacyViewId = params.get('view') || undefined;
737
+ }
738
+
739
+ // personalizedViewId takes precedence over legacyViewId (when passed as part of liveboardId)
740
+ const effectiveViewId = personalizedViewId || legacyViewId;
741
+
742
+ let suffix = `/embed/viz/${liveboardGuid}`;
676
743
  if (activeTabId) {
677
- suffix = `${suffix}/tab/${activeTabId} `;
744
+ suffix = `${suffix}/tab/${activeTabId}`;
678
745
  }
679
746
  if (vizId) {
680
747
  suffix = `${suffix}/${vizId}`;
681
748
  }
682
- const tsPostHashParams = this.getThoughtSpotPostUrlParams();
749
+ const additionalParams: { [key: string]: string } = {};
750
+ if (effectiveViewId) {
751
+ additionalParams.view = effectiveViewId;
752
+ }
753
+ const tsPostHashParams = this.getThoughtSpotPostUrlParams(additionalParams);
683
754
  suffix = `${suffix}${tsPostHashParams}`;
684
755
  return suffix;
685
756
  }
@@ -687,7 +758,7 @@ export class LiveboardEmbed extends V1Embed {
687
758
  private sendFullHeightLazyLoadData = () => {
688
759
  const data = calculateVisibleElementData(this.iFrame);
689
760
  this.trigger(HostEvent.VisibleEmbedCoordinates, data);
690
- }
761
+ };
691
762
 
692
763
  /**
693
764
  * This is a handler for the RequestVisibleEmbedCoordinates event.
@@ -706,7 +777,7 @@ export class LiveboardEmbed extends V1Embed {
706
777
  * to be loaded within the iFrame.
707
778
  */
708
779
  private getIFrameSrc(): string {
709
- const { vizId, activeTabId } = this.viewConfig;
780
+ const { vizId, activeTabId, personalizedViewId } = this.viewConfig;
710
781
  const liveboardId = this.viewConfig.liveboardId ?? this.viewConfig.pinboardId;
711
782
 
712
783
  if (!liveboardId) {
@@ -721,6 +792,7 @@ export class LiveboardEmbed extends V1Embed {
721
792
  liveboardId,
722
793
  vizId,
723
794
  activeTabId,
795
+ personalizedViewId,
724
796
  )}`;
725
797
  }
726
798
 
@@ -813,18 +885,25 @@ export class LiveboardEmbed extends V1Embed {
813
885
  liveboardId: this.viewConfig.liveboardId,
814
886
  vizId: this.viewConfig.vizId,
815
887
  activeTabId: this.viewConfig.activeTabId,
888
+ personalizedViewId: this.viewConfig.personalizedViewId,
816
889
  };
817
890
 
818
891
  protected beforePrerenderVisible(): void {
819
892
  const embedObj = this.getPreRenderObj<LiveboardEmbed>();
820
893
 
821
894
  this.executeAfterEmbedContainerLoaded(() => {
822
- this.navigateToLiveboard(this.viewConfig.liveboardId, this.viewConfig.vizId, this.viewConfig.activeTabId);
895
+ this.navigateToLiveboard(
896
+ this.viewConfig.liveboardId,
897
+ this.viewConfig.vizId,
898
+ this.viewConfig.activeTabId,
899
+ this.viewConfig.personalizedViewId,
900
+ );
823
901
  if (embedObj) {
824
902
  embedObj.currentLiveboardState = {
825
903
  liveboardId: this.viewConfig.liveboardId,
826
904
  vizId: this.viewConfig.vizId,
827
905
  activeTabId: this.viewConfig.activeTabId,
906
+ personalizedViewId: this.viewConfig.personalizedViewId,
828
907
  };
829
908
  }
830
909
  });
@@ -902,11 +981,17 @@ export class LiveboardEmbed extends V1Embed {
902
981
  return this;
903
982
  }
904
983
 
905
- public navigateToLiveboard(liveboardId: string, vizId?: string, activeTabId?: string) {
906
- const path = this.getIframeSuffixSrc(liveboardId, vizId, activeTabId);
984
+ public navigateToLiveboard(
985
+ liveboardId: string,
986
+ vizId?: string,
987
+ activeTabId?: string,
988
+ personalizedViewId?: string,
989
+ ) {
990
+ const path = this.getIframeSuffixSrc(liveboardId, vizId, activeTabId, personalizedViewId);
907
991
  this.viewConfig.liveboardId = liveboardId;
908
992
  this.viewConfig.activeTabId = activeTabId;
909
993
  this.viewConfig.vizId = vizId;
994
+ this.viewConfig.personalizedViewId = personalizedViewId;
910
995
  if (this.isRendered) {
911
996
  this.trigger(HostEvent.Navigate, path.substring(1));
912
997
  } else if (this.viewConfig.preRenderId) {
@@ -931,6 +1016,10 @@ export class LiveboardEmbed extends V1Embed {
931
1016
  url = `${url}/${this.viewConfig.vizId}`;
932
1017
  }
933
1018
 
1019
+ if (this.viewConfig.personalizedViewId) {
1020
+ url = `${url}?view=${this.viewConfig.personalizedViewId}`;
1021
+ }
1022
+
934
1023
  return url;
935
1024
  }
936
1025
  }
package/src/errors.ts CHANGED
@@ -29,6 +29,7 @@ export const ERROR_MESSAGE = {
29
29
  ERROR_PARSING_API_INTERCEPT_BODY: 'Error parsing api intercept body',
30
30
  SSR_ENVIRONMENT_ERROR: 'SSR environment detected. This function cannot be called in SSR environment.',
31
31
  UPDATE_PARAMS_FAILED: 'Failed to update embed parameters',
32
+ INVALID_SPOTTER_DOCUMENTATION_URL: 'Invalid spotterDocumentationUrl. Please provide a valid http or https URL.',
32
33
  };
33
34
 
34
35
  export const CUSTOM_ACTIONS_ERROR_MESSAGE = {
package/src/index.ts CHANGED
@@ -32,7 +32,7 @@ import { PinboardEmbed, LiveboardViewConfig, LiveboardEmbed } from './embed/live
32
32
  import { SearchEmbed, SearchViewConfig } from './embed/search';
33
33
  import { SearchBarEmbed, SearchBarViewConfig } from './embed/search-bar';
34
34
  import { SpotterAgentEmbed, SpotterAgentEmbedViewConfig, BodylessConversation, BodylessConversationViewConfig} from './embed/bodyless-conversation';
35
- import { SpotterEmbed, SpotterEmbedViewConfig, ConversationEmbed, ConversationViewConfig } from './embed/conversation';
35
+ import { SpotterEmbed, SpotterEmbedViewConfig, SpotterChatViewConfig, SpotterSidebarViewConfig, ConversationEmbed, ConversationViewConfig } from './embed/conversation';
36
36
  import {
37
37
  AuthFailureType, AuthStatus, AuthEvent, AuthEventEmitter,
38
38
  } from './auth';
@@ -67,6 +67,7 @@ import {
67
67
  CustomActionTarget,
68
68
  InterceptedApiType,
69
69
  EmbedErrorCodes,
70
+ EmbedErrorDetailsEvent,
70
71
  ErrorDetailsTypes,
71
72
  ContextType,
72
73
  } from './types';
@@ -106,6 +107,8 @@ export {
106
107
  BodylessConversation,
107
108
  SpotterEmbed,
108
109
  SpotterEmbedViewConfig,
110
+ SpotterChatViewConfig,
111
+ SpotterSidebarViewConfig,
109
112
  ConversationViewConfig,
110
113
  ConversationEmbed,
111
114
  AuthFailureType,
@@ -161,6 +164,7 @@ export {
161
164
  CustomActionTarget,
162
165
  InterceptedApiType,
163
166
  EmbedErrorCodes,
167
+ EmbedErrorDetailsEvent,
164
168
  ErrorDetailsTypes,
165
169
  };
166
170