@thoughtspot/visual-embed-sdk 1.35.3 → 1.35.5-hostEvent.2

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 (185) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/auth.spec.js +12 -0
  3. package/cjs/src/auth.spec.js.map +1 -1
  4. package/cjs/src/authToken.spec.js +1 -1
  5. package/cjs/src/authToken.spec.js.map +1 -1
  6. package/cjs/src/embed/bodyless-conversation.spec.js +0 -1
  7. package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
  8. package/cjs/src/embed/hostEventClient/contracts.d.ts +91 -0
  9. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -0
  10. package/cjs/src/embed/hostEventClient/contracts.js +15 -0
  11. package/cjs/src/embed/hostEventClient/contracts.js.map +1 -0
  12. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +11 -0
  13. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -0
  14. package/cjs/src/embed/hostEventClient/host-event-client.js +50 -0
  15. package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -0
  16. package/cjs/src/embed/hostEventClient/host-event-client.spec.d.ts +2 -0
  17. package/cjs/src/embed/hostEventClient/host-event-client.spec.d.ts.map +1 -0
  18. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +171 -0
  19. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -0
  20. package/cjs/src/embed/liveboard.d.ts +2 -1
  21. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  22. package/cjs/src/embed/liveboard.js +1 -1
  23. package/cjs/src/embed/liveboard.js.map +1 -1
  24. package/cjs/src/embed/liveboard.spec.js +30 -0
  25. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  26. package/cjs/src/embed/search.spec.js +11 -0
  27. package/cjs/src/embed/search.spec.js.map +1 -1
  28. package/cjs/src/embed/searchEmbed-basic-auth.spec.d.ts +2 -0
  29. package/cjs/src/embed/searchEmbed-basic-auth.spec.d.ts.map +1 -0
  30. package/cjs/src/embed/searchEmbed-basic-auth.spec.js +104 -0
  31. package/cjs/src/embed/searchEmbed-basic-auth.spec.js.map +1 -0
  32. package/cjs/src/embed/ts-embed.d.ts +13 -1
  33. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  34. package/cjs/src/embed/ts-embed.js +16 -3
  35. package/cjs/src/embed/ts-embed.js.map +1 -1
  36. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  37. package/cjs/src/embed/ts-embed.spec.js +26 -1
  38. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  39. package/cjs/src/hostEventsTypeMapping.d.ts +2 -0
  40. package/cjs/src/hostEventsTypeMapping.d.ts.map +1 -0
  41. package/cjs/src/hostEventsTypeMapping.js +4 -0
  42. package/cjs/src/hostEventsTypeMapping.js.map +1 -0
  43. package/cjs/src/index.d.ts +2 -1
  44. package/cjs/src/index.d.ts.map +1 -1
  45. package/cjs/src/index.js +3 -1
  46. package/cjs/src/index.js.map +1 -1
  47. package/cjs/src/react/all-types-export.d.ts +1 -1
  48. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  49. package/cjs/src/react/all-types-export.js +2 -1
  50. package/cjs/src/react/all-types-export.js.map +1 -1
  51. package/cjs/src/types.d.ts +13 -3
  52. package/cjs/src/types.d.ts.map +1 -1
  53. package/cjs/src/types.js +12 -2
  54. package/cjs/src/types.js.map +1 -1
  55. package/cjs/src/utils/embedApi/contracts.d.ts +101 -0
  56. package/cjs/src/utils/embedApi/contracts.d.ts.map +1 -0
  57. package/cjs/src/utils/embedApi/contracts.js +17 -0
  58. package/cjs/src/utils/embedApi/contracts.js.map +1 -0
  59. package/cjs/src/utils/embedApi/embedApiClient.d.ts +12 -0
  60. package/cjs/src/utils/embedApi/embedApiClient.d.ts.map +1 -0
  61. package/cjs/src/utils/embedApi/embedApiClient.js +46 -0
  62. package/cjs/src/utils/embedApi/embedApiClient.js.map +1 -0
  63. package/cjs/src/utils/embedApi/processEmbedApi.d.ts +9 -0
  64. package/cjs/src/utils/embedApi/processEmbedApi.d.ts.map +1 -0
  65. package/cjs/src/utils/embedApi/processEmbedApi.js +18 -0
  66. package/cjs/src/utils/embedApi/processEmbedApi.js.map +1 -0
  67. package/dist/{index-BaGHDCpW.js → index-CbltIawo.js} +1 -1
  68. package/dist/index-CzwzS0P4.js +7370 -0
  69. package/dist/index-DFwi_pV_.js +7370 -0
  70. package/dist/src/embed/hostEventClient/contracts.d.ts +91 -0
  71. package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -0
  72. package/dist/src/embed/hostEventClient/host-event-client.d.ts +11 -0
  73. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -0
  74. package/dist/src/embed/hostEventClient/host-event-client.spec.d.ts +2 -0
  75. package/dist/src/embed/hostEventClient/host-event-client.spec.d.ts.map +1 -0
  76. package/dist/src/embed/liveboard.d.ts +2 -1
  77. package/dist/src/embed/liveboard.d.ts.map +1 -1
  78. package/dist/src/embed/searchEmbed-basic-auth.spec.d.ts +2 -0
  79. package/dist/src/embed/searchEmbed-basic-auth.spec.d.ts.map +1 -0
  80. package/dist/src/embed/ts-embed.d.ts +13 -1
  81. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  82. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  83. package/dist/src/hostEventsTypeMapping.d.ts +2 -0
  84. package/dist/src/hostEventsTypeMapping.d.ts.map +1 -0
  85. package/dist/src/index.d.ts +2 -1
  86. package/dist/src/index.d.ts.map +1 -1
  87. package/dist/src/react/all-types-export.d.ts +1 -1
  88. package/dist/src/react/all-types-export.d.ts.map +1 -1
  89. package/dist/src/types.d.ts +13 -3
  90. package/dist/src/types.d.ts.map +1 -1
  91. package/dist/src/utils/embedApi/contracts.d.ts +101 -0
  92. package/dist/src/utils/embedApi/contracts.d.ts.map +1 -0
  93. package/dist/src/utils/embedApi/embedApiClient.d.ts +12 -0
  94. package/dist/src/utils/embedApi/embedApiClient.d.ts.map +1 -0
  95. package/dist/src/utils/embedApi/processEmbedApi.d.ts +9 -0
  96. package/dist/src/utils/embedApi/processEmbedApi.d.ts.map +1 -0
  97. package/dist/tsembed-react.es.js +85 -8
  98. package/dist/tsembed-react.js +84 -7
  99. package/dist/tsembed.es.js +86 -9
  100. package/dist/tsembed.js +84 -7
  101. package/dist/visual-embed-sdk-react-full.d.ts +125 -6
  102. package/dist/visual-embed-sdk-react.d.ts +125 -6
  103. package/dist/visual-embed-sdk.d.ts +125 -6
  104. package/lib/package.json +1 -1
  105. package/lib/src/auth.spec.js +12 -0
  106. package/lib/src/auth.spec.js.map +1 -1
  107. package/lib/src/authToken.spec.js +1 -1
  108. package/lib/src/authToken.spec.js.map +1 -1
  109. package/lib/src/embed/bodyless-conversation.spec.js +0 -1
  110. package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
  111. package/lib/src/embed/hostEventClient/contracts.d.ts +91 -0
  112. package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -0
  113. package/lib/src/embed/hostEventClient/contracts.js +12 -0
  114. package/lib/src/embed/hostEventClient/contracts.js.map +1 -0
  115. package/lib/src/embed/hostEventClient/host-event-client.d.ts +11 -0
  116. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -0
  117. package/lib/src/embed/hostEventClient/host-event-client.js +46 -0
  118. package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -0
  119. package/lib/src/embed/hostEventClient/host-event-client.spec.d.ts +2 -0
  120. package/lib/src/embed/hostEventClient/host-event-client.spec.d.ts.map +1 -0
  121. package/lib/src/embed/hostEventClient/host-event-client.spec.js +169 -0
  122. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -0
  123. package/lib/src/embed/liveboard.d.ts +2 -1
  124. package/lib/src/embed/liveboard.d.ts.map +1 -1
  125. package/lib/src/embed/liveboard.js +1 -1
  126. package/lib/src/embed/liveboard.js.map +1 -1
  127. package/lib/src/embed/liveboard.spec.js +30 -0
  128. package/lib/src/embed/liveboard.spec.js.map +1 -1
  129. package/lib/src/embed/search.spec.js +11 -0
  130. package/lib/src/embed/search.spec.js.map +1 -1
  131. package/lib/src/embed/searchEmbed-basic-auth.spec.d.ts +2 -0
  132. package/lib/src/embed/searchEmbed-basic-auth.spec.d.ts.map +1 -0
  133. package/lib/src/embed/searchEmbed-basic-auth.spec.js +101 -0
  134. package/lib/src/embed/searchEmbed-basic-auth.spec.js.map +1 -0
  135. package/lib/src/embed/ts-embed.d.ts +13 -1
  136. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  137. package/lib/src/embed/ts-embed.js +16 -3
  138. package/lib/src/embed/ts-embed.js.map +1 -1
  139. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  140. package/lib/src/embed/ts-embed.spec.js +28 -3
  141. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  142. package/lib/src/hostEventsTypeMapping.d.ts +2 -0
  143. package/lib/src/hostEventsTypeMapping.d.ts.map +1 -0
  144. package/lib/src/hostEventsTypeMapping.js +2 -0
  145. package/lib/src/hostEventsTypeMapping.js.map +1 -0
  146. package/lib/src/index.d.ts +2 -1
  147. package/lib/src/index.d.ts.map +1 -1
  148. package/lib/src/index.js +2 -1
  149. package/lib/src/index.js.map +1 -1
  150. package/lib/src/react/all-types-export.d.ts +1 -1
  151. package/lib/src/react/all-types-export.d.ts.map +1 -1
  152. package/lib/src/react/all-types-export.js +1 -1
  153. package/lib/src/react/all-types-export.js.map +1 -1
  154. package/lib/src/types.d.ts +13 -3
  155. package/lib/src/types.d.ts.map +1 -1
  156. package/lib/src/types.js +12 -2
  157. package/lib/src/types.js.map +1 -1
  158. package/lib/src/utils/embedApi/contracts.d.ts +101 -0
  159. package/lib/src/utils/embedApi/contracts.d.ts.map +1 -0
  160. package/lib/src/utils/embedApi/contracts.js +14 -0
  161. package/lib/src/utils/embedApi/contracts.js.map +1 -0
  162. package/lib/src/utils/embedApi/embedApiClient.d.ts +12 -0
  163. package/lib/src/utils/embedApi/embedApiClient.d.ts.map +1 -0
  164. package/lib/src/utils/embedApi/embedApiClient.js +42 -0
  165. package/lib/src/utils/embedApi/embedApiClient.js.map +1 -0
  166. package/lib/src/utils/embedApi/processEmbedApi.d.ts +9 -0
  167. package/lib/src/utils/embedApi/processEmbedApi.d.ts.map +1 -0
  168. package/lib/src/utils/embedApi/processEmbedApi.js +14 -0
  169. package/lib/src/utils/embedApi/processEmbedApi.js.map +1 -0
  170. package/lib/src/visual-embed-sdk.d.ts +136 -6
  171. package/package.json +1 -1
  172. package/src/auth.spec.ts +13 -0
  173. package/src/authToken.spec.ts +1 -1
  174. package/src/embed/bodyless-conversation.spec.ts +0 -1
  175. package/src/embed/hostEventClient/contracts.ts +102 -0
  176. package/src/embed/hostEventClient/host-event-client.spec.ts +234 -0
  177. package/src/embed/hostEventClient/host-event-client.ts +78 -0
  178. package/src/embed/liveboard.spec.ts +32 -0
  179. package/src/embed/liveboard.ts +5 -1
  180. package/src/embed/search.spec.ts +15 -0
  181. package/src/embed/ts-embed.spec.ts +40 -1
  182. package/src/embed/ts-embed.ts +35 -5
  183. package/src/index.ts +2 -0
  184. package/src/react/all-types-export.ts +1 -0
  185. package/src/types.ts +12 -2
@@ -0,0 +1,78 @@
1
+ import { HostEvent } from '../../types';
2
+ import { processTrigger } from '../../utils/processTrigger';
3
+ import {
4
+ UiPassthroughArrayResponse,
5
+ UiPassthroughEvent, HostEventRequest, HostEventResponse,
6
+ UiPassthroughRequest,
7
+ UiPassthroughResponse,
8
+ } from './contracts';
9
+
10
+ export class HostEventClient {
11
+ thoughtSpotHost: string;
12
+
13
+ constructor(thoughtSpotHost: string) {
14
+ this.thoughtSpotHost = thoughtSpotHost;
15
+ }
16
+
17
+ public async executeUiPassthroughApi<UiPassthroughEventT extends UiPassthroughEvent>(
18
+ iFrame: HTMLIFrameElement,
19
+ apiName: UiPassthroughEventT,
20
+ parameters: UiPassthroughRequest<UiPassthroughEventT>,
21
+ ): UiPassthroughArrayResponse<UiPassthroughEventT> {
22
+ const res = await processTrigger(iFrame, HostEvent.UiPassthrough, this.thoughtSpotHost, {
23
+ type: apiName,
24
+ parameters,
25
+ });
26
+
27
+ return res;
28
+ }
29
+
30
+ public async handleUiPassthroughForHostEvent<UiPassthroughEventT extends UiPassthroughEvent>(
31
+ iFrame: HTMLIFrameElement,
32
+ apiName: UiPassthroughEventT,
33
+ parameters: UiPassthroughRequest<UiPassthroughEventT>,
34
+ ): Promise<UiPassthroughResponse<UiPassthroughEventT>> {
35
+ const response = (await this.executeUiPassthroughApi(iFrame, apiName, parameters))
36
+ ?.filter?.((r) => r.error || r.value)[0];
37
+
38
+ if (!response) {
39
+ const error = `No answer found${parameters.vizId ? ` for vizId: ${parameters.vizId}` : ''}.`;
40
+ // eslint-disable-next-line no-throw-literal
41
+ throw { error };
42
+ }
43
+
44
+ const errors = response.error || (response.value as any)?.errors;
45
+ if (errors) {
46
+ // eslint-disable-next-line no-throw-literal
47
+ throw { error: response.error };
48
+ }
49
+
50
+ return { ...response.value };
51
+ }
52
+
53
+ public async hostEventFallback(
54
+ iFrame: HTMLIFrameElement, hostEvent: HostEvent, data: any,
55
+ ): Promise<any> {
56
+ return processTrigger(iFrame, hostEvent, this.thoughtSpotHost, data);
57
+ }
58
+
59
+ public async executeHostEvent<T extends HostEvent>(
60
+ iFrame: HTMLIFrameElement,
61
+ hostEvent: HostEvent,
62
+ payload?: HostEventRequest<T>,
63
+ ): Promise<HostEventResponse<HostEvent>> {
64
+ if (hostEvent === HostEvent.Pin && payload?.newVizName) {
65
+ return this.handleUiPassthroughForHostEvent(
66
+ iFrame, UiPassthroughEvent.addVizToPinboard, payload,
67
+ );
68
+ }
69
+ if (hostEvent === HostEvent.SaveAnswer && payload?.name) {
70
+ return this.handleUiPassthroughForHostEvent(
71
+ iFrame, UiPassthroughEvent.saveAnswer, payload,
72
+ );
73
+ }
74
+ // fallback for save answer is Save
75
+ if (hostEvent === HostEvent.SaveAnswer) hostEvent = HostEvent.Save;
76
+ return this.hostEventFallback(iFrame, hostEvent, payload);
77
+ }
78
+ }
@@ -570,6 +570,27 @@ describe('Liveboard/viz embed tests', () => {
570
570
  done();
571
571
  });
572
572
  });
573
+
574
+ test('navigateToLiveboard with preRender', (done) => {
575
+ mockMessageChannel();
576
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
577
+ ...defaultViewConfig,
578
+ preRenderId: 'test',
579
+ } as LiveboardViewConfig);
580
+ const onSpy = jest.spyOn(liveboardEmbed, 'trigger');
581
+ liveboardEmbed.prerenderGeneric();
582
+ executeAfterWait(() => {
583
+ const iframe = getIFrameEl();
584
+ postMessageToParent(iframe.contentWindow, {
585
+ type: EmbedEvent.APP_INIT,
586
+ });
587
+ });
588
+ executeAfterWait(() => {
589
+ liveboardEmbed.navigateToLiveboard('lb1', 'viz1');
590
+ expect(onSpy).toHaveBeenCalledWith(HostEvent.Navigate, 'embed/viz/lb1/viz1');
591
+ done();
592
+ });
593
+ });
573
594
  test('should set runtime parametere values in url params', async () => {
574
595
  const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
575
596
  ...defaultViewConfig,
@@ -659,6 +680,17 @@ describe('Liveboard/viz embed tests', () => {
659
680
  });
660
681
  });
661
682
 
683
+ test('get liveboard url value', async () => {
684
+ const libEmbed = new LiveboardEmbed(getRootEl(), {
685
+ liveboardId: '1234',
686
+ });
687
+ await libEmbed.render();
688
+ await executeAfterWait(() => {
689
+ const url = libEmbed.getLiveboardUrl();
690
+ expect(url).toEqual('http://tshost/#/pinboard/1234');
691
+ });
692
+ });
693
+
662
694
  test('Show preview loader should show the loader if viz embed and showPreviewLoader is true', async () => {
663
695
  jest.spyOn(previewService, 'getPreview').mockResolvedValue({
664
696
  vizContent: '<div id=test>test</div>',
@@ -23,6 +23,7 @@ import { getQueryParamString, isUndefined } from '../utils';
23
23
  import { getAuthPromise } from './base';
24
24
  import { V1Embed } from './ts-embed';
25
25
  import { addPreviewStylesIfNotPresent } from '../utils/global-styles';
26
+ import { HostEventRequest, HostEventResponse } from './hostEventClient/contracts';
26
27
 
27
28
  /**
28
29
  * The configuration for the embedded Liveboard or visualization page view.
@@ -636,7 +637,10 @@ export class LiveboardEmbed extends V1Embed {
636
637
  * @param messageType The event type
637
638
  * @param data The payload to send with the message
638
639
  */
639
- public trigger(messageType: HostEvent, data: any = {}): Promise<any> {
640
+ public trigger<HostEventT extends HostEvent>(
641
+ messageType: HostEventT,
642
+ data?: HostEventRequest<HostEventT>,
643
+ ): Promise<HostEventResponse<HostEventT>> {
640
644
  const dataWithVizId = data;
641
645
  if (messageType === HostEvent.SetActiveTab) {
642
646
  this.setActiveTab(data);
@@ -16,6 +16,7 @@ import {
16
16
  expectUrlMatchesWithParams,
17
17
  } from '../test/test-utils';
18
18
  import { version } from '../../package.json';
19
+ import { SearchBarEmbed } from './search-bar';
19
20
 
20
21
  const defaultViewConfig = {
21
22
  frameParams: {
@@ -504,6 +505,20 @@ describe('Search embed tests', () => {
504
505
  });
505
506
  });
506
507
 
508
+ test('should set dataPanelCustomGroupsAccordionInitialState to EXPAND_FIRST when passed', async () => {
509
+ const searchEmbed = new SearchBarEmbed(getRootEl() as any, {
510
+ ...defaultViewConfig,
511
+ // eslint-disable-next-line max-len
512
+ });
513
+ searchEmbed.render();
514
+ await executeAfterWait(() => {
515
+ expectUrlMatchesWithParams(
516
+ getIFrameSrc(),
517
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&useLastSelectedSources=false${prefixParams}#/embed/search-bar-embed`,
518
+ );
519
+ });
520
+ });
521
+
507
522
  test('should set dataPanelCustomGroupsAccordionInitialState to EXPAND_FIRST when passed', async () => {
508
523
  const searchEmbed = new SearchEmbed(getRootEl(), {
509
524
  ...defaultViewConfig,
@@ -15,6 +15,7 @@ import {
15
15
  ConversationViewConfig,
16
16
  ConversationEmbed,
17
17
  SearchViewConfig,
18
+ AnswerService,
18
19
  } from '../index';
19
20
  import {
20
21
  Action, HomeLeftNavItem, RuntimeFilter, RuntimeFilterOp, HomepageModule, HostEvent,
@@ -48,7 +49,12 @@ import * as authService from '../utils/authService/authService';
48
49
  import { logger } from '../utils/logger';
49
50
  import { version } from '../../package.json';
50
51
  import { HiddenActionItemByDefaultForSearchEmbed } from './search';
52
+ import { processTrigger } from '../utils/processTrigger';
53
+ import { UiPassthroughEvent } from './hostEventClient/contracts';
51
54
 
55
+ jest.mock('../utils/processTrigger');
56
+
57
+ const mockProcessTrigger = processTrigger as jest.Mock;
52
58
  const defaultViewConfig = {
53
59
  frameParams: {
54
60
  width: 1280,
@@ -127,6 +133,39 @@ describe('Unit test case for ts embed', () => {
127
133
  });
128
134
  });
129
135
 
136
+ test('should get answer service', async () => {
137
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
138
+ searchEmbed.render();
139
+ mockProcessTrigger.mockResolvedValue({ session: 'test' });
140
+ await executeAfterWait(async () => {
141
+ expect(await searchEmbed.getAnswerService()).toBeInstanceOf(AnswerService);
142
+ });
143
+ });
144
+
145
+ test('triggerUiPassThrough with params', async () => {
146
+ const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
147
+ searchEmbed.render();
148
+ mockProcessTrigger.mockResolvedValue({ session: 'test' });
149
+ await executeAfterWait(async () => {
150
+ const payload = { newVizName: 'test' };
151
+ expect(
152
+ await searchEmbed.triggerUiPassThrough(
153
+ UiPassthroughEvent.addVizToPinboard,
154
+ payload,
155
+ ),
156
+ );
157
+ expect(mockProcessTrigger).toHaveBeenCalledWith(
158
+ getIFrameEl(),
159
+ HostEvent.UiPassthrough,
160
+ 'http://tshost',
161
+ {
162
+ parameters: payload,
163
+ type: UiPassthroughEvent.addVizToPinboard,
164
+ },
165
+ );
166
+ });
167
+ });
168
+
130
169
  test('should set proper height, width and min-height to iframe', async () => {
131
170
  // we dont have origin specific policies so just checking if
132
171
  // policies are ending with ;
@@ -1351,7 +1390,6 @@ describe('Unit test case for ts embed', () => {
1351
1390
  },
1352
1391
  });
1353
1392
  await appEmbed.render();
1354
- console.log('val ', getIFrameSrc());
1355
1393
  expectUrlMatchesWithParams(
1356
1394
  getIFrameSrc(),
1357
1395
  `http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&${defaultParamsForPinboardEmbed}`
@@ -1817,6 +1855,7 @@ describe('Unit test case for ts embed', () => {
1817
1855
  afterAll(() => {
1818
1856
  const rootEle = document.getElementById('myRoot');
1819
1857
  rootEle.remove();
1858
+ jest.clearAllMocks();
1820
1859
  });
1821
1860
 
1822
1861
  it('should preRender and hide the iframe', async () => {
@@ -9,6 +9,13 @@
9
9
  import isEqual from 'lodash/isEqual';
10
10
  import isEmpty from 'lodash/isEmpty';
11
11
  import isObject from 'lodash/isObject';
12
+ import {
13
+ HostEventRequest,
14
+ HostEventResponse,
15
+ UiPassthroughArrayResponse,
16
+ UiPassthroughEvent,
17
+ UiPassthroughRequest,
18
+ } from './hostEventClient/contracts';
12
19
  import { logger } from '../utils/logger';
13
20
  import { getAuthenticationToken } from '../authToken';
14
21
  import { AnswerService } from '../utils/graphql/answerService/answerService';
@@ -62,6 +69,7 @@ import {
62
69
  import { AuthFailureType } from '../auth';
63
70
  import { getEmbedConfig } from './embedConfig';
64
71
  import { ERROR_MESSAGE } from '../errors';
72
+ import { HostEventClient } from './hostEventClient/host-event-client';
65
73
 
66
74
  const { version } = pkgInfo;
67
75
 
@@ -121,8 +129,8 @@ export class TsEmbed {
121
129
  protected thoughtSpotHost: string;
122
130
 
123
131
  /*
124
- * This is the base to access ThoughtSpot V2.
125
- */
132
+ * This is the base to access ThoughtSpot V2.
133
+ */
126
134
  protected thoughtSpotV2Base: string;
127
135
 
128
136
  /**
@@ -159,6 +167,8 @@ export class TsEmbed {
159
167
 
160
168
  private resizeObserver: ResizeObserver;
161
169
 
170
+ protected hostEventClient: HostEventClient;
171
+
162
172
  constructor(domSelector: DOMSelector, viewConfig?: ViewConfig) {
163
173
  this.el = getDOMNode(domSelector);
164
174
  // TODO: handle error
@@ -180,6 +190,7 @@ export class TsEmbed {
180
190
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_EMBED_CREATE, {
181
191
  ...viewConfig,
182
192
  });
193
+ this.hostEventClient = new HostEventClient(this.embedConfig.thoughtSpotHost);
183
194
  }
184
195
 
185
196
  /**
@@ -985,8 +996,12 @@ export class TsEmbed {
985
996
  * Triggers an event to the embedded app
986
997
  * @param messageType The event type
987
998
  * @param data The payload to send with the message
999
+ * @returns A promise that resolves with the response from the embedded app
988
1000
  */
989
- public trigger(messageType: HostEvent, data: any = {}): Promise<any> {
1001
+ public trigger<HostEventT extends HostEvent>(
1002
+ messageType: HostEventT,
1003
+ data?: HostEventRequest<HostEventT>,
1004
+ ): Promise<HostEventResponse<HostEventT>> {
990
1005
  uploadMixpanelEvent(`${MIXPANEL_EVENT.VISUAL_SDK_TRIGGER}-${messageType}`);
991
1006
 
992
1007
  if (!this.isRendered) {
@@ -998,7 +1013,23 @@ export class TsEmbed {
998
1013
  this.handleError('Host event type is undefined');
999
1014
  return null;
1000
1015
  }
1001
- return processTrigger(this.iFrame, messageType, this.thoughtSpotHost, data);
1016
+
1017
+ return this.hostEventClient.executeHostEvent(this.iFrame, messageType, data);
1018
+ }
1019
+
1020
+ /**
1021
+ * Triggers an event to the embedded app, skipping the UI flow.
1022
+ * @param {UiPassthroughEvent} apiName - The name of the API to be triggered.
1023
+ * @param {UiPassthroughRequest} parameters - The parameters to be passed to the API.
1024
+ * @returns {Promise<UiPassthroughRequest>} - A promise that resolves with the response
1025
+ * from the embedded app.
1026
+ */
1027
+ // eslint-disable-next-line arrow-body-style
1028
+ public triggerUiPassThrough<UiPassthroughEventT extends UiPassthroughEvent>(
1029
+ apiName: UiPassthroughEventT,
1030
+ parameters: UiPassthroughRequest<UiPassthroughEventT>,
1031
+ ): UiPassthroughArrayResponse<UiPassthroughEventT> {
1032
+ return this.hostEventClient.executeUiPassthroughApi(this.iFrame, apiName, parameters);
1002
1033
  }
1003
1034
 
1004
1035
  /**
@@ -1245,7 +1276,6 @@ export class TsEmbed {
1245
1276
  */
1246
1277
  public async getAnswerService(vizId?: string): Promise<AnswerService> {
1247
1278
  const { session } = await this.trigger(HostEvent.GetAnswerSession, vizId ? { vizId } : {});
1248
-
1249
1279
  return new AnswerService(session, null, this.embedConfig.thoughtSpotHost);
1250
1280
  }
1251
1281
  }
package/src/index.ts CHANGED
@@ -61,6 +61,7 @@ import { uploadMixpanelEvent, MIXPANEL_EVENT } from './mixpanel-service';
61
61
  import { tokenizedFetch } from './tokenizedFetch';
62
62
  import { getAnswerFromQuery } from './utils/graphql/nlsService/nls-answer-service';
63
63
  import { createLiveboardWithAnswers } from './utils/liveboardService/liveboardService';
64
+ import { UiPassthroughEvent } from './embed/hostEventClient/contracts';
64
65
 
65
66
  export {
66
67
  init,
@@ -127,6 +128,7 @@ export {
127
128
  HomePageSearchBarMode,
128
129
  VizPoint,
129
130
  CustomActionPayload,
131
+ UiPassthroughEvent,
130
132
  };
131
133
 
132
134
  export { resetCachedAuthToken } from './authToken';
@@ -51,4 +51,5 @@ export {
51
51
  CustomCssVariables,
52
52
  RuntimeParameter,
53
53
  resetCachedAuthToken,
54
+ UiPassthroughEvent,
54
55
  } from '../index';
package/src/types.ts CHANGED
@@ -1714,8 +1714,8 @@ export enum EmbedEvent {
1714
1714
  *
1715
1715
  * **Note**: This event is deprecated in v1.21.0.
1716
1716
  * To fire an event when a download action is initiated on a chart or table,
1717
- * use `EmbedEvent.DownloadAsPng`, `EmbedEvent.DownloadAsPDF`, `EmbedEvent.DownloadAsCSV`,
1718
- * or `EmbedEvent.DownloadAsXLSX`
1717
+ * use `EmbedEvent.DownloadAsPng`, `EmbedEvent.DownloadAsPDF`,
1718
+ * `EmbedEvent.DownloadAsCSV`, or `EmbedEvent.DownloadAsXLSX`
1719
1719
  * @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
1720
1720
  * @example
1721
1721
  *```js
@@ -3199,6 +3199,16 @@ export enum HostEvent {
3199
3199
  * @version SDK: 1.36.0 | Thoughtspot: 10.6.0.cl
3200
3200
  */
3201
3201
  UpdatePersonalisedView = 'UpdatePersonalisedView',
3202
+ /**
3203
+ * Triggers the action to get the current view of the liveboard
3204
+ * @version SDK: 1.36.0 | Thoughtspot: 10.6.0.cl
3205
+ */
3206
+ SaveAnswer = 'saveAnswer',
3207
+ /**
3208
+ * EmbedApi
3209
+ * @hidden
3210
+ */
3211
+ UiPassthrough = 'UiPassthrough',
3202
3212
  }
3203
3213
 
3204
3214
  /**