@thoughtspot/visual-embed-sdk 1.13.0-alpha.2 → 1.13.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/CHANGELOG.md +31 -6
- package/README.md +1 -1
- package/dist/src/auth.d.ts +4 -1
- package/dist/src/auth.spec.d.ts +1 -0
- package/dist/src/embed/app.d.ts +5 -0
- package/dist/src/embed/liveboard.d.ts +12 -1
- package/dist/src/embed/search.d.ts +5 -0
- package/dist/src/embed/searchEmbed-basic-auth.spec.d.ts +1 -0
- package/dist/src/embed/ts-embed.d.ts +12 -3
- package/dist/src/errors.d.ts +2 -0
- package/dist/src/test/test-utils.d.ts +6 -0
- package/dist/src/types.d.ts +211 -4
- package/dist/src/utils/processTrigger.d.ts +1 -1
- package/dist/src/utils.d.ts +3 -1
- package/dist/tsembed.es.js +292 -24
- package/dist/tsembed.js +292 -24
- package/lib/package.json +4 -2
- package/lib/src/auth.d.ts +4 -1
- package/lib/src/auth.js +11 -2
- package/lib/src/auth.js.map +1 -1
- package/lib/src/auth.spec.d.ts +1 -0
- package/lib/src/auth.spec.js +13 -1
- package/lib/src/auth.spec.js.map +1 -1
- package/lib/src/config.spec.js +7 -0
- package/lib/src/config.spec.js.map +1 -1
- package/lib/src/embed/app.d.ts +5 -0
- package/lib/src/embed/app.js +1 -1
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +18 -6
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/embed.spec.js +2 -0
- package/lib/src/embed/embed.spec.js.map +1 -1
- package/lib/src/embed/events.spec.js +3 -1
- package/lib/src/embed/events.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +12 -1
- package/lib/src/embed/liveboard.js +22 -4
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +33 -6
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/pinboard.spec.js +7 -5
- package/lib/src/embed/pinboard.spec.js.map +1 -1
- package/lib/src/embed/search.d.ts +5 -0
- package/lib/src/embed/search.js +10 -2
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/search.spec.js +9 -1
- package/lib/src/embed/search.spec.js.map +1 -1
- package/lib/src/embed/searchEmbed-basic-auth.spec.d.ts +1 -0
- package/lib/src/embed/searchEmbed-basic-auth.spec.js +96 -0
- package/lib/src/embed/searchEmbed-basic-auth.spec.js.map +1 -0
- package/lib/src/embed/ts-embed.d.ts +12 -3
- package/lib/src/embed/ts-embed.js +29 -10
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +38 -5
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/errors.d.ts +2 -0
- package/lib/src/errors.js +2 -0
- package/lib/src/errors.js.map +1 -1
- package/lib/src/react/index.js +3 -2
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +6 -4
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/test/test-utils.d.ts +6 -0
- package/lib/src/test/test-utils.js +15 -0
- package/lib/src/test/test-utils.js.map +1 -1
- package/lib/src/types.d.ts +211 -4
- package/lib/src/types.js +176 -0
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/processTrigger.d.ts +1 -1
- package/lib/src/utils/processTrigger.js +28 -8
- package/lib/src/utils/processTrigger.js.map +1 -1
- package/lib/src/utils/processTrigger.spec.js +11 -1
- package/lib/src/utils/processTrigger.spec.js.map +1 -1
- package/lib/src/utils.d.ts +3 -1
- package/lib/src/utils.js +20 -0
- package/lib/src/utils.js.map +1 -1
- package/lib/src/utils.spec.js +22 -1
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +240 -9
- package/package.json +4 -2
- package/src/auth.spec.ts +20 -1
- package/src/auth.ts +12 -2
- package/src/config.spec.ts +11 -0
- package/src/embed/app.spec.ts +22 -3
- package/src/embed/app.ts +6 -0
- package/src/embed/embed.spec.ts +2 -0
- package/src/embed/events.spec.ts +3 -0
- package/src/embed/liveboard.spec.ts +46 -6
- package/src/embed/liveboard.ts +34 -2
- package/src/embed/pinboard.spec.ts +8 -6
- package/src/embed/search.spec.ts +11 -1
- package/src/embed/search.ts +20 -1
- package/src/embed/searchEmbed-basic-auth.spec.ts +115 -0
- package/src/embed/ts-embed.spec.ts +51 -5
- package/src/embed/ts-embed.ts +40 -12
- package/src/errors.ts +3 -0
- package/src/react/index.spec.tsx +7 -2
- package/src/react/index.tsx +3 -2
- package/src/test/test-utils.ts +16 -0
- package/src/types.ts +209 -0
- package/src/utils/processTrigger.spec.ts +11 -1
- package/src/utils/processTrigger.ts +36 -12
- package/src/utils.spec.ts +29 -0
- package/src/utils.ts +34 -1
package/src/embed/ts-embed.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
getOffsetTop,
|
|
14
14
|
embedEventStatus,
|
|
15
15
|
setAttributes,
|
|
16
|
+
getCustomisations,
|
|
16
17
|
} from '../utils';
|
|
17
18
|
import {
|
|
18
19
|
getThoughtSpotHost,
|
|
@@ -31,6 +32,7 @@ import {
|
|
|
31
32
|
Param,
|
|
32
33
|
EmbedConfig,
|
|
33
34
|
MessageOptions,
|
|
35
|
+
MessagePayload,
|
|
34
36
|
MessageCallbackObj,
|
|
35
37
|
} from '../types';
|
|
36
38
|
import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
|
|
@@ -75,7 +77,7 @@ export interface FrameParams {
|
|
|
75
77
|
* This parameters will be passed on the iframe
|
|
76
78
|
* as is.
|
|
77
79
|
*/
|
|
78
|
-
[key: string]: string | number | boolean;
|
|
80
|
+
[key: string]: string | number | boolean | undefined;
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
/**
|
|
@@ -202,6 +204,8 @@ export class TsEmbed {
|
|
|
202
204
|
*/
|
|
203
205
|
private shouldEncodeUrlQueryParams = false;
|
|
204
206
|
|
|
207
|
+
private defaultHiddenActions = [Action.ReportError];
|
|
208
|
+
|
|
205
209
|
constructor(domSelector: DOMSelector, viewConfig?: ViewConfig) {
|
|
206
210
|
this.el = this.getDOMNode(domSelector);
|
|
207
211
|
// TODO: handle error
|
|
@@ -212,6 +216,7 @@ export class TsEmbed {
|
|
|
212
216
|
this.isError = false;
|
|
213
217
|
this.viewConfig = viewConfig;
|
|
214
218
|
this.shouldEncodeUrlQueryParams = this.embedConfig.shouldEncodeUrlQueryParams;
|
|
219
|
+
this.registerAppInit();
|
|
215
220
|
}
|
|
216
221
|
|
|
217
222
|
/**
|
|
@@ -242,7 +247,7 @@ export class TsEmbed {
|
|
|
242
247
|
error,
|
|
243
248
|
});
|
|
244
249
|
// Log error
|
|
245
|
-
console.
|
|
250
|
+
console.error(error);
|
|
246
251
|
}
|
|
247
252
|
|
|
248
253
|
/**
|
|
@@ -308,6 +313,23 @@ export class TsEmbed {
|
|
|
308
313
|
});
|
|
309
314
|
}
|
|
310
315
|
|
|
316
|
+
/**
|
|
317
|
+
* Send Custom style as part of payload of APP_INIT
|
|
318
|
+
*/
|
|
319
|
+
private appInitCb = (_: any, responder: any) => {
|
|
320
|
+
responder({
|
|
321
|
+
type: EmbedEvent.APP_INIT,
|
|
322
|
+
data: { customisations: getCustomisations(this.embedConfig) },
|
|
323
|
+
});
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Register APP_INIT event and sendback init payload
|
|
328
|
+
*/
|
|
329
|
+
private registerAppInit = () => {
|
|
330
|
+
this.on(EmbedEvent.APP_INIT, this.appInitCb);
|
|
331
|
+
};
|
|
332
|
+
|
|
311
333
|
/**
|
|
312
334
|
* Constructs the base URL string to load the ThoughtSpot app.
|
|
313
335
|
*/
|
|
@@ -355,6 +377,7 @@ export class TsEmbed {
|
|
|
355
377
|
) {
|
|
356
378
|
queryParams[Param.DisableLoginRedirect] = true;
|
|
357
379
|
}
|
|
380
|
+
// TODO remove this
|
|
358
381
|
if (this.embedConfig.customCssUrl) {
|
|
359
382
|
queryParams[Param.CustomCSSUrl] = this.embedConfig.customCssUrl;
|
|
360
383
|
}
|
|
@@ -382,9 +405,10 @@ export class TsEmbed {
|
|
|
382
405
|
if (disabledActionReason) {
|
|
383
406
|
queryParams[Param.DisableActionReason] = disabledActionReason;
|
|
384
407
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
408
|
+
queryParams[Param.HideActions] = [
|
|
409
|
+
...this.defaultHiddenActions,
|
|
410
|
+
...(hiddenActions ?? []),
|
|
411
|
+
];
|
|
388
412
|
if (Array.isArray(visibleActions)) {
|
|
389
413
|
queryParams[Param.VisibleActions] = visibleActions;
|
|
390
414
|
}
|
|
@@ -412,12 +436,16 @@ export class TsEmbed {
|
|
|
412
436
|
showPrimaryNavbar = false,
|
|
413
437
|
disableProfileAndHelp = false,
|
|
414
438
|
isAppEmbed = false,
|
|
439
|
+
enableSearchAssist = false,
|
|
415
440
|
): string {
|
|
416
441
|
const queryStringFrag = queryString ? `&${queryString}` : '';
|
|
417
442
|
const primaryNavParam = `&primaryNavHidden=${!showPrimaryNavbar}`;
|
|
418
443
|
const disableProfileAndHelpParam = `&profileAndHelpInNavBarHidden=${disableProfileAndHelp}`;
|
|
444
|
+
const enableSearchAssistParam = `&${Param.EnableSearchAssist}=${enableSearchAssist}`;
|
|
419
445
|
let queryParams = `?embedApp=true${isAppEmbed ? primaryNavParam : ''}${
|
|
420
446
|
isAppEmbed ? disableProfileAndHelpParam : ''
|
|
447
|
+
}${
|
|
448
|
+
enableSearchAssist ? enableSearchAssistParam : ''
|
|
421
449
|
}${queryStringFrag}`;
|
|
422
450
|
if (this.shouldEncodeUrlQueryParams) {
|
|
423
451
|
queryParams = `?base64UrlEncodedFlags=${getEncodedQueryParamsString(
|
|
@@ -459,7 +487,6 @@ export class TsEmbed {
|
|
|
459
487
|
});
|
|
460
488
|
|
|
461
489
|
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_START);
|
|
462
|
-
|
|
463
490
|
getAuthPromise()
|
|
464
491
|
?.then((isLoggedIn: boolean) => {
|
|
465
492
|
if (!isLoggedIn) {
|
|
@@ -691,15 +718,16 @@ export class TsEmbed {
|
|
|
691
718
|
* @param messageType The event type
|
|
692
719
|
* @param data The payload to send with the message
|
|
693
720
|
*/
|
|
694
|
-
public trigger(
|
|
695
|
-
messageType: HostEvent,
|
|
696
|
-
data: any,
|
|
697
|
-
): typeof TsEmbed.prototype {
|
|
698
|
-
processTrigger(this.iFrame, messageType, this.thoughtSpotHost, data);
|
|
721
|
+
public trigger(messageType: HostEvent, data: any): Promise<any> {
|
|
699
722
|
uploadMixpanelEvent(
|
|
700
723
|
`${MIXPANEL_EVENT.VISUAL_SDK_TRIGGER}-${messageType}`,
|
|
701
724
|
);
|
|
702
|
-
return
|
|
725
|
+
return processTrigger(
|
|
726
|
+
this.iFrame,
|
|
727
|
+
messageType,
|
|
728
|
+
this.thoughtSpotHost,
|
|
729
|
+
data,
|
|
730
|
+
);
|
|
703
731
|
}
|
|
704
732
|
|
|
705
733
|
/**
|
package/src/errors.ts
CHANGED
|
@@ -3,4 +3,7 @@ export const ERROR_MESSAGE = {
|
|
|
3
3
|
'Error parsing ThoughtSpot host. Please provide a valid URL.',
|
|
4
4
|
LIVEBOARD_VIZ_ID_VALIDATION:
|
|
5
5
|
'Please provide either liveboardId or pinboardId',
|
|
6
|
+
TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
|
|
7
|
+
SEARCHEMBED_BETA_WRANING_MESSAGE:
|
|
8
|
+
'Search Embed is in Beta in this release.',
|
|
6
9
|
};
|
package/src/react/index.spec.tsx
CHANGED
|
@@ -2,15 +2,17 @@ import React from 'react';
|
|
|
2
2
|
import '@testing-library/jest-dom';
|
|
3
3
|
import '@testing-library/jest-dom/extend-expect';
|
|
4
4
|
import { cleanup, fireEvent, render, waitFor } from '@testing-library/react';
|
|
5
|
+
import { Action, EmbedEvent, HostEvent } from '../types';
|
|
5
6
|
import {
|
|
6
7
|
executeAfterWait,
|
|
7
8
|
getIFrameEl,
|
|
8
9
|
getIFrameSrc,
|
|
9
10
|
postMessageToParent,
|
|
11
|
+
mockMessageChannel,
|
|
10
12
|
} from '../test/test-utils';
|
|
11
13
|
import { SearchEmbed, AppEmbed, LiveboardEmbed, useEmbedRef } from './index';
|
|
12
14
|
import { AuthType, init } from '../index';
|
|
13
|
-
|
|
15
|
+
|
|
14
16
|
import { version } from '../../package.json';
|
|
15
17
|
|
|
16
18
|
const thoughtSpotHost = 'localhost';
|
|
@@ -20,6 +22,7 @@ beforeAll(() => {
|
|
|
20
22
|
thoughtSpotHost,
|
|
21
23
|
authType: AuthType.None,
|
|
22
24
|
});
|
|
25
|
+
spyOn(window, 'alert');
|
|
23
26
|
});
|
|
24
27
|
|
|
25
28
|
describe('React Components', () => {
|
|
@@ -37,7 +40,7 @@ describe('React Components', () => {
|
|
|
37
40
|
),
|
|
38
41
|
).toBe(true);
|
|
39
42
|
expect(getIFrameSrc(container)).toBe(
|
|
40
|
-
`http://${thoughtSpotHost}/?hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&hideAction=[%22editACopy%22,%22saveAsView%22,%22updateTSL%22,%22editTSL%22,%22onDeleteAnswer%22]&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true#/embed/answer`,
|
|
43
|
+
`http://${thoughtSpotHost}/?hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&hideAction=[%22${Action.ReportError}%22,%22editACopy%22,%22saveAsView%22,%22updateTSL%22,%22editTSL%22,%22onDeleteAnswer%22]&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true#/embed/answer`,
|
|
41
44
|
);
|
|
42
45
|
});
|
|
43
46
|
|
|
@@ -73,6 +76,7 @@ describe('React Components', () => {
|
|
|
73
76
|
describe('LiveboardEmbed', () => {
|
|
74
77
|
//
|
|
75
78
|
it('Should be able to trigger events on the embed using refs', async () => {
|
|
79
|
+
mockMessageChannel();
|
|
76
80
|
const TestComponent = () => {
|
|
77
81
|
const embedRef = useEmbedRef();
|
|
78
82
|
const onLiveboardRendered = () => {
|
|
@@ -109,6 +113,7 @@ describe('React Components', () => {
|
|
|
109
113
|
data: ['viz1', 'viz2'],
|
|
110
114
|
},
|
|
111
115
|
`http://${thoughtSpotHost}`,
|
|
116
|
+
expect.anything(),
|
|
112
117
|
);
|
|
113
118
|
});
|
|
114
119
|
});
|
package/src/react/index.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import useDeepCompareEffect from 'use-deep-compare-effect';
|
|
2
3
|
import { SearchEmbed as _SearchEmbed, SearchViewConfig } from '../embed/search';
|
|
3
4
|
import { AppEmbed as _AppEmbed, AppViewConfig } from '../embed/app';
|
|
4
5
|
import {
|
|
@@ -25,7 +26,7 @@ const componentFactory = <
|
|
|
25
26
|
Omit<U, 'className'>,
|
|
26
27
|
V
|
|
27
28
|
>(embedProps);
|
|
28
|
-
|
|
29
|
+
useDeepCompareEffect(() => {
|
|
29
30
|
const tsEmbed = new EmbedConstructor(ref!.current, {
|
|
30
31
|
...viewConfig,
|
|
31
32
|
});
|
|
@@ -40,7 +41,7 @@ const componentFactory = <
|
|
|
40
41
|
// eslint-disable-next-line no-param-reassign
|
|
41
42
|
forwardedRef.current = tsEmbed;
|
|
42
43
|
}
|
|
43
|
-
}, [
|
|
44
|
+
}, [viewConfig, listeners]);
|
|
44
45
|
|
|
45
46
|
return (
|
|
46
47
|
<div
|
package/src/test/test-utils.ts
CHANGED
|
@@ -70,3 +70,19 @@ export const EVENT_WAIT_TIME = 1000;
|
|
|
70
70
|
export function fixedEncodeURI(str: string) {
|
|
71
71
|
return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']');
|
|
72
72
|
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* MessageChannel is available in Node > 15.0.0. Since the current node environment's
|
|
76
|
+
* used for github actions is not above 14, we are mocking this for the current unit tests.
|
|
77
|
+
*/
|
|
78
|
+
export const messageChannelMock: any = {
|
|
79
|
+
port1: {},
|
|
80
|
+
port2: {},
|
|
81
|
+
};
|
|
82
|
+
export const mockMessageChannel = () => {
|
|
83
|
+
messageChannelMock.port1.close = jest.fn();
|
|
84
|
+
messageChannelMock.port2.onmessage = jest.fn();
|
|
85
|
+
window.MessageChannel = function MessageChannelMock() {
|
|
86
|
+
return messageChannelMock;
|
|
87
|
+
} as any;
|
|
88
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -19,8 +19,13 @@ export enum AuthType {
|
|
|
19
19
|
None = 'None',
|
|
20
20
|
/**
|
|
21
21
|
* SSO using SAML
|
|
22
|
+
* @deprecated Use {@link SAML} instead
|
|
22
23
|
*/
|
|
23
24
|
SSO = 'SSO_SAML',
|
|
25
|
+
/**
|
|
26
|
+
* SSO using SAML
|
|
27
|
+
*/
|
|
28
|
+
SAML = 'SSO_SAML',
|
|
24
29
|
/**
|
|
25
30
|
* SSO using OIDC
|
|
26
31
|
*/
|
|
@@ -40,6 +45,28 @@ export enum AuthType {
|
|
|
40
45
|
|
|
41
46
|
export type DOMSelector = string | HTMLElement;
|
|
42
47
|
|
|
48
|
+
interface customCssInterface {
|
|
49
|
+
variables?: {
|
|
50
|
+
[variableName: string]: string;
|
|
51
|
+
};
|
|
52
|
+
// eslint-disable-next-line camelcase
|
|
53
|
+
rules_UNSTABLE?: {
|
|
54
|
+
[selector: string]: {
|
|
55
|
+
[declaration: string]: string;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
interface CustomStyles {
|
|
60
|
+
customCSSUrl?: string;
|
|
61
|
+
customCss?: customCssInterface;
|
|
62
|
+
}
|
|
63
|
+
export interface CustomisationsInterface {
|
|
64
|
+
style: CustomStyles;
|
|
65
|
+
content: {
|
|
66
|
+
[key: string]: string;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
43
70
|
/**
|
|
44
71
|
* The configuration object for embedding ThoughtSpot content.
|
|
45
72
|
* It includes the ThoughtSpot hostname or IP address,
|
|
@@ -177,6 +204,17 @@ export interface EmbedConfig {
|
|
|
177
204
|
* @version SDK: 1.10.4 | ThoughtSpot: *
|
|
178
205
|
*/
|
|
179
206
|
detectCookieAccessSlow?: boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Hide beta alert warning message for SearchEmbed.
|
|
209
|
+
*
|
|
210
|
+
* @version SDK: 1.12.0 | ThoughtSpot: *
|
|
211
|
+
*/
|
|
212
|
+
suppressSearchEmbedBetaWarning?: boolean;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Custom style params for embed Config
|
|
216
|
+
*/
|
|
217
|
+
customisations?: CustomisationsInterface;
|
|
180
218
|
}
|
|
181
219
|
|
|
182
220
|
/**
|
|
@@ -551,6 +589,65 @@ export enum EmbedEvent {
|
|
|
551
589
|
* @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl
|
|
552
590
|
*/
|
|
553
591
|
AnswerChartSwitcher = 'answerChartSwitcher',
|
|
592
|
+
/**
|
|
593
|
+
*
|
|
594
|
+
*/
|
|
595
|
+
APP_INIT = 'appInit',
|
|
596
|
+
/**
|
|
597
|
+
* Emitted when a user clicks Show Liveboard details on a Liveboard
|
|
598
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
599
|
+
*/
|
|
600
|
+
LiveboardInfo = 'pinboardInfo',
|
|
601
|
+
/**
|
|
602
|
+
* Emitted when a user clicks on the Favorite icon on a Liveboard
|
|
603
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
604
|
+
*/
|
|
605
|
+
AddToFavorites = 'addToFavorites',
|
|
606
|
+
/**
|
|
607
|
+
* Emitted when a user clicks Schedule on a Liveboard
|
|
608
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
609
|
+
*/
|
|
610
|
+
Schedule = 'subscription',
|
|
611
|
+
/**
|
|
612
|
+
* Emitted when a user clicks Edit on a Liveboard or visualization
|
|
613
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
614
|
+
*/
|
|
615
|
+
Edit = 'edit',
|
|
616
|
+
/**
|
|
617
|
+
* Emitted when a user clicks Make a copy on a Liveboard
|
|
618
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
619
|
+
*/
|
|
620
|
+
MakeACopy = 'makeACopy',
|
|
621
|
+
/**
|
|
622
|
+
* Emitted when a user clicks Present on a Liveboard or visualization
|
|
623
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
624
|
+
*/
|
|
625
|
+
Present = 'present',
|
|
626
|
+
/**
|
|
627
|
+
* Emitted when a user clicks Delete on a Liveboard
|
|
628
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
629
|
+
*/
|
|
630
|
+
Delete = 'delete',
|
|
631
|
+
/**
|
|
632
|
+
* Emitted when a user clicks Manage schedules on a Liveboard
|
|
633
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
634
|
+
*/
|
|
635
|
+
SchedulesList = 'schedule-list',
|
|
636
|
+
/**
|
|
637
|
+
* Emitted when a user clicks Cancel in edit mode on a Liveboard
|
|
638
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
639
|
+
*/
|
|
640
|
+
Cancel = 'cancel',
|
|
641
|
+
/**
|
|
642
|
+
* Emitted when a user clicks Explore on a visualization
|
|
643
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
644
|
+
*/
|
|
645
|
+
Explore = 'explore',
|
|
646
|
+
/**
|
|
647
|
+
* Emitted when a user clicks Copy link action on a visualization
|
|
648
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
649
|
+
*/
|
|
650
|
+
CopyLink = 'embedDocument',
|
|
554
651
|
}
|
|
555
652
|
|
|
556
653
|
/**
|
|
@@ -608,6 +705,112 @@ export enum HostEvent {
|
|
|
608
705
|
* @version SDK: 1.12.0 | ThoughtSpot: 8.4.0.cl
|
|
609
706
|
*/
|
|
610
707
|
Navigate = 'Navigate',
|
|
708
|
+
/**
|
|
709
|
+
* Gets the current pinboard content.
|
|
710
|
+
* @version SDK: 1.13.0 | ThoughtSpot: 8.5.0.cl
|
|
711
|
+
*/
|
|
712
|
+
getExportRequestForCurrentPinboard = 'getExportRequestForCurrentPinboard',
|
|
713
|
+
/**
|
|
714
|
+
* Triggers the Pin action on an embedded object
|
|
715
|
+
* @param - incase of Liveboard embed, takes in an object with vizId as a key
|
|
716
|
+
* can be left empty for search and visualization embeds
|
|
717
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
718
|
+
*/
|
|
719
|
+
Pin = 'pin',
|
|
720
|
+
/**
|
|
721
|
+
* Triggers the Show Liveboard details action on a Liveboard
|
|
722
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
723
|
+
*/
|
|
724
|
+
LiveboardInfo = 'pinboardInfo',
|
|
725
|
+
/**
|
|
726
|
+
* Triggers the Schedule action on a Liveboard
|
|
727
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
728
|
+
*/
|
|
729
|
+
Schedule = 'subscription',
|
|
730
|
+
/**
|
|
731
|
+
* Triggers the Manage schedule action on a Liveboard
|
|
732
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
733
|
+
*/
|
|
734
|
+
SchedulesList = 'schedule-list',
|
|
735
|
+
/**
|
|
736
|
+
* Triggers the Export TML action on a Liveboard
|
|
737
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
738
|
+
*/
|
|
739
|
+
ExportTML = 'exportTSL',
|
|
740
|
+
/**
|
|
741
|
+
* Triggers the Edit TML action on a Liveboard
|
|
742
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
743
|
+
*/
|
|
744
|
+
EditTML = 'editTSL',
|
|
745
|
+
/**
|
|
746
|
+
* Triggers the Update TML action on a Liveboard
|
|
747
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
748
|
+
*/
|
|
749
|
+
UpdateTML = 'updateTSL',
|
|
750
|
+
/**
|
|
751
|
+
* Triggers the Download PDF action on a Liveboard
|
|
752
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
753
|
+
*/
|
|
754
|
+
DownloadAsPdf = 'downloadAsPdf',
|
|
755
|
+
/**
|
|
756
|
+
* Triggers the Make a copy action on a Liveboard
|
|
757
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
758
|
+
*/
|
|
759
|
+
MakeACopy = 'makeACopy',
|
|
760
|
+
/**
|
|
761
|
+
* Triggers the Delete action on a Liveboard
|
|
762
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
763
|
+
*/
|
|
764
|
+
Remove = 'delete',
|
|
765
|
+
/**
|
|
766
|
+
* Triggers the Explore action on a visualization
|
|
767
|
+
* @param - an object with vizId as a key
|
|
768
|
+
* eg: {vizId: '730496d6-6903-4601-937e-2c691821af3c'}
|
|
769
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
770
|
+
*/
|
|
771
|
+
Explore = 'explore',
|
|
772
|
+
/**
|
|
773
|
+
* Triggers the Create alert action on a visualization
|
|
774
|
+
* @param - an object with vizId as a key
|
|
775
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
776
|
+
*/
|
|
777
|
+
CreateMonitor = 'createMonitor',
|
|
778
|
+
/**
|
|
779
|
+
* Triggers the Manage alert action on a visualization
|
|
780
|
+
* @param - an object with vizId as a key
|
|
781
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
782
|
+
*/
|
|
783
|
+
ManageMonitor = 'manageMonitor',
|
|
784
|
+
/**
|
|
785
|
+
* Triggers the Edit action on a Liveboard or visualization
|
|
786
|
+
* @param - object - to trigger the action for a specfic visualization in Liveboard embed, pass in vizId as a key
|
|
787
|
+
* @example
|
|
788
|
+
* liveboardEmbed.trigger(HostEvent.Edit)
|
|
789
|
+
* liveboardEmbed.trigger(HostEvent.Edit, {vizId: '730496d6-6903-4601-937e-2c691821af3c'})
|
|
790
|
+
* vizEmbed.trigger((HostEvent.Edit)
|
|
791
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
792
|
+
*/
|
|
793
|
+
Edit = 'edit',
|
|
794
|
+
/**
|
|
795
|
+
* Triggers the Copy link action on a Liveboard or visualization
|
|
796
|
+
* @param - object - to trigger the action for a specfic visualization in Liveboard embed, pass in vizId as a key
|
|
797
|
+
* @example
|
|
798
|
+
* liveboardEmbed.trigger(HostEvent.CopyLink)
|
|
799
|
+
* liveboardEmbed.trigger(HostEvent.CopyLink, {vizId: '730496d6-6903-4601-937e-2c691821af3c'})
|
|
800
|
+
* vizEmbed.trigger((HostEvent.CopyLink)
|
|
801
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
802
|
+
*/
|
|
803
|
+
CopyLink = 'embedDocument',
|
|
804
|
+
/**
|
|
805
|
+
* Triggers the Present action on a Liveboard or visualization
|
|
806
|
+
* @param - object - to trigger the action for a specfic visualization in Liveboard embed, pass in vizId as a key
|
|
807
|
+
* @example
|
|
808
|
+
* liveboardEmbed.trigger(HostEvent.Present)
|
|
809
|
+
* liveboardEmbed.trigger(HostEvent.Present, {vizId: '730496d6-6903-4601-937e-2c691821af3c'})
|
|
810
|
+
* vizEmbed.trigger((HostEvent.Present)
|
|
811
|
+
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl
|
|
812
|
+
*/
|
|
813
|
+
Present = 'present',
|
|
611
814
|
}
|
|
612
815
|
|
|
613
816
|
/**
|
|
@@ -656,6 +859,7 @@ export enum Param {
|
|
|
656
859
|
fullHeight = 'isFullHeightPinboard',
|
|
657
860
|
livedBoardEmbed = 'isLiveboardEmbed',
|
|
658
861
|
searchEmbed = 'isSearchEmbed',
|
|
862
|
+
vizEmbed = 'isVizEmbed',
|
|
659
863
|
Version = 'sdkVersion',
|
|
660
864
|
ViewPortHeight = 'viewPortHeight',
|
|
661
865
|
ViewPortWidth = 'viewPortWidth',
|
|
@@ -666,6 +870,7 @@ export enum Param {
|
|
|
666
870
|
LiveboardV2Enabled = 'isPinboardV2Enabled',
|
|
667
871
|
ShowAlerts = 'showAlerts',
|
|
668
872
|
Locale = 'locale',
|
|
873
|
+
CustomStyle = 'customStyle',
|
|
669
874
|
}
|
|
670
875
|
|
|
671
876
|
/**
|
|
@@ -808,6 +1013,10 @@ export enum Action {
|
|
|
808
1013
|
* @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl
|
|
809
1014
|
*/
|
|
810
1015
|
CreateMonitor = 'createMonitor',
|
|
1016
|
+
/**
|
|
1017
|
+
* @version SDK: 1.11.1 | ThoughtSpot: 8.3.0.cl
|
|
1018
|
+
*/
|
|
1019
|
+
ReportError = 'reportError',
|
|
811
1020
|
}
|
|
812
1021
|
|
|
813
1022
|
export interface SessionInterface {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as _processTriggerInstance from './processTrigger';
|
|
2
2
|
import { HostEvent } from '../types';
|
|
3
|
+
import { messageChannelMock, mockMessageChannel } from '../test/test-utils';
|
|
3
4
|
|
|
4
5
|
describe('Unit test for processTrigger', () => {
|
|
5
6
|
const iFrame: any = {
|
|
@@ -29,12 +30,21 @@ describe('Unit test for processTrigger', () => {
|
|
|
29
30
|
const messageType = HostEvent.Search;
|
|
30
31
|
const thoughtSpotHost = 'http://localhost:3000';
|
|
31
32
|
const data = {};
|
|
32
|
-
|
|
33
|
+
mockMessageChannel();
|
|
34
|
+
const triggerPromise = _processTriggerInstance.processTrigger(
|
|
33
35
|
iFrame,
|
|
34
36
|
messageType,
|
|
35
37
|
thoughtSpotHost,
|
|
36
38
|
data,
|
|
37
39
|
);
|
|
38
40
|
expect(iFrame.contentWindow.postMessage).toBeCalled();
|
|
41
|
+
const res = {
|
|
42
|
+
data: {
|
|
43
|
+
test: '123',
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
messageChannelMock.port1.onmessage(res);
|
|
47
|
+
expect(messageChannelMock.port1.close).toBeCalled();
|
|
48
|
+
expect(triggerPromise).resolves.toEqual(res.data);
|
|
39
49
|
});
|
|
40
50
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ERROR_MESSAGE } from '../errors';
|
|
1
2
|
import { HostEvent } from '../types';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -17,24 +18,47 @@ function postIframeMessage(
|
|
|
17
18
|
iFrame: HTMLIFrameElement,
|
|
18
19
|
message: { type: HostEvent; data: any },
|
|
19
20
|
thoughtSpotHost: string,
|
|
21
|
+
channel?: MessageChannel,
|
|
20
22
|
) {
|
|
21
|
-
return iFrame.contentWindow.postMessage(message, thoughtSpotHost
|
|
23
|
+
return iFrame.contentWindow.postMessage(message, thoughtSpotHost, [
|
|
24
|
+
channel?.port2,
|
|
25
|
+
]);
|
|
22
26
|
}
|
|
23
27
|
|
|
28
|
+
const TRIGGER_TIMEOUT = 30000;
|
|
29
|
+
|
|
24
30
|
export function processTrigger(
|
|
25
31
|
iFrame: HTMLIFrameElement,
|
|
26
32
|
messageType: HostEvent,
|
|
27
33
|
thoughtSpotHost: string,
|
|
28
34
|
data: any,
|
|
29
|
-
) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
)
|
|
39
|
-
|
|
35
|
+
): Promise<any> {
|
|
36
|
+
return new Promise<any>((res, rej) => {
|
|
37
|
+
if (messageType === HostEvent.Reload) {
|
|
38
|
+
reload(iFrame);
|
|
39
|
+
return res(null);
|
|
40
|
+
}
|
|
41
|
+
const channel = new MessageChannel();
|
|
42
|
+
channel.port1.onmessage = ({ data: responseData }) => {
|
|
43
|
+
channel.port1.close();
|
|
44
|
+
if (responseData.error) {
|
|
45
|
+
rej(responseData.error);
|
|
46
|
+
} else {
|
|
47
|
+
res(responseData);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Close the messageChannel and resolve the promise if timeout.
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
channel.port1.close();
|
|
54
|
+
res(new Error(ERROR_MESSAGE.TRIGGER_TIMED_OUT));
|
|
55
|
+
}, TRIGGER_TIMEOUT);
|
|
56
|
+
|
|
57
|
+
return postIframeMessage(
|
|
58
|
+
iFrame,
|
|
59
|
+
{ type: messageType, data },
|
|
60
|
+
thoughtSpotHost,
|
|
61
|
+
channel,
|
|
62
|
+
);
|
|
63
|
+
});
|
|
40
64
|
}
|
package/src/utils.spec.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
getEncodedQueryParamsString,
|
|
10
10
|
appendToUrlHash,
|
|
11
11
|
getRedirectUrl,
|
|
12
|
+
checkReleaseVersionInBeta,
|
|
12
13
|
} from './utils';
|
|
13
14
|
import { RuntimeFilterOp } from './types';
|
|
14
15
|
|
|
@@ -110,4 +111,32 @@ describe('unit test for utils', () => {
|
|
|
110
111
|
expect(getEncodedQueryParamsString('')).toBe('');
|
|
111
112
|
expect(getEncodedQueryParamsString('test')).toBe('dGVzdA');
|
|
112
113
|
});
|
|
114
|
+
|
|
115
|
+
test('when ReleaseVersion is empty ', () => {
|
|
116
|
+
expect(checkReleaseVersionInBeta('', false)).toBe(false);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('when ReleaseVersion is 7.0.1.cl ', () => {
|
|
120
|
+
expect(checkReleaseVersionInBeta('7.0.1.cl', false)).toBe(false);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('when cluster has dev version', () => {
|
|
124
|
+
expect(checkReleaseVersionInBeta('dev', false)).toBe(false);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('when cluster is above 8.4.0.cl-11 software version', () => {
|
|
128
|
+
expect(checkReleaseVersionInBeta('8.4.0.cl-117', false)).toBe(false);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test('when cluster is bellow 8.0.0.sw software version', () => {
|
|
132
|
+
expect(checkReleaseVersionInBeta('7.2.1.sw', false)).toBe(true);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test('when suppressBetaWarning is true and ReleaseVersion is 7.0.1', () => {
|
|
136
|
+
expect(checkReleaseVersionInBeta('7.0.1', true)).toBe(false);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('when suppressBetaWarning is false ReleaseVersion is 7.0.1', () => {
|
|
140
|
+
expect(checkReleaseVersionInBeta('7.0.1', false)).toBe(true);
|
|
141
|
+
});
|
|
113
142
|
});
|
package/src/utils.ts
CHANGED
|
@@ -7,7 +7,12 @@
|
|
|
7
7
|
* @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
EmbedConfig,
|
|
12
|
+
QueryParams,
|
|
13
|
+
RuntimeFilter,
|
|
14
|
+
CustomisationsInterface,
|
|
15
|
+
} from './types';
|
|
11
16
|
|
|
12
17
|
/**
|
|
13
18
|
* Construct a runtime filters query string from the given filters.
|
|
@@ -154,3 +159,31 @@ export const setAttributes = (
|
|
|
154
159
|
element.setAttribute(key, attributes[key].toString());
|
|
155
160
|
});
|
|
156
161
|
};
|
|
162
|
+
|
|
163
|
+
const isCloudRelease = (version: string) => version.endsWith('.cl');
|
|
164
|
+
|
|
165
|
+
/* For Search Embed: ReleaseVersionInBeta */
|
|
166
|
+
export const checkReleaseVersionInBeta = (
|
|
167
|
+
releaseVersion: string,
|
|
168
|
+
suppressBetaWarning: boolean,
|
|
169
|
+
): boolean => {
|
|
170
|
+
if (releaseVersion !== '' && !isCloudRelease(releaseVersion)) {
|
|
171
|
+
const splittedReleaseVersion = releaseVersion.split('.');
|
|
172
|
+
const majorVersion = Number(splittedReleaseVersion[0]);
|
|
173
|
+
const isBetaVersion = majorVersion < 8;
|
|
174
|
+
return !suppressBetaWarning && isBetaVersion;
|
|
175
|
+
}
|
|
176
|
+
return false;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export const getCustomisations = (
|
|
180
|
+
embedConfig: EmbedConfig,
|
|
181
|
+
): CustomisationsInterface => {
|
|
182
|
+
const { customCssUrl } = embedConfig;
|
|
183
|
+
let { customisations } = embedConfig;
|
|
184
|
+
customisations = customisations || ({} as CustomisationsInterface);
|
|
185
|
+
customisations.style = customisations.style || {};
|
|
186
|
+
customisations.style.customCSSUrl =
|
|
187
|
+
customisations.style.customCSSUrl || customCssUrl;
|
|
188
|
+
return customisations;
|
|
189
|
+
};
|