@thoughtspot/visual-embed-sdk 1.20.0-prerender.2 → 1.20.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/README.md +1 -1
- package/dist/src/auth.d.ts +2 -38
- package/dist/src/auth.d.ts.map +1 -1
- package/dist/src/config.d.ts +0 -1
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts +5 -17
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts +9 -20
- package/dist/src/embed/base.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +5 -17
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/search-bar.d.ts +0 -3
- package/dist/src/embed/search-bar.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +5 -9
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +6 -43
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/mixpanel-service.d.ts +0 -8
- package/dist/src/mixpanel-service.d.ts.map +1 -1
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/react/util.d.ts +0 -4
- package/dist/src/react/util.d.ts.map +1 -1
- package/dist/src/test/test-utils.d.ts +2 -11
- package/dist/src/test/test-utils.d.ts.map +1 -1
- package/dist/src/types.d.ts +76 -273
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/answerService.d.ts +0 -7
- package/dist/src/utils/answerService.d.ts.map +1 -1
- package/dist/src/utils/authService.d.ts +0 -30
- package/dist/src/utils/authService.d.ts.map +1 -1
- package/dist/src/utils/processData.d.ts +0 -12
- package/dist/src/utils/processData.d.ts.map +1 -1
- package/dist/src/utils/processTrigger.d.ts +0 -7
- package/dist/src/utils/processTrigger.d.ts.map +1 -1
- package/dist/src/utils.d.ts +0 -12
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/tsembed.es.js +262 -637
- package/dist/tsembed.js +261 -629
- package/lib/package.json +8 -3
- package/lib/src/auth.d.ts +2 -38
- package/lib/src/auth.d.ts.map +1 -1
- package/lib/src/auth.js +25 -70
- package/lib/src/auth.js.map +1 -1
- package/lib/src/auth.spec.js +5 -14
- package/lib/src/auth.spec.js.map +1 -1
- package/lib/src/config.d.ts +0 -1
- package/lib/src/config.d.ts.map +1 -1
- package/lib/src/config.js +3 -5
- package/lib/src/config.js.map +1 -1
- package/lib/src/config.spec.js.map +1 -1
- package/lib/src/embed/app.d.ts +5 -17
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +15 -25
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +12 -12
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts +9 -20
- package/lib/src/embed/base.d.ts.map +1 -1
- package/lib/src/embed/base.js +15 -31
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/base.spec.js.map +1 -1
- package/lib/src/embed/embed.spec.js +1 -1
- package/lib/src/embed/embed.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +5 -17
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +37 -49
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +30 -37
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/pinboard.spec.js +26 -14
- package/lib/src/embed/pinboard.spec.js.map +1 -1
- package/lib/src/embed/search-bar.d.ts +0 -3
- package/lib/src/embed/search-bar.d.ts.map +1 -1
- package/lib/src/embed/search-bar.js +6 -5
- package/lib/src/embed/search-bar.js.map +1 -1
- package/lib/src/embed/search.d.ts +5 -9
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +14 -18
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/search.spec.js +19 -16
- package/lib/src/embed/search.spec.js.map +1 -1
- package/lib/src/embed/searchEmbed-basic-auth.spec.js +0 -4
- package/lib/src/embed/searchEmbed-basic-auth.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +6 -43
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +72 -117
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +24 -23
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/errors.d.ts.map +1 -1
- package/lib/src/errors.js.map +1 -1
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -2
- package/lib/src/index.js.map +1 -1
- package/lib/src/mixpanel-service.d.ts +0 -8
- package/lib/src/mixpanel-service.d.ts.map +1 -1
- package/lib/src/mixpanel-service.js +1 -13
- package/lib/src/mixpanel-service.js.map +1 -1
- package/lib/src/mixpanel-service.spec.js.map +1 -1
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +6 -6
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +6 -15
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/react/util.d.ts +0 -4
- package/lib/src/react/util.d.ts.map +1 -1
- package/lib/src/react/util.js +0 -4
- package/lib/src/react/util.js.map +1 -1
- package/lib/src/test/test-utils.d.ts +2 -11
- package/lib/src/test/test-utils.d.ts.map +1 -1
- package/lib/src/test/test-utils.js +25 -36
- package/lib/src/test/test-utils.js.map +1 -1
- package/lib/src/types.d.ts +76 -273
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +54 -200
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/answerService.d.ts +0 -7
- package/lib/src/utils/answerService.d.ts.map +1 -1
- package/lib/src/utils/answerService.js +0 -7
- package/lib/src/utils/answerService.js.map +1 -1
- package/lib/src/utils/answerService.spec.js.map +1 -1
- package/lib/src/utils/authService.d.ts +0 -30
- package/lib/src/utils/authService.d.ts.map +1 -1
- package/lib/src/utils/authService.js +2 -39
- package/lib/src/utils/authService.js.map +1 -1
- package/lib/src/utils/authService.spec.js.map +1 -1
- package/lib/src/utils/processData.d.ts +0 -12
- package/lib/src/utils/processData.d.ts.map +1 -1
- package/lib/src/utils/processData.js +5 -33
- package/lib/src/utils/processData.js.map +1 -1
- package/lib/src/utils/processData.spec.js.map +1 -1
- package/lib/src/utils/processTrigger.d.ts +0 -7
- package/lib/src/utils/processTrigger.d.ts.map +1 -1
- package/lib/src/utils/processTrigger.js +3 -17
- package/lib/src/utils/processTrigger.js.map +1 -1
- package/lib/src/utils/processTrigger.spec.js.map +1 -1
- package/lib/src/utils.d.ts +0 -12
- package/lib/src/utils.d.ts.map +1 -1
- package/lib/src/utils.js +19 -24
- package/lib/src/utils.js.map +1 -1
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +102 -406
- package/package.json +8 -3
- package/src/auth.spec.ts +150 -68
- package/src/auth.ts +108 -102
- package/src/config.spec.ts +4 -2
- package/src/config.ts +3 -5
- package/src/embed/app.spec.ts +14 -25
- package/src/embed/app.ts +35 -47
- package/src/embed/base.spec.ts +9 -3
- package/src/embed/base.ts +53 -51
- package/src/embed/embed.spec.ts +6 -5
- package/src/embed/liveboard.spec.ts +37 -56
- package/src/embed/liveboard.ts +64 -66
- package/src/embed/pinboard.spec.ts +29 -26
- package/src/embed/search-bar.tsx +8 -10
- package/src/embed/search.spec.ts +21 -31
- package/src/embed/search.ts +25 -26
- package/src/embed/searchEmbed-basic-auth.spec.ts +28 -22
- package/src/embed/ts-embed.spec.ts +148 -70
- package/src/embed/ts-embed.ts +157 -147
- package/src/errors.ts +6 -3
- package/src/index.ts +10 -4
- package/src/mixpanel-service.spec.ts +3 -1
- package/src/mixpanel-service.ts +1 -13
- package/src/react/index.spec.tsx +13 -37
- package/src/react/index.tsx +57 -38
- package/src/react/util.ts +4 -8
- package/src/test/test-utils.ts +39 -43
- package/src/types.ts +78 -270
- package/src/utils/answerService.spec.ts +5 -3
- package/src/utils/answerService.ts +17 -21
- package/src/utils/authService.spec.ts +41 -26
- package/src/utils/authService.ts +21 -47
- package/src/utils/processData.spec.ts +59 -26
- package/src/utils/processData.ts +14 -36
- package/src/utils/processTrigger.spec.ts +6 -1
- package/src/utils/processTrigger.ts +9 -18
- package/src/utils.spec.ts +12 -8
- package/src/utils.ts +26 -25
package/src/embed/ts-embed.ts
CHANGED
|
@@ -15,8 +15,6 @@ import {
|
|
|
15
15
|
setAttributes,
|
|
16
16
|
getCustomisations,
|
|
17
17
|
getDOMNode,
|
|
18
|
-
getFilterQuery,
|
|
19
|
-
getQueryParamString,
|
|
20
18
|
} from '../utils';
|
|
21
19
|
import {
|
|
22
20
|
getThoughtSpotHost,
|
|
@@ -40,7 +38,6 @@ import {
|
|
|
40
38
|
ViewConfig,
|
|
41
39
|
FrameParams,
|
|
42
40
|
ContextMenuTriggerOptions,
|
|
43
|
-
RuntimeFilter,
|
|
44
41
|
} from '../types';
|
|
45
42
|
import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
|
|
46
43
|
import { processEventData } from '../utils/processData';
|
|
@@ -67,7 +64,6 @@ const TS_EMBED_ID = '_thoughtspot-embed';
|
|
|
67
64
|
* The event id map from v2 event names to v1 event id
|
|
68
65
|
* v1 events are the classic embed events implemented in Blink v1
|
|
69
66
|
* We cannot rename v1 event types to maintain backward compatibility
|
|
70
|
-
*
|
|
71
67
|
* @internal
|
|
72
68
|
*/
|
|
73
69
|
const V1EventMap = {};
|
|
@@ -91,8 +87,6 @@ export class TsEmbed {
|
|
|
91
87
|
*/
|
|
92
88
|
private el: Element;
|
|
93
89
|
|
|
94
|
-
protected isAppInitialized = false;
|
|
95
|
-
|
|
96
90
|
/**
|
|
97
91
|
* A reference to the iframe within which the ThoughtSpot app
|
|
98
92
|
* will be rendered.
|
|
@@ -134,7 +128,6 @@ export class TsEmbed {
|
|
|
134
128
|
* Should we encode URL Query Params using base64 encoding which thoughtspot
|
|
135
129
|
* will generate for embedding. This provides additional security to
|
|
136
130
|
* thoughtspot clusters against Cross site scripting attacks.
|
|
137
|
-
*
|
|
138
131
|
* @default false
|
|
139
132
|
*/
|
|
140
133
|
private shouldEncodeUrlQueryParams = false;
|
|
@@ -163,7 +156,6 @@ export class TsEmbed {
|
|
|
163
156
|
|
|
164
157
|
/**
|
|
165
158
|
* Handles errors within the SDK
|
|
166
|
-
*
|
|
167
159
|
* @param error The error message or object
|
|
168
160
|
*/
|
|
169
161
|
protected handleError(error: string | Record<string, unknown>) {
|
|
@@ -177,7 +169,6 @@ export class TsEmbed {
|
|
|
177
169
|
|
|
178
170
|
/**
|
|
179
171
|
* Extracts the type field from the event payload
|
|
180
|
-
*
|
|
181
172
|
* @param event The window message event
|
|
182
173
|
*/
|
|
183
174
|
private getEventType(event: MessageEvent) {
|
|
@@ -187,7 +178,6 @@ export class TsEmbed {
|
|
|
187
178
|
|
|
188
179
|
/**
|
|
189
180
|
* Extracts the port field from the event payload
|
|
190
|
-
*
|
|
191
181
|
* @param event The window message event
|
|
192
182
|
* @returns
|
|
193
183
|
*/
|
|
@@ -201,9 +191,6 @@ export class TsEmbed {
|
|
|
201
191
|
/**
|
|
202
192
|
* fix for ts7.sep.cl
|
|
203
193
|
* will be removed for ts7.oct.cl
|
|
204
|
-
*
|
|
205
|
-
* @param event
|
|
206
|
-
* @param eventType
|
|
207
194
|
* @hidden
|
|
208
195
|
*/
|
|
209
196
|
private formatEventData(event: MessageEvent, eventType: string) {
|
|
@@ -231,7 +218,12 @@ export class TsEmbed {
|
|
|
231
218
|
if (event.source === this.iFrame.contentWindow) {
|
|
232
219
|
this.executeCallbacks(
|
|
233
220
|
eventType,
|
|
234
|
-
processEventData(
|
|
221
|
+
processEventData(
|
|
222
|
+
eventType,
|
|
223
|
+
eventData,
|
|
224
|
+
this.thoughtSpotHost,
|
|
225
|
+
this.el,
|
|
226
|
+
),
|
|
235
227
|
eventPort,
|
|
236
228
|
);
|
|
237
229
|
}
|
|
@@ -240,20 +232,19 @@ export class TsEmbed {
|
|
|
240
232
|
|
|
241
233
|
/**
|
|
242
234
|
* Send Custom style as part of payload of APP_INIT
|
|
243
|
-
*
|
|
244
|
-
* @param _
|
|
245
|
-
* @param responder
|
|
246
235
|
*/
|
|
247
236
|
private appInitCb = async (_: any, responder: any) => {
|
|
248
237
|
let authToken = '';
|
|
249
238
|
if (this.embedConfig.authType === AuthType.TrustedAuthTokenCookieless) {
|
|
250
239
|
authToken = await getAuthenticaionToken(this.embedConfig);
|
|
251
240
|
}
|
|
252
|
-
this.isAppInitialized = true;
|
|
253
241
|
responder({
|
|
254
242
|
type: EmbedEvent.APP_INIT,
|
|
255
243
|
data: {
|
|
256
|
-
customisations: getCustomisations(
|
|
244
|
+
customisations: getCustomisations(
|
|
245
|
+
this.embedConfig,
|
|
246
|
+
this.viewConfig,
|
|
247
|
+
),
|
|
257
248
|
authToken,
|
|
258
249
|
},
|
|
259
250
|
});
|
|
@@ -261,9 +252,6 @@ export class TsEmbed {
|
|
|
261
252
|
|
|
262
253
|
/**
|
|
263
254
|
* Sends updated auth token to the iFrame to avoid user logout
|
|
264
|
-
*
|
|
265
|
-
* @param _
|
|
266
|
-
* @param responder
|
|
267
255
|
*/
|
|
268
256
|
private updateAuthToken = async (_: any, responder: any) => {
|
|
269
257
|
const { autoLogin = false, authType } = this.embedConfig; // Set autoLogin default to false
|
|
@@ -289,8 +277,6 @@ export class TsEmbed {
|
|
|
289
277
|
|
|
290
278
|
/**
|
|
291
279
|
* Constructs the base URL string to load the ThoughtSpot app.
|
|
292
|
-
*
|
|
293
|
-
* @param query
|
|
294
280
|
*/
|
|
295
281
|
protected getEmbedBasePath(query: string): string {
|
|
296
282
|
let queryString = query;
|
|
@@ -299,25 +285,31 @@ export class TsEmbed {
|
|
|
299
285
|
queryString.substr(1),
|
|
300
286
|
)}`;
|
|
301
287
|
}
|
|
302
|
-
const basePath = [
|
|
288
|
+
const basePath = [
|
|
289
|
+
this.thoughtSpotHost,
|
|
290
|
+
this.thoughtSpotV2Base,
|
|
291
|
+
queryString,
|
|
292
|
+
]
|
|
303
293
|
.filter((x) => x.length > 0)
|
|
304
294
|
.join('/');
|
|
305
295
|
|
|
306
|
-
return `${basePath}
|
|
296
|
+
return `${basePath}#/embed`;
|
|
307
297
|
}
|
|
308
298
|
|
|
309
299
|
/**
|
|
310
300
|
* Common query params set for all the embed modes.
|
|
311
|
-
*
|
|
312
|
-
* @param queryParams
|
|
313
301
|
* @returns queryParams
|
|
314
302
|
*/
|
|
315
|
-
protected getBaseQueryParams(
|
|
303
|
+
protected getBaseQueryParams() {
|
|
304
|
+
const queryParams = {};
|
|
316
305
|
let hostAppUrl = window?.location?.host || '';
|
|
317
306
|
|
|
318
|
-
// The below check is needed because TS Cloud firewall, blocks
|
|
319
|
-
//
|
|
320
|
-
if (
|
|
307
|
+
// The below check is needed because TS Cloud firewall, blocks localhost/127.0.0.1
|
|
308
|
+
// in any url param.
|
|
309
|
+
if (
|
|
310
|
+
hostAppUrl.includes('localhost') ||
|
|
311
|
+
hostAppUrl.includes('127.0.0.1')
|
|
312
|
+
) {
|
|
321
313
|
hostAppUrl = 'local-host';
|
|
322
314
|
}
|
|
323
315
|
queryParams[Param.HostAppUrl] = encodeURIComponent(hostAppUrl);
|
|
@@ -325,7 +317,10 @@ export class TsEmbed {
|
|
|
325
317
|
queryParams[Param.ViewPortWidth] = window.innerWidth;
|
|
326
318
|
queryParams[Param.Version] = version;
|
|
327
319
|
queryParams[Param.AuthType] = this.embedConfig.authType;
|
|
328
|
-
if (
|
|
320
|
+
if (
|
|
321
|
+
this.embedConfig.disableLoginRedirect === true ||
|
|
322
|
+
this.embedConfig.autoLogin === true
|
|
323
|
+
) {
|
|
329
324
|
queryParams[Param.DisableLoginRedirect] = true;
|
|
330
325
|
}
|
|
331
326
|
if (this.embedConfig.authType === AuthType.EmbeddedSSO) {
|
|
@@ -350,12 +345,16 @@ export class TsEmbed {
|
|
|
350
345
|
} = this.viewConfig;
|
|
351
346
|
|
|
352
347
|
if (Array.isArray(visibleActions) && Array.isArray(hiddenActions)) {
|
|
353
|
-
this.handleError(
|
|
348
|
+
this.handleError(
|
|
349
|
+
'You cannot have both hidden actions and visible actions',
|
|
350
|
+
);
|
|
354
351
|
return queryParams;
|
|
355
352
|
}
|
|
356
353
|
|
|
357
354
|
// TODO remove embedConfig.customCssUrl
|
|
358
|
-
const cssUrlParam =
|
|
355
|
+
const cssUrlParam =
|
|
356
|
+
customizations?.style?.customCSSUrl ||
|
|
357
|
+
this.embedConfig.customCssUrl;
|
|
359
358
|
|
|
360
359
|
if (cssUrlParam) {
|
|
361
360
|
queryParams[Param.CustomCSSUrl] = cssUrlParam;
|
|
@@ -367,25 +366,31 @@ export class TsEmbed {
|
|
|
367
366
|
if (disabledActionReason) {
|
|
368
367
|
queryParams[Param.DisableActionReason] = disabledActionReason;
|
|
369
368
|
}
|
|
370
|
-
queryParams[Param.HideActions] = [
|
|
369
|
+
queryParams[Param.HideActions] = [
|
|
370
|
+
...this.defaultHiddenActions,
|
|
371
|
+
...(hiddenActions ?? []),
|
|
372
|
+
];
|
|
371
373
|
if (Array.isArray(visibleActions)) {
|
|
372
374
|
queryParams[Param.VisibleActions] = visibleActions;
|
|
373
375
|
}
|
|
374
376
|
|
|
375
|
-
/**
|
|
376
|
-
*
|
|
377
|
-
* from version 9.2.0.cl the user have an option to override context
|
|
378
|
-
* menu click
|
|
377
|
+
/** Default behavior for context menu will be left-click
|
|
378
|
+
* from version 9.2.0.cl the user have an option to override context menu click
|
|
379
379
|
*/
|
|
380
380
|
if (contextMenuTrigger === ContextMenuTriggerOptions.LEFT_CLICK) {
|
|
381
381
|
queryParams[Param.ContextMenuTrigger] = true;
|
|
382
|
-
} else if (
|
|
382
|
+
} else if (
|
|
383
|
+
contextMenuTrigger === ContextMenuTriggerOptions.RIGHT_CLICK
|
|
384
|
+
) {
|
|
383
385
|
queryParams[Param.ContextMenuTrigger] = false;
|
|
384
386
|
}
|
|
385
387
|
|
|
386
388
|
const spriteUrl = customizations?.iconSpriteUrl;
|
|
387
389
|
if (spriteUrl) {
|
|
388
|
-
queryParams[Param.IconSpriteUrl] = spriteUrl.replace(
|
|
390
|
+
queryParams[Param.IconSpriteUrl] = spriteUrl.replace(
|
|
391
|
+
'https://',
|
|
392
|
+
'',
|
|
393
|
+
);
|
|
389
394
|
}
|
|
390
395
|
|
|
391
396
|
if (showAlerts !== undefined) {
|
|
@@ -409,72 +414,48 @@ export class TsEmbed {
|
|
|
409
414
|
/**
|
|
410
415
|
* Constructs the base URL string to load v1 of the ThoughtSpot app.
|
|
411
416
|
* This is used for embedding Liveboards, visualizations, and full application.
|
|
412
|
-
*
|
|
413
417
|
* @param queryString The query string to append to the URL.
|
|
414
418
|
* @param isAppEmbed A Boolean parameter to specify if you are embedding
|
|
415
419
|
* the full application.
|
|
416
420
|
*/
|
|
417
|
-
protected getV1EmbedBasePath(
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
421
|
+
protected getV1EmbedBasePath(
|
|
422
|
+
queryString: string,
|
|
423
|
+
showPrimaryNavbar = false,
|
|
424
|
+
disableProfileAndHelp = false,
|
|
425
|
+
isAppEmbed = false,
|
|
426
|
+
enableSearchAssist = false,
|
|
427
|
+
): string {
|
|
428
|
+
const queryStringFrag = queryString ? `&${queryString}` : '';
|
|
429
|
+
const primaryNavParam = `&primaryNavHidden=${!showPrimaryNavbar}`;
|
|
430
|
+
const disableProfileAndHelpParam = `&profileAndHelpInNavBarHidden=${disableProfileAndHelp}`;
|
|
431
|
+
const enableSearchAssistParam = `&${Param.EnableSearchAssist}=${enableSearchAssist}`;
|
|
432
|
+
let queryParams = `?embedApp=true${isAppEmbed ? primaryNavParam : ''}${
|
|
433
|
+
isAppEmbed ? disableProfileAndHelpParam : ''
|
|
434
|
+
}${
|
|
435
|
+
enableSearchAssist ? enableSearchAssistParam : ''
|
|
436
|
+
}${queryStringFrag}`;
|
|
437
|
+
if (this.shouldEncodeUrlQueryParams) {
|
|
438
|
+
queryParams = `?base64UrlEncodedFlags=${getEncodedQueryParamsString(
|
|
439
|
+
queryParams.substr(1),
|
|
440
|
+
)}`;
|
|
441
|
+
}
|
|
442
|
+
let path = `${this.thoughtSpotHost}/${queryParams}#`;
|
|
443
|
+
if (!isAppEmbed) {
|
|
444
|
+
path = `${path}/embed`;
|
|
445
|
+
}
|
|
422
446
|
return path;
|
|
423
447
|
}
|
|
424
448
|
|
|
425
|
-
protected getEmbedParams() {
|
|
426
|
-
const queryParams = this.getBaseQueryParams();
|
|
427
|
-
return getQueryParamString(queryParams);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
protected getRootIframeSrc() {
|
|
431
|
-
const query = this.getEmbedParams();
|
|
432
|
-
return this.getEmbedBasePath(query);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
protected createIframeEl(frameSrc: string): HTMLIFrameElement {
|
|
436
|
-
const iFrame = document.createElement('iframe');
|
|
437
|
-
|
|
438
|
-
iFrame.src = frameSrc;
|
|
439
|
-
iFrame.id = TS_EMBED_ID;
|
|
440
|
-
|
|
441
|
-
// according to screenfull.js documentation
|
|
442
|
-
// allowFullscreen, webkitallowfullscreen and mozallowfullscreen must be
|
|
443
|
-
// true
|
|
444
|
-
iFrame.allowFullscreen = true;
|
|
445
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
446
|
-
// @ts-ignore
|
|
447
|
-
iFrame.webkitallowfullscreen = true;
|
|
448
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
449
|
-
// @ts-ignore
|
|
450
|
-
iFrame.mozallowfullscreen = true;
|
|
451
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
452
|
-
// @ts-ignore
|
|
453
|
-
iFrame.allow = 'clipboard-read; clipboard-write';
|
|
454
|
-
|
|
455
|
-
const {
|
|
456
|
-
height: frameHeight,
|
|
457
|
-
width: frameWidth, ...restParams
|
|
458
|
-
} = this.viewConfig.frameParams || {};
|
|
459
|
-
const width = getCssDimension(frameWidth || DEFAULT_EMBED_WIDTH);
|
|
460
|
-
const height = getCssDimension(frameHeight || DEFAULT_EMBED_HEIGHT);
|
|
461
|
-
setAttributes(iFrame, restParams);
|
|
462
|
-
|
|
463
|
-
iFrame.style.width = `${width}`;
|
|
464
|
-
iFrame.style.height = `${height}`;
|
|
465
|
-
iFrame.style.border = '0';
|
|
466
|
-
iFrame.name = 'ThoughtSpot Embedded Analytics';
|
|
467
|
-
return iFrame;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
449
|
/**
|
|
471
450
|
* Renders the embedded ThoughtSpot app in an iframe and sets up
|
|
472
451
|
* event listeners.
|
|
473
|
-
*
|
|
474
452
|
* @param url
|
|
475
453
|
* @param frameOptions
|
|
476
454
|
*/
|
|
477
|
-
protected async renderIFrame(
|
|
455
|
+
protected async renderIFrame(
|
|
456
|
+
url: string,
|
|
457
|
+
frameOptions: FrameParams = {},
|
|
458
|
+
): Promise<any> {
|
|
478
459
|
if (this.isError) {
|
|
479
460
|
return null;
|
|
480
461
|
}
|
|
@@ -503,8 +484,45 @@ export class TsEmbed {
|
|
|
503
484
|
return;
|
|
504
485
|
}
|
|
505
486
|
|
|
506
|
-
uploadMixpanelEvent(
|
|
507
|
-
|
|
487
|
+
uploadMixpanelEvent(
|
|
488
|
+
MIXPANEL_EVENT.VISUAL_SDK_RENDER_COMPLETE,
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
this.iFrame =
|
|
492
|
+
this.iFrame || document.createElement('iframe');
|
|
493
|
+
|
|
494
|
+
this.iFrame.src = url;
|
|
495
|
+
this.iFrame.id = TS_EMBED_ID;
|
|
496
|
+
|
|
497
|
+
// according to screenfull.js documentation
|
|
498
|
+
// allowFullscreen, webkitallowfullscreen and mozallowfullscreen must be true
|
|
499
|
+
this.iFrame.allowFullscreen = true;
|
|
500
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
501
|
+
// @ts-ignore
|
|
502
|
+
this.iFrame.webkitallowfullscreen = true;
|
|
503
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
504
|
+
// @ts-ignore
|
|
505
|
+
this.iFrame.mozallowfullscreen = true;
|
|
506
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
507
|
+
// @ts-ignore
|
|
508
|
+
this.iFrame.allow = 'clipboard-read; clipboard-write';
|
|
509
|
+
const {
|
|
510
|
+
height: frameHeight,
|
|
511
|
+
width: frameWidth,
|
|
512
|
+
...restParams
|
|
513
|
+
} = frameOptions;
|
|
514
|
+
const width = getCssDimension(
|
|
515
|
+
frameWidth || DEFAULT_EMBED_WIDTH,
|
|
516
|
+
);
|
|
517
|
+
const height = getCssDimension(
|
|
518
|
+
frameHeight || DEFAULT_EMBED_HEIGHT,
|
|
519
|
+
);
|
|
520
|
+
setAttributes(this.iFrame, restParams);
|
|
521
|
+
|
|
522
|
+
this.iFrame.style.width = `${width}`;
|
|
523
|
+
this.iFrame.style.height = `${height}`;
|
|
524
|
+
this.iFrame.style.border = '0';
|
|
525
|
+
this.iFrame.name = 'ThoughtSpot Embedded Analytics';
|
|
508
526
|
this.iFrame.addEventListener('load', () => {
|
|
509
527
|
nextInQueue();
|
|
510
528
|
const loadTimestamp = Date.now();
|
|
@@ -514,15 +532,20 @@ export class TsEmbed {
|
|
|
514
532
|
},
|
|
515
533
|
type: EmbedEvent.Load,
|
|
516
534
|
});
|
|
517
|
-
uploadMixpanelEvent(
|
|
518
|
-
|
|
519
|
-
|
|
535
|
+
uploadMixpanelEvent(
|
|
536
|
+
MIXPANEL_EVENT.VISUAL_SDK_IFRAME_LOAD_PERFORMANCE,
|
|
537
|
+
{
|
|
538
|
+
timeTookToLoad: loadTimestamp - initTimestamp,
|
|
539
|
+
},
|
|
540
|
+
);
|
|
520
541
|
});
|
|
521
542
|
this.iFrame.addEventListener('error', () => {
|
|
522
543
|
nextInQueue();
|
|
523
544
|
});
|
|
524
545
|
this.insertIntoDOM(this.iFrame);
|
|
525
|
-
const prefetchIframe = document.querySelectorAll(
|
|
546
|
+
const prefetchIframe = document.querySelectorAll(
|
|
547
|
+
'.prefetchIframe',
|
|
548
|
+
);
|
|
526
549
|
if (prefetchIframe.length) {
|
|
527
550
|
prefetchIframe.forEach((el) => {
|
|
528
551
|
el.remove();
|
|
@@ -532,9 +555,10 @@ export class TsEmbed {
|
|
|
532
555
|
})
|
|
533
556
|
.catch((error) => {
|
|
534
557
|
nextInQueue();
|
|
535
|
-
uploadMixpanelEvent(
|
|
536
|
-
|
|
537
|
-
|
|
558
|
+
uploadMixpanelEvent(
|
|
559
|
+
MIXPANEL_EVENT.VISUAL_SDK_RENDER_FAILED,
|
|
560
|
+
{ error: JSON.stringify(error) },
|
|
561
|
+
);
|
|
538
562
|
this.insertIntoDOM(this.embedConfig.loginFailedMessage);
|
|
539
563
|
this.handleError(error);
|
|
540
564
|
});
|
|
@@ -567,7 +591,6 @@ export class TsEmbed {
|
|
|
567
591
|
|
|
568
592
|
/**
|
|
569
593
|
* Sets the height of the iframe
|
|
570
|
-
*
|
|
571
594
|
* @param height The height in pixels
|
|
572
595
|
*/
|
|
573
596
|
protected setIFrameHeight(height: number): void {
|
|
@@ -576,7 +599,6 @@ export class TsEmbed {
|
|
|
576
599
|
|
|
577
600
|
/**
|
|
578
601
|
* Executes all registered event handlers for a particular event type
|
|
579
|
-
*
|
|
580
602
|
* @param eventType The event type
|
|
581
603
|
* @param data The payload invoked with the event handler
|
|
582
604
|
* @param eventPort The event Port for a specific MessageChannel
|
|
@@ -592,12 +614,10 @@ export class TsEmbed {
|
|
|
592
614
|
const dataStatus = data?.status || embedEventStatus.END;
|
|
593
615
|
callbacks.forEach((callbackObj) => {
|
|
594
616
|
if (
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
(callbackObj.options.start &&
|
|
598
|
-
|
|
599
|
-
// payload
|
|
600
|
-
|| (!callbackObj.options.start && dataStatus === embedEventStatus.END)
|
|
617
|
+
(callbackObj.options.start &&
|
|
618
|
+
dataStatus === embedEventStatus.START) || // When start status is true it trigger only start releated payload
|
|
619
|
+
(!callbackObj.options.start &&
|
|
620
|
+
dataStatus === embedEventStatus.END) // When start status is false it trigger only end releated payload
|
|
601
621
|
) {
|
|
602
622
|
callbackObj.callback(data, (payload) => {
|
|
603
623
|
this.triggerEventOnPort(eventPort, payload);
|
|
@@ -615,7 +635,6 @@ export class TsEmbed {
|
|
|
615
635
|
|
|
616
636
|
/**
|
|
617
637
|
* Gets the v1 event type (if applicable) for the EmbedEvent type
|
|
618
|
-
*
|
|
619
638
|
* @param eventType The v2 event type
|
|
620
639
|
* @returns The corresponding v1 event type if one exists
|
|
621
640
|
* or else the v2 event type itself
|
|
@@ -628,7 +647,6 @@ export class TsEmbed {
|
|
|
628
647
|
* Calculates the iframe center for the current visible viewPort
|
|
629
648
|
* of iframe using Scroll position of Host App, offsetTop for iframe
|
|
630
649
|
* in Host app. ViewPort height of the tab.
|
|
631
|
-
*
|
|
632
650
|
* @returns iframe Center in visible viewport,
|
|
633
651
|
* Iframe height,
|
|
634
652
|
* View port height.
|
|
@@ -643,11 +661,18 @@ export class TsEmbed {
|
|
|
643
661
|
let iframeOffset;
|
|
644
662
|
|
|
645
663
|
if (iframeScrolled < 0) {
|
|
646
|
-
iframeVisibleViewPort =
|
|
647
|
-
|
|
664
|
+
iframeVisibleViewPort =
|
|
665
|
+
viewPortHeight - (offsetTopClient - scrollTopClient);
|
|
666
|
+
iframeVisibleViewPort = Math.min(
|
|
667
|
+
iframeHeight,
|
|
668
|
+
iframeVisibleViewPort,
|
|
669
|
+
);
|
|
648
670
|
iframeOffset = 0;
|
|
649
671
|
} else {
|
|
650
|
-
iframeVisibleViewPort = Math.min(
|
|
672
|
+
iframeVisibleViewPort = Math.min(
|
|
673
|
+
iframeHeight - iframeScrolled,
|
|
674
|
+
viewPortHeight,
|
|
675
|
+
);
|
|
651
676
|
iframeOffset = iframeScrolled;
|
|
652
677
|
}
|
|
653
678
|
const iframeCenter = iframeOffset + iframeVisibleViewPort / 2;
|
|
@@ -688,7 +713,9 @@ export class TsEmbed {
|
|
|
688
713
|
options: MessageOptions = { start: false },
|
|
689
714
|
): typeof TsEmbed.prototype {
|
|
690
715
|
if (this.isRendered) {
|
|
691
|
-
this.handleError(
|
|
716
|
+
this.handleError(
|
|
717
|
+
'Please register event handlers before calling render',
|
|
718
|
+
);
|
|
692
719
|
}
|
|
693
720
|
const callbacks = this.eventHandlerMap.get(messageType) || [];
|
|
694
721
|
callbacks.push({ options, callback });
|
|
@@ -699,11 +726,8 @@ export class TsEmbed {
|
|
|
699
726
|
/**
|
|
700
727
|
* Triggers an event on specific Port registered against
|
|
701
728
|
* for the EmbedEvent
|
|
702
|
-
*
|
|
703
729
|
* @param eventType The message type
|
|
704
730
|
* @param data The payload to send
|
|
705
|
-
* @param eventPort
|
|
706
|
-
* @param payload
|
|
707
731
|
*/
|
|
708
732
|
private triggerEventOnPort(eventPort: MessagePort | void, payload: any) {
|
|
709
733
|
if (eventPort) {
|
|
@@ -723,20 +747,25 @@ export class TsEmbed {
|
|
|
723
747
|
|
|
724
748
|
/**
|
|
725
749
|
* Triggers an event to the embedded app
|
|
726
|
-
*
|
|
727
750
|
* @param messageType The event type
|
|
728
751
|
* @param data The payload to send with the message
|
|
729
752
|
*/
|
|
730
753
|
public trigger(messageType: HostEvent, data: any = {}): Promise<any> {
|
|
731
|
-
uploadMixpanelEvent(
|
|
732
|
-
|
|
754
|
+
uploadMixpanelEvent(
|
|
755
|
+
`${MIXPANEL_EVENT.VISUAL_SDK_TRIGGER}-${messageType}`,
|
|
756
|
+
);
|
|
757
|
+
return processTrigger(
|
|
758
|
+
this.iFrame,
|
|
759
|
+
messageType,
|
|
760
|
+
this.thoughtSpotHost,
|
|
761
|
+
data,
|
|
762
|
+
);
|
|
733
763
|
}
|
|
734
764
|
|
|
735
765
|
/**
|
|
736
766
|
* Marks the ThoughtSpot object to have been rendered
|
|
737
767
|
* Needs to be overridden by subclasses to do the actual
|
|
738
768
|
* rendering of the iframe.
|
|
739
|
-
*
|
|
740
769
|
* @param args
|
|
741
770
|
*/
|
|
742
771
|
public render(): TsEmbed {
|
|
@@ -749,7 +778,6 @@ export class TsEmbed {
|
|
|
749
778
|
* Get the Post Url Params for THOUGHTSPOT from the current
|
|
750
779
|
* host app URL.
|
|
751
780
|
* THOUGHTSPOT URL params starts with a prefix "ts-"
|
|
752
|
-
*
|
|
753
781
|
* @version SDK: 1.14.0 | ThoughtSpot: 8.4.0.cl, 8.4.1-sw
|
|
754
782
|
*/
|
|
755
783
|
public getThoughtSpotPostUrlParams(): string {
|
|
@@ -777,7 +805,6 @@ export class TsEmbed {
|
|
|
777
805
|
|
|
778
806
|
/**
|
|
779
807
|
* Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
|
|
780
|
-
*
|
|
781
808
|
* @version SDK: 1.19.1 | ThoughtSpot: *
|
|
782
809
|
*/
|
|
783
810
|
public destroy(): void {
|
|
@@ -787,15 +814,6 @@ export class TsEmbed {
|
|
|
787
814
|
console.log('Error destroying TS Embed', e);
|
|
788
815
|
}
|
|
789
816
|
}
|
|
790
|
-
|
|
791
|
-
public getUnderlyingFrameElement(): HTMLIFrameElement {
|
|
792
|
-
return this.iFrame;
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
public async prerenderGeneric(): Promise<any> {
|
|
796
|
-
const prerenderFrameSrc = this.getRootIframeSrc();
|
|
797
|
-
return this.renderIFrame(prerenderFrameSrc);
|
|
798
|
-
}
|
|
799
817
|
}
|
|
800
818
|
|
|
801
819
|
/**
|
|
@@ -815,23 +833,15 @@ export class V1Embed extends TsEmbed {
|
|
|
815
833
|
|
|
816
834
|
/**
|
|
817
835
|
* Render the ap p in an iframe and set up event handlers
|
|
818
|
-
*
|
|
819
836
|
* @param iframeSrc
|
|
820
837
|
*/
|
|
821
838
|
protected renderV1Embed(iframeSrc: string): any {
|
|
822
|
-
return this.renderIFrame(iframeSrc);
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
protected getRootIframeSrc(): string {
|
|
826
|
-
const runtimeFilters = this.viewConfig.runtimeFilters;
|
|
827
|
-
const filterQuery = getFilterQuery(runtimeFilters || []);
|
|
828
|
-
const queryParams = this.getEmbedParams();
|
|
829
|
-
const queryString = [filterQuery, queryParams].filter(Boolean).join('&');
|
|
830
|
-
return this.getV1EmbedBasePath(queryString);
|
|
839
|
+
return this.renderIFrame(iframeSrc, this.viewConfig.frameParams);
|
|
831
840
|
}
|
|
832
841
|
|
|
833
842
|
/**
|
|
834
|
-
* @inheritdoc
|
|
843
|
+
* @inheritdoc TsEmbed.on
|
|
844
|
+
*
|
|
835
845
|
* @example
|
|
836
846
|
* ```js
|
|
837
847
|
* tsEmbed.on(EmbedEvent.Error, (data) => {
|
package/src/errors.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export const ERROR_MESSAGE = {
|
|
2
|
-
INVALID_THOUGHTSPOT_HOST:
|
|
3
|
-
|
|
2
|
+
INVALID_THOUGHTSPOT_HOST:
|
|
3
|
+
'Error parsing ThoughtSpot host. Please provide a valid URL.',
|
|
4
|
+
LIVEBOARD_VIZ_ID_VALIDATION:
|
|
5
|
+
'Please provide either liveboardId or pinboardId',
|
|
4
6
|
TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
|
|
5
|
-
SEARCHEMBED_BETA_WRANING_MESSAGE:
|
|
7
|
+
SEARCHEMBED_BETA_WRANING_MESSAGE:
|
|
8
|
+
'Search Embed is in Beta in this release.',
|
|
6
9
|
};
|
package/src/index.ts
CHANGED
|
@@ -8,14 +8,20 @@
|
|
|
8
8
|
* @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
|
|
9
9
|
*/
|
|
10
10
|
import { AppEmbed, Page, AppViewConfig } from './embed/app';
|
|
11
|
+
import { init, prefetch, logout, getEmbedConfig } from './embed/base';
|
|
11
12
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
PinboardEmbed,
|
|
14
|
+
LiveboardViewConfig,
|
|
15
|
+
LiveboardEmbed,
|
|
16
|
+
} from './embed/liveboard';
|
|
15
17
|
import { SearchEmbed, SearchViewConfig } from './embed/search';
|
|
16
18
|
import { SearchBarEmbed, SearchBarViewConfig } from './embed/search-bar';
|
|
17
19
|
import {
|
|
18
|
-
AuthFailureType,
|
|
20
|
+
AuthFailureType,
|
|
21
|
+
AuthStatus,
|
|
22
|
+
AuthEvent,
|
|
23
|
+
AuthEventEmitter,
|
|
24
|
+
getSessionInfo,
|
|
19
25
|
} from './auth';
|
|
20
26
|
import {
|
|
21
27
|
AuthType,
|
|
@@ -49,7 +49,9 @@ describe('Unit test for mixpanel', () => {
|
|
|
49
49
|
initMixpanel(sessionInfo);
|
|
50
50
|
|
|
51
51
|
expect(mixpanel.init).toHaveBeenCalledWith(sessionInfo.mixpanelToken);
|
|
52
|
-
expect(mixpanel.identify).not.toHaveBeenCalledWith(
|
|
52
|
+
expect(mixpanel.identify).not.toHaveBeenCalledWith(
|
|
53
|
+
sessionInfo.userGUID,
|
|
54
|
+
);
|
|
53
55
|
});
|
|
54
56
|
|
|
55
57
|
test('when not init, should queue events and flush on init', () => {
|