@thoughtspot/visual-embed-sdk 1.48.0 → 1.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/package.json +1 -1
- package/cjs/src/css-variables.d.ts +140 -0
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/app.d.ts +62 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +57 -6
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +191 -1
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/auto-frame-renderer.js +7 -2
- package/cjs/src/embed/auto-frame-renderer.js.map +1 -1
- package/cjs/src/embed/auto-frame-renderer.spec.js +385 -6
- package/cjs/src/embed/auto-frame-renderer.spec.js.map +1 -1
- package/cjs/src/embed/base.d.ts +1 -0
- package/cjs/src/embed/base.d.ts.map +1 -1
- package/cjs/src/embed/base.js +13 -1
- package/cjs/src/embed/base.js.map +1 -1
- package/cjs/src/embed/base.spec.js +21 -0
- package/cjs/src/embed/base.spec.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.spec.js +86 -0
- package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts +16 -1
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +5 -1
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +26 -0
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +47 -1
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +47 -6
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +129 -1
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.d.ts +85 -0
- package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -0
- package/cjs/src/embed/spotter-viz-utils.js +17 -0
- package/cjs/src/embed/spotter-viz-utils.js.map +1 -0
- package/cjs/src/embed/spotter-viz-utils.spec.d.ts +2 -0
- package/cjs/src/embed/spotter-viz-utils.spec.d.ts.map +1 -0
- package/cjs/src/embed/spotter-viz-utils.spec.js +31 -0
- package/cjs/src/embed/spotter-viz-utils.spec.js.map +1 -0
- package/cjs/src/embed/ts-embed.d.ts +58 -38
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +247 -151
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +369 -123
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/index.d.ts +2 -1
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/mixpanel-service.js +2 -2
- package/cjs/src/mixpanel-service.js.map +1 -1
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +3 -0
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/types.d.ts +267 -27
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +223 -19
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/authService/tokenizedAuthService.spec.js +6 -7
- package/cjs/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
- package/cjs/src/utils/logger.js +2 -1
- package/cjs/src/utils/logger.js.map +1 -1
- package/cjs/src/utils/logger.spec.d.ts +1 -0
- package/cjs/src/utils/logger.spec.d.ts.map +1 -1
- package/cjs/src/utils/logger.spec.js +10 -9
- package/cjs/src/utils/logger.spec.js.map +1 -1
- package/cjs/src/utils/sdk-version.d.ts +2 -0
- package/cjs/src/utils/sdk-version.d.ts.map +1 -0
- package/cjs/src/utils/sdk-version.js +7 -0
- package/cjs/src/utils/sdk-version.js.map +1 -0
- package/cjs/src/utils.d.ts +4 -1
- package/cjs/src/utils.d.ts.map +1 -1
- package/cjs/src/utils.js +107 -10
- package/cjs/src/utils.js.map +1 -1
- package/cjs/src/utils.spec.js +163 -4
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/{index-Ck-r09gt.js → index-B6Rn561t.js} +1 -1
- package/dist/src/css-variables.d.ts +140 -0
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts +62 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts +1 -0
- package/dist/src/embed/base.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts +16 -1
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +47 -1
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/spotter-viz-utils.d.ts +85 -0
- package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -0
- package/dist/src/embed/spotter-viz-utils.spec.d.ts +2 -0
- package/dist/src/embed/spotter-viz-utils.spec.d.ts.map +1 -0
- package/dist/src/embed/ts-embed.d.ts +58 -38
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +267 -27
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/logger.spec.d.ts +1 -0
- package/dist/src/utils/logger.spec.d.ts.map +1 -1
- package/dist/src/utils/sdk-version.d.ts +2 -0
- package/dist/src/utils/sdk-version.d.ts.map +1 -0
- package/dist/src/utils.d.ts +4 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +3710 -3226
- package/dist/tsembed-react.js +3360 -2876
- package/dist/tsembed.es.js +3715 -3229
- package/dist/tsembed.js +3710 -3224
- package/dist/visual-embed-sdk-react-full.d.ts +643 -63
- package/dist/visual-embed-sdk-react.d.ts +643 -63
- package/dist/visual-embed-sdk.d.ts +658 -65
- package/lib/package.json +1 -1
- package/lib/src/css-variables.d.ts +140 -0
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/app.d.ts +62 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +58 -7
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +192 -2
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/auto-frame-renderer.js +7 -2
- package/lib/src/embed/auto-frame-renderer.js.map +1 -1
- package/lib/src/embed/auto-frame-renderer.spec.js +387 -8
- package/lib/src/embed/auto-frame-renderer.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts +1 -0
- package/lib/src/embed/base.d.ts.map +1 -1
- package/lib/src/embed/base.js +11 -0
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/base.spec.js +22 -1
- package/lib/src/embed/base.spec.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.spec.js +86 -0
- package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/lib/src/embed/conversation.d.ts +16 -1
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js +5 -1
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +27 -1
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +47 -1
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +48 -7
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +129 -1
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/spotter-viz-utils.d.ts +85 -0
- package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -0
- package/lib/src/embed/spotter-viz-utils.js +13 -0
- package/lib/src/embed/spotter-viz-utils.js.map +1 -0
- package/lib/src/embed/spotter-viz-utils.spec.d.ts +2 -0
- package/lib/src/embed/spotter-viz-utils.spec.d.ts.map +1 -0
- package/lib/src/embed/spotter-viz-utils.spec.js +29 -0
- package/lib/src/embed/spotter-viz-utils.spec.js.map +1 -0
- package/lib/src/embed/ts-embed.d.ts +58 -38
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +249 -153
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +369 -123
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/index.d.ts +2 -1
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js.map +1 -1
- package/lib/src/mixpanel-service.js +1 -1
- package/lib/src/mixpanel-service.js.map +1 -1
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +3 -0
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/types.d.ts +267 -27
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +223 -19
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/authService/tokenizedAuthService.spec.js +6 -7
- package/lib/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
- package/lib/src/utils/logger.js +2 -1
- package/lib/src/utils/logger.js.map +1 -1
- package/lib/src/utils/logger.spec.d.ts +1 -0
- package/lib/src/utils/logger.spec.d.ts.map +1 -1
- package/lib/src/utils/logger.spec.js +10 -9
- package/lib/src/utils/logger.spec.js.map +1 -1
- package/lib/src/utils/sdk-version.d.ts +2 -0
- package/lib/src/utils/sdk-version.d.ts.map +1 -0
- package/lib/src/utils/sdk-version.js +3 -0
- package/lib/src/utils/sdk-version.js.map +1 -0
- package/lib/src/utils.d.ts +4 -1
- package/lib/src/utils.d.ts.map +1 -1
- package/lib/src/utils.js +103 -9
- package/lib/src/utils.js.map +1 -1
- package/lib/src/utils.spec.js +164 -5
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +658 -65
- package/package.json +1 -1
- package/src/css-variables.ts +175 -1
- package/src/embed/app.spec.ts +247 -3
- package/src/embed/app.ts +125 -5
- package/src/embed/auto-frame-renderer.spec.ts +457 -58
- package/src/embed/auto-frame-renderer.ts +7 -2
- package/src/embed/base.spec.ts +25 -1
- package/src/embed/base.ts +19 -5
- package/src/embed/bodyless-conversation.spec.ts +93 -0
- package/src/embed/conversation.spec.ts +34 -0
- package/src/embed/conversation.ts +22 -1
- package/src/embed/liveboard.spec.ts +149 -1
- package/src/embed/liveboard.ts +102 -6
- package/src/embed/spotter-viz-utils.spec.ts +30 -0
- package/src/embed/spotter-viz-utils.ts +94 -0
- package/src/embed/ts-embed.spec.ts +532 -234
- package/src/embed/ts-embed.ts +384 -258
- package/src/index.ts +3 -0
- package/src/mixpanel-service.ts +1 -1
- package/src/react/index.tsx +3 -0
- package/src/types.ts +284 -23
- package/src/utils/authService/tokenizedAuthService.spec.ts +6 -6
- package/src/utils/logger.spec.ts +11 -9
- package/src/utils/logger.ts +2 -2
- package/src/utils/sdk-version.ts +3 -0
- package/src/utils.spec.ts +200 -4
- package/src/utils.ts +128 -9
package/src/embed/ts-embed.ts
CHANGED
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
removeStyleProperties,
|
|
36
36
|
isUndefined,
|
|
37
37
|
getHostEventsConfig,
|
|
38
|
+
getValueFromWindow,
|
|
38
39
|
} from '../utils';
|
|
39
40
|
import { getCustomActions } from '../utils/custom-actions';
|
|
40
41
|
import {
|
|
@@ -67,18 +68,27 @@ import {
|
|
|
67
68
|
} from '../types';
|
|
68
69
|
import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
|
|
69
70
|
import { processEventData, processAuthFailure } from '../utils/processData';
|
|
70
|
-
import { version } from '
|
|
71
|
+
import { version } from '../utils/sdk-version';
|
|
71
72
|
import {
|
|
72
|
-
getAuthPromise,
|
|
73
|
+
getAuthPromise,
|
|
74
|
+
renderInQueue,
|
|
75
|
+
handleAuth,
|
|
76
|
+
notifyAuthFailure,
|
|
73
77
|
getInitPromise,
|
|
74
78
|
getIsInitCalled,
|
|
79
|
+
getIsInitCompleted,
|
|
75
80
|
} from './base';
|
|
76
81
|
import { AuthFailureType } from '../auth';
|
|
77
82
|
import { getEmbedConfig } from './embedConfig';
|
|
78
83
|
import { ERROR_MESSAGE } from '../errors';
|
|
79
84
|
import { getPreauthInfo } from '../utils/sessionInfoService';
|
|
80
85
|
import { HostEventClient } from './hostEventClient/host-event-client';
|
|
81
|
-
import {
|
|
86
|
+
import {
|
|
87
|
+
getInterceptInitData,
|
|
88
|
+
handleInterceptEvent,
|
|
89
|
+
processApiInterceptResponse,
|
|
90
|
+
processLegacyInterceptResponse,
|
|
91
|
+
} from '../api-intercept';
|
|
82
92
|
|
|
83
93
|
/**
|
|
84
94
|
* Global prefix for all ThoughtSpot postHash Params.
|
|
@@ -111,7 +121,7 @@ export class TsEmbed {
|
|
|
111
121
|
/**
|
|
112
122
|
* The DOM node where the ThoughtSpot app is to be embedded.
|
|
113
123
|
*/
|
|
114
|
-
protected
|
|
124
|
+
protected hostElement: HTMLElement;
|
|
115
125
|
|
|
116
126
|
/**
|
|
117
127
|
* The key to store the embed instance in the DOM node
|
|
@@ -135,7 +145,11 @@ export class TsEmbed {
|
|
|
135
145
|
this.hostEventClient.setIframeElement(iFrame);
|
|
136
146
|
}
|
|
137
147
|
|
|
138
|
-
protected viewConfig: ViewConfig & {
|
|
148
|
+
protected viewConfig: ViewConfig & {
|
|
149
|
+
visibleTabs?: string[];
|
|
150
|
+
hiddenTabs?: string[];
|
|
151
|
+
showAlerts?: boolean;
|
|
152
|
+
};
|
|
139
153
|
|
|
140
154
|
protected embedConfig: EmbedConfig;
|
|
141
155
|
|
|
@@ -186,6 +200,7 @@ export class TsEmbed {
|
|
|
186
200
|
protected hostEventClient: HostEventClient;
|
|
187
201
|
|
|
188
202
|
protected isReadyForRenderPromise;
|
|
203
|
+
protected shouldWaitForRenderPromise: boolean;
|
|
189
204
|
|
|
190
205
|
/**
|
|
191
206
|
* Handler for fullscreen change events
|
|
@@ -193,7 +208,7 @@ export class TsEmbed {
|
|
|
193
208
|
private fullscreenChangeHandler: (() => void) | null = null;
|
|
194
209
|
|
|
195
210
|
constructor(domSelector: DOMSelector, viewConfig?: ViewConfig) {
|
|
196
|
-
this.
|
|
211
|
+
this.hostElement = getDOMNode(domSelector);
|
|
197
212
|
this.eventHandlerMap = new Map();
|
|
198
213
|
this.isError = false;
|
|
199
214
|
this.viewConfig = {
|
|
@@ -206,17 +221,42 @@ export class TsEmbed {
|
|
|
206
221
|
...viewConfig,
|
|
207
222
|
});
|
|
208
223
|
const embedConfig = getEmbedConfig();
|
|
209
|
-
|
|
210
|
-
|
|
224
|
+
if (embedConfig) {
|
|
225
|
+
this.embedConfig = embedConfig;
|
|
226
|
+
this.thoughtSpotHost = getThoughtSpotHost(embedConfig);
|
|
227
|
+
this.thoughtSpotV2Base = getV2BasePath(embedConfig);
|
|
228
|
+
}
|
|
211
229
|
this.hostEventClient = new HostEventClient(this.iFrame);
|
|
212
|
-
this.
|
|
213
|
-
|
|
230
|
+
this.shouldWaitForRenderPromise = !getIsInitCompleted();
|
|
231
|
+
const afterInit = () => {
|
|
232
|
+
// Prefer the config captured at construction time; fall back to
|
|
233
|
+
// getEmbedConfig() for the case where init()
|
|
234
|
+
// hadn't been called yet.
|
|
235
|
+
this.embedConfig = embedConfig ?? getEmbedConfig();
|
|
236
|
+
if (!this.embedConfig) {
|
|
237
|
+
logger.error('embedConfig unavailable in afterInit; init() may not have completed');
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (!this.embedConfig.authTriggerContainer && !this.embedConfig.useEventForSAMLPopup) {
|
|
214
241
|
this.embedConfig.authTriggerContainer = domSelector;
|
|
215
242
|
}
|
|
216
|
-
this.thoughtSpotHost = getThoughtSpotHost(embedConfig);
|
|
217
|
-
this.thoughtSpotV2Base = getV2BasePath(embedConfig);
|
|
218
|
-
this.shouldEncodeUrlQueryParams = embedConfig.shouldEncodeUrlQueryParams;
|
|
219
|
-
}
|
|
243
|
+
this.thoughtSpotHost = getThoughtSpotHost(this.embedConfig);
|
|
244
|
+
this.thoughtSpotV2Base = getV2BasePath(this.embedConfig);
|
|
245
|
+
this.shouldEncodeUrlQueryParams = this.embedConfig.shouldEncodeUrlQueryParams;
|
|
246
|
+
};
|
|
247
|
+
if (!this.shouldWaitForRenderPromise) {
|
|
248
|
+
afterInit();
|
|
249
|
+
} else {
|
|
250
|
+
this.isReadyForRenderPromise = getInitPromise()
|
|
251
|
+
.then(afterInit)
|
|
252
|
+
.catch((err) => {
|
|
253
|
+
logger.error('SDK init failed before embed could be configured', err);
|
|
254
|
+
this.throwInitError();
|
|
255
|
+
})
|
|
256
|
+
.finally(() => {
|
|
257
|
+
this.shouldWaitForRenderPromise = false;
|
|
258
|
+
});
|
|
259
|
+
}
|
|
220
260
|
}
|
|
221
261
|
|
|
222
262
|
/**
|
|
@@ -227,7 +267,7 @@ export class TsEmbed {
|
|
|
227
267
|
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
228
268
|
message: ERROR_MESSAGE.INIT_SDK_REQUIRED,
|
|
229
269
|
code: EmbedErrorCodes.INIT_ERROR,
|
|
230
|
-
error
|
|
270
|
+
error: ERROR_MESSAGE.INIT_SDK_REQUIRED,
|
|
231
271
|
});
|
|
232
272
|
}
|
|
233
273
|
|
|
@@ -248,7 +288,6 @@ export class TsEmbed {
|
|
|
248
288
|
* @param event The window message event
|
|
249
289
|
*/
|
|
250
290
|
private getEventType(event: MessageEvent) {
|
|
251
|
-
|
|
252
291
|
return event.data?.type || event.data?.__type;
|
|
253
292
|
}
|
|
254
293
|
|
|
@@ -278,11 +317,10 @@ export class TsEmbed {
|
|
|
278
317
|
// 3. FullAppEmbed has primary navbar visible since:
|
|
279
318
|
// - primary navbar requires fresh auth state for navigation
|
|
280
319
|
// - cached auth may not reflect current user permissions
|
|
281
|
-
const isDisabled =
|
|
282
|
-
this.viewConfig.overrideOrgId !== undefined
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
);
|
|
320
|
+
const isDisabled =
|
|
321
|
+
this.viewConfig.overrideOrgId !== undefined ||
|
|
322
|
+
this.embedConfig.disablePreauthCache === true ||
|
|
323
|
+
this.isFullAppEmbedWithVisiblePrimaryNavbar();
|
|
286
324
|
return !isDisabled;
|
|
287
325
|
}
|
|
288
326
|
|
|
@@ -296,8 +334,8 @@ export class TsEmbed {
|
|
|
296
334
|
// Check if this is a FullAppEmbed (AppEmbed)
|
|
297
335
|
// showPrimaryNavbar defaults to true if not explicitly set to false
|
|
298
336
|
return (
|
|
299
|
-
appViewConfig.embedComponentType === 'AppEmbed'
|
|
300
|
-
|
|
337
|
+
appViewConfig.embedComponentType === 'AppEmbed' &&
|
|
338
|
+
appViewConfig.showPrimaryNavbar === true
|
|
301
339
|
);
|
|
302
340
|
}
|
|
303
341
|
|
|
@@ -338,7 +376,7 @@ export class TsEmbed {
|
|
|
338
376
|
errorType: ErrorDetailsTypes.NETWORK,
|
|
339
377
|
message: ERROR_MESSAGE.OFFLINE_WARNING,
|
|
340
378
|
code: EmbedErrorCodes.NETWORK_ERROR,
|
|
341
|
-
offlineWarning
|
|
379
|
+
offlineWarning: ERROR_MESSAGE.OFFLINE_WARNING,
|
|
342
380
|
};
|
|
343
381
|
this.executeCallbacks(EmbedEvent.Error, errorDetails);
|
|
344
382
|
logger.warn(errorDetails);
|
|
@@ -349,15 +387,29 @@ export class TsEmbed {
|
|
|
349
387
|
this.subscribedListeners.offline = offlineEventListener;
|
|
350
388
|
}
|
|
351
389
|
|
|
352
|
-
private handleApiInterceptEvent({
|
|
390
|
+
private handleApiInterceptEvent({
|
|
391
|
+
eventData,
|
|
392
|
+
eventPort,
|
|
393
|
+
}: {
|
|
394
|
+
eventData: any;
|
|
395
|
+
eventPort: MessagePort | void;
|
|
396
|
+
}) {
|
|
353
397
|
const executeEvent = (_eventType: EmbedEvent, data: any) => {
|
|
354
398
|
this.executeCallbacks(_eventType, data, eventPort);
|
|
355
|
-
}
|
|
356
|
-
const getUnsavedAnswerTml = async (props: { sessionId?: string
|
|
357
|
-
const response = await this.triggerUIPassThrough(
|
|
399
|
+
};
|
|
400
|
+
const getUnsavedAnswerTml = async (props: { sessionId?: string; vizId?: string }) => {
|
|
401
|
+
const response = await this.triggerUIPassThrough(
|
|
402
|
+
UIPassthroughEvent.GetUnsavedAnswerTML,
|
|
403
|
+
props,
|
|
404
|
+
);
|
|
358
405
|
return response.filter((item) => item.value)?.[0]?.value;
|
|
359
|
-
}
|
|
360
|
-
handleInterceptEvent({
|
|
406
|
+
};
|
|
407
|
+
handleInterceptEvent({
|
|
408
|
+
eventData,
|
|
409
|
+
executeEvent,
|
|
410
|
+
viewConfig: this.viewConfig,
|
|
411
|
+
getUnsavedAnswerTml,
|
|
412
|
+
});
|
|
361
413
|
}
|
|
362
414
|
|
|
363
415
|
private messageEventListener = (event: MessageEvent<any>) => {
|
|
@@ -369,7 +421,7 @@ export class TsEmbed {
|
|
|
369
421
|
eventType,
|
|
370
422
|
eventData,
|
|
371
423
|
this.thoughtSpotHost,
|
|
372
|
-
this.isPreRendered ? this.preRenderWrapper : this.
|
|
424
|
+
this.isPreRendered ? this.preRenderWrapper : this.hostElement,
|
|
373
425
|
);
|
|
374
426
|
|
|
375
427
|
if (eventType === EmbedEvent.ApiIntercept) {
|
|
@@ -377,11 +429,7 @@ export class TsEmbed {
|
|
|
377
429
|
return;
|
|
378
430
|
}
|
|
379
431
|
|
|
380
|
-
this.executeCallbacks(
|
|
381
|
-
eventType,
|
|
382
|
-
processedEventData,
|
|
383
|
-
eventPort,
|
|
384
|
-
);
|
|
432
|
+
this.executeCallbacks(eventType, processedEventData, eventPort);
|
|
385
433
|
}
|
|
386
434
|
};
|
|
387
435
|
/**
|
|
@@ -394,7 +442,6 @@ export class TsEmbed {
|
|
|
394
442
|
|
|
395
443
|
this.subscribedListeners.message = this.messageEventListener;
|
|
396
444
|
}
|
|
397
|
-
|
|
398
445
|
|
|
399
446
|
/**
|
|
400
447
|
* Adds event listeners for both network and message events.
|
|
@@ -409,7 +456,6 @@ export class TsEmbed {
|
|
|
409
456
|
this.subscribeToMessageEvents();
|
|
410
457
|
}
|
|
411
458
|
|
|
412
|
-
|
|
413
459
|
private unsubscribeToNetworkEvents() {
|
|
414
460
|
if (this.subscribedListeners.online) {
|
|
415
461
|
window.removeEventListener('online', this.subscribedListeners.online);
|
|
@@ -441,7 +487,7 @@ export class TsEmbed {
|
|
|
441
487
|
try {
|
|
442
488
|
authToken = await getAuthenticationToken(this.embedConfig);
|
|
443
489
|
} catch (e) {
|
|
444
|
-
processAuthFailure(e, this.isPreRendered ? this.preRenderWrapper : this.
|
|
490
|
+
processAuthFailure(e, this.isPreRendered ? this.preRenderWrapper : this.hostElement);
|
|
445
491
|
throw e;
|
|
446
492
|
}
|
|
447
493
|
|
|
@@ -452,15 +498,18 @@ export class TsEmbed {
|
|
|
452
498
|
const authToken = await this.getAuthTokenForCookielessInit();
|
|
453
499
|
const customActionsResult = getCustomActions([
|
|
454
500
|
...(this.viewConfig.customActions || []),
|
|
455
|
-
...(this.embedConfig.customActions || [])
|
|
501
|
+
...(this.embedConfig.customActions || []),
|
|
456
502
|
]);
|
|
457
503
|
if (customActionsResult.errors.length > 0) {
|
|
458
504
|
this.handleError({
|
|
459
|
-
|
|
505
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
506
|
+
message: customActionsResult.errors,
|
|
507
|
+
code: EmbedErrorCodes.CUSTOM_ACTION_VALIDATION,
|
|
508
|
+
error: {
|
|
509
|
+
type: EmbedErrorCodes.CUSTOM_ACTION_VALIDATION,
|
|
460
510
|
message: customActionsResult.errors,
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
});
|
|
511
|
+
},
|
|
512
|
+
});
|
|
464
513
|
}
|
|
465
514
|
const baseInitData = {
|
|
466
515
|
customisations: getCustomisations(this.embedConfig, this.viewConfig),
|
|
@@ -521,11 +570,11 @@ export class TsEmbed {
|
|
|
521
570
|
private async refreshAuthTokenForCookieless(
|
|
522
571
|
responder: (data: any) => void,
|
|
523
572
|
eventType: EmbedEvent,
|
|
524
|
-
forceRefresh: boolean = false
|
|
573
|
+
forceRefresh: boolean = false,
|
|
525
574
|
): Promise<void> {
|
|
526
575
|
const { authType, autoLogin } = this.embedConfig;
|
|
527
|
-
const isAutoLoginTrue = autoLogin ??
|
|
528
|
-
|
|
576
|
+
const isAutoLoginTrue = autoLogin ?? authType === AuthType.TrustedAuthTokenCookieless;
|
|
577
|
+
|
|
529
578
|
if (isAutoLoginTrue && authType === AuthType.TrustedAuthTokenCookieless) {
|
|
530
579
|
const authToken = await getAuthenticationToken(this.embedConfig, forceRefresh);
|
|
531
580
|
responder({
|
|
@@ -537,21 +586,24 @@ export class TsEmbed {
|
|
|
537
586
|
|
|
538
587
|
private handleAuthFailure = (error: Error) => {
|
|
539
588
|
logger.error(`${ERROR_MESSAGE.INVALID_TOKEN_ERROR} Error : ${error?.message}`);
|
|
540
|
-
processAuthFailure(error, this.isPreRendered ? this.preRenderWrapper : this.
|
|
541
|
-
}
|
|
589
|
+
processAuthFailure(error, this.isPreRendered ? this.preRenderWrapper : this.hostElement);
|
|
590
|
+
};
|
|
542
591
|
|
|
543
592
|
/**
|
|
544
593
|
* Refresh the auth token if the autoLogin is true and the authType is TrustedAuthTokenCookieless
|
|
545
594
|
* @param _
|
|
546
595
|
* @param responder
|
|
547
596
|
*/
|
|
548
|
-
private tokenRefresh = async (
|
|
597
|
+
private tokenRefresh = async (
|
|
598
|
+
_: MessagePayload,
|
|
599
|
+
responder: (data: { type: EmbedEvent; data: { authToken: string } }) => void,
|
|
600
|
+
) => {
|
|
549
601
|
try {
|
|
550
602
|
await this.refreshAuthTokenForCookieless(responder, EmbedEvent.RefreshAuthToken, true);
|
|
551
603
|
} catch (e) {
|
|
552
604
|
this.handleAuthFailure(e);
|
|
553
605
|
}
|
|
554
|
-
}
|
|
606
|
+
};
|
|
555
607
|
|
|
556
608
|
/**
|
|
557
609
|
* Sends updated auth token to the iFrame to avoid user logout
|
|
@@ -562,14 +614,14 @@ export class TsEmbed {
|
|
|
562
614
|
const { authType, autoLogin: autoLoginConfig } = this.embedConfig;
|
|
563
615
|
// Default autoLogin: true for cookieless if undefined/null, otherwise
|
|
564
616
|
// false
|
|
565
|
-
const autoLogin = autoLoginConfig ??
|
|
566
|
-
|
|
617
|
+
const autoLogin = autoLoginConfig ?? authType === AuthType.TrustedAuthTokenCookieless;
|
|
618
|
+
|
|
567
619
|
try {
|
|
568
620
|
await this.refreshAuthTokenForCookieless(responder, EmbedEvent.AuthExpire, false);
|
|
569
621
|
} catch (e) {
|
|
570
622
|
this.handleAuthFailure(e);
|
|
571
623
|
}
|
|
572
|
-
|
|
624
|
+
|
|
573
625
|
if (autoLogin && authType !== AuthType.TrustedAuthTokenCookieless) {
|
|
574
626
|
handleAuth();
|
|
575
627
|
}
|
|
@@ -582,20 +634,22 @@ export class TsEmbed {
|
|
|
582
634
|
* @param responder
|
|
583
635
|
*/
|
|
584
636
|
private idleSessionTimeout = (_: any, responder: any) => {
|
|
585
|
-
handleAuth()
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
637
|
+
handleAuth()
|
|
638
|
+
.then(async () => {
|
|
639
|
+
let authToken = '';
|
|
640
|
+
try {
|
|
641
|
+
authToken = await getAuthenticationToken(this.embedConfig);
|
|
642
|
+
responder({
|
|
643
|
+
type: EmbedEvent.IdleSessionTimeout,
|
|
644
|
+
data: { authToken },
|
|
645
|
+
});
|
|
646
|
+
} catch (e) {
|
|
647
|
+
this.handleAuthFailure(e);
|
|
648
|
+
}
|
|
649
|
+
})
|
|
650
|
+
.catch((e) => {
|
|
651
|
+
logger.error(`Auto Login failed, Error : ${e?.message}`);
|
|
652
|
+
});
|
|
599
653
|
notifyAuthFailure(AuthFailureType.IDLE_SESSION_TIMEOUT);
|
|
600
654
|
};
|
|
601
655
|
|
|
@@ -607,9 +661,11 @@ export class TsEmbed {
|
|
|
607
661
|
this.on(EmbedEvent.AuthExpire, this.updateAuthToken, { start: false }, true);
|
|
608
662
|
this.on(EmbedEvent.IdleSessionTimeout, this.idleSessionTimeout, { start: false }, true);
|
|
609
663
|
|
|
610
|
-
const embedListenerReadyHandler = this.createEmbedContainerHandler(
|
|
664
|
+
const embedListenerReadyHandler = this.createEmbedContainerHandler(
|
|
665
|
+
EmbedEvent.EmbedListenerReady,
|
|
666
|
+
);
|
|
611
667
|
this.on(EmbedEvent.EmbedListenerReady, embedListenerReadyHandler, { start: false }, true);
|
|
612
|
-
|
|
668
|
+
|
|
613
669
|
const authInitHandler = this.createEmbedContainerHandler(EmbedEvent.AuthInit);
|
|
614
670
|
this.on(EmbedEvent.AuthInit, authInitHandler, { start: false }, true);
|
|
615
671
|
this.on(EmbedEvent.RefreshAuthToken, this.tokenRefresh, { start: false }, true);
|
|
@@ -637,7 +693,7 @@ export class TsEmbed {
|
|
|
637
693
|
let queryParams = this.getEmbedParamsObject();
|
|
638
694
|
const appInitData = await this.getAppInitData();
|
|
639
695
|
queryParams = { ...this.viewConfig, ...queryParams, ...appInitData };
|
|
640
|
-
|
|
696
|
+
|
|
641
697
|
return queryParams;
|
|
642
698
|
}
|
|
643
699
|
|
|
@@ -718,7 +774,7 @@ export class TsEmbed {
|
|
|
718
774
|
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
719
775
|
message: ERROR_MESSAGE.CONFLICTING_ACTIONS_CONFIG,
|
|
720
776
|
code: EmbedErrorCodes.CONFLICTING_ACTIONS_CONFIG,
|
|
721
|
-
error
|
|
777
|
+
error: ERROR_MESSAGE.CONFLICTING_ACTIONS_CONFIG,
|
|
722
778
|
});
|
|
723
779
|
return queryParams;
|
|
724
780
|
}
|
|
@@ -728,7 +784,7 @@ export class TsEmbed {
|
|
|
728
784
|
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
729
785
|
message: ERROR_MESSAGE.CONFLICTING_TABS_CONFIG,
|
|
730
786
|
code: EmbedErrorCodes.CONFLICTING_TABS_CONFIG,
|
|
731
|
-
error
|
|
787
|
+
error: ERROR_MESSAGE.CONFLICTING_TABS_CONFIG,
|
|
732
788
|
});
|
|
733
789
|
return queryParams;
|
|
734
790
|
}
|
|
@@ -774,8 +830,8 @@ export class TsEmbed {
|
|
|
774
830
|
queryParams[Param.IconSpriteUrl] = spriteUrl.replace('https://', '');
|
|
775
831
|
}
|
|
776
832
|
|
|
777
|
-
const stringIDsUrl =
|
|
778
|
-
|| embedCustomizations?.content?.stringIDsUrl;
|
|
833
|
+
const stringIDsUrl =
|
|
834
|
+
customizations?.content?.stringIDsUrl || embedCustomizations?.content?.stringIDsUrl;
|
|
779
835
|
if (stringIDsUrl) {
|
|
780
836
|
queryParams[Param.StringIDsUrl] = stringIDsUrl;
|
|
781
837
|
}
|
|
@@ -786,13 +842,10 @@ export class TsEmbed {
|
|
|
786
842
|
if (locale !== undefined) {
|
|
787
843
|
queryParams[Param.Locale] = locale;
|
|
788
844
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
if (enableLinkOverridesV2) {
|
|
845
|
+
|
|
846
|
+
if (!disableRedirectionLinksInNewTab && (enableLinkOverridesV2 || linkOverride)) {
|
|
792
847
|
queryParams[Param.EnableLinkOverridesV2] = true;
|
|
793
848
|
queryParams[Param.LinkOverride] = true;
|
|
794
|
-
} else if (linkOverride) {
|
|
795
|
-
queryParams[Param.LinkOverride] = linkOverride;
|
|
796
849
|
}
|
|
797
850
|
if (insertInToSlide) {
|
|
798
851
|
queryParams[Param.ShowInsertToSlide] = insertInToSlide;
|
|
@@ -889,8 +942,14 @@ export class TsEmbed {
|
|
|
889
942
|
return iFrame;
|
|
890
943
|
}
|
|
891
944
|
|
|
945
|
+
/**
|
|
946
|
+
* Returns true if this embed instance is configured for pre-rendering.
|
|
947
|
+
*/
|
|
948
|
+
protected isPreRenderEmbed() {
|
|
949
|
+
return !!this.viewConfig.preRenderId;
|
|
950
|
+
}
|
|
892
951
|
protected handleInsertionIntoDOM(child: string | Node): void {
|
|
893
|
-
if (this.
|
|
952
|
+
if (this.isPreRenderEmbed()) {
|
|
894
953
|
this.insertIntoDOMForPreRender(child);
|
|
895
954
|
} else {
|
|
896
955
|
this.insertIntoDOM(child);
|
|
@@ -898,6 +957,9 @@ export class TsEmbed {
|
|
|
898
957
|
if (this.insertedDomEl instanceof Node) {
|
|
899
958
|
(this.insertedDomEl as any)[this.embedNodeKey] = this;
|
|
900
959
|
}
|
|
960
|
+
if (this.preRenderWrapper) {
|
|
961
|
+
(this.preRenderWrapper as any)[this.embedNodeKey] = this;
|
|
962
|
+
}
|
|
901
963
|
}
|
|
902
964
|
|
|
903
965
|
/**
|
|
@@ -990,7 +1052,7 @@ export class TsEmbed {
|
|
|
990
1052
|
errorType: ErrorDetailsTypes.API,
|
|
991
1053
|
message: error.message || ERROR_MESSAGE.LOGIN_FAILED,
|
|
992
1054
|
code: EmbedErrorCodes.LOGIN_FAILED,
|
|
993
|
-
error
|
|
1055
|
+
error: error,
|
|
994
1056
|
});
|
|
995
1057
|
});
|
|
996
1058
|
});
|
|
@@ -1019,6 +1081,14 @@ export class TsEmbed {
|
|
|
1019
1081
|
|
|
1020
1082
|
protected preRenderChild: HTMLElement;
|
|
1021
1083
|
|
|
1084
|
+
/**
|
|
1085
|
+
* Checks for an existing pre-rendered component and connects to it.
|
|
1086
|
+
*
|
|
1087
|
+
* If a matching pre-rendered component is found in the DOM, this method
|
|
1088
|
+
* sets the internal properties of the embed object to reference it.
|
|
1089
|
+
*
|
|
1090
|
+
* @returns True if a connection was successfully established, false otherwise.
|
|
1091
|
+
*/
|
|
1022
1092
|
protected connectPreRendered(): boolean {
|
|
1023
1093
|
const preRenderIds = this.getPreRenderIds();
|
|
1024
1094
|
const preRenderWrapperElement = document.getElementById(preRenderIds.wrapper);
|
|
@@ -1031,19 +1101,14 @@ export class TsEmbed {
|
|
|
1031
1101
|
if (this.preRenderChild instanceof HTMLIFrameElement) {
|
|
1032
1102
|
this.setIframeElement(this.preRenderChild);
|
|
1033
1103
|
}
|
|
1034
|
-
this.insertedDomEl = this.preRenderWrapper;
|
|
1035
1104
|
this.isRendered = true;
|
|
1036
1105
|
}
|
|
1037
1106
|
|
|
1038
|
-
return this.
|
|
1107
|
+
return this.isPreRenderConnected();
|
|
1039
1108
|
}
|
|
1040
1109
|
|
|
1041
|
-
protected
|
|
1042
|
-
return (
|
|
1043
|
-
this.isRendered
|
|
1044
|
-
&& this.isPreRendered
|
|
1045
|
-
&& Boolean(this.preRenderWrapper && this.preRenderChild)
|
|
1046
|
-
);
|
|
1110
|
+
protected isPreRenderConnected(): boolean {
|
|
1111
|
+
return Boolean(this.preRenderWrapper && this.preRenderChild);
|
|
1047
1112
|
}
|
|
1048
1113
|
|
|
1049
1114
|
protected createPreRenderChild(child: string | Node): HTMLElement {
|
|
@@ -1069,6 +1134,24 @@ export class TsEmbed {
|
|
|
1069
1134
|
return divChildNode;
|
|
1070
1135
|
}
|
|
1071
1136
|
|
|
1137
|
+
/**
|
|
1138
|
+
* Creates the in-flow placeholder div inserted into the host element when
|
|
1139
|
+
* showPreRender() is called. The wrapper observes this element to stay
|
|
1140
|
+
* aligned with the host layout.
|
|
1141
|
+
*/
|
|
1142
|
+
private createPreRenderPlaceholder(): HTMLDivElement {
|
|
1143
|
+
const placeholder = document.createElement('div');
|
|
1144
|
+
const id = this.getPreRenderIds();
|
|
1145
|
+
const { width: frameWidth, height: frameHeight } = this.viewConfig.frameParams || {};
|
|
1146
|
+
const width = getCssDimension(frameWidth || DEFAULT_EMBED_WIDTH);
|
|
1147
|
+
const height = getCssDimension(frameHeight || DEFAULT_EMBED_HEIGHT);
|
|
1148
|
+
placeholder.style.width = width;
|
|
1149
|
+
placeholder.style.height = height;
|
|
1150
|
+
// we can improve this , lol
|
|
1151
|
+
placeholder.id = id.placeHolder;
|
|
1152
|
+
return placeholder;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1072
1155
|
protected insertIntoDOMForPreRender(child: string | Node): void {
|
|
1073
1156
|
const preRenderChild = this.createPreRenderChild(child);
|
|
1074
1157
|
const preRenderWrapper = this.createPreRenderWrapper();
|
|
@@ -1080,7 +1163,11 @@ export class TsEmbed {
|
|
|
1080
1163
|
if (preRenderChild instanceof HTMLIFrameElement) {
|
|
1081
1164
|
this.setIframeElement(preRenderChild);
|
|
1082
1165
|
}
|
|
1083
|
-
|
|
1166
|
+
|
|
1167
|
+
if (this.iFrame) {
|
|
1168
|
+
this.iFrame.style.height = '100%';
|
|
1169
|
+
this.iFrame.style.width = '100%';
|
|
1170
|
+
}
|
|
1084
1171
|
|
|
1085
1172
|
if (this.showPreRenderByDefault) {
|
|
1086
1173
|
this.showPreRender();
|
|
@@ -1102,17 +1189,17 @@ export class TsEmbed {
|
|
|
1102
1189
|
|
|
1103
1190
|
child = div;
|
|
1104
1191
|
}
|
|
1105
|
-
if (this.
|
|
1106
|
-
this.
|
|
1192
|
+
if (this.hostElement.nextElementSibling?.id === TS_EMBED_ID) {
|
|
1193
|
+
this.hostElement.nextElementSibling.remove();
|
|
1107
1194
|
}
|
|
1108
|
-
this.
|
|
1195
|
+
this.hostElement.parentElement.insertBefore(child, this.hostElement.nextSibling);
|
|
1109
1196
|
this.insertedDomEl = child;
|
|
1110
1197
|
} else if (typeof child === 'string') {
|
|
1111
|
-
this.
|
|
1112
|
-
this.insertedDomEl = this.
|
|
1198
|
+
this.hostElement.innerHTML = child;
|
|
1199
|
+
this.insertedDomEl = this.hostElement.children[0];
|
|
1113
1200
|
} else {
|
|
1114
|
-
this.
|
|
1115
|
-
this.
|
|
1201
|
+
this.hostElement.innerHTML = '';
|
|
1202
|
+
this.hostElement.appendChild(child);
|
|
1116
1203
|
this.insertedDomEl = child;
|
|
1117
1204
|
}
|
|
1118
1205
|
}
|
|
@@ -1122,7 +1209,16 @@ export class TsEmbed {
|
|
|
1122
1209
|
* @param height The height in pixels
|
|
1123
1210
|
*/
|
|
1124
1211
|
protected setIFrameHeight(height: number | string): void {
|
|
1125
|
-
this.
|
|
1212
|
+
if (this.isPreRendered) {
|
|
1213
|
+
if (this.insertedDomEl) {
|
|
1214
|
+
(this.insertedDomEl as HTMLElement).style.height = getCssDimension(height);
|
|
1215
|
+
} else if (this.preRenderWrapper) {
|
|
1216
|
+
this.preRenderWrapper.style.height = getCssDimension(height);
|
|
1217
|
+
}
|
|
1218
|
+
} else {
|
|
1219
|
+
// normal (non-preRender) mode: size the iframe directly
|
|
1220
|
+
this.iFrame.style.height = getCssDimension(height);
|
|
1221
|
+
}
|
|
1126
1222
|
}
|
|
1127
1223
|
|
|
1128
1224
|
/**
|
|
@@ -1130,10 +1226,12 @@ export class TsEmbed {
|
|
|
1130
1226
|
* Embed event handler -> responder -> createEmbedEventResponder -> send response
|
|
1131
1227
|
* @param eventPort The event port for a specific MessageChannel
|
|
1132
1228
|
* @param eventType The event type
|
|
1133
|
-
* @returns
|
|
1229
|
+
* @returns
|
|
1134
1230
|
*/
|
|
1135
|
-
protected createEmbedEventResponder = (
|
|
1136
|
-
|
|
1231
|
+
protected createEmbedEventResponder = (
|
|
1232
|
+
eventPort: MessagePort | void,
|
|
1233
|
+
eventType: EmbedEvent,
|
|
1234
|
+
) => {
|
|
1137
1235
|
const getPayloadToSend = (payload: any) => {
|
|
1138
1236
|
if (eventType === EmbedEvent.OnBeforeGetVizDataIntercept) {
|
|
1139
1237
|
return processLegacyInterceptResponse(payload);
|
|
@@ -1142,25 +1240,26 @@ export class TsEmbed {
|
|
|
1142
1240
|
return processApiInterceptResponse(payload);
|
|
1143
1241
|
}
|
|
1144
1242
|
return payload;
|
|
1145
|
-
}
|
|
1243
|
+
};
|
|
1146
1244
|
return (payload: any) => {
|
|
1147
1245
|
const payloadToSend = getPayloadToSend(payload);
|
|
1148
1246
|
this.triggerEventOnPort(eventPort, payloadToSend);
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1247
|
+
};
|
|
1248
|
+
};
|
|
1151
1249
|
|
|
1152
|
-
private shouldSkipEvent(eventType: EmbedEvent, data: any): boolean {
|
|
1153
|
-
const errorType = data?.errorType ?? data?.data?.code;
|
|
1154
|
-
if (
|
|
1155
|
-
eventType === EmbedEvent.Error
|
|
1156
|
-
|
|
1157
|
-
|
|
1250
|
+
private shouldSkipEvent(eventType: EmbedEvent, data: any): boolean {
|
|
1251
|
+
const errorType = data?.errorType ?? data?.data?.code;
|
|
1252
|
+
if (
|
|
1253
|
+
eventType === EmbedEvent.Error &&
|
|
1254
|
+
errorType === EmbedErrorCodes.HOST_EVENT_VALIDATION &&
|
|
1255
|
+
(!getHostEventsConfig(this.viewConfig).useHostEventsV2 ||
|
|
1256
|
+
getHostEventsConfig(this.viewConfig).shouldBypassPayloadValidation)
|
|
1158
1257
|
) {
|
|
1159
1258
|
logger.warn(`Host Event Validation failed: ${data?.data?.message}`);
|
|
1160
|
-
return true;
|
|
1161
|
-
}
|
|
1259
|
+
return true;
|
|
1260
|
+
}
|
|
1162
1261
|
return false;
|
|
1163
|
-
}
|
|
1262
|
+
}
|
|
1164
1263
|
/**
|
|
1165
1264
|
* Executes all registered event handlers for a particular event type
|
|
1166
1265
|
* @param eventType The event type
|
|
@@ -1181,10 +1280,10 @@ export class TsEmbed {
|
|
|
1181
1280
|
if (
|
|
1182
1281
|
// When start status is true it trigger only start releated
|
|
1183
1282
|
// payload
|
|
1184
|
-
(callbackObj.options.start && dataStatus === embedEventStatus.START)
|
|
1283
|
+
(callbackObj.options.start && dataStatus === embedEventStatus.START) ||
|
|
1185
1284
|
// When start status is false it trigger only end releated
|
|
1186
1285
|
// payload
|
|
1187
|
-
|
|
1286
|
+
(!callbackObj.options.start && dataStatus === embedEventStatus.END)
|
|
1188
1287
|
) {
|
|
1189
1288
|
const responder = this.createEmbedEventResponder(eventPort, eventType);
|
|
1190
1289
|
callbackObj.callback(data, responder);
|
|
@@ -1330,22 +1429,22 @@ export class TsEmbed {
|
|
|
1330
1429
|
}
|
|
1331
1430
|
|
|
1332
1431
|
/**
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1432
|
+
* @hidden
|
|
1433
|
+
* Internal state to track if the embed container is loaded.
|
|
1434
|
+
* This is used to trigger events after the embed container is loaded.
|
|
1435
|
+
*/
|
|
1337
1436
|
public isEmbedContainerLoaded = false;
|
|
1338
1437
|
|
|
1339
1438
|
/**
|
|
1340
1439
|
* @hidden
|
|
1341
|
-
* Internal state to track the callbacks to be executed after the embed container
|
|
1440
|
+
* Internal state to track the callbacks to be executed after the embed container
|
|
1342
1441
|
* is loaded.
|
|
1343
1442
|
* This is used to trigger events after the embed container is loaded.
|
|
1344
1443
|
*/
|
|
1345
1444
|
private embedContainerReadyCallbacks: Array<() => void> = [];
|
|
1346
1445
|
|
|
1347
1446
|
protected getPreRenderObj<T extends TsEmbed>(): T {
|
|
1348
|
-
const embedObj = (this.
|
|
1447
|
+
const embedObj = (this.preRenderWrapper as any)?.[this.embedNodeKey] as T;
|
|
1349
1448
|
if (embedObj === (this as any)) {
|
|
1350
1449
|
logger.info('embedObj is same as this');
|
|
1351
1450
|
}
|
|
@@ -1383,22 +1482,23 @@ export class TsEmbed {
|
|
|
1383
1482
|
}
|
|
1384
1483
|
}
|
|
1385
1484
|
|
|
1386
|
-
protected createEmbedContainerHandler =
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1485
|
+
protected createEmbedContainerHandler =
|
|
1486
|
+
(source: EmbedEvent.AuthInit | EmbedEvent.EmbedListenerReady) => () => {
|
|
1487
|
+
const processEmbedContainerReady = () => {
|
|
1488
|
+
logger.debug('processEmbedContainerReady');
|
|
1489
|
+
this.isEmbedContainerLoaded = true;
|
|
1490
|
+
this.executeEmbedContainerReadyCallbacks();
|
|
1491
|
+
};
|
|
1492
|
+
if (source === EmbedEvent.AuthInit) {
|
|
1493
|
+
const AUTH_INIT_FALLBACK_DELAY = 1000;
|
|
1494
|
+
// Wait for 1 second to ensure the embed container is loaded
|
|
1495
|
+
// This is a workaround to ensure the embed container is loaded
|
|
1496
|
+
// this is needed until all clusters have EmbedListenerReady event
|
|
1497
|
+
setTimeout(processEmbedContainerReady, AUTH_INIT_FALLBACK_DELAY);
|
|
1498
|
+
} else if (source === EmbedEvent.EmbedListenerReady) {
|
|
1499
|
+
processEmbedContainerReady();
|
|
1500
|
+
}
|
|
1501
|
+
};
|
|
1402
1502
|
|
|
1403
1503
|
/**
|
|
1404
1504
|
* Triggers an event to the embedded app
|
|
@@ -1447,7 +1547,7 @@ export class TsEmbed {
|
|
|
1447
1547
|
return null;
|
|
1448
1548
|
}
|
|
1449
1549
|
|
|
1450
|
-
// Check if iframe exists before triggering -
|
|
1550
|
+
// Check if iframe exists before triggering -
|
|
1451
1551
|
// this prevents the error when auth fails
|
|
1452
1552
|
if (!this.iFrame) {
|
|
1453
1553
|
logger.debug(
|
|
@@ -1457,21 +1557,30 @@ export class TsEmbed {
|
|
|
1457
1557
|
}
|
|
1458
1558
|
|
|
1459
1559
|
// send an empty object, this is needed for liveboard default handlers
|
|
1460
|
-
return this.hostEventClient.triggerHostEvent(messageType, data, context).catch(
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
}
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1560
|
+
return this.hostEventClient.triggerHostEvent(messageType, data, context).catch(
|
|
1561
|
+
(
|
|
1562
|
+
err: Error & {
|
|
1563
|
+
isValidationError?: boolean;
|
|
1564
|
+
embedErrorDetails?: {
|
|
1565
|
+
errorType: ErrorDetailsTypes;
|
|
1566
|
+
message: string;
|
|
1567
|
+
code: EmbedErrorCodes;
|
|
1568
|
+
error: string;
|
|
1569
|
+
};
|
|
1570
|
+
},
|
|
1571
|
+
): Promise<null> => {
|
|
1572
|
+
if (err?.isValidationError) {
|
|
1573
|
+
const errorDetails = err.embedErrorDetails ?? {
|
|
1574
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1575
|
+
message: err.message || ERROR_MESSAGE.UPDATEFILTERS_INVALID_PAYLOAD,
|
|
1576
|
+
code: EmbedErrorCodes.UPDATEFILTERS_INVALID_PAYLOAD,
|
|
1577
|
+
error: err.message,
|
|
1578
|
+
};
|
|
1579
|
+
this.handleError(errorDetails);
|
|
1580
|
+
}
|
|
1581
|
+
throw err;
|
|
1582
|
+
},
|
|
1583
|
+
);
|
|
1475
1584
|
}
|
|
1476
1585
|
|
|
1477
1586
|
/**
|
|
@@ -1499,7 +1608,7 @@ export class TsEmbed {
|
|
|
1499
1608
|
if (!getIsInitCalled()) {
|
|
1500
1609
|
logger.error(ERROR_MESSAGE.RENDER_CALLED_BEFORE_INIT);
|
|
1501
1610
|
}
|
|
1502
|
-
await this.isReadyForRenderPromise;
|
|
1611
|
+
if (this.shouldWaitForRenderPromise) await this.isReadyForRenderPromise;
|
|
1503
1612
|
this.isRendered = true;
|
|
1504
1613
|
|
|
1505
1614
|
return this;
|
|
@@ -1514,33 +1623,33 @@ export class TsEmbed {
|
|
|
1514
1623
|
}
|
|
1515
1624
|
|
|
1516
1625
|
/**
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1626
|
+
* Context object for the embedded component.
|
|
1627
|
+
* @returns {ContextObject} The current context object containing the page type and object ids.
|
|
1628
|
+
* @example
|
|
1629
|
+
* ```js
|
|
1630
|
+
* const context = await embed.getCurrentContext();
|
|
1631
|
+
* console.log(context);
|
|
1632
|
+
*
|
|
1633
|
+
* // Example output
|
|
1634
|
+
* {
|
|
1635
|
+
* stack: [
|
|
1636
|
+
* {
|
|
1637
|
+
* name: 'Liveboard',
|
|
1638
|
+
* type: ContextType.Liveboard,
|
|
1639
|
+
* objectIds: {
|
|
1640
|
+
* liveboardId: '123',
|
|
1641
|
+
* },
|
|
1642
|
+
* },
|
|
1643
|
+
* ],
|
|
1644
|
+
* currentContext: {
|
|
1645
|
+
* name: 'Liveboard',
|
|
1646
|
+
* type: ContextType.Liveboard,
|
|
1647
|
+
* objectIds: {
|
|
1648
|
+
* liveboardId: '123',
|
|
1649
|
+
* },
|
|
1650
|
+
* },
|
|
1651
|
+
* }
|
|
1652
|
+
* ```
|
|
1544
1653
|
* @version SDK: 1.45.2 | ThoughtSpot: 26.3.0.cl
|
|
1545
1654
|
*/
|
|
1546
1655
|
public async getCurrentContext(): Promise<ContextObject> {
|
|
@@ -1560,7 +1669,7 @@ export class TsEmbed {
|
|
|
1560
1669
|
*
|
|
1561
1670
|
* @param eventName - The host or action event to generate the subscribed event name for.
|
|
1562
1671
|
* @returns The formatted event name (e.g., "Save Subscribed").
|
|
1563
|
-
*
|
|
1672
|
+
*
|
|
1564
1673
|
* @version SDK: 1.47.2 | ThoughtSpot: 26.3.0.cl
|
|
1565
1674
|
*/
|
|
1566
1675
|
public subscribedEvent(eventName: HostEvent | Action): string {
|
|
@@ -1572,7 +1681,10 @@ export class TsEmbed {
|
|
|
1572
1681
|
* @param showPreRenderByDefault - Show the preRender after render, hidden by default
|
|
1573
1682
|
*/
|
|
1574
1683
|
|
|
1575
|
-
public async preRender(
|
|
1684
|
+
public async preRender(
|
|
1685
|
+
showPreRenderByDefault = false,
|
|
1686
|
+
replaceExistingPreRender = false,
|
|
1687
|
+
): Promise<TsEmbed> {
|
|
1576
1688
|
if (!this.viewConfig.preRenderId) {
|
|
1577
1689
|
logger.error(ERROR_MESSAGE.PRERENDER_ID_MISSING);
|
|
1578
1690
|
return this;
|
|
@@ -1582,6 +1694,9 @@ export class TsEmbed {
|
|
|
1582
1694
|
|
|
1583
1695
|
const isAlreadyRendered = this.connectPreRendered();
|
|
1584
1696
|
if (isAlreadyRendered && !replaceExistingPreRender) {
|
|
1697
|
+
if (this.showPreRenderByDefault) {
|
|
1698
|
+
this.showPreRender();
|
|
1699
|
+
}
|
|
1585
1700
|
return this;
|
|
1586
1701
|
}
|
|
1587
1702
|
|
|
@@ -1628,26 +1743,29 @@ export class TsEmbed {
|
|
|
1628
1743
|
try {
|
|
1629
1744
|
this.removeFullscreenChangeHandler();
|
|
1630
1745
|
this.unsubscribeToEvents();
|
|
1746
|
+
this.preRenderWrapper?.remove();
|
|
1631
1747
|
if (!this.isRendered) {
|
|
1632
1748
|
return;
|
|
1633
1749
|
}
|
|
1634
1750
|
if (!getEmbedConfig().waitForCleanupOnDestroy) {
|
|
1635
|
-
this.trigger(HostEvent.DestroyEmbed)
|
|
1751
|
+
this.trigger(HostEvent.DestroyEmbed);
|
|
1636
1752
|
this.insertedDomEl?.parentNode?.removeChild(this.insertedDomEl);
|
|
1637
1753
|
} else {
|
|
1638
1754
|
const cleanupTimeout = getEmbedConfig().cleanupTimeout;
|
|
1639
1755
|
Promise.race([
|
|
1640
1756
|
this.trigger(HostEvent.DestroyEmbed),
|
|
1641
1757
|
new Promise((resolve) => setTimeout(resolve, cleanupTimeout)),
|
|
1642
|
-
])
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1758
|
+
])
|
|
1759
|
+
.catch((e) => {
|
|
1760
|
+
logger.log('Error destroying TS Embed', e);
|
|
1761
|
+
})
|
|
1762
|
+
.finally(() => {
|
|
1763
|
+
try {
|
|
1764
|
+
this.insertedDomEl?.parentNode?.removeChild(this.insertedDomEl);
|
|
1765
|
+
} catch (e) {
|
|
1766
|
+
logger.log('Error removing DOM element on destroy', e);
|
|
1767
|
+
}
|
|
1768
|
+
});
|
|
1651
1769
|
}
|
|
1652
1770
|
} catch (e) {
|
|
1653
1771
|
logger.log('Error destroying TS Embed', e);
|
|
@@ -1669,7 +1787,7 @@ export class TsEmbed {
|
|
|
1669
1787
|
if (!getIsInitCalled()) {
|
|
1670
1788
|
logger.error(ERROR_MESSAGE.RENDER_CALLED_BEFORE_INIT);
|
|
1671
1789
|
}
|
|
1672
|
-
await this.isReadyForRenderPromise;
|
|
1790
|
+
if (this.shouldWaitForRenderPromise) await this.isReadyForRenderPromise;
|
|
1673
1791
|
|
|
1674
1792
|
const prerenderFrameSrc = this.getRootIframeSrc();
|
|
1675
1793
|
this.isRendered = true;
|
|
@@ -1677,80 +1795,72 @@ export class TsEmbed {
|
|
|
1677
1795
|
}
|
|
1678
1796
|
|
|
1679
1797
|
protected beforePrerenderVisible(): void {
|
|
1680
|
-
//
|
|
1798
|
+
// We can ignore this as its a bit expensive and the newer customers
|
|
1799
|
+
// have moved on to UpdateEmbedParams supported clusters
|
|
1800
|
+
// this.validatePreRenderViewConfig(this.viewConfig); removed in #517
|
|
1801
|
+
logger.debug('triggering UpdateEmbedParams', this.viewConfig);
|
|
1802
|
+
this.executeAfterEmbedContainerLoaded(async () => {
|
|
1803
|
+
try {
|
|
1804
|
+
const params = await this.getUpdateEmbedParamsObject();
|
|
1805
|
+
this.trigger(HostEvent.UpdateEmbedParams, params);
|
|
1806
|
+
} catch (error) {
|
|
1807
|
+
logger.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
|
|
1808
|
+
this.handleError({
|
|
1809
|
+
errorType: ErrorDetailsTypes.API,
|
|
1810
|
+
message: error?.message || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
|
|
1811
|
+
code: EmbedErrorCodes.UPDATE_PARAMS_FAILED,
|
|
1812
|
+
error: error?.message || error,
|
|
1813
|
+
});
|
|
1814
|
+
}
|
|
1815
|
+
});
|
|
1681
1816
|
}
|
|
1682
1817
|
|
|
1683
|
-
private validatePreRenderViewConfig = (viewConfig: ViewConfig) => {
|
|
1684
|
-
const preRenderAllowedKeys = ['preRenderId', 'vizId', 'liveboardId'];
|
|
1685
|
-
const preRenderedObject = (this.insertedDomEl as any)?.[this.embedNodeKey] as TsEmbed;
|
|
1686
|
-
if (!preRenderedObject) return;
|
|
1687
|
-
if (viewConfig.preRenderId) {
|
|
1688
|
-
const allOtherKeys = Object.keys(viewConfig).filter(
|
|
1689
|
-
(key) => !preRenderAllowedKeys.includes(key) && !key.startsWith('on'),
|
|
1690
|
-
);
|
|
1691
|
-
|
|
1692
|
-
allOtherKeys.forEach((key: keyof ViewConfig) => {
|
|
1693
|
-
if (
|
|
1694
|
-
!isUndefined(viewConfig[key])
|
|
1695
|
-
&& !isEqual(viewConfig[key], preRenderedObject.viewConfig[key])
|
|
1696
|
-
) {
|
|
1697
|
-
logger.warn(
|
|
1698
|
-
`${viewConfig.embedComponentType || 'Component'} was pre-rendered with `
|
|
1699
|
-
+ `"${key}" as "${JSON.stringify(preRenderedObject.viewConfig[key])}" `
|
|
1700
|
-
+ `but a different value "${JSON.stringify(viewConfig[key])}" `
|
|
1701
|
-
+ 'was passed to the Embed component. '
|
|
1702
|
-
+ 'The new value provided is ignored, the value provided during '
|
|
1703
|
-
+ 'preRender is used.',
|
|
1704
|
-
);
|
|
1705
|
-
}
|
|
1706
|
-
});
|
|
1707
|
-
}
|
|
1708
|
-
};
|
|
1709
|
-
|
|
1710
1818
|
/**
|
|
1711
|
-
* Displays the
|
|
1712
|
-
* If the component
|
|
1713
|
-
*
|
|
1714
|
-
*
|
|
1819
|
+
* Displays the pre-rendered component inside the host element.
|
|
1820
|
+
* If the component has not been pre-rendered yet, it initiates rendering first.
|
|
1821
|
+
* Inserts a placeholder element into the host and positions the pre-render
|
|
1822
|
+
* wrapper to overlay it.
|
|
1715
1823
|
*/
|
|
1716
1824
|
public async showPreRender(): Promise<TsEmbed> {
|
|
1825
|
+
if (this.shouldWaitForRenderPromise) await this.isReadyForRenderPromise;
|
|
1826
|
+
|
|
1717
1827
|
if (!this.viewConfig.preRenderId) {
|
|
1718
1828
|
logger.error(ERROR_MESSAGE.PRERENDER_ID_MISSING);
|
|
1719
1829
|
return this;
|
|
1720
1830
|
}
|
|
1721
|
-
if (!this.
|
|
1722
|
-
|
|
1831
|
+
if (!this.isPreRenderConnected()) {
|
|
1832
|
+
// this will call showPreRender down the line
|
|
1833
|
+
return this.preRender(true);
|
|
1834
|
+
}
|
|
1835
|
+
this.isRendered = true;
|
|
1836
|
+
this.beforePrerenderVisible();
|
|
1723
1837
|
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
const params = await this.getUpdateEmbedParamsObject();
|
|
1733
|
-
this.trigger(HostEvent.UpdateEmbedParams, params);
|
|
1734
|
-
} catch (error) {
|
|
1735
|
-
logger.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
|
|
1736
|
-
this.handleError({
|
|
1737
|
-
errorType: ErrorDetailsTypes.API,
|
|
1738
|
-
message: error?.message || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
|
|
1739
|
-
code: EmbedErrorCodes.UPDATE_PARAMS_FAILED,
|
|
1740
|
-
error: error?.message || error,
|
|
1741
|
-
});
|
|
1838
|
+
if (this.hostElement) {
|
|
1839
|
+
this.insertedDomEl = this.createPreRenderPlaceholder();
|
|
1840
|
+
if ((this.viewConfig as { fullHeight: boolean }).fullHeight) {
|
|
1841
|
+
// If fullHeight has already sized the wrapper, seed the placeholder
|
|
1842
|
+
// with the same height so syncPreRenderStyle gets an accurate rect.
|
|
1843
|
+
const existingHeight = this.preRenderWrapper.style.height;
|
|
1844
|
+
if (existingHeight) {
|
|
1845
|
+
(this.insertedDomEl as HTMLDivElement).style.height = existingHeight;
|
|
1742
1846
|
}
|
|
1743
|
-
}
|
|
1744
|
-
}
|
|
1847
|
+
}
|
|
1745
1848
|
|
|
1746
|
-
|
|
1849
|
+
const placeHolderId = this.getPreRenderIds().placeHolder;
|
|
1850
|
+
const oldEle = this.hostElement.querySelector(`#${placeHolderId}`);
|
|
1851
|
+
if (oldEle) {
|
|
1852
|
+
this.hostElement.removeChild(oldEle);
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
this.hostElement.appendChild(this.insertedDomEl);
|
|
1747
1856
|
|
|
1748
|
-
if (this.el) {
|
|
1749
1857
|
this.syncPreRenderStyle();
|
|
1858
|
+
|
|
1750
1859
|
if (!this.viewConfig.doNotTrackPreRenderSize) {
|
|
1860
|
+
const observeTarget = (this.insertedDomEl as HTMLElement) ?? this.hostElement;
|
|
1751
1861
|
this.resizeObserver = new ResizeObserver((entries) => {
|
|
1752
1862
|
entries.forEach((entry) => {
|
|
1753
|
-
if (entry.contentRect && entry.target ===
|
|
1863
|
+
if (entry.contentRect && entry.target === observeTarget) {
|
|
1754
1864
|
setStyleProperties(this.preRenderWrapper, {
|
|
1755
1865
|
width: `${entry.contentRect.width}px`,
|
|
1756
1866
|
height: `${entry.contentRect.height}px`,
|
|
@@ -1758,12 +1868,16 @@ export class TsEmbed {
|
|
|
1758
1868
|
}
|
|
1759
1869
|
});
|
|
1760
1870
|
});
|
|
1761
|
-
this.resizeObserver.observe(
|
|
1871
|
+
this.resizeObserver.observe(observeTarget);
|
|
1762
1872
|
}
|
|
1763
1873
|
}
|
|
1764
1874
|
|
|
1765
|
-
removeStyleProperties(this.preRenderWrapper, [
|
|
1766
|
-
|
|
1875
|
+
removeStyleProperties(this.preRenderWrapper, [
|
|
1876
|
+
'z-index',
|
|
1877
|
+
'opacity',
|
|
1878
|
+
'pointer-events',
|
|
1879
|
+
'overflow',
|
|
1880
|
+
]);
|
|
1767
1881
|
this.subscribeToEvents();
|
|
1768
1882
|
|
|
1769
1883
|
// Setup fullscreen change handler for prerendered components
|
|
@@ -1774,6 +1888,10 @@ export class TsEmbed {
|
|
|
1774
1888
|
return this;
|
|
1775
1889
|
}
|
|
1776
1890
|
|
|
1891
|
+
protected getPreRenderPlaceHolderElement() {
|
|
1892
|
+
return this.insertedDomEl as HTMLDivElement;
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1777
1895
|
/**
|
|
1778
1896
|
* Synchronizes the style properties of the PreRender component with the embedding
|
|
1779
1897
|
* element. This function adjusts the position, width, and height of the PreRender
|
|
@@ -1783,17 +1901,18 @@ export class TsEmbed {
|
|
|
1783
1901
|
* is not defined or not found.
|
|
1784
1902
|
*/
|
|
1785
1903
|
public syncPreRenderStyle(): void {
|
|
1786
|
-
if (!this.
|
|
1904
|
+
if (!this.isPreRenderConnected() || !this.getPreRenderPlaceHolderElement()) {
|
|
1787
1905
|
logger.error(ERROR_MESSAGE.SYNC_STYLE_CALLED_BEFORE_RENDER);
|
|
1788
1906
|
return;
|
|
1789
1907
|
}
|
|
1790
|
-
const elBoundingClient = this.
|
|
1908
|
+
const elBoundingClient = this.getPreRenderPlaceHolderElement().getBoundingClientRect();
|
|
1791
1909
|
|
|
1792
1910
|
setStyleProperties(this.preRenderWrapper, {
|
|
1793
1911
|
top: `${elBoundingClient.y + window.scrollY}px`,
|
|
1794
1912
|
left: `${elBoundingClient.x + window.scrollX}px`,
|
|
1795
1913
|
width: `${elBoundingClient.width}px`,
|
|
1796
1914
|
height: `${elBoundingClient.height}px`,
|
|
1915
|
+
position: 'absolute',
|
|
1797
1916
|
});
|
|
1798
1917
|
}
|
|
1799
1918
|
|
|
@@ -1802,7 +1921,8 @@ export class TsEmbed {
|
|
|
1802
1921
|
* If the component is not preRendered, it issues a warning.
|
|
1803
1922
|
*/
|
|
1804
1923
|
public hidePreRender(): void {
|
|
1805
|
-
|
|
1924
|
+
logger.debug('HidePreRender Called');
|
|
1925
|
+
if (!this.isPreRenderConnected()) {
|
|
1806
1926
|
// if the embed component is not preRendered , nothing to hide
|
|
1807
1927
|
logger.warn('PreRender should be called before hiding it using hidePreRender.');
|
|
1808
1928
|
return;
|
|
@@ -1822,6 +1942,11 @@ export class TsEmbed {
|
|
|
1822
1942
|
this.resizeObserver.disconnect();
|
|
1823
1943
|
}
|
|
1824
1944
|
|
|
1945
|
+
const placeHolderEle = this.getPreRenderPlaceHolderElement();
|
|
1946
|
+
if (placeHolderEle) {
|
|
1947
|
+
placeHolderEle.parentElement.removeChild(placeHolderEle);
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1825
1950
|
this.unsubscribeToEvents();
|
|
1826
1951
|
}
|
|
1827
1952
|
|
|
@@ -1836,6 +1961,7 @@ export class TsEmbed {
|
|
|
1836
1961
|
return {
|
|
1837
1962
|
wrapper: `tsEmbed-pre-render-wrapper-${this.viewConfig.preRenderId}`,
|
|
1838
1963
|
child: `tsEmbed-pre-render-child-${this.viewConfig.preRenderId}`,
|
|
1964
|
+
placeHolder: `tsEmbed-pre-render-placeholder-${this.viewConfig.preRenderId}`,
|
|
1839
1965
|
};
|
|
1840
1966
|
}
|
|
1841
1967
|
|