@thoughtspot/visual-embed-sdk 1.15.0 → 1.16.0
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/dist/src/auth.d.ts +3 -3
- package/dist/src/embed/base.d.ts +9 -8
- package/dist/src/embed/liveboard.d.ts +4 -1
- package/dist/src/embed/search-bar.d.ts +39 -0
- package/dist/src/embed/search.d.ts +1 -2
- package/dist/src/embed/ts-embed.d.ts +1 -0
- package/dist/src/index.d.ts +3 -2
- package/dist/src/react/index.d.ts +4 -0
- package/dist/src/types.d.ts +6 -0
- package/dist/tsembed.es.js +17471 -189
- package/dist/tsembed.js +17470 -188
- package/lib/package.json +2 -1
- package/lib/src/auth.d.ts +3 -3
- package/lib/src/auth.js +3 -3
- package/lib/src/config.spec.js +9 -1
- package/lib/src/config.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts +9 -8
- package/lib/src/embed/base.js +34 -15
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/base.spec.js +23 -2
- package/lib/src/embed/base.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +4 -1
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +13 -0
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/pinboard.spec.js.map +1 -1
- package/lib/src/embed/search-bar.d.ts +39 -0
- package/lib/src/embed/search-bar.js +58 -0
- package/lib/src/embed/search-bar.js.map +1 -0
- package/lib/src/embed/search.d.ts +1 -2
- package/lib/src/embed/ts-embed.d.ts +1 -0
- package/lib/src/embed/ts-embed.js +1 -0
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/index.d.ts +3 -2
- package/lib/src/index.js +4 -3
- package/lib/src/index.js.map +1 -1
- package/lib/src/react/index.d.ts +4 -0
- package/lib/src/react/index.js +2 -0
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +12 -1
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/types.d.ts +6 -0
- package/lib/src/types.js +7 -0
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/authService.js.map +1 -1
- package/lib/src/utils/processData.spec.js +1 -3
- package/lib/src/utils/processData.spec.js.map +1 -1
- package/lib/src/utils/processTrigger.spec.js +16 -0
- package/lib/src/utils/processTrigger.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +63 -16
- package/package.json +2 -1
- package/src/auth.ts +3 -3
- package/src/config.spec.ts +10 -1
- package/src/embed/base.spec.ts +26 -2
- package/src/embed/base.ts +42 -15
- package/src/embed/liveboard.spec.ts +16 -2
- package/src/embed/liveboard.ts +4 -1
- package/src/embed/pinboard.spec.ts +1 -2
- package/src/embed/search-bar.tsx +88 -0
- package/src/embed/search.ts +1 -1
- package/src/embed/ts-embed.ts +1 -0
- package/src/index.ts +5 -0
- package/src/react/index.spec.tsx +34 -1
- package/src/react/index.tsx +12 -0
- package/src/types.ts +7 -0
- package/src/utils/processData.spec.ts +1 -3
- package/src/utils/processTrigger.spec.ts +22 -0
package/src/embed/base.spec.ts
CHANGED
|
@@ -55,7 +55,11 @@ describe('Base TS Embed', () => {
|
|
|
55
55
|
|
|
56
56
|
test('Should add the prefetch iframe when prefetch is called. Should remove it once init is called.', async () => {
|
|
57
57
|
const url = 'https://10.87.90.95/';
|
|
58
|
-
index.
|
|
58
|
+
index.init({
|
|
59
|
+
thoughtSpotHost: url,
|
|
60
|
+
authType: index.AuthType.None,
|
|
61
|
+
callPrefetch: true,
|
|
62
|
+
});
|
|
59
63
|
expect(getAllIframeEl().length).toBe(1);
|
|
60
64
|
const prefetchIframe = document.querySelectorAll<HTMLIFrameElement>(
|
|
61
65
|
'.prefetchIframe',
|
|
@@ -65,6 +69,25 @@ describe('Base TS Embed', () => {
|
|
|
65
69
|
expect(firstIframe.src).toBe(url);
|
|
66
70
|
});
|
|
67
71
|
|
|
72
|
+
test('Should add the prefetch iframe when prefetch is called with multiple options', async () => {
|
|
73
|
+
const url = 'https://10.87.90.95/';
|
|
74
|
+
const searchUrl = `${url}v2/#/embed/answer`;
|
|
75
|
+
const liveboardUrl = url;
|
|
76
|
+
index.prefetch(url, [
|
|
77
|
+
index.PrefetchFeatures.SearchEmbed,
|
|
78
|
+
index.PrefetchFeatures.LiveboardEmbed,
|
|
79
|
+
]);
|
|
80
|
+
expect(getAllIframeEl().length).toBe(2);
|
|
81
|
+
const prefetchIframe = document.querySelectorAll<HTMLIFrameElement>(
|
|
82
|
+
'.prefetchIframe',
|
|
83
|
+
);
|
|
84
|
+
expect(prefetchIframe.length).toBe(2);
|
|
85
|
+
const firstIframe = <HTMLIFrameElement>prefetchIframe[0];
|
|
86
|
+
expect(firstIframe.src).toBe(searchUrl);
|
|
87
|
+
const secondIframe = <HTMLIFrameElement>prefetchIframe[1];
|
|
88
|
+
expect(secondIframe.src).toBe(liveboardUrl);
|
|
89
|
+
});
|
|
90
|
+
|
|
68
91
|
test('Should not generate a prefetch iframe when url is empty string', async () => {
|
|
69
92
|
const url = '';
|
|
70
93
|
index.prefetch(url);
|
|
@@ -162,6 +185,7 @@ describe('Base without init', () => {
|
|
|
162
185
|
base.notifyAuthSuccess();
|
|
163
186
|
base.notifyAuthFailure(auth.AuthFailureType.SDK);
|
|
164
187
|
base.notifyLogout();
|
|
165
|
-
|
|
188
|
+
base.notifyAuthSDKSuccess();
|
|
189
|
+
expect(global.console.error).toHaveBeenCalledTimes(4);
|
|
166
190
|
});
|
|
167
191
|
});
|
package/src/embed/base.ts
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
|
|
9
9
|
*/
|
|
10
10
|
import EventEmitter from 'eventemitter3';
|
|
11
|
+
import _ from 'lodash';
|
|
11
12
|
import { getThoughtSpotHost } from '../config';
|
|
12
|
-
import { AuthType, EmbedConfig } from '../types';
|
|
13
|
+
import { AuthType, EmbedConfig, PrefetchFeatures } from '../types';
|
|
13
14
|
import {
|
|
14
15
|
authenticate,
|
|
15
16
|
logout as _logout,
|
|
@@ -83,35 +84,54 @@ export const handleAuth = (): Promise<boolean> => {
|
|
|
83
84
|
return authPromise;
|
|
84
85
|
};
|
|
85
86
|
|
|
87
|
+
const hostUrlToFeatureUrl = {
|
|
88
|
+
[PrefetchFeatures.SearchEmbed]: (url: string) => `${url}v2/#/embed/answer`,
|
|
89
|
+
[PrefetchFeatures.LiveboardEmbed]: (url: string) => url,
|
|
90
|
+
[PrefetchFeatures.FullApp]: (url: string) => url,
|
|
91
|
+
[PrefetchFeatures.VizEmbed]: (url: string) => url,
|
|
92
|
+
};
|
|
93
|
+
|
|
86
94
|
/**
|
|
87
95
|
* Prefetches static resources from the specified URL. Web browsers can then cache the prefetched resources and serve them from the user's local disk to provide faster access to your app.
|
|
88
96
|
* @param url The URL provided for prefetch
|
|
97
|
+
* @param prefetchFeatures Specify features which needs to be prefetched.
|
|
98
|
+
* @version SDK: 1.4.0 | ThoughtSpot: ts7.sep.cl, 7.2.1
|
|
89
99
|
*/
|
|
90
|
-
export const prefetch = (
|
|
100
|
+
export const prefetch = (
|
|
101
|
+
url?: string,
|
|
102
|
+
prefetchFeatures?: PrefetchFeatures[],
|
|
103
|
+
): void => {
|
|
91
104
|
if (url === '') {
|
|
92
105
|
// eslint-disable-next-line no-console
|
|
93
106
|
console.warn('The prefetch method does not have a valid URL');
|
|
94
107
|
} else {
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
108
|
+
const features = prefetchFeatures || [PrefetchFeatures.FullApp];
|
|
109
|
+
let hostUrl = url || config.thoughtSpotHost;
|
|
110
|
+
hostUrl = hostUrl[hostUrl.length - 1] === '/' ? hostUrl : `${hostUrl}/`;
|
|
111
|
+
_.uniq(
|
|
112
|
+
features.map((feature) => hostUrlToFeatureUrl[feature](hostUrl)),
|
|
113
|
+
).forEach((prefetchUrl, index) => {
|
|
114
|
+
const iFrame = document.createElement('iframe');
|
|
115
|
+
iFrame.src = prefetchUrl;
|
|
116
|
+
iFrame.style.width = '0';
|
|
117
|
+
iFrame.style.height = '0';
|
|
118
|
+
iFrame.style.border = '0';
|
|
119
|
+
iFrame.classList.add('prefetchIframe');
|
|
120
|
+
iFrame.classList.add(`prefetchIframeNum-${index}`);
|
|
121
|
+
document.body.appendChild(iFrame);
|
|
122
|
+
});
|
|
102
123
|
}
|
|
103
124
|
};
|
|
104
125
|
|
|
105
126
|
/**
|
|
106
|
-
*
|
|
127
|
+
* Initializes the Visual Embed SDK globally and perform
|
|
107
128
|
* authentication if applicable.
|
|
108
129
|
* @param embedConfig The configuration object containing ThoughtSpot host,
|
|
109
130
|
* authentication mechanism and so on.
|
|
110
|
-
*
|
|
111
|
-
* eg: authStatus = init(config);
|
|
131
|
+
* example: authStatus = init(config);
|
|
112
132
|
* authStatus.on(AuthStatus.FAILURE, (reason) => { // do something here });
|
|
113
|
-
*
|
|
114
|
-
* @
|
|
133
|
+
* @returns event emitter which emits events on authentication success, failure and logout. See {@link AuthStatus}
|
|
134
|
+
* @version SDK: 1.0.0 | ThoughtSpot ts7.april.cl, 7.2.1
|
|
115
135
|
*/
|
|
116
136
|
export const init = (embedConfig: EmbedConfig): EventEmitter => {
|
|
117
137
|
config = {
|
|
@@ -125,6 +145,13 @@ export const init = (embedConfig: EmbedConfig): EventEmitter => {
|
|
|
125
145
|
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_CALLED_INIT, {
|
|
126
146
|
authType: config.authType,
|
|
127
147
|
host: config.thoughtSpotHost,
|
|
148
|
+
usedCustomizationSheet:
|
|
149
|
+
embedConfig.customisations?.style?.customCSSUrl != null,
|
|
150
|
+
usedCustomizationVariables:
|
|
151
|
+
embedConfig.customisations?.style?.customCss?.variables != null,
|
|
152
|
+
usedCustomizationRules:
|
|
153
|
+
embedConfig.customisations?.style?.customCss?.rules_UNSTABLE !=
|
|
154
|
+
null,
|
|
128
155
|
});
|
|
129
156
|
|
|
130
157
|
if (config.callPrefetch) {
|
|
@@ -138,7 +165,7 @@ export function disableAutoLogin(): void {
|
|
|
138
165
|
}
|
|
139
166
|
|
|
140
167
|
/**
|
|
141
|
-
*
|
|
168
|
+
* Logs out from ThoughtSpot. This also sets the autoLogin flag to false, to prevent
|
|
142
169
|
* the SDK from automatically logging in again.
|
|
143
170
|
*
|
|
144
171
|
* You can call the `init` method again to re login, if autoLogin is set to true in this
|
|
@@ -29,8 +29,7 @@ const thoughtSpotHost = 'tshost';
|
|
|
29
29
|
const defaultParamsSansHideAction = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
|
|
30
30
|
const defaultParams = `${defaultParamsSansHideAction}&hideAction=[%22${Action.ReportError}%22]`;
|
|
31
31
|
const prefixParams = '&isLiveboardEmbed=true';
|
|
32
|
-
const prefixParamsVizEmbed =
|
|
33
|
-
'&isLiveboardEmbed=true&isVizEmbed=true';
|
|
32
|
+
const prefixParamsVizEmbed = '&isLiveboardEmbed=true&isVizEmbed=true';
|
|
34
33
|
|
|
35
34
|
beforeAll(() => {
|
|
36
35
|
init({
|
|
@@ -249,4 +248,19 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
249
248
|
);
|
|
250
249
|
});
|
|
251
250
|
});
|
|
251
|
+
test('Should set liveboard options', async () => {
|
|
252
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
253
|
+
liveboardId,
|
|
254
|
+
activeTabId,
|
|
255
|
+
liveboardV2: true,
|
|
256
|
+
defaultHeight: 100,
|
|
257
|
+
preventLiveboardFilterRemoval: true,
|
|
258
|
+
} as LiveboardViewConfig);
|
|
259
|
+
liveboardEmbed.render();
|
|
260
|
+
await executeAfterWait(() => {
|
|
261
|
+
expect(getIFrameSrc()).toBe(
|
|
262
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&preventPinboardFilterRemoval=true&isLiveboardEmbed=true&isPinboardV2Enabled=true#/embed/viz/${liveboardId}/tab/${activeTabId}`,
|
|
263
|
+
);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
252
266
|
});
|
package/src/embed/liveboard.ts
CHANGED
|
@@ -29,6 +29,7 @@ export interface LiveboardViewConfig extends ViewConfig {
|
|
|
29
29
|
/**
|
|
30
30
|
* If set to true, the embedded object container dynamically resizes
|
|
31
31
|
* according to the height of the Liveboard.
|
|
32
|
+
* @version SDK: 1.1.0 | ThoughtSpot: ts7.may.cl, 7.2.1
|
|
32
33
|
*/
|
|
33
34
|
fullHeight?: boolean;
|
|
34
35
|
/**
|
|
@@ -40,12 +41,13 @@ export interface LiveboardViewConfig extends ViewConfig {
|
|
|
40
41
|
*/
|
|
41
42
|
defaultHeight?: number;
|
|
42
43
|
/**
|
|
43
|
-
* If set to true, the context menu in visualizations will be enabled.
|
|
44
|
+
* @Deprecated If set to true, the context menu in visualizations will be enabled.
|
|
44
45
|
*/
|
|
45
46
|
enableVizTransformations?: boolean;
|
|
46
47
|
/**
|
|
47
48
|
* The Liveboard to display in the embedded view.
|
|
48
49
|
* Use either of liveboardId or pinboardId to reference the Liveboard to embed.
|
|
50
|
+
* @version SDK: 1.3.0 | ThoughtSpot ts7.aug.cl, 7.2.1
|
|
49
51
|
*/
|
|
50
52
|
liveboardId?: string;
|
|
51
53
|
/**
|
|
@@ -60,6 +62,7 @@ export interface LiveboardViewConfig extends ViewConfig {
|
|
|
60
62
|
/**
|
|
61
63
|
* If set to true, all filter chips from a
|
|
62
64
|
* Liveboard page will be read-only (no X buttons)
|
|
65
|
+
* @version SDK: 1.3.0 | ThoughtSpot ts7.aug.cl, 7.2.1
|
|
63
66
|
*/
|
|
64
67
|
preventLiveboardFilterRemoval?: boolean;
|
|
65
68
|
/**
|
|
@@ -21,8 +21,7 @@ const thoughtSpotHost = 'tshost';
|
|
|
21
21
|
const defaultParamsWithoutHideActions = `&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}`;
|
|
22
22
|
const defaultParams = `${defaultParamsWithoutHideActions}&hideAction=[%22${Action.ReportError}%22]`;
|
|
23
23
|
const prefixParams = '&isLiveboardEmbed=true';
|
|
24
|
-
const prefixParamsVizEmbed =
|
|
25
|
-
'&isLiveboardEmbed=true&isVizEmbed=true';
|
|
24
|
+
const prefixParamsVizEmbed = '&isLiveboardEmbed=true&isVizEmbed=true';
|
|
26
25
|
beforeAll(() => {
|
|
27
26
|
init({
|
|
28
27
|
thoughtSpotHost,
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { DOMSelector, Param, Action } from '../types';
|
|
2
|
+
import { getQueryParamString } from '../utils';
|
|
3
|
+
import { TsEmbed, ViewConfig } from './ts-embed';
|
|
4
|
+
import { SearchOptions } from './search';
|
|
5
|
+
|
|
6
|
+
export interface SearchBarViewConfig extends ViewConfig {
|
|
7
|
+
/**
|
|
8
|
+
* If set to true, hides the data sources panel.
|
|
9
|
+
*/
|
|
10
|
+
hideDataSources?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* The array of data source GUIDs to set on load.
|
|
13
|
+
*/
|
|
14
|
+
dataSources?: string[];
|
|
15
|
+
/**
|
|
16
|
+
* Configuration for search options
|
|
17
|
+
*/
|
|
18
|
+
searchOptions?: SearchOptions;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Embed ThoughtSpot search bar
|
|
23
|
+
*
|
|
24
|
+
* @Category Search Embed
|
|
25
|
+
* @version: SDK: 1.17.0 | ThoughtSpot: 8.10.0
|
|
26
|
+
*/
|
|
27
|
+
export class SearchBarEmbed extends TsEmbed {
|
|
28
|
+
/**
|
|
29
|
+
* The view configuration for the embedded ThoughtSpot search bar.
|
|
30
|
+
*/
|
|
31
|
+
protected viewConfig: SearchBarViewConfig;
|
|
32
|
+
|
|
33
|
+
constructor(domSelector: string, viewConfig: SearchBarViewConfig) {
|
|
34
|
+
super(domSelector);
|
|
35
|
+
this.viewConfig = viewConfig;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Construct the URL of the embedded ThoughtSpot search to be
|
|
40
|
+
* loaded in the iframe
|
|
41
|
+
* @param dataSources A list of data source GUIDs
|
|
42
|
+
*/
|
|
43
|
+
private getIFrameSrc(dataSources?: string[]) {
|
|
44
|
+
const { searchOptions } = this.viewConfig;
|
|
45
|
+
const path = 'search-bar-embed';
|
|
46
|
+
const queryParams = this.getBaseQueryParams();
|
|
47
|
+
|
|
48
|
+
queryParams[Param.HideActions] = [
|
|
49
|
+
...(queryParams[Param.HideActions] ?? []),
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
if (dataSources && dataSources.length) {
|
|
53
|
+
queryParams[Param.DataSources] = JSON.stringify(dataSources);
|
|
54
|
+
}
|
|
55
|
+
if (searchOptions?.searchTokenString) {
|
|
56
|
+
queryParams[Param.searchTokenString] = encodeURIComponent(
|
|
57
|
+
searchOptions.searchTokenString,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
if (searchOptions.executeSearch) {
|
|
61
|
+
queryParams[Param.executeSearch] = true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
queryParams[Param.UseLastSelectedDataSource] = false;
|
|
66
|
+
queryParams[Param.searchEmbed] = true;
|
|
67
|
+
let query = '';
|
|
68
|
+
const queryParamsString = getQueryParamString(queryParams, true);
|
|
69
|
+
if (queryParamsString) {
|
|
70
|
+
query = `?${queryParamsString}`;
|
|
71
|
+
}
|
|
72
|
+
const tsPostHashParams = this.getThoughtSpotPostUrlParams();
|
|
73
|
+
|
|
74
|
+
return `${this.getEmbedBasePath(query)}/${path}${tsPostHashParams}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Render the embedded ThoughtSpot search
|
|
79
|
+
*/
|
|
80
|
+
public render(): SearchBarEmbed {
|
|
81
|
+
super.render();
|
|
82
|
+
const { dataSources } = this.viewConfig;
|
|
83
|
+
|
|
84
|
+
const src = this.getIFrameSrc(dataSources);
|
|
85
|
+
this.renderIFrame(src, this.viewConfig.frameParams);
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
}
|
package/src/embed/search.ts
CHANGED
package/src/embed/ts-embed.ts
CHANGED
|
@@ -746,6 +746,7 @@ export class TsEmbed {
|
|
|
746
746
|
* Get the Post Url Params for THOUGHTSPOT from the current
|
|
747
747
|
* host app URL.
|
|
748
748
|
* THOUGHTSPOT URL params starts with a prefix "ts-"
|
|
749
|
+
* @version SDK: 1.14.0 | ThoughtSpot: 8.4.0.cl, 8.4.1-sw
|
|
749
750
|
*/
|
|
750
751
|
public getThoughtSpotPostUrlParams(): string {
|
|
751
752
|
const urlHash = window.location.hash;
|
package/src/index.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
LiveboardEmbed,
|
|
17
17
|
} from './embed/liveboard';
|
|
18
18
|
import { SearchEmbed, SearchViewConfig } from './embed/search';
|
|
19
|
+
import { SearchBarEmbed, SearchBarViewConfig } from './embed/search-bar';
|
|
19
20
|
import { AuthFailureType, AuthStatus } from './auth';
|
|
20
21
|
import {
|
|
21
22
|
AuthType,
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
DataSourceVisualMode,
|
|
27
28
|
Action,
|
|
28
29
|
EmbedConfig,
|
|
30
|
+
PrefetchFeatures,
|
|
29
31
|
} from './types';
|
|
30
32
|
|
|
31
33
|
export {
|
|
@@ -33,6 +35,7 @@ export {
|
|
|
33
35
|
logout,
|
|
34
36
|
prefetch,
|
|
35
37
|
SearchEmbed,
|
|
38
|
+
SearchBarEmbed,
|
|
36
39
|
PinboardEmbed,
|
|
37
40
|
LiveboardEmbed,
|
|
38
41
|
AppEmbed,
|
|
@@ -49,6 +52,8 @@ export {
|
|
|
49
52
|
Action,
|
|
50
53
|
EmbedConfig,
|
|
51
54
|
SearchViewConfig,
|
|
55
|
+
SearchBarViewConfig,
|
|
52
56
|
LiveboardViewConfig,
|
|
53
57
|
AppViewConfig,
|
|
58
|
+
PrefetchFeatures,
|
|
54
59
|
};
|
package/src/react/index.spec.tsx
CHANGED
|
@@ -10,7 +10,13 @@ import {
|
|
|
10
10
|
postMessageToParent,
|
|
11
11
|
mockMessageChannel,
|
|
12
12
|
} from '../test/test-utils';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
SearchEmbed,
|
|
15
|
+
AppEmbed,
|
|
16
|
+
LiveboardEmbed,
|
|
17
|
+
useEmbedRef,
|
|
18
|
+
SearchBarEmbed,
|
|
19
|
+
} from './index';
|
|
14
20
|
import { AuthType, init } from '../index';
|
|
15
21
|
|
|
16
22
|
import { version } from '../../package.json';
|
|
@@ -118,4 +124,31 @@ describe('React Components', () => {
|
|
|
118
124
|
});
|
|
119
125
|
});
|
|
120
126
|
});
|
|
127
|
+
|
|
128
|
+
describe('SearchBarEmbed', () => {
|
|
129
|
+
it('Should Render the Iframe with props', async () => {
|
|
130
|
+
const { container } = render(
|
|
131
|
+
<SearchBarEmbed
|
|
132
|
+
hideDataSources={true}
|
|
133
|
+
className="embedClass"
|
|
134
|
+
dataSources={['test']}
|
|
135
|
+
searchOptions={{
|
|
136
|
+
searchTokenString: '[revenue]',
|
|
137
|
+
executeSearch: true,
|
|
138
|
+
}}
|
|
139
|
+
/>,
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
await waitFor(() => getIFrameEl(container));
|
|
143
|
+
|
|
144
|
+
expect(
|
|
145
|
+
getIFrameEl(container).parentElement.classList.contains(
|
|
146
|
+
'embedClass',
|
|
147
|
+
),
|
|
148
|
+
).toBe(true);
|
|
149
|
+
expect(getIFrameSrc(container)).toBe(
|
|
150
|
+
`http://${thoughtSpotHost}/?hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&hideAction=[%22${Action.ReportError}%22]&dataSources=[%22test%22]&searchTokenString=%5Brevenue%5D&executeSearch=true&useLastSelectedSources=false&isSearchEmbed=true#/embed/search-bar-embed`,
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
121
154
|
});
|
package/src/react/index.tsx
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import useDeepCompareEffect from 'use-deep-compare-effect';
|
|
3
|
+
import {
|
|
4
|
+
SearchBarEmbed as _SearchBarEmbed,
|
|
5
|
+
SearchBarViewConfig,
|
|
6
|
+
} from '../embed/search-bar';
|
|
3
7
|
import { SearchEmbed as _SearchEmbed, SearchViewConfig } from '../embed/search';
|
|
4
8
|
import { AppEmbed as _AppEmbed, AppViewConfig } from '../embed/app';
|
|
5
9
|
import {
|
|
@@ -83,6 +87,14 @@ export const PinboardEmbed = componentFactory<
|
|
|
83
87
|
LiveboardViewConfig
|
|
84
88
|
>(_LiveboardEmbed);
|
|
85
89
|
|
|
90
|
+
interface SearchBarEmbedProps extends EmbedProps, SearchBarViewConfig {}
|
|
91
|
+
|
|
92
|
+
export const SearchBarEmbed = componentFactory<
|
|
93
|
+
typeof _SearchBarEmbed,
|
|
94
|
+
SearchBarEmbedProps,
|
|
95
|
+
SearchBarViewConfig
|
|
96
|
+
>(_SearchBarEmbed);
|
|
97
|
+
|
|
86
98
|
export const useEmbedRef = (): React.MutableRefObject<TsEmbed> => {
|
|
87
99
|
return React.useRef<TsEmbed>(null);
|
|
88
100
|
};
|
package/src/types.ts
CHANGED
|
@@ -1041,3 +1041,10 @@ export enum OperationType {
|
|
|
1041
1041
|
export interface AnswerServiceType {
|
|
1042
1042
|
getAnswer?: (offset: number, batchSize: number) => any;
|
|
1043
1043
|
}
|
|
1044
|
+
|
|
1045
|
+
export enum PrefetchFeatures {
|
|
1046
|
+
FullApp = 'FullApp',
|
|
1047
|
+
SearchEmbed = 'SearchEmbed',
|
|
1048
|
+
LiveboardEmbed = 'LiveboardEmbed',
|
|
1049
|
+
VizEmbed = 'VizEmbed',
|
|
1050
|
+
}
|
|
@@ -98,9 +98,7 @@ describe('Unit test for process data', () => {
|
|
|
98
98
|
const e = { type: EmbedEvent.AuthExpire };
|
|
99
99
|
jest.spyOn(base, 'notifyAuthFailure');
|
|
100
100
|
jest.spyOn(base, 'handleAuth');
|
|
101
|
-
jest.spyOn(base, 'getEmbedConfig').mockReturnValue({
|
|
102
|
-
autoLogin: false,
|
|
103
|
-
});
|
|
101
|
+
jest.spyOn(base, 'getEmbedConfig').mockReturnValue({});
|
|
104
102
|
expect(
|
|
105
103
|
processDataInstance.processEventData(e.type, e, '', null),
|
|
106
104
|
).toEqual({
|
|
@@ -47,4 +47,26 @@ describe('Unit test for processTrigger', () => {
|
|
|
47
47
|
expect(messageChannelMock.port1.close).toBeCalled();
|
|
48
48
|
expect(triggerPromise).resolves.toEqual(res.data);
|
|
49
49
|
});
|
|
50
|
+
|
|
51
|
+
test('Reject promise if error returned', async () => {
|
|
52
|
+
const messageType = HostEvent.Search;
|
|
53
|
+
const thoughtSpotHost = 'http://localhost:3000';
|
|
54
|
+
const data = {};
|
|
55
|
+
mockMessageChannel();
|
|
56
|
+
const triggerPromise = _processTriggerInstance.processTrigger(
|
|
57
|
+
iFrame,
|
|
58
|
+
messageType,
|
|
59
|
+
thoughtSpotHost,
|
|
60
|
+
data,
|
|
61
|
+
);
|
|
62
|
+
expect(iFrame.contentWindow.postMessage).toBeCalled();
|
|
63
|
+
const res = {
|
|
64
|
+
data: {
|
|
65
|
+
error: 'error',
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
messageChannelMock.port1.onmessage(res);
|
|
69
|
+
expect(messageChannelMock.port1.close).toBeCalled();
|
|
70
|
+
expect(triggerPromise).rejects.toEqual(res.data.error);
|
|
71
|
+
});
|
|
50
72
|
});
|