@thoughtspot/visual-embed-sdk 1.35.2 → 1.35.5-hostEvent.1
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.
- package/cjs/package.json +1 -1
- package/cjs/src/auth.spec.js +12 -0
- package/cjs/src/auth.spec.js.map +1 -1
- package/cjs/src/authToken.spec.js +1 -1
- package/cjs/src/authToken.spec.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.spec.js +0 -1
- package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.d.ts +97 -0
- package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -0
- package/cjs/src/embed/hostEventClient/contracts.js +16 -0
- package/cjs/src/embed/hostEventClient/contracts.js.map +1 -0
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts +14 -0
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -0
- package/cjs/src/embed/hostEventClient/host-event-client.js +50 -0
- package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.d.ts +2 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.d.ts.map +1 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js +171 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -0
- package/cjs/src/embed/liveboard.d.ts +2 -1
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +1 -1
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +30 -0
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/search.spec.js +11 -0
- package/cjs/src/embed/search.spec.js.map +1 -1
- package/cjs/src/embed/searchEmbed-basic-auth.spec.d.ts +2 -0
- package/cjs/src/embed/searchEmbed-basic-auth.spec.d.ts.map +1 -0
- package/cjs/src/embed/searchEmbed-basic-auth.spec.js +104 -0
- package/cjs/src/embed/searchEmbed-basic-auth.spec.js.map +1 -0
- package/cjs/src/embed/ts-embed.d.ts +13 -1
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +19 -3
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +38 -1
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/hostEventsTypeMapping.d.ts +2 -0
- package/cjs/src/hostEventsTypeMapping.d.ts.map +1 -0
- package/cjs/src/hostEventsTypeMapping.js +4 -0
- package/cjs/src/hostEventsTypeMapping.js.map +1 -0
- package/cjs/src/index.d.ts +2 -1
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +3 -1
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/react/all-types-export.d.ts +1 -1
- package/cjs/src/react/all-types-export.d.ts.map +1 -1
- package/cjs/src/react/all-types-export.js +2 -1
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/types.d.ts +13 -3
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +12 -2
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/embedApi/contracts.d.ts +101 -0
- package/cjs/src/utils/embedApi/contracts.d.ts.map +1 -0
- package/cjs/src/utils/embedApi/contracts.js +17 -0
- package/cjs/src/utils/embedApi/contracts.js.map +1 -0
- package/cjs/src/utils/embedApi/embedApiClient.d.ts +12 -0
- package/cjs/src/utils/embedApi/embedApiClient.d.ts.map +1 -0
- package/cjs/src/utils/embedApi/embedApiClient.js +46 -0
- package/cjs/src/utils/embedApi/embedApiClient.js.map +1 -0
- package/cjs/src/utils/embedApi/processEmbedApi.d.ts +9 -0
- package/cjs/src/utils/embedApi/processEmbedApi.d.ts.map +1 -0
- package/cjs/src/utils/embedApi/processEmbedApi.js +18 -0
- package/cjs/src/utils/embedApi/processEmbedApi.js.map +1 -0
- package/dist/{index-DoPTJLbd.js → index-CbltIawo.js} +1 -1
- package/dist/index-CzwzS0P4.js +7370 -0
- package/dist/src/embed/hostEventClient/contracts.d.ts +97 -0
- package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -0
- package/dist/src/embed/hostEventClient/host-event-client.d.ts +14 -0
- package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -0
- package/dist/src/embed/hostEventClient/host-event-client.spec.d.ts +2 -0
- package/dist/src/embed/hostEventClient/host-event-client.spec.d.ts.map +1 -0
- package/dist/src/embed/liveboard.d.ts +2 -1
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/searchEmbed-basic-auth.spec.d.ts +2 -0
- package/dist/src/embed/searchEmbed-basic-auth.spec.d.ts.map +1 -0
- package/dist/src/embed/ts-embed.d.ts +13 -1
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/dist/src/hostEventsTypeMapping.d.ts +2 -0
- package/dist/src/hostEventsTypeMapping.d.ts.map +1 -0
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/react/all-types-export.d.ts +1 -1
- package/dist/src/react/all-types-export.d.ts.map +1 -1
- package/dist/src/types.d.ts +13 -3
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/embedApi/contracts.d.ts +101 -0
- package/dist/src/utils/embedApi/contracts.d.ts.map +1 -0
- package/dist/src/utils/embedApi/embedApiClient.d.ts +12 -0
- package/dist/src/utils/embedApi/embedApiClient.d.ts.map +1 -0
- package/dist/src/utils/embedApi/processEmbedApi.d.ts +9 -0
- package/dist/src/utils/embedApi/processEmbedApi.d.ts.map +1 -0
- package/dist/tsembed-react.es.js +89 -8
- package/dist/tsembed-react.js +88 -7
- package/dist/tsembed.es.js +90 -9
- package/dist/tsembed.js +88 -7
- package/dist/visual-embed-sdk-react-full.d.ts +134 -6
- package/dist/visual-embed-sdk-react.d.ts +134 -6
- package/dist/visual-embed-sdk.d.ts +134 -6
- package/lib/package.json +1 -1
- package/lib/src/auth.spec.js +12 -0
- package/lib/src/auth.spec.js.map +1 -1
- package/lib/src/authToken.spec.js +1 -1
- package/lib/src/authToken.spec.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.spec.js +0 -1
- package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.d.ts +97 -0
- package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -0
- package/lib/src/embed/hostEventClient/contracts.js +13 -0
- package/lib/src/embed/hostEventClient/contracts.js.map +1 -0
- package/lib/src/embed/hostEventClient/host-event-client.d.ts +14 -0
- package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -0
- package/lib/src/embed/hostEventClient/host-event-client.js +46 -0
- package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.d.ts +2 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.d.ts.map +1 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.js +169 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -0
- package/lib/src/embed/liveboard.d.ts +2 -1
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +1 -1
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +30 -0
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/search.spec.js +11 -0
- package/lib/src/embed/search.spec.js.map +1 -1
- package/lib/src/embed/searchEmbed-basic-auth.spec.d.ts +2 -0
- package/lib/src/embed/searchEmbed-basic-auth.spec.d.ts.map +1 -0
- package/lib/src/embed/searchEmbed-basic-auth.spec.js +101 -0
- package/lib/src/embed/searchEmbed-basic-auth.spec.js.map +1 -0
- package/lib/src/embed/ts-embed.d.ts +13 -1
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +19 -3
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +40 -3
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/hostEventsTypeMapping.d.ts +2 -0
- package/lib/src/hostEventsTypeMapping.d.ts.map +1 -0
- package/lib/src/hostEventsTypeMapping.js +2 -0
- package/lib/src/hostEventsTypeMapping.js.map +1 -0
- package/lib/src/index.d.ts +2 -1
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -1
- package/lib/src/index.js.map +1 -1
- package/lib/src/react/all-types-export.d.ts +1 -1
- package/lib/src/react/all-types-export.d.ts.map +1 -1
- package/lib/src/react/all-types-export.js +1 -1
- package/lib/src/react/all-types-export.js.map +1 -1
- package/lib/src/types.d.ts +13 -3
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +12 -2
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/embedApi/contracts.d.ts +101 -0
- package/lib/src/utils/embedApi/contracts.d.ts.map +1 -0
- package/lib/src/utils/embedApi/contracts.js +14 -0
- package/lib/src/utils/embedApi/contracts.js.map +1 -0
- package/lib/src/utils/embedApi/embedApiClient.d.ts +12 -0
- package/lib/src/utils/embedApi/embedApiClient.d.ts.map +1 -0
- package/lib/src/utils/embedApi/embedApiClient.js +42 -0
- package/lib/src/utils/embedApi/embedApiClient.js.map +1 -0
- package/lib/src/utils/embedApi/processEmbedApi.d.ts +9 -0
- package/lib/src/utils/embedApi/processEmbedApi.d.ts.map +1 -0
- package/lib/src/utils/embedApi/processEmbedApi.js +14 -0
- package/lib/src/utils/embedApi/processEmbedApi.js.map +1 -0
- package/lib/src/visual-embed-sdk.d.ts +145 -6
- package/package.json +1 -1
- package/src/auth.spec.ts +13 -0
- package/src/authToken.spec.ts +1 -1
- package/src/embed/bodyless-conversation.spec.ts +0 -1
- package/src/embed/hostEventClient/contracts.ts +108 -0
- package/src/embed/hostEventClient/host-event-client.spec.ts +234 -0
- package/src/embed/hostEventClient/host-event-client.ts +81 -0
- package/src/embed/liveboard.spec.ts +32 -0
- package/src/embed/liveboard.ts +5 -1
- package/src/embed/search.spec.ts +15 -0
- package/src/embed/ts-embed.spec.ts +53 -1
- package/src/embed/ts-embed.ts +29 -5
- package/src/index.ts +2 -0
- package/src/react/all-types-export.ts +1 -0
- package/src/types.ts +12 -2
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { HostEvent } from '../../types';
|
|
2
|
+
import { processTrigger } from '../../utils/processTrigger';
|
|
3
|
+
import {
|
|
4
|
+
UiPassthroughArrayResponse,
|
|
5
|
+
UiPassthroughEvent, HostEventRequest, HostEventResponse,
|
|
6
|
+
UiPassthroughRequest,
|
|
7
|
+
FlattenType,
|
|
8
|
+
} from './contracts';
|
|
9
|
+
|
|
10
|
+
type UiPassthroughHandlerWithIframe = <UiPassthroughEventT extends UiPassthroughEvent>(
|
|
11
|
+
iFrame: HTMLIFrameElement,
|
|
12
|
+
apiName: UiPassthroughEventT,
|
|
13
|
+
parameters: FlattenType<UiPassthroughRequest<UiPassthroughEventT>>,
|
|
14
|
+
) => UiPassthroughArrayResponse<UiPassthroughEventT>;
|
|
15
|
+
|
|
16
|
+
export type UiPassthroughHandler = <UiPassthroughEventT extends UiPassthroughEvent>(
|
|
17
|
+
apiName: UiPassthroughEventT,
|
|
18
|
+
parameters: FlattenType<UiPassthroughRequest<UiPassthroughEventT>>,
|
|
19
|
+
) => UiPassthroughArrayResponse<UiPassthroughEventT>;
|
|
20
|
+
|
|
21
|
+
export class HostEventClient {
|
|
22
|
+
thoughtSpotHost: string;
|
|
23
|
+
|
|
24
|
+
constructor(thoughtSpotHost: string) {
|
|
25
|
+
this.thoughtSpotHost = thoughtSpotHost;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
executeUiPassthroughApi:UiPassthroughHandlerWithIframe = async (iFrame, apiName, parameters) => {
|
|
29
|
+
const res = await processTrigger(iFrame, HostEvent.UiPassthrough, this.thoughtSpotHost, {
|
|
30
|
+
type: apiName,
|
|
31
|
+
parameters,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return res;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
handleUiPassthroughForHostEvent:UiPassthroughHandlerWithIframe =
|
|
38
|
+
async (iFrame, apiName, parameters) => {
|
|
39
|
+
const response = (await this.executeUiPassthroughApi(iFrame, apiName, parameters))
|
|
40
|
+
?.filter?.((r) => r.error || r.value)[0];
|
|
41
|
+
|
|
42
|
+
if (!response) {
|
|
43
|
+
const error = `No answer found${parameters.vizId ? ` for vizId: ${parameters.vizId}` : ''}.`;
|
|
44
|
+
// eslint-disable-next-line no-throw-literal
|
|
45
|
+
throw { error };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const errors = response.error || (response.value as any)?.errors;
|
|
49
|
+
if (errors) {
|
|
50
|
+
// eslint-disable-next-line no-throw-literal
|
|
51
|
+
throw { error: response.error };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return { ...response.value };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async hostEventFallback(
|
|
58
|
+
iFrame: HTMLIFrameElement, hostEvent: HostEvent, data: any,
|
|
59
|
+
): Promise<any> {
|
|
60
|
+
return processTrigger(iFrame, hostEvent, this.thoughtSpotHost, data);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async executeHostEvent<T extends HostEvent>(
|
|
64
|
+
iFrame: HTMLIFrameElement, hostEvent: HostEvent, payload?: HostEventRequest<T>,
|
|
65
|
+
):
|
|
66
|
+
Promise<HostEventResponse<HostEvent>> {
|
|
67
|
+
if (hostEvent === HostEvent.Pin && payload?.newVizName) {
|
|
68
|
+
return this.handleUiPassthroughForHostEvent(
|
|
69
|
+
iFrame, UiPassthroughEvent.addVizToPinboard, payload,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
if (hostEvent === HostEvent.SaveAnswer && payload?.name) {
|
|
73
|
+
return this.handleUiPassthroughForHostEvent(
|
|
74
|
+
iFrame, UiPassthroughEvent.saveAnswer, payload,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
// fallback for save answer is Save
|
|
78
|
+
if (hostEvent === HostEvent.SaveAnswer) hostEvent = HostEvent.Save;
|
|
79
|
+
return this.hostEventFallback(iFrame, hostEvent, payload);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -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>',
|
package/src/embed/liveboard.ts
CHANGED
|
@@ -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
|
|
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);
|
package/src/embed/search.spec.ts
CHANGED
|
@@ -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,
|
|
@@ -126,6 +132,52 @@ describe('Unit test case for ts embed', () => {
|
|
|
126
132
|
});
|
|
127
133
|
});
|
|
128
134
|
});
|
|
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
|
+
|
|
169
|
+
test('should set proper height, width and min-height to iframe', async () => {
|
|
170
|
+
// we dont have origin specific policies so just checking if
|
|
171
|
+
// policies are ending with ;
|
|
172
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
173
|
+
searchEmbed.render();
|
|
174
|
+
await executeAfterWait(() => {
|
|
175
|
+
const iframe = getIFrameEl();
|
|
176
|
+
expect(iframe.style.width).toBe(`${defaultViewConfig.frameParams.width}px`);
|
|
177
|
+
expect(iframe.style.height).toBe(`${defaultViewConfig.frameParams.height}px`);
|
|
178
|
+
expect(iframe.style.minHeight).toBe(`${defaultViewConfig.frameParams.height}px`);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
129
181
|
});
|
|
130
182
|
|
|
131
183
|
describe('AuthExpire embedEvent in cookieless authentication authType', () => {
|
|
@@ -1338,7 +1390,6 @@ describe('Unit test case for ts embed', () => {
|
|
|
1338
1390
|
},
|
|
1339
1391
|
});
|
|
1340
1392
|
await appEmbed.render();
|
|
1341
|
-
console.log('val ', getIFrameSrc());
|
|
1342
1393
|
expectUrlMatchesWithParams(
|
|
1343
1394
|
getIFrameSrc(),
|
|
1344
1395
|
`http://${thoughtSpotHost}/?embedApp=true&primaryNavHidden=true&profileAndHelpInNavBarHidden=false&${defaultParamsForPinboardEmbed}`
|
|
@@ -1804,6 +1855,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
1804
1855
|
afterAll(() => {
|
|
1805
1856
|
const rootEle = document.getElementById('myRoot');
|
|
1806
1857
|
rootEle.remove();
|
|
1858
|
+
jest.clearAllMocks();
|
|
1807
1859
|
});
|
|
1808
1860
|
|
|
1809
1861
|
it('should preRender and hide the iframe', async () => {
|
package/src/embed/ts-embed.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import isEqual from 'lodash/isEqual';
|
|
10
10
|
import isEmpty from 'lodash/isEmpty';
|
|
11
11
|
import isObject from 'lodash/isObject';
|
|
12
|
+
import { HostEventRequest, HostEventResponse } from './hostEventClient/contracts';
|
|
12
13
|
import { logger } from '../utils/logger';
|
|
13
14
|
import { getAuthenticationToken } from '../authToken';
|
|
14
15
|
import { AnswerService } from '../utils/graphql/answerService/answerService';
|
|
@@ -62,6 +63,7 @@ import {
|
|
|
62
63
|
import { AuthFailureType } from '../auth';
|
|
63
64
|
import { getEmbedConfig } from './embedConfig';
|
|
64
65
|
import { ERROR_MESSAGE } from '../errors';
|
|
66
|
+
import { HostEventClient, UiPassthroughHandler } from './hostEventClient/host-event-client';
|
|
65
67
|
|
|
66
68
|
const { version } = pkgInfo;
|
|
67
69
|
|
|
@@ -121,8 +123,8 @@ export class TsEmbed {
|
|
|
121
123
|
protected thoughtSpotHost: string;
|
|
122
124
|
|
|
123
125
|
/*
|
|
124
|
-
|
|
125
|
-
|
|
126
|
+
* This is the base to access ThoughtSpot V2.
|
|
127
|
+
*/
|
|
126
128
|
protected thoughtSpotV2Base: string;
|
|
127
129
|
|
|
128
130
|
/**
|
|
@@ -159,6 +161,8 @@ export class TsEmbed {
|
|
|
159
161
|
|
|
160
162
|
private resizeObserver: ResizeObserver;
|
|
161
163
|
|
|
164
|
+
protected hostEventClient: HostEventClient;
|
|
165
|
+
|
|
162
166
|
constructor(domSelector: DOMSelector, viewConfig?: ViewConfig) {
|
|
163
167
|
this.el = getDOMNode(domSelector);
|
|
164
168
|
// TODO: handle error
|
|
@@ -180,6 +184,7 @@ export class TsEmbed {
|
|
|
180
184
|
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_EMBED_CREATE, {
|
|
181
185
|
...viewConfig,
|
|
182
186
|
});
|
|
187
|
+
this.hostEventClient = new HostEventClient(this.embedConfig.thoughtSpotHost);
|
|
183
188
|
}
|
|
184
189
|
|
|
185
190
|
/**
|
|
@@ -594,6 +599,9 @@ export class TsEmbed {
|
|
|
594
599
|
|
|
595
600
|
iFrame.style.width = `${width}`;
|
|
596
601
|
iFrame.style.height = `${height}`;
|
|
602
|
+
// Set minimum height to the frame so that,
|
|
603
|
+
// scaling down on the fullheight doesn't make it too small.
|
|
604
|
+
iFrame.style.minHeight = `${height}`;
|
|
597
605
|
iFrame.style.border = '0';
|
|
598
606
|
iFrame.name = 'ThoughtSpot Embedded Analytics';
|
|
599
607
|
return iFrame;
|
|
@@ -982,8 +990,12 @@ export class TsEmbed {
|
|
|
982
990
|
* Triggers an event to the embedded app
|
|
983
991
|
* @param messageType The event type
|
|
984
992
|
* @param data The payload to send with the message
|
|
993
|
+
* @returns A promise that resolves with the response from the embedded app
|
|
985
994
|
*/
|
|
986
|
-
public trigger
|
|
995
|
+
public trigger<HostEventT extends HostEvent>(
|
|
996
|
+
messageType: HostEventT,
|
|
997
|
+
data?: HostEventRequest<HostEventT>,
|
|
998
|
+
): Promise<HostEventResponse<HostEventT>> {
|
|
987
999
|
uploadMixpanelEvent(`${MIXPANEL_EVENT.VISUAL_SDK_TRIGGER}-${messageType}`);
|
|
988
1000
|
|
|
989
1001
|
if (!this.isRendered) {
|
|
@@ -995,7 +1007,20 @@ export class TsEmbed {
|
|
|
995
1007
|
this.handleError('Host event type is undefined');
|
|
996
1008
|
return null;
|
|
997
1009
|
}
|
|
998
|
-
|
|
1010
|
+
|
|
1011
|
+
return this.hostEventClient.executeHostEvent(this.iFrame, messageType, data);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Triggers an event to the embedded app, skipping the UI flow.
|
|
1016
|
+
* @param {UiPassthroughEvent} apiName - The name of the API to be triggered.
|
|
1017
|
+
* @param {UiPassthroughRequest} parameters - The parameters to be passed to the API.
|
|
1018
|
+
* @returns {Promise<UiPassthroughRequest>} - A promise that resolves with the response
|
|
1019
|
+
* from the embedded app.
|
|
1020
|
+
*/
|
|
1021
|
+
// eslint-disable-next-line arrow-body-style
|
|
1022
|
+
public triggerUiPassThrough: UiPassthroughHandler = (apiName, parameters) => {
|
|
1023
|
+
return this.hostEventClient.executeUiPassthroughApi(this.iFrame, apiName, parameters);
|
|
999
1024
|
}
|
|
1000
1025
|
|
|
1001
1026
|
/**
|
|
@@ -1242,7 +1267,6 @@ export class TsEmbed {
|
|
|
1242
1267
|
*/
|
|
1243
1268
|
public async getAnswerService(vizId?: string): Promise<AnswerService> {
|
|
1244
1269
|
const { session } = await this.trigger(HostEvent.GetAnswerSession, vizId ? { vizId } : {});
|
|
1245
|
-
|
|
1246
1270
|
return new AnswerService(session, null, this.embedConfig.thoughtSpotHost);
|
|
1247
1271
|
}
|
|
1248
1272
|
}
|
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';
|
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`,
|
|
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.34.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
|
/**
|