@thoughtspot/visual-embed-sdk 1.41.1 → 1.42.1-alpha.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 +9 -9
- package/cjs/src/api-intercept.d.ts +25 -0
- package/cjs/src/api-intercept.d.ts.map +1 -0
- package/cjs/src/api-intercept.js +115 -0
- package/cjs/src/api-intercept.js.map +1 -0
- package/cjs/src/css-variables.d.ts +52 -14
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +7 -2
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +20 -0
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.d.ts +1 -0
- package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/cjs/src/embed/bodyless-conversation.js +7 -3
- package/cjs/src/embed/bodyless-conversation.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts +1 -0
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +7 -2
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.d.ts +11 -1
- package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.js +1 -0
- package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +1 -0
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +10 -2
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +35 -0
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/sage.d.ts +1 -0
- package/cjs/src/embed/sage.d.ts.map +1 -1
- package/cjs/src/embed/sage.js +10 -6
- package/cjs/src/embed/sage.js.map +1 -1
- package/cjs/src/embed/search-bar.d.ts +1 -0
- package/cjs/src/embed/search-bar.d.ts.map +1 -1
- package/cjs/src/embed/search-bar.js +11 -7
- package/cjs/src/embed/search-bar.js.map +1 -1
- package/cjs/src/embed/search.d.ts +1 -0
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js +10 -9
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +21 -4
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +115 -34
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +83 -0
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/errors.d.ts +1 -0
- package/cjs/src/errors.d.ts.map +1 -1
- package/cjs/src/errors.js +1 -0
- package/cjs/src/errors.js.map +1 -1
- package/cjs/src/index.d.ts +2 -2
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +2 -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/react/all-types-export.spec.js +1 -1
- package/cjs/src/react/all-types-export.spec.js.map +1 -1
- package/cjs/src/react/util.js.map +1 -1
- package/cjs/src/react/util.spec.d.ts +2 -0
- package/cjs/src/react/util.spec.d.ts.map +1 -0
- package/cjs/src/react/util.spec.js +78 -0
- package/cjs/src/react/util.spec.js.map +1 -0
- package/cjs/src/types.d.ts +135 -8
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +73 -4
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/processData.d.ts +1 -1
- package/cjs/src/utils/processData.d.ts.map +1 -1
- package/cjs/src/utils/processData.js +8 -8
- package/cjs/src/utils/processData.js.map +1 -1
- package/dist/index-BEzW4MDA.js +7371 -0
- package/dist/{index-DQueHwfQ.js → index-DvNA626T.js} +1 -1
- package/dist/src/api-intercept.d.ts +25 -0
- package/dist/src/api-intercept.d.ts.map +1 -0
- package/dist/src/css-variables.d.ts +52 -14
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/bodyless-conversation.d.ts +1 -0
- package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts +1 -0
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/contracts.d.ts +11 -1
- package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +1 -0
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/sage.d.ts +1 -0
- package/dist/src/embed/sage.d.ts.map +1 -1
- package/dist/src/embed/search-bar.d.ts +1 -0
- package/dist/src/embed/search-bar.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +1 -0
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +21 -4
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/errors.d.ts +1 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- 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/react/util.spec.d.ts +2 -0
- package/dist/src/react/util.spec.d.ts.map +1 -0
- package/dist/src/types.d.ts +135 -8
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/processData.d.ts +1 -1
- package/dist/src/utils/processData.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +370 -90
- package/dist/tsembed-react.js +369 -89
- package/dist/tsembed.es.js +371 -91
- package/dist/tsembed.js +369 -89
- package/dist/visual-embed-sdk-react-full.d.ts +9431 -9915
- package/dist/visual-embed-sdk-react.d.ts +9301 -9922
- package/dist/visual-embed-sdk.d.ts +9470 -9532
- package/lib/package.json +9 -9
- package/lib/src/api-intercept.d.ts +25 -0
- package/lib/src/api-intercept.d.ts.map +1 -0
- package/lib/src/api-intercept.js +108 -0
- package/lib/src/api-intercept.js.map +1 -0
- package/lib/src/css-variables.d.ts +52 -14
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +7 -2
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +20 -0
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.d.ts +1 -0
- package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/lib/src/embed/bodyless-conversation.js +7 -3
- package/lib/src/embed/bodyless-conversation.js.map +1 -1
- package/lib/src/embed/conversation.d.ts +1 -0
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js +7 -2
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.d.ts +11 -1
- package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.js +1 -0
- package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +1 -0
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +10 -2
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +35 -0
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/sage.d.ts +1 -0
- package/lib/src/embed/sage.d.ts.map +1 -1
- package/lib/src/embed/sage.js +10 -6
- package/lib/src/embed/sage.js.map +1 -1
- package/lib/src/embed/search-bar.d.ts +1 -0
- package/lib/src/embed/search-bar.d.ts.map +1 -1
- package/lib/src/embed/search-bar.js +11 -7
- package/lib/src/embed/search-bar.js.map +1 -1
- package/lib/src/embed/search.d.ts +1 -0
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +10 -9
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +21 -4
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +115 -34
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +83 -0
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/errors.d.ts +1 -0
- package/lib/src/errors.d.ts.map +1 -1
- package/lib/src/errors.js +1 -0
- package/lib/src/errors.js.map +1 -1
- package/lib/src/index.d.ts +2 -2
- 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/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/react/all-types-export.spec.js +1 -1
- package/lib/src/react/all-types-export.spec.js.map +1 -1
- package/lib/src/react/util.js.map +1 -1
- package/lib/src/react/util.spec.d.ts +2 -0
- package/lib/src/react/util.spec.d.ts.map +1 -0
- package/lib/src/react/util.spec.js +76 -0
- package/lib/src/react/util.spec.js.map +1 -0
- package/lib/src/types.d.ts +135 -8
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +72 -3
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/processData.d.ts +1 -1
- package/lib/src/utils/processData.d.ts.map +1 -1
- package/lib/src/utils/processData.js +8 -8
- package/lib/src/utils/processData.js.map +1 -1
- package/package.json +9 -9
- package/src/api-intercept.ts +134 -0
- package/src/css-variables.ts +53 -16
- package/src/embed/app.spec.ts +28 -0
- package/src/embed/app.ts +9 -1
- package/src/embed/bodyless-conversation.ts +8 -3
- package/src/embed/conversation.ts +17 -2
- package/src/embed/hostEventClient/contracts.ts +10 -0
- package/src/embed/liveboard.spec.ts +44 -0
- package/src/embed/liveboard.ts +12 -1
- package/src/embed/sage.ts +14 -9
- package/src/embed/search-bar.tsx +14 -7
- package/src/embed/search.ts +21 -8
- package/src/embed/ts-embed.spec.ts +116 -5
- package/src/embed/ts-embed.ts +152 -50
- package/src/errors.ts +1 -0
- package/src/index.ts +2 -0
- package/src/react/all-types-export.spec.ts +1 -1
- package/src/react/all-types-export.ts +1 -0
- package/src/react/util.spec.tsx +88 -0
- package/src/react/util.ts +3 -3
- package/src/types.ts +195 -64
- package/src/utils/processData.ts +11 -11
- package/lib/src/visual-embed-sdk.d.ts +0 -9779
package/src/embed/ts-embed.ts
CHANGED
|
@@ -71,6 +71,7 @@ import { getEmbedConfig } from './embedConfig';
|
|
|
71
71
|
import { ERROR_MESSAGE } from '../errors';
|
|
72
72
|
import { getPreauthInfo } from '../utils/sessionInfoService';
|
|
73
73
|
import { HostEventClient } from './hostEventClient/host-event-client';
|
|
74
|
+
import { getInterceptInitData, handleInterceptEvent, processLegacyInterceptResponse } from '../api-intercept';
|
|
74
75
|
|
|
75
76
|
const { version } = pkgInfo;
|
|
76
77
|
|
|
@@ -199,11 +200,11 @@ export class TsEmbed {
|
|
|
199
200
|
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_EMBED_CREATE, {
|
|
200
201
|
...viewConfig,
|
|
201
202
|
});
|
|
202
|
-
|
|
203
|
+
const embedConfig = getEmbedConfig();
|
|
204
|
+
this.embedConfig = embedConfig;
|
|
203
205
|
|
|
206
|
+
this.hostEventClient = new HostEventClient(this.iFrame);
|
|
204
207
|
this.isReadyForRenderPromise = getInitPromise().then(async () => {
|
|
205
|
-
const embedConfig = getEmbedConfig();
|
|
206
|
-
this.embedConfig = embedConfig;
|
|
207
208
|
if (!embedConfig.authTriggerContainer && !embedConfig.useEventForSAMLPopup) {
|
|
208
209
|
this.embedConfig.authTriggerContainer = domSelector;
|
|
209
210
|
}
|
|
@@ -312,31 +313,11 @@ export class TsEmbed {
|
|
|
312
313
|
private subscribedListeners: Record<string, any> = {};
|
|
313
314
|
|
|
314
315
|
/**
|
|
315
|
-
*
|
|
316
|
-
*
|
|
317
|
-
* embed instance through an identifier contained in the payload,
|
|
318
|
-
* and executes the registered callbacks accordingly.
|
|
316
|
+
* Subscribe to network events (online/offline) that should
|
|
317
|
+
* work regardless of auth status
|
|
319
318
|
*/
|
|
320
|
-
private
|
|
321
|
-
this.
|
|
322
|
-
const messageEventListener = (event: MessageEvent<any>) => {
|
|
323
|
-
const eventType = this.getEventType(event);
|
|
324
|
-
const eventPort = this.getEventPort(event);
|
|
325
|
-
const eventData = this.formatEventData(event, eventType);
|
|
326
|
-
if (event.source === this.iFrame.contentWindow) {
|
|
327
|
-
this.executeCallbacks(
|
|
328
|
-
eventType,
|
|
329
|
-
processEventData(
|
|
330
|
-
eventType,
|
|
331
|
-
eventData,
|
|
332
|
-
this.thoughtSpotHost,
|
|
333
|
-
this.isPreRendered ? this.preRenderWrapper : this.el,
|
|
334
|
-
),
|
|
335
|
-
eventPort,
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
window.addEventListener('message', messageEventListener);
|
|
319
|
+
private subscribeToNetworkEvents() {
|
|
320
|
+
this.unsubscribeToNetworkEvents();
|
|
340
321
|
|
|
341
322
|
const onlineEventListener = (e: Event) => {
|
|
342
323
|
this.trigger(HostEvent.Reload);
|
|
@@ -344,7 +325,7 @@ export class TsEmbed {
|
|
|
344
325
|
window.addEventListener('online', onlineEventListener);
|
|
345
326
|
|
|
346
327
|
const offlineEventListener = (e: Event) => {
|
|
347
|
-
const offlineWarning =
|
|
328
|
+
const offlineWarning = ERROR_MESSAGE.OFFLINE_WARNING;
|
|
348
329
|
this.executeCallbacks(EmbedEvent.Error, {
|
|
349
330
|
offlineWarning,
|
|
350
331
|
});
|
|
@@ -352,11 +333,84 @@ export class TsEmbed {
|
|
|
352
333
|
};
|
|
353
334
|
window.addEventListener('offline', offlineEventListener);
|
|
354
335
|
|
|
355
|
-
this.subscribedListeners =
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
336
|
+
this.subscribedListeners.online = onlineEventListener;
|
|
337
|
+
this.subscribedListeners.offline = offlineEventListener;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
private messageEventListener = async (event: MessageEvent<any>) => {
|
|
341
|
+
const eventType = this.getEventType(event);
|
|
342
|
+
const eventPort = this.getEventPort(event);
|
|
343
|
+
const eventData = this.formatEventData(event, eventType);
|
|
344
|
+
if (event.source === this.iFrame.contentWindow) {
|
|
345
|
+
const processedEventData = await processEventData(
|
|
346
|
+
eventType,
|
|
347
|
+
eventData,
|
|
348
|
+
this.thoughtSpotHost,
|
|
349
|
+
this.isPreRendered ? this.preRenderWrapper : this.el,
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
const executeEvent = (_eventType: EmbedEvent, data: any) => {
|
|
353
|
+
this.executeCallbacks(_eventType, data, eventPort);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (eventType === EmbedEvent.ApiIntercept && this.viewConfig.enableApiIntercept) {
|
|
357
|
+
const getUnsavedAnswerTml = async (props: { sessionId?: string, vizId?: string }) => {
|
|
358
|
+
const response = await this.triggerUIPassThrough(UIPassthroughEvent.GetUnsavedAnswerTML, props);
|
|
359
|
+
return response[0]?.value;
|
|
360
|
+
}
|
|
361
|
+
handleInterceptEvent({ eventData: processedEventData, executeEvent, embedConfig: this.embedConfig, viewConfig: this.viewConfig, getUnsavedAnswerTml });
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
this.executeCallbacks(
|
|
366
|
+
eventType,
|
|
367
|
+
processedEventData,
|
|
368
|
+
eventPort,
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
/**
|
|
373
|
+
* Subscribe to message events that depend on successful iframe setup
|
|
374
|
+
*/
|
|
375
|
+
private subscribeToMessageEvents() {
|
|
376
|
+
this.unsubscribeToMessageEvents();
|
|
377
|
+
|
|
378
|
+
window.addEventListener('message', this.messageEventListener);
|
|
379
|
+
|
|
380
|
+
this.subscribedListeners.message = this.messageEventListener;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Adds event listeners for both network and message events.
|
|
386
|
+
* This maintains backward compatibility with the existing method.
|
|
387
|
+
* Adds a global event listener to window for "message" events.
|
|
388
|
+
* ThoughtSpot detects if a particular event is targeted to this
|
|
389
|
+
* embed instance through an identifier contained in the payload,
|
|
390
|
+
* and executes the registered callbacks accordingly.
|
|
391
|
+
*/
|
|
392
|
+
private subscribeToEvents() {
|
|
393
|
+
this.subscribeToNetworkEvents();
|
|
394
|
+
this.subscribeToMessageEvents();
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
private unsubscribeToNetworkEvents() {
|
|
399
|
+
if (this.subscribedListeners.online) {
|
|
400
|
+
window.removeEventListener('online', this.subscribedListeners.online);
|
|
401
|
+
delete this.subscribedListeners.online;
|
|
402
|
+
}
|
|
403
|
+
if (this.subscribedListeners.offline) {
|
|
404
|
+
window.removeEventListener('offline', this.subscribedListeners.offline);
|
|
405
|
+
delete this.subscribedListeners.offline;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
private unsubscribeToMessageEvents() {
|
|
410
|
+
if (this.subscribedListeners.message) {
|
|
411
|
+
window.removeEventListener('message', this.subscribedListeners.message);
|
|
412
|
+
delete this.subscribedListeners.message;
|
|
413
|
+
}
|
|
360
414
|
}
|
|
361
415
|
|
|
362
416
|
private unsubscribeToEvents() {
|
|
@@ -391,7 +445,7 @@ export class TsEmbed {
|
|
|
391
445
|
message: customActionsResult.errors,
|
|
392
446
|
});
|
|
393
447
|
}
|
|
394
|
-
|
|
448
|
+
const baseInitData = {
|
|
395
449
|
customisations: getCustomisations(this.embedConfig, this.viewConfig),
|
|
396
450
|
authToken,
|
|
397
451
|
runtimeFilterParams: this.viewConfig.excludeRuntimeFiltersfromURL
|
|
@@ -410,7 +464,10 @@ export class TsEmbed {
|
|
|
410
464
|
this.embedConfig.customVariablesForThirdPartyTools || {},
|
|
411
465
|
hiddenListColumns: this.viewConfig.hiddenListColumns || [],
|
|
412
466
|
customActions: customActionsResult.actions,
|
|
467
|
+
...getInterceptInitData(this.embedConfig, this.viewConfig),
|
|
413
468
|
};
|
|
469
|
+
|
|
470
|
+
return baseInitData;
|
|
414
471
|
}
|
|
415
472
|
|
|
416
473
|
protected async getAppInitData() {
|
|
@@ -494,10 +551,10 @@ export class TsEmbed {
|
|
|
494
551
|
this.on(EmbedEvent.APP_INIT, this.appInitCb, { start: false }, true);
|
|
495
552
|
this.on(EmbedEvent.AuthExpire, this.updateAuthToken, { start: false }, true);
|
|
496
553
|
this.on(EmbedEvent.IdleSessionTimeout, this.idleSessionTimeout, { start: false }, true);
|
|
497
|
-
|
|
498
|
-
const embedListenerReadyHandler = this.createEmbedContainerHandler(EmbedEvent.EmbedListenerReady);
|
|
554
|
+
|
|
555
|
+
const embedListenerReadyHandler = this.createEmbedContainerHandler(EmbedEvent.EmbedListenerReady);
|
|
499
556
|
this.on(EmbedEvent.EmbedListenerReady, embedListenerReadyHandler, { start: false }, true);
|
|
500
|
-
|
|
557
|
+
|
|
501
558
|
const authInitHandler = this.createEmbedContainerHandler(EmbedEvent.AuthInit);
|
|
502
559
|
this.on(EmbedEvent.AuthInit, authInitHandler, { start: false }, true);
|
|
503
560
|
};
|
|
@@ -520,6 +577,12 @@ export class TsEmbed {
|
|
|
520
577
|
return `${basePath}#`;
|
|
521
578
|
}
|
|
522
579
|
|
|
580
|
+
protected getUpdateEmbedParamsObject() {
|
|
581
|
+
let queryParams = this.getEmbedParamsObject();
|
|
582
|
+
queryParams = { ...this.viewConfig, ...queryParams };
|
|
583
|
+
return queryParams;
|
|
584
|
+
}
|
|
585
|
+
|
|
523
586
|
/**
|
|
524
587
|
* Common query params set for all the embed modes.
|
|
525
588
|
* @param queryParams
|
|
@@ -702,10 +765,15 @@ export class TsEmbed {
|
|
|
702
765
|
}
|
|
703
766
|
|
|
704
767
|
protected getEmbedParams() {
|
|
705
|
-
const queryParams = this.
|
|
768
|
+
const queryParams = this.getEmbedParamsObject();
|
|
706
769
|
return getQueryParamString(queryParams);
|
|
707
770
|
}
|
|
708
771
|
|
|
772
|
+
protected getEmbedParamsObject() {
|
|
773
|
+
const params = this.getBaseQueryParams();
|
|
774
|
+
return params;
|
|
775
|
+
}
|
|
776
|
+
|
|
709
777
|
protected getRootIframeSrc() {
|
|
710
778
|
const query = this.getEmbedParams();
|
|
711
779
|
return this.getEmbedBasePath(query);
|
|
@@ -787,6 +855,9 @@ export class TsEmbed {
|
|
|
787
855
|
|
|
788
856
|
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_START);
|
|
789
857
|
|
|
858
|
+
// Always subscribe to network events, regardless of auth status
|
|
859
|
+
this.subscribeToNetworkEvents();
|
|
860
|
+
|
|
790
861
|
return getAuthPromise()
|
|
791
862
|
?.then((isLoggedIn: boolean) => {
|
|
792
863
|
if (!isLoggedIn) {
|
|
@@ -832,7 +903,9 @@ export class TsEmbed {
|
|
|
832
903
|
el.remove();
|
|
833
904
|
});
|
|
834
905
|
}
|
|
835
|
-
|
|
906
|
+
// Subscribe to message events only after successful
|
|
907
|
+
// auth and iframe setup
|
|
908
|
+
this.subscribeToMessageEvents();
|
|
836
909
|
})
|
|
837
910
|
.catch((error) => {
|
|
838
911
|
nextInQueue();
|
|
@@ -972,6 +1045,21 @@ export class TsEmbed {
|
|
|
972
1045
|
this.iFrame.style.height = getCssDimension(height);
|
|
973
1046
|
}
|
|
974
1047
|
|
|
1048
|
+
protected createEmbedEventResponder = (eventPort: MessagePort | void, eventType: EmbedEvent) => {
|
|
1049
|
+
|
|
1050
|
+
const { enableApiIntercept } = getInterceptInitData(this.embedConfig, this.viewConfig);
|
|
1051
|
+
if (eventType === EmbedEvent.OnBeforeGetVizDataIntercept && enableApiIntercept) {
|
|
1052
|
+
return (payload: any) => {
|
|
1053
|
+
const payloadToSend = processLegacyInterceptResponse(payload);
|
|
1054
|
+
this.triggerEventOnPort(eventPort, payloadToSend);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
return (payload: any) => {
|
|
1059
|
+
this.triggerEventOnPort(eventPort, payload);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
|
|
975
1063
|
/**
|
|
976
1064
|
* Executes all registered event handlers for a particular event type
|
|
977
1065
|
* @param eventType The event type
|
|
@@ -996,9 +1084,8 @@ export class TsEmbed {
|
|
|
996
1084
|
// payload
|
|
997
1085
|
|| (!callbackObj.options.start && dataStatus === embedEventStatus.END)
|
|
998
1086
|
) {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
});
|
|
1087
|
+
const responder = this.createEmbedEventResponder(eventPort, eventType);
|
|
1088
|
+
callbackObj.callback(data, responder);
|
|
1002
1089
|
}
|
|
1003
1090
|
});
|
|
1004
1091
|
}
|
|
@@ -1141,10 +1228,10 @@ export class TsEmbed {
|
|
|
1141
1228
|
}
|
|
1142
1229
|
|
|
1143
1230
|
/**
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1231
|
+
* @hidden
|
|
1232
|
+
* Internal state to track if the embed container is loaded.
|
|
1233
|
+
* This is used to trigger events after the embed container is loaded.
|
|
1234
|
+
*/
|
|
1148
1235
|
public isEmbedContainerLoaded = false;
|
|
1149
1236
|
|
|
1150
1237
|
/**
|
|
@@ -1191,7 +1278,7 @@ export class TsEmbed {
|
|
|
1191
1278
|
} else {
|
|
1192
1279
|
logger.debug('pushing callback to embedContainerReadyCallbacks', callback);
|
|
1193
1280
|
this.embedContainerReadyCallbacks.push(callback);
|
|
1194
|
-
|
|
1281
|
+
}
|
|
1195
1282
|
}
|
|
1196
1283
|
|
|
1197
1284
|
protected createEmbedContainerHandler = (source: EmbedEvent.AuthInit | EmbedEvent.EmbedListenerReady) => () => {
|
|
@@ -1232,6 +1319,16 @@ export class TsEmbed {
|
|
|
1232
1319
|
this.handleError('Host event type is undefined');
|
|
1233
1320
|
return null;
|
|
1234
1321
|
}
|
|
1322
|
+
|
|
1323
|
+
// Check if iframe exists before triggering -
|
|
1324
|
+
// this prevents the error when auth fails
|
|
1325
|
+
if (!this.iFrame) {
|
|
1326
|
+
logger.debug(
|
|
1327
|
+
`Cannot trigger ${messageType} - iframe not available (likely due to auth failure)`,
|
|
1328
|
+
);
|
|
1329
|
+
return null;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1235
1332
|
// send an empty object, this is needed for liveboard default handlers
|
|
1236
1333
|
return this.hostEventClient.triggerHostEvent(messageType, data);
|
|
1237
1334
|
}
|
|
@@ -1279,6 +1376,7 @@ export class TsEmbed {
|
|
|
1279
1376
|
* Creates the preRender shell
|
|
1280
1377
|
* @param showPreRenderByDefault - Show the preRender after render, hidden by default
|
|
1281
1378
|
*/
|
|
1379
|
+
|
|
1282
1380
|
public async preRender(showPreRenderByDefault = false, replaceExistingPreRender = false): Promise<TsEmbed> {
|
|
1283
1381
|
if (!this.viewConfig.preRenderId) {
|
|
1284
1382
|
logger.error(ERROR_MESSAGE.PRERENDER_ID_MISSING);
|
|
@@ -1286,7 +1384,7 @@ export class TsEmbed {
|
|
|
1286
1384
|
}
|
|
1287
1385
|
this.isPreRendered = true;
|
|
1288
1386
|
this.showPreRenderByDefault = showPreRenderByDefault;
|
|
1289
|
-
|
|
1387
|
+
|
|
1290
1388
|
const isAlreadyRendered = this.connectPreRendered();
|
|
1291
1389
|
if (isAlreadyRendered && !replaceExistingPreRender) {
|
|
1292
1390
|
return this;
|
|
@@ -1413,8 +1511,14 @@ export class TsEmbed {
|
|
|
1413
1511
|
return this.preRender(true);
|
|
1414
1512
|
}
|
|
1415
1513
|
this.validatePreRenderViewConfig(this.viewConfig);
|
|
1514
|
+
logger.debug('triggering UpdateEmbedParams', this.viewConfig);
|
|
1515
|
+
this.executeAfterEmbedContainerLoaded(() => {
|
|
1516
|
+
this.trigger(HostEvent.UpdateEmbedParams, this.getUpdateEmbedParamsObject());
|
|
1517
|
+
});
|
|
1416
1518
|
}
|
|
1417
1519
|
|
|
1520
|
+
this.beforePrerenderVisible();
|
|
1521
|
+
|
|
1418
1522
|
if (this.el) {
|
|
1419
1523
|
this.syncPreRenderStyle();
|
|
1420
1524
|
if (!this.viewConfig.doNotTrackPreRenderSize) {
|
|
@@ -1432,8 +1536,6 @@ export class TsEmbed {
|
|
|
1432
1536
|
}
|
|
1433
1537
|
}
|
|
1434
1538
|
|
|
1435
|
-
this.beforePrerenderVisible();
|
|
1436
|
-
|
|
1437
1539
|
removeStyleProperties(this.preRenderWrapper, ['z-index', 'opacity', 'pointer-events']);
|
|
1438
1540
|
|
|
1439
1541
|
this.subscribeToEvents();
|
package/src/errors.ts
CHANGED
|
@@ -19,6 +19,7 @@ export const ERROR_MESSAGE = {
|
|
|
19
19
|
MISSING_REPORTING_OBSERVER: 'ReportingObserver not supported',
|
|
20
20
|
RENDER_CALLED_BEFORE_INIT: 'Looks like render was called before calling init, the render won\'t start until init is called.\nFor more info check\n1. https://developers.thoughtspot.com/docs/Function_init#_init\n2.https://developers.thoughtspot.com/docs/getting-started#initSdk',
|
|
21
21
|
SPOTTER_AGENT_NOT_INITIALIZED: 'SpotterAgent not initialized',
|
|
22
|
+
OFFLINE_WARNING : 'Network not Detected. Embed is offline. Please reconnect and refresh',
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
export const CUSTOM_ACTIONS_ERROR_MESSAGE = {
|
package/src/index.ts
CHANGED
|
@@ -64,6 +64,7 @@ import {
|
|
|
64
64
|
ListPageColumns,
|
|
65
65
|
CustomActionsPosition,
|
|
66
66
|
CustomActionTarget,
|
|
67
|
+
InterceptedApiType,
|
|
67
68
|
} from './types';
|
|
68
69
|
import { CustomCssVariables } from './css-variables';
|
|
69
70
|
import { SageEmbed, SageViewConfig } from './embed/sage';
|
|
@@ -152,6 +153,7 @@ export {
|
|
|
152
153
|
DataPanelCustomColumnGroupsAccordionState,
|
|
153
154
|
CustomActionsPosition,
|
|
154
155
|
CustomActionTarget,
|
|
156
|
+
InterceptedApiType,
|
|
155
157
|
};
|
|
156
158
|
|
|
157
159
|
export { resetCachedAuthToken } from './authToken';
|
|
@@ -6,6 +6,6 @@ describe('Exports', () => {
|
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
it('should not have undefined exports', () => {
|
|
9
|
-
Object.
|
|
9
|
+
Object.entries(Exports).forEach(([, exportValue]) => {expect(Boolean(exportValue)).toBe(true);});
|
|
10
10
|
});
|
|
11
11
|
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { getViewPropsAndListeners } from './util';
|
|
2
|
+
import { EmbedEvent, MessageCallback } from '../types';
|
|
3
|
+
|
|
4
|
+
describe('React util functions', () => {
|
|
5
|
+
describe('getViewPropsAndListeners', () => {
|
|
6
|
+
test('should return empty viewConfig and listeners for empty props', () => {
|
|
7
|
+
const props = {};
|
|
8
|
+
const result = getViewPropsAndListeners(props);
|
|
9
|
+
|
|
10
|
+
expect(result.viewConfig).toEqual({});
|
|
11
|
+
expect(result.listeners).toEqual({});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('should separate view config properties from props', () => {
|
|
15
|
+
const props = {
|
|
16
|
+
frameParams: { width: 100, height: 200 },
|
|
17
|
+
showLiveboardTitle: true,
|
|
18
|
+
liveboardId: 'test-liveboard-id',
|
|
19
|
+
vizId: 'test-viz-id',
|
|
20
|
+
className: 'test-class',
|
|
21
|
+
style: { color: 'red' },
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const result = getViewPropsAndListeners(props);
|
|
25
|
+
|
|
26
|
+
expect(result.viewConfig).toEqual({
|
|
27
|
+
frameParams: { width: 100, height: 200 },
|
|
28
|
+
showLiveboardTitle: true,
|
|
29
|
+
liveboardId: 'test-liveboard-id',
|
|
30
|
+
vizId: 'test-viz-id',
|
|
31
|
+
className: 'test-class',
|
|
32
|
+
style: { color: 'red' },
|
|
33
|
+
});
|
|
34
|
+
expect(result.listeners).toEqual({});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('should separate event handlers from props', () => {
|
|
38
|
+
const onInit: MessageCallback = jest.fn();
|
|
39
|
+
const onLoad: MessageCallback = jest.fn();
|
|
40
|
+
const onData: MessageCallback = jest.fn();
|
|
41
|
+
|
|
42
|
+
const props = {
|
|
43
|
+
onInit,
|
|
44
|
+
onLoad,
|
|
45
|
+
onData,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const result = getViewPropsAndListeners(props);
|
|
49
|
+
|
|
50
|
+
expect(result.viewConfig).toEqual({});
|
|
51
|
+
expect(result.listeners).toEqual({
|
|
52
|
+
[EmbedEvent.Init]: onInit,
|
|
53
|
+
[EmbedEvent.Load]: onLoad,
|
|
54
|
+
[EmbedEvent.Data]: onData,
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('should handle both view config and event handlers', () => {
|
|
59
|
+
const onInit: MessageCallback = jest.fn();
|
|
60
|
+
const onAuthInit: MessageCallback = jest.fn();
|
|
61
|
+
const onQueryChanged: MessageCallback = jest.fn();
|
|
62
|
+
|
|
63
|
+
const props = {
|
|
64
|
+
liveboardId: 'test-liveboard-id',
|
|
65
|
+
showLiveboardTitle: false,
|
|
66
|
+
frameParams: { height: 500 },
|
|
67
|
+
onInit,
|
|
68
|
+
onAuthInit,
|
|
69
|
+
onQueryChanged,
|
|
70
|
+
className: 'embed-container',
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const result = getViewPropsAndListeners(props);
|
|
74
|
+
|
|
75
|
+
expect(result.viewConfig).toEqual({
|
|
76
|
+
liveboardId: 'test-liveboard-id',
|
|
77
|
+
showLiveboardTitle: false,
|
|
78
|
+
frameParams: { height: 500 },
|
|
79
|
+
className: 'embed-container',
|
|
80
|
+
});
|
|
81
|
+
expect(result.listeners).toEqual({
|
|
82
|
+
[EmbedEvent.Init]: onInit,
|
|
83
|
+
[EmbedEvent.AuthInit]: onAuthInit,
|
|
84
|
+
[EmbedEvent.QueryChanged]: onQueryChanged,
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
package/src/react/util.ts
CHANGED
|
@@ -24,10 +24,10 @@ export function getViewPropsAndListeners<
|
|
|
24
24
|
return Object.keys(props).reduce(
|
|
25
25
|
(accu, key) => {
|
|
26
26
|
if (key.startsWith('on')) {
|
|
27
|
-
const eventName = key.substr(2);
|
|
28
|
-
accu.listeners[EmbedEvent[eventName]] = props[key];
|
|
27
|
+
const eventName = key.substr(2) as any;
|
|
28
|
+
(accu.listeners as any)[EmbedEvent[eventName as keyof typeof EmbedEvent] as any] = props[key as keyof T];
|
|
29
29
|
} else {
|
|
30
|
-
accu.viewConfig[key] = props[key];
|
|
30
|
+
(accu.viewConfig as any)[key] = props[key as keyof T];
|
|
31
31
|
}
|
|
32
32
|
return accu;
|
|
33
33
|
},
|