@thoughtspot/visual-embed-sdk 1.26.2 → 1.26.3
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/embed/app.d.ts +0 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +1 -1
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +0 -1
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +1 -1
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/sage.d.ts +0 -1
- package/cjs/src/embed/sage.d.ts.map +1 -1
- package/cjs/src/embed/sage.js +1 -1
- package/cjs/src/embed/sage.js.map +1 -1
- package/cjs/src/embed/search.d.ts +0 -1
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js +2 -3
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +0 -1
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +1 -3
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/types.d.ts +6 -0
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js.map +1 -1
- package/dist/src/embed/app.d.ts +0 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +0 -1
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/sage.d.ts +0 -1
- package/dist/src/embed/sage.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +0 -1
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +0 -1
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/types.d.ts +6 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +7 -10
- package/dist/tsembed-react.js +7 -10
- package/dist/tsembed.es.js +7 -10
- package/dist/tsembed.js +7 -10
- package/dist/visual-embed-sdk-react-full.d.ts +6 -5
- package/dist/visual-embed-sdk-react.d.ts +6 -5
- package/dist/visual-embed-sdk.d.ts +6 -5
- package/lib/package.json +1 -1
- package/lib/src/embed/app.d.ts +0 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +1 -1
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +0 -1
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +1 -1
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/sage.d.ts +0 -1
- package/lib/src/embed/sage.d.ts.map +1 -1
- package/lib/src/embed/sage.js +1 -1
- package/lib/src/embed/sage.js.map +1 -1
- package/lib/src/embed/search.d.ts +0 -1
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +2 -3
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +0 -1
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +1 -3
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/types.d.ts +6 -0
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +6 -5
- package/package.json +1 -1
- package/src/embed/app.ts +1 -2
- package/src/embed/liveboard.ts +1 -2
- package/src/embed/sage.ts +1 -2
- package/src/embed/search.ts +2 -4
- package/src/embed/ts-embed.ts +6 -9
- package/src/types.ts +16 -10
- package/cjs/src/embed/TsEmbed.d.ts +0 -302
- package/cjs/src/embed/TsEmbed.d.ts.map +0 -1
- package/cjs/src/embed/TsEmbed.js +0 -851
- package/cjs/src/embed/TsEmbed.js.map +0 -1
- package/cjs/src/utils/answerService.d.ts +0 -10
- package/cjs/src/utils/answerService.d.ts.map +0 -1
- package/cjs/src/utils/answerService.js +0 -61
- package/cjs/src/utils/answerService.js.map +0 -1
- package/cjs/src/utils/answerService.spec.d.ts +0 -2
- package/cjs/src/utils/answerService.spec.d.ts.map +0 -1
- package/cjs/src/utils/answerService.spec.js +0 -31
- package/cjs/src/utils/answerService.spec.js.map +0 -1
- package/cjs/src/utils/authService/tokenisedAuthSerice.d.ts +0 -11
- package/cjs/src/utils/authService/tokenisedAuthSerice.d.ts.map +0 -1
- package/cjs/src/utils/authService/tokenisedAuthSerice.js +0 -44
- package/cjs/src/utils/authService/tokenisedAuthSerice.js.map +0 -1
- package/cjs/src/utils/authService.d.ts +0 -55
- package/cjs/src/utils/authService.d.ts.map +0 -1
- package/cjs/src/utils/authService.js +0 -139
- package/cjs/src/utils/authService.js.map +0 -1
- package/cjs/src/utils/authService.spec.d.ts +0 -2
- package/cjs/src/utils/authService.spec.d.ts.map +0 -1
- package/cjs/src/utils/authService.spec.js +0 -82
- package/cjs/src/utils/authService.spec.js.map +0 -1
- package/cjs/src/utils/graphql/graphql-request.spec.d.ts +0 -2
- package/cjs/src/utils/graphql/graphql-request.spec.d.ts.map +0 -1
- package/cjs/src/utils/graphql/graphql-request.spec.js +0 -39
- package/cjs/src/utils/graphql/graphql-request.spec.js.map +0 -1
- package/cjs/src/utils/logger.d.ts +0 -28
- package/cjs/src/utils/logger.d.ts.map +0 -1
- package/cjs/src/utils/logger.js +0 -82
- package/cjs/src/utils/logger.js.map +0 -1
- package/dist/src/utils/answerService.d.ts +0 -10
- package/dist/src/utils/answerService.d.ts.map +0 -1
- package/dist/src/utils/answerService.spec.d.ts +0 -2
- package/dist/src/utils/answerService.spec.d.ts.map +0 -1
- package/dist/src/utils/authService/tokenisedAuthSerice.d.ts +0 -11
- package/dist/src/utils/authService/tokenisedAuthSerice.d.ts.map +0 -1
- package/dist/src/utils/authService.d.ts +0 -55
- package/dist/src/utils/authService.d.ts.map +0 -1
- package/dist/src/utils/authService.spec.d.ts +0 -2
- package/dist/src/utils/authService.spec.d.ts.map +0 -1
- package/dist/src/utils/graphql/graphql-request.spec.d.ts +0 -2
- package/dist/src/utils/graphql/graphql-request.spec.d.ts.map +0 -1
- package/dist/src/utils/logger.d.ts +0 -28
- package/dist/src/utils/logger.d.ts.map +0 -1
- package/lib/src/embed/TsEmbed.d.ts +0 -302
- package/lib/src/embed/TsEmbed.d.ts.map +0 -1
- package/lib/src/embed/TsEmbed.js +0 -847
- package/lib/src/embed/TsEmbed.js.map +0 -1
- package/lib/src/utils/answerService.d.ts +0 -10
- package/lib/src/utils/answerService.d.ts.map +0 -1
- package/lib/src/utils/answerService.js +0 -57
- package/lib/src/utils/answerService.js.map +0 -1
- package/lib/src/utils/answerService.spec.d.ts +0 -2
- package/lib/src/utils/answerService.spec.d.ts.map +0 -1
- package/lib/src/utils/answerService.spec.js +0 -29
- package/lib/src/utils/answerService.spec.js.map +0 -1
- package/lib/src/utils/authService/tokenisedAuthSerice.d.ts +0 -11
- package/lib/src/utils/authService/tokenisedAuthSerice.d.ts.map +0 -1
- package/lib/src/utils/authService/tokenisedAuthSerice.js +0 -39
- package/lib/src/utils/authService/tokenisedAuthSerice.js.map +0 -1
- package/lib/src/utils/authService.d.ts +0 -55
- package/lib/src/utils/authService.d.ts.map +0 -1
- package/lib/src/utils/authService.js +0 -129
- package/lib/src/utils/authService.js.map +0 -1
- package/lib/src/utils/authService.spec.d.ts +0 -2
- package/lib/src/utils/authService.spec.d.ts.map +0 -1
- package/lib/src/utils/authService.spec.js +0 -80
- package/lib/src/utils/authService.spec.js.map +0 -1
- package/lib/src/utils/graphql/graphql-request.spec.d.ts +0 -2
- package/lib/src/utils/graphql/graphql-request.spec.d.ts.map +0 -1
- package/lib/src/utils/graphql/graphql-request.spec.js +0 -36
- package/lib/src/utils/graphql/graphql-request.spec.js.map +0 -1
- package/lib/src/utils/logger.d.ts +0 -28
- package/lib/src/utils/logger.d.ts.map +0 -1
- package/lib/src/utils/logger.js +0 -75
- package/lib/src/utils/logger.js.map +0 -1
package/lib/src/embed/TsEmbed.js
DELETED
|
@@ -1,847 +0,0 @@
|
|
|
1
|
-
import { getEncodedQueryParamsString, getCssDimension, getOffsetTop, embedEventStatus, setAttributes, getCustomisations, getRuntimeFilters, getDOMNode, getQueryParamString, setStyleProperties, removeStyleProperties } from '../utils';
|
|
2
|
-
import { getThoughtSpotHost, URL_MAX_LENGTH, DEFAULT_EMBED_WIDTH, DEFAULT_EMBED_HEIGHT, getV2BasePath } from '../config';
|
|
3
|
-
import { AuthType, HostEvent, EmbedEvent, Action, Param, ContextMenuTriggerOptions } from '../types';
|
|
4
|
-
import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
|
|
5
|
-
import { processEventData } from '../utils/processData';
|
|
6
|
-
import { processTrigger } from '../utils/processTrigger';
|
|
7
|
-
import { getAuthPromise, getEmbedConfig, renderInQueue, handleAuth, notifyAuthFailure } from './base';
|
|
8
|
-
import { AuthFailureType, getAuthenticaionToken } from '../auth';
|
|
9
|
-
import { TS_EMBED_ID, V1EventMap, THOUGHTSPOT_PARAM_PREFIX } from './ts-embed';
|
|
10
|
-
/**
|
|
11
|
-
* Base class for embedding v2 experience
|
|
12
|
-
* Note: the v2 version of ThoughtSpot Blink is built on the new stack:
|
|
13
|
-
* React+GraphQL
|
|
14
|
-
*/
|
|
15
|
-
export class TsEmbed {
|
|
16
|
-
constructor(domSelector, viewConfig) {
|
|
17
|
-
this.isAppInitialized = false;
|
|
18
|
-
this.embedComponentType = 'TsEmbed';
|
|
19
|
-
/**
|
|
20
|
-
* Should we encode URL Query Params using base64 encoding which thoughtspot
|
|
21
|
-
* will generate for embedding. This provides additional security to
|
|
22
|
-
* thoughtspot clusters against Cross site scripting attacks.
|
|
23
|
-
*
|
|
24
|
-
* @default false
|
|
25
|
-
*/
|
|
26
|
-
this.shouldEncodeUrlQueryParams = false;
|
|
27
|
-
this.defaultHiddenActions = [Action.ReportError];
|
|
28
|
-
this.subscribedListeners = {};
|
|
29
|
-
/**
|
|
30
|
-
* Send Custom style as part of payload of APP_INIT
|
|
31
|
-
*
|
|
32
|
-
* @param _
|
|
33
|
-
* @param responder
|
|
34
|
-
*/
|
|
35
|
-
this.appInitCb = async (_, responder) => {
|
|
36
|
-
var _a, _b;
|
|
37
|
-
let authToken = '';
|
|
38
|
-
if (this.embedConfig.authType === AuthType.TrustedAuthTokenCookieless) {
|
|
39
|
-
authToken = await getAuthenticaionToken(this.embedConfig);
|
|
40
|
-
}
|
|
41
|
-
this.isAppInitialized = true;
|
|
42
|
-
responder({
|
|
43
|
-
type: EmbedEvent.APP_INIT,
|
|
44
|
-
data: {
|
|
45
|
-
customisations: getCustomisations(this.embedConfig, this.viewConfig),
|
|
46
|
-
authToken,
|
|
47
|
-
runtimeFilterParams: this.viewConfig.excludeRuntimeFiltersfromURL
|
|
48
|
-
? getRuntimeFilters(this.viewConfig.runtimeFilters)
|
|
49
|
-
: null,
|
|
50
|
-
hiddenHomepageModules: this.viewConfig.hiddenHomepageModules || [],
|
|
51
|
-
reorderedHomepageModules: this.viewConfig.reorderedHomepageModules || [],
|
|
52
|
-
hostConfig: this.embedConfig.hostConfig,
|
|
53
|
-
hiddenHomeLeftNavItems: ((_a = this.viewConfig) === null || _a === void 0 ? void 0 : _a.hiddenHomeLeftNavItems)
|
|
54
|
-
? (_b = this.viewConfig) === null || _b === void 0 ? void 0 : _b.hiddenHomeLeftNavItems
|
|
55
|
-
: [],
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* Sends updated auth token to the iFrame to avoid user logout
|
|
61
|
-
*
|
|
62
|
-
* @param _
|
|
63
|
-
* @param responder
|
|
64
|
-
*/
|
|
65
|
-
this.updateAuthToken = async (_, responder) => {
|
|
66
|
-
const { autoLogin = false, authType } = this.embedConfig; // Set autoLogin default to false
|
|
67
|
-
if (authType === AuthType.TrustedAuthTokenCookieless) {
|
|
68
|
-
const authToken = await getAuthenticaionToken(this.embedConfig);
|
|
69
|
-
responder({
|
|
70
|
-
type: EmbedEvent.AuthExpire,
|
|
71
|
-
data: { authToken },
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
else if (autoLogin) {
|
|
75
|
-
handleAuth();
|
|
76
|
-
}
|
|
77
|
-
notifyAuthFailure(AuthFailureType.EXPIRY);
|
|
78
|
-
};
|
|
79
|
-
/**
|
|
80
|
-
* Register APP_INIT event and sendback init payload
|
|
81
|
-
*/
|
|
82
|
-
this.registerAppInit = () => {
|
|
83
|
-
this.on(EmbedEvent.APP_INIT, this.appInitCb, { start: false }, true);
|
|
84
|
-
this.on(EmbedEvent.AuthExpire, this.updateAuthToken, { start: false }, true);
|
|
85
|
-
};
|
|
86
|
-
this.el = getDOMNode(domSelector);
|
|
87
|
-
// TODO: handle error
|
|
88
|
-
this.embedConfig = getEmbedConfig();
|
|
89
|
-
if (!this.embedConfig.authTriggerContainer && !this.embedConfig.useEventForSAMLPopup) {
|
|
90
|
-
this.embedConfig.authTriggerContainer = domSelector;
|
|
91
|
-
}
|
|
92
|
-
this.thoughtSpotHost = getThoughtSpotHost(this.embedConfig);
|
|
93
|
-
this.thoughtSpotV2Base = getV2BasePath(this.embedConfig);
|
|
94
|
-
this.eventHandlerMap = new Map();
|
|
95
|
-
this.isError = false;
|
|
96
|
-
this.viewConfig = viewConfig;
|
|
97
|
-
this.shouldEncodeUrlQueryParams = this.embedConfig.shouldEncodeUrlQueryParams;
|
|
98
|
-
this.registerAppInit();
|
|
99
|
-
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_EMBED_CREATE, {
|
|
100
|
-
...viewConfig,
|
|
101
|
-
embedComponentType: this.embedComponentType,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Throws error encountered during initialization.
|
|
106
|
-
*/
|
|
107
|
-
throwInitError() {
|
|
108
|
-
this.handleError('You need to init the ThoughtSpot SDK module first');
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Handles errors within the SDK
|
|
112
|
-
*
|
|
113
|
-
* @param error The error message or object
|
|
114
|
-
*/
|
|
115
|
-
handleError(error) {
|
|
116
|
-
this.isError = true;
|
|
117
|
-
this.executeCallbacks(EmbedEvent.Error, {
|
|
118
|
-
error,
|
|
119
|
-
});
|
|
120
|
-
// Log error
|
|
121
|
-
console.error(error);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Extracts the type field from the event payload
|
|
125
|
-
*
|
|
126
|
-
* @param event The window message event
|
|
127
|
-
*/
|
|
128
|
-
getEventType(event) {
|
|
129
|
-
var _a, _b;
|
|
130
|
-
// eslint-disable-next-line no-underscore-dangle
|
|
131
|
-
return ((_a = event.data) === null || _a === void 0 ? void 0 : _a.type) || ((_b = event.data) === null || _b === void 0 ? void 0 : _b.__type);
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Extracts the port field from the event payload
|
|
135
|
-
*
|
|
136
|
-
* @param event The window message event
|
|
137
|
-
* @returns
|
|
138
|
-
*/
|
|
139
|
-
getEventPort(event) {
|
|
140
|
-
if (event.ports.length && event.ports[0]) {
|
|
141
|
-
return event.ports[0];
|
|
142
|
-
}
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* fix for ts7.sep.cl
|
|
147
|
-
* will be removed for ts7.oct.cl
|
|
148
|
-
*
|
|
149
|
-
* @param event
|
|
150
|
-
* @param eventType
|
|
151
|
-
* @hidden
|
|
152
|
-
*/
|
|
153
|
-
formatEventData(event, eventType) {
|
|
154
|
-
const eventData = {
|
|
155
|
-
...event.data,
|
|
156
|
-
type: eventType,
|
|
157
|
-
};
|
|
158
|
-
if (!eventData.data) {
|
|
159
|
-
eventData.data = event.data.payload;
|
|
160
|
-
}
|
|
161
|
-
return eventData;
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Adds a global event listener to window for "message" events.
|
|
165
|
-
* ThoughtSpot detects if a particular event is targeted to this
|
|
166
|
-
* embed instance through an identifier contained in the payload,
|
|
167
|
-
* and executes the registered callbacks accordingly.
|
|
168
|
-
*/
|
|
169
|
-
subscribeToEvents() {
|
|
170
|
-
this.unsubscribeToEvents();
|
|
171
|
-
const messageEventListener = (event) => {
|
|
172
|
-
const eventType = this.getEventType(event);
|
|
173
|
-
const eventPort = this.getEventPort(event);
|
|
174
|
-
const eventData = this.formatEventData(event, eventType);
|
|
175
|
-
if (event.source === this.iFrame.contentWindow) {
|
|
176
|
-
this.executeCallbacks(eventType, processEventData(eventType, eventData, this.thoughtSpotHost, this.el), eventPort);
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
window.addEventListener('message', messageEventListener);
|
|
180
|
-
const onlineEventListener = (e) => {
|
|
181
|
-
this.trigger(HostEvent.Reload);
|
|
182
|
-
};
|
|
183
|
-
window.addEventListener('online', onlineEventListener);
|
|
184
|
-
const offlineEventListener = (e) => {
|
|
185
|
-
const offlineWarning = 'Network not Detected. Embed is offline. Please reconnect and refresh';
|
|
186
|
-
this.executeCallbacks(EmbedEvent.Error, {
|
|
187
|
-
offlineWarning,
|
|
188
|
-
});
|
|
189
|
-
console.warn(offlineWarning);
|
|
190
|
-
};
|
|
191
|
-
window.addEventListener('offline', offlineEventListener);
|
|
192
|
-
this.subscribedListeners = {
|
|
193
|
-
message: messageEventListener,
|
|
194
|
-
online: onlineEventListener,
|
|
195
|
-
offline: offlineEventListener,
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
unsubscribeToEvents() {
|
|
199
|
-
Object.keys(this.subscribedListeners).forEach((key) => {
|
|
200
|
-
window.removeEventListener(key, this.subscribedListeners[key]);
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Constructs the base URL string to load the ThoughtSpot app.
|
|
205
|
-
*
|
|
206
|
-
* @param query
|
|
207
|
-
*/
|
|
208
|
-
getEmbedBasePath(query) {
|
|
209
|
-
let queryString = query;
|
|
210
|
-
if (this.shouldEncodeUrlQueryParams) {
|
|
211
|
-
queryString = `?base64UrlEncodedFlags=${getEncodedQueryParamsString(queryString.substr(1))}`;
|
|
212
|
-
}
|
|
213
|
-
const basePath = [this.thoughtSpotHost, this.thoughtSpotV2Base, queryString]
|
|
214
|
-
.filter((x) => x.length > 0)
|
|
215
|
-
.join('/');
|
|
216
|
-
return `${basePath}#`;
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Common query params set for all the embed modes.
|
|
220
|
-
*
|
|
221
|
-
* @param queryParams
|
|
222
|
-
* @returns queryParams
|
|
223
|
-
*/
|
|
224
|
-
getBaseQueryParams(queryParams = {}) {
|
|
225
|
-
var _a, _b, _c, _d;
|
|
226
|
-
let hostAppUrl = ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.host) || '';
|
|
227
|
-
// The below check is needed because TS Cloud firewall, blocks
|
|
228
|
-
// localhost/127.0.0.1 in any url param.
|
|
229
|
-
if (hostAppUrl.includes('localhost') || hostAppUrl.includes('127.0.0.1')) {
|
|
230
|
-
hostAppUrl = 'local-host';
|
|
231
|
-
}
|
|
232
|
-
queryParams[Param.HostAppUrl] = encodeURIComponent(hostAppUrl);
|
|
233
|
-
queryParams[Param.ViewPortHeight] = window.innerHeight;
|
|
234
|
-
queryParams[Param.ViewPortWidth] = window.innerWidth;
|
|
235
|
-
queryParams[Param.Version] = version;
|
|
236
|
-
queryParams[Param.AuthType] = this.embedConfig.authType;
|
|
237
|
-
queryParams[Param.blockNonEmbedFullAppAccess] = (_b = this.embedConfig.blockNonEmbedFullAppAccess) !== null && _b !== void 0 ? _b : true;
|
|
238
|
-
if (this.embedConfig.disableLoginRedirect === true || this.embedConfig.autoLogin === true) {
|
|
239
|
-
queryParams[Param.DisableLoginRedirect] = true;
|
|
240
|
-
}
|
|
241
|
-
if (this.embedConfig.authType === AuthType.EmbeddedSSO) {
|
|
242
|
-
queryParams[Param.ForceSAMLAutoRedirect] = true;
|
|
243
|
-
}
|
|
244
|
-
if (this.embedConfig.authType === AuthType.TrustedAuthTokenCookieless) {
|
|
245
|
-
queryParams[Param.cookieless] = true;
|
|
246
|
-
}
|
|
247
|
-
if (this.embedConfig.pendoTrackingKey) {
|
|
248
|
-
queryParams[Param.PendoTrackingKey] = this.embedConfig.pendoTrackingKey;
|
|
249
|
-
}
|
|
250
|
-
const { disabledActions, disabledActionReason, hiddenActions, visibleActions, hiddenTabs, visibleTabs, showAlerts, additionalFlags, locale, customizations, contextMenuTrigger, linkOverride, insertInToSlide, hideLiveboardHeader, showLiveboardDescription, showLiveboardTitle, } = this.viewConfig;
|
|
251
|
-
if (Array.isArray(visibleActions) && Array.isArray(hiddenActions)) {
|
|
252
|
-
this.handleError('You cannot have both hidden actions and visible actions');
|
|
253
|
-
return queryParams;
|
|
254
|
-
}
|
|
255
|
-
if (Array.isArray(visibleTabs) && Array.isArray(hiddenTabs)) {
|
|
256
|
-
this.handleError('You cannot have both hidden Tabs and visible Tabs');
|
|
257
|
-
return queryParams;
|
|
258
|
-
}
|
|
259
|
-
// TODO remove embedConfig.customCssUrl
|
|
260
|
-
const cssUrlParam = ((_c = customizations === null || customizations === void 0 ? void 0 : customizations.style) === null || _c === void 0 ? void 0 : _c.customCSSUrl) || this.embedConfig.customCssUrl;
|
|
261
|
-
if (cssUrlParam) {
|
|
262
|
-
queryParams[Param.CustomCSSUrl] = cssUrlParam;
|
|
263
|
-
}
|
|
264
|
-
if (disabledActions === null || disabledActions === void 0 ? void 0 : disabledActions.length) {
|
|
265
|
-
queryParams[Param.DisableActions] = disabledActions;
|
|
266
|
-
}
|
|
267
|
-
if (disabledActionReason) {
|
|
268
|
-
queryParams[Param.DisableActionReason] = disabledActionReason;
|
|
269
|
-
}
|
|
270
|
-
queryParams[Param.HideActions] = [...this.defaultHiddenActions, ...(hiddenActions !== null && hiddenActions !== void 0 ? hiddenActions : [])];
|
|
271
|
-
if (Array.isArray(visibleActions)) {
|
|
272
|
-
queryParams[Param.VisibleActions] = visibleActions;
|
|
273
|
-
}
|
|
274
|
-
if (Array.isArray(hiddenTabs)) {
|
|
275
|
-
queryParams[Param.HiddenTabs] = hiddenTabs;
|
|
276
|
-
}
|
|
277
|
-
if (Array.isArray(visibleTabs)) {
|
|
278
|
-
queryParams[Param.VisibleTabs] = visibleTabs;
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Default behavior for context menu will be left-click
|
|
282
|
-
* from version 9.2.0.cl the user have an option to override context
|
|
283
|
-
* menu click
|
|
284
|
-
*/
|
|
285
|
-
if (contextMenuTrigger === ContextMenuTriggerOptions.LEFT_CLICK) {
|
|
286
|
-
queryParams[Param.ContextMenuTrigger] = true;
|
|
287
|
-
}
|
|
288
|
-
else if (contextMenuTrigger === ContextMenuTriggerOptions.RIGHT_CLICK) {
|
|
289
|
-
queryParams[Param.ContextMenuTrigger] = false;
|
|
290
|
-
}
|
|
291
|
-
const spriteUrl = (customizations === null || customizations === void 0 ? void 0 : customizations.iconSpriteUrl)
|
|
292
|
-
|| ((_d = this.embedConfig.customizations) === null || _d === void 0 ? void 0 : _d.iconSpriteUrl);
|
|
293
|
-
if (spriteUrl) {
|
|
294
|
-
queryParams[Param.IconSpriteUrl] = spriteUrl.replace('https://', '');
|
|
295
|
-
}
|
|
296
|
-
if (showAlerts !== undefined) {
|
|
297
|
-
queryParams[Param.ShowAlerts] = showAlerts;
|
|
298
|
-
}
|
|
299
|
-
if (locale !== undefined) {
|
|
300
|
-
queryParams[Param.Locale] = locale;
|
|
301
|
-
}
|
|
302
|
-
if (additionalFlags && additionalFlags.constructor.name === 'Object') {
|
|
303
|
-
Object.assign(queryParams, additionalFlags);
|
|
304
|
-
}
|
|
305
|
-
if (linkOverride) {
|
|
306
|
-
queryParams[Param.LinkOverride] = linkOverride;
|
|
307
|
-
}
|
|
308
|
-
if (insertInToSlide) {
|
|
309
|
-
queryParams[Param.ShowInsertToSlide] = insertInToSlide;
|
|
310
|
-
}
|
|
311
|
-
if (hideLiveboardHeader) {
|
|
312
|
-
queryParams[Param.HideLiveboardHeader] = hideLiveboardHeader;
|
|
313
|
-
}
|
|
314
|
-
if (showLiveboardDescription) {
|
|
315
|
-
queryParams[Param.ShowLiveboardDescription] = showLiveboardDescription;
|
|
316
|
-
}
|
|
317
|
-
if (showLiveboardTitle) {
|
|
318
|
-
queryParams[Param.ShowLiveboardTitle] = showLiveboardTitle;
|
|
319
|
-
}
|
|
320
|
-
return queryParams;
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Constructs the base URL string to load v1 of the ThoughtSpot app.
|
|
324
|
-
* This is used for embedding Liveboards, visualizations, and full application.
|
|
325
|
-
*
|
|
326
|
-
* @param queryString The query string to append to the URL.
|
|
327
|
-
* @param isAppEmbed A Boolean parameter to specify if you are embedding
|
|
328
|
-
* the full application.
|
|
329
|
-
*/
|
|
330
|
-
getV1EmbedBasePath(queryString) {
|
|
331
|
-
const queryParams = this.shouldEncodeUrlQueryParams
|
|
332
|
-
? `?base64UrlEncodedFlags=${getEncodedQueryParamsString(queryString)}`
|
|
333
|
-
: `?${queryString}`;
|
|
334
|
-
const path = `${this.thoughtSpotHost}/${queryParams}#`;
|
|
335
|
-
return path;
|
|
336
|
-
}
|
|
337
|
-
getEmbedParams() {
|
|
338
|
-
const queryParams = this.getBaseQueryParams();
|
|
339
|
-
return getQueryParamString(queryParams);
|
|
340
|
-
}
|
|
341
|
-
getRootIframeSrc() {
|
|
342
|
-
const query = this.getEmbedParams();
|
|
343
|
-
return this.getEmbedBasePath(query);
|
|
344
|
-
}
|
|
345
|
-
createIframeEl(frameSrc) {
|
|
346
|
-
const iFrame = document.createElement('iframe');
|
|
347
|
-
iFrame.src = frameSrc;
|
|
348
|
-
iFrame.id = TS_EMBED_ID;
|
|
349
|
-
// according to screenfull.js documentation
|
|
350
|
-
// allowFullscreen, webkitallowfullscreen and mozallowfullscreen must be
|
|
351
|
-
// true
|
|
352
|
-
iFrame.allowFullscreen = true;
|
|
353
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
354
|
-
// @ts-ignore
|
|
355
|
-
iFrame.webkitallowfullscreen = true;
|
|
356
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
357
|
-
// @ts-ignore
|
|
358
|
-
iFrame.mozallowfullscreen = true;
|
|
359
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
360
|
-
// @ts-ignore
|
|
361
|
-
iFrame.allow = 'clipboard-read; clipboard-write';
|
|
362
|
-
const { height: frameHeight, width: frameWidth, ...restParams } = this.viewConfig.frameParams || {};
|
|
363
|
-
const width = getCssDimension(frameWidth || DEFAULT_EMBED_WIDTH);
|
|
364
|
-
const height = getCssDimension(frameHeight || DEFAULT_EMBED_HEIGHT);
|
|
365
|
-
setAttributes(iFrame, restParams);
|
|
366
|
-
iFrame.style.width = `${width}`;
|
|
367
|
-
iFrame.style.height = `${height}`;
|
|
368
|
-
iFrame.style.border = '0';
|
|
369
|
-
iFrame.name = 'ThoughtSpot Embedded Analytics';
|
|
370
|
-
return iFrame;
|
|
371
|
-
}
|
|
372
|
-
handleInsertionIntoDOM(child, showPreRenderByDefault = false) {
|
|
373
|
-
if (this.isPreRendered) {
|
|
374
|
-
this.insertIntoDOMForPreRender(this.embedConfig.loginFailedMessage, showPreRenderByDefault);
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
this.insertIntoDOM(this.embedConfig.loginFailedMessage);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
/**
|
|
381
|
-
* Renders the embedded ThoughtSpot app in an iframe and sets up
|
|
382
|
-
* event listeners.
|
|
383
|
-
*
|
|
384
|
-
* @param url - The URL of the embedded ThoughtSpot app.
|
|
385
|
-
* @param showPreRenderByDefault - The flag to show the preRender by default.
|
|
386
|
-
*/
|
|
387
|
-
async renderIFrame(url, showPreRenderByDefault = false) {
|
|
388
|
-
if (this.isError) {
|
|
389
|
-
return null;
|
|
390
|
-
}
|
|
391
|
-
if (!this.thoughtSpotHost) {
|
|
392
|
-
this.throwInitError();
|
|
393
|
-
}
|
|
394
|
-
if (url.length > URL_MAX_LENGTH) {
|
|
395
|
-
// warn: The URL is too long
|
|
396
|
-
}
|
|
397
|
-
return renderInQueue((nextInQueue) => {
|
|
398
|
-
var _a;
|
|
399
|
-
const initTimestamp = Date.now();
|
|
400
|
-
this.executeCallbacks(EmbedEvent.Init, {
|
|
401
|
-
data: {
|
|
402
|
-
timestamp: initTimestamp,
|
|
403
|
-
},
|
|
404
|
-
type: EmbedEvent.Init,
|
|
405
|
-
});
|
|
406
|
-
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_START);
|
|
407
|
-
return (_a = getAuthPromise()) === null || _a === void 0 ? void 0 : _a.then((isLoggedIn) => {
|
|
408
|
-
if (!isLoggedIn) {
|
|
409
|
-
this.handleInsertionIntoDOM(this.embedConfig.loginFailedMessage, showPreRenderByDefault);
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
|
-
this.iFrame = this.iFrame || this.createIframeEl(url);
|
|
413
|
-
this.iFrame.addEventListener('load', () => {
|
|
414
|
-
nextInQueue();
|
|
415
|
-
const loadTimestamp = Date.now();
|
|
416
|
-
this.executeCallbacks(EmbedEvent.Load, {
|
|
417
|
-
data: {
|
|
418
|
-
timestamp: loadTimestamp,
|
|
419
|
-
},
|
|
420
|
-
type: EmbedEvent.Load,
|
|
421
|
-
});
|
|
422
|
-
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_COMPLETE, {
|
|
423
|
-
elWidth: this.iFrame.clientWidth,
|
|
424
|
-
elHeight: this.iFrame.clientHeight,
|
|
425
|
-
timeTookToLoad: loadTimestamp - initTimestamp,
|
|
426
|
-
});
|
|
427
|
-
});
|
|
428
|
-
this.iFrame.addEventListener('error', () => {
|
|
429
|
-
nextInQueue();
|
|
430
|
-
});
|
|
431
|
-
this.handleInsertionIntoDOM(this.iFrame, showPreRenderByDefault);
|
|
432
|
-
const prefetchIframe = document.querySelectorAll('.prefetchIframe');
|
|
433
|
-
if (prefetchIframe.length) {
|
|
434
|
-
prefetchIframe.forEach((el) => {
|
|
435
|
-
el.remove();
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
this.subscribeToEvents();
|
|
439
|
-
}).catch((error) => {
|
|
440
|
-
nextInQueue();
|
|
441
|
-
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_FAILED, {
|
|
442
|
-
error: JSON.stringify(error),
|
|
443
|
-
});
|
|
444
|
-
this.handleInsertionIntoDOM(this.embedConfig.loginFailedMessage);
|
|
445
|
-
this.handleError(error);
|
|
446
|
-
});
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
getPreRenderIds() {
|
|
450
|
-
return {
|
|
451
|
-
wrapper: `tsEmbed-pre-render-wrapper-${this.viewConfig.preRenderId}`,
|
|
452
|
-
shield: `tsEmbed-pre-render-shield-${this.viewConfig.preRenderId}`,
|
|
453
|
-
child: `tsEmbed-pre-render-child-${this.viewConfig.preRenderId}`,
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
createPreRenderWrapper(child) {
|
|
457
|
-
if (!this.viewConfig.preRenderId) {
|
|
458
|
-
throw new Error('PreRender id is required');
|
|
459
|
-
}
|
|
460
|
-
const preRenderIds = this.getPreRenderIds();
|
|
461
|
-
[preRenderIds.wrapper, preRenderIds.shield, preRenderIds.child]
|
|
462
|
-
.map((id) => document.getElementById(id))
|
|
463
|
-
.filter((element) => element)
|
|
464
|
-
.forEach((existingElement) => existingElement.remove());
|
|
465
|
-
const preRenderWrapper = document.createElement('div');
|
|
466
|
-
preRenderWrapper.id = preRenderIds.wrapper;
|
|
467
|
-
setStyleProperties(preRenderWrapper, { position: 'absolute', width: '100vw', height: '100vh' });
|
|
468
|
-
// const preRenderShield = document.createElement('div');
|
|
469
|
-
// preRenderShield.id = preRenderIds.shield;
|
|
470
|
-
// setStyleProperties(preRenderShield, { position: 'absolute', width: '100%', height: '100%' });
|
|
471
|
-
child.id = preRenderIds.child;
|
|
472
|
-
preRenderWrapper.appendChild(child);
|
|
473
|
-
// preRenderWrapper.appendChild(preRenderShield);
|
|
474
|
-
this.preRenderWrapper = preRenderWrapper;
|
|
475
|
-
// this.preRenderShield = preRenderShield;
|
|
476
|
-
this.preRenderChild = child;
|
|
477
|
-
return preRenderWrapper;
|
|
478
|
-
}
|
|
479
|
-
connectPreRendered() {
|
|
480
|
-
const preRenderIds = this.getPreRenderIds();
|
|
481
|
-
this.preRenderWrapper = this.preRenderWrapper
|
|
482
|
-
|| document.getElementById(preRenderIds.wrapper);
|
|
483
|
-
// this.preRenderShield = this.preRenderShield
|
|
484
|
-
// || document.getElementById(preRenderIds.shield);
|
|
485
|
-
this.preRenderChild = this.preRenderChild
|
|
486
|
-
|| document.getElementById(preRenderIds.child);
|
|
487
|
-
if (this.preRenderWrapper && this.preRenderChild) {
|
|
488
|
-
this.isPreRendered = true;
|
|
489
|
-
this.iFrame = this.preRenderChild;
|
|
490
|
-
}
|
|
491
|
-
return this.isPreRenderAvailable();
|
|
492
|
-
}
|
|
493
|
-
isPreRenderAvailable() {
|
|
494
|
-
return this.isPreRendered;
|
|
495
|
-
}
|
|
496
|
-
insertIntoDOMForPreRender(child, showPreRenderByDefault = false) {
|
|
497
|
-
let childNode;
|
|
498
|
-
if (typeof child === 'string') {
|
|
499
|
-
const divChildNode = document.createElement('div');
|
|
500
|
-
divChildNode.innerHTML = child;
|
|
501
|
-
childNode = divChildNode;
|
|
502
|
-
}
|
|
503
|
-
else {
|
|
504
|
-
childNode = child;
|
|
505
|
-
}
|
|
506
|
-
const preRenderWrapper = this.createPreRenderWrapper(childNode);
|
|
507
|
-
if (showPreRenderByDefault) {
|
|
508
|
-
this.showPreRender();
|
|
509
|
-
}
|
|
510
|
-
else {
|
|
511
|
-
this.hidePreRender();
|
|
512
|
-
}
|
|
513
|
-
document.body.appendChild(preRenderWrapper);
|
|
514
|
-
}
|
|
515
|
-
hidePreRender() {
|
|
516
|
-
if (!this.isPreRenderAvailable()) {
|
|
517
|
-
// if the embed component is not preRendered , nothing to hide
|
|
518
|
-
console.log('No preRender found, not hiding ');
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
setStyleProperties(this.preRenderWrapper, {
|
|
522
|
-
opacity: '0',
|
|
523
|
-
pointerEvents: 'none',
|
|
524
|
-
zIndex: '-1000',
|
|
525
|
-
position: 'absolute ',
|
|
526
|
-
top: '0',
|
|
527
|
-
left: '0',
|
|
528
|
-
});
|
|
529
|
-
const childBoundingRect = this.preRenderChild.getBoundingClientRect();
|
|
530
|
-
setStyleProperties(this.preRenderShield, {
|
|
531
|
-
opacity: '0',
|
|
532
|
-
pointerEvents: 'none',
|
|
533
|
-
zIndex: '1',
|
|
534
|
-
width: `${childBoundingRect.width}px`,
|
|
535
|
-
height: `${childBoundingRect.height}px`,
|
|
536
|
-
position: 'absolute',
|
|
537
|
-
top: '0',
|
|
538
|
-
left: '0',
|
|
539
|
-
});
|
|
540
|
-
this.unsubscribeToEvents();
|
|
541
|
-
}
|
|
542
|
-
showPreRender() {
|
|
543
|
-
if (!this.isPreRenderAvailable()) {
|
|
544
|
-
const isAvailable = this.connectPreRendered();
|
|
545
|
-
if (!isAvailable) {
|
|
546
|
-
// if the Embed component is nor preRendered , Render it now and
|
|
547
|
-
// show it (hide is defalt behaviour)
|
|
548
|
-
console.log('No preRender found, creating new ');
|
|
549
|
-
this.preRender(true);
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
this.syncPreRenderStyle();
|
|
554
|
-
removeStyleProperties(this.preRenderWrapper, ['z-index', 'opacity', 'pointer-events']);
|
|
555
|
-
setStyleProperties(this.preRenderShield, { zIndex: '-1' });
|
|
556
|
-
this.subscribeToEvents();
|
|
557
|
-
}
|
|
558
|
-
syncPreRenderStyle() {
|
|
559
|
-
if (!this.el) {
|
|
560
|
-
throw new Error('Embed element is not defined');
|
|
561
|
-
}
|
|
562
|
-
const elBoundingClient = this.el.getBoundingClientRect();
|
|
563
|
-
setStyleProperties(this.preRenderWrapper, {
|
|
564
|
-
top: `${elBoundingClient.y}px`, left: `${elBoundingClient.x}px`, width: `${elBoundingClient.width}px`, height: `${elBoundingClient.height}px`,
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
insertIntoDOM(child) {
|
|
568
|
-
var _a;
|
|
569
|
-
if (this.viewConfig.insertAsSibling) {
|
|
570
|
-
if (typeof child === 'string') {
|
|
571
|
-
const div = document.createElement('div');
|
|
572
|
-
div.innerHTML = child;
|
|
573
|
-
div.id = TS_EMBED_ID;
|
|
574
|
-
// eslint-disable-next-line no-param-reassign
|
|
575
|
-
child = div;
|
|
576
|
-
}
|
|
577
|
-
if (((_a = this.el.nextElementSibling) === null || _a === void 0 ? void 0 : _a.id) === TS_EMBED_ID) {
|
|
578
|
-
this.el.nextElementSibling.remove();
|
|
579
|
-
}
|
|
580
|
-
this.el.parentElement.insertBefore(child, this.el.nextSibling);
|
|
581
|
-
this.insertedDomEl = child;
|
|
582
|
-
}
|
|
583
|
-
else if (typeof child === 'string') {
|
|
584
|
-
this.el.innerHTML = child;
|
|
585
|
-
this.insertedDomEl = this.el.children[0];
|
|
586
|
-
}
|
|
587
|
-
else {
|
|
588
|
-
this.el.innerHTML = '';
|
|
589
|
-
this.el.appendChild(child);
|
|
590
|
-
this.insertedDomEl = child;
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
* Sets the height of the iframe
|
|
595
|
-
*
|
|
596
|
-
* @param height The height in pixels
|
|
597
|
-
*/
|
|
598
|
-
setIFrameHeight(height) {
|
|
599
|
-
this.iFrame.style.height = getCssDimension(height);
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Executes all registered event handlers for a particular event type
|
|
603
|
-
*
|
|
604
|
-
* @param eventType The event type
|
|
605
|
-
* @param data The payload invoked with the event handler
|
|
606
|
-
* @param eventPort The event Port for a specific MessageChannel
|
|
607
|
-
*/
|
|
608
|
-
executeCallbacks(eventType, data, eventPort) {
|
|
609
|
-
const eventHandlers = this.eventHandlerMap.get(eventType) || [];
|
|
610
|
-
const allHandlers = this.eventHandlerMap.get(EmbedEvent.ALL) || [];
|
|
611
|
-
const callbacks = [...eventHandlers, ...allHandlers];
|
|
612
|
-
const dataStatus = (data === null || data === void 0 ? void 0 : data.status) || embedEventStatus.END;
|
|
613
|
-
callbacks.forEach((callbackObj) => {
|
|
614
|
-
if (
|
|
615
|
-
// When start status is true it trigger only start releated
|
|
616
|
-
// payload
|
|
617
|
-
(callbackObj.options.start && dataStatus === embedEventStatus.START)
|
|
618
|
-
// When start status is false it trigger only end releated
|
|
619
|
-
// payload
|
|
620
|
-
|| (!callbackObj.options.start && dataStatus === embedEventStatus.END)) {
|
|
621
|
-
callbackObj.callback(data, (payload) => {
|
|
622
|
-
this.triggerEventOnPort(eventPort, payload);
|
|
623
|
-
});
|
|
624
|
-
}
|
|
625
|
-
});
|
|
626
|
-
}
|
|
627
|
-
/**
|
|
628
|
-
* Returns the ThoughtSpot hostname or IP address.
|
|
629
|
-
*/
|
|
630
|
-
getThoughtSpotHost() {
|
|
631
|
-
return this.thoughtSpotHost;
|
|
632
|
-
}
|
|
633
|
-
/**
|
|
634
|
-
* Gets the v1 event type (if applicable) for the EmbedEvent type
|
|
635
|
-
*
|
|
636
|
-
* @param eventType The v2 event type
|
|
637
|
-
* @returns The corresponding v1 event type if one exists
|
|
638
|
-
* or else the v2 event type itself
|
|
639
|
-
*/
|
|
640
|
-
getCompatibleEventType(eventType) {
|
|
641
|
-
return V1EventMap[eventType] || eventType;
|
|
642
|
-
}
|
|
643
|
-
/**
|
|
644
|
-
* Calculates the iframe center for the current visible viewPort
|
|
645
|
-
* of iframe using Scroll position of Host App, offsetTop for iframe
|
|
646
|
-
* in Host app. ViewPort height of the tab.
|
|
647
|
-
*
|
|
648
|
-
* @returns iframe Center in visible viewport,
|
|
649
|
-
* Iframe height,
|
|
650
|
-
* View port height.
|
|
651
|
-
*/
|
|
652
|
-
getIframeCenter() {
|
|
653
|
-
const offsetTopClient = getOffsetTop(this.iFrame);
|
|
654
|
-
const scrollTopClient = window.scrollY;
|
|
655
|
-
const viewPortHeight = window.innerHeight;
|
|
656
|
-
const iframeHeight = this.iFrame.offsetHeight;
|
|
657
|
-
const iframeScrolled = scrollTopClient - offsetTopClient;
|
|
658
|
-
let iframeVisibleViewPort;
|
|
659
|
-
let iframeOffset;
|
|
660
|
-
if (iframeScrolled < 0) {
|
|
661
|
-
iframeVisibleViewPort = viewPortHeight - (offsetTopClient - scrollTopClient);
|
|
662
|
-
iframeVisibleViewPort = Math.min(iframeHeight, iframeVisibleViewPort);
|
|
663
|
-
iframeOffset = 0;
|
|
664
|
-
}
|
|
665
|
-
else {
|
|
666
|
-
iframeVisibleViewPort = Math.min(iframeHeight - iframeScrolled, viewPortHeight);
|
|
667
|
-
iframeOffset = iframeScrolled;
|
|
668
|
-
}
|
|
669
|
-
const iframeCenter = iframeOffset + iframeVisibleViewPort / 2;
|
|
670
|
-
return {
|
|
671
|
-
iframeCenter,
|
|
672
|
-
iframeScrolled,
|
|
673
|
-
iframeHeight,
|
|
674
|
-
viewPortHeight,
|
|
675
|
-
iframeVisibleViewPort,
|
|
676
|
-
};
|
|
677
|
-
}
|
|
678
|
-
/**
|
|
679
|
-
* Registers an event listener to trigger an alert when the ThoughtSpot app
|
|
680
|
-
* sends an event of a particular message type to the host application.
|
|
681
|
-
*
|
|
682
|
-
* @param messageType The message type
|
|
683
|
-
* @param callback A callback as a function
|
|
684
|
-
* @param options The message options
|
|
685
|
-
* @param isSelf
|
|
686
|
-
* @param isRegisteredBySDK
|
|
687
|
-
* @example
|
|
688
|
-
* ```js
|
|
689
|
-
* tsEmbed.on(EmbedEvent.Error, (data) => {
|
|
690
|
-
* console.error(data);
|
|
691
|
-
* });
|
|
692
|
-
* ```
|
|
693
|
-
* @example
|
|
694
|
-
* ```js
|
|
695
|
-
* tsEmbed.on(EmbedEvent.Save, (data) => {
|
|
696
|
-
* console.log("Answer save clicked", data);
|
|
697
|
-
* }, {
|
|
698
|
-
* start: true // This will trigger the callback on start of save
|
|
699
|
-
* });
|
|
700
|
-
* ```
|
|
701
|
-
*/
|
|
702
|
-
on(messageType, callback, options = { start: false }, isRegisteredBySDK = false) {
|
|
703
|
-
uploadMixpanelEvent(`${MIXPANEL_EVENT.VISUAL_SDK_ON}-${messageType}`, {
|
|
704
|
-
isRegisteredBySDK,
|
|
705
|
-
});
|
|
706
|
-
if (this.isRendered) {
|
|
707
|
-
this.handleError('Please register event handlers before calling render');
|
|
708
|
-
}
|
|
709
|
-
const callbacks = this.eventHandlerMap.get(messageType) || [];
|
|
710
|
-
callbacks.push({ options, callback });
|
|
711
|
-
this.eventHandlerMap.set(messageType, callbacks);
|
|
712
|
-
return this;
|
|
713
|
-
}
|
|
714
|
-
/**
|
|
715
|
-
* Removes an event listener for a particular event type.
|
|
716
|
-
*
|
|
717
|
-
* @param messageType The message type
|
|
718
|
-
* @param callback The callback to remove
|
|
719
|
-
* @example
|
|
720
|
-
* ```js
|
|
721
|
-
* const errorHandler = (data) => { console.error(data); };
|
|
722
|
-
* tsEmbed.on(EmbedEvent.Error, errorHandler);
|
|
723
|
-
* tsEmbed.off(EmbedEvent.Error, errorHandler);
|
|
724
|
-
* ```
|
|
725
|
-
*/
|
|
726
|
-
off(messageType, callback) {
|
|
727
|
-
const callbacks = this.eventHandlerMap.get(messageType) || [];
|
|
728
|
-
const index = callbacks.findIndex((cb) => cb.callback === callback);
|
|
729
|
-
if (index > -1) {
|
|
730
|
-
callbacks.splice(index, 1);
|
|
731
|
-
}
|
|
732
|
-
return this;
|
|
733
|
-
}
|
|
734
|
-
/**
|
|
735
|
-
* Triggers an event on specific Port registered against
|
|
736
|
-
* for the EmbedEvent
|
|
737
|
-
*
|
|
738
|
-
* @param eventType The message type
|
|
739
|
-
* @param data The payload to send
|
|
740
|
-
* @param eventPort
|
|
741
|
-
* @param payload
|
|
742
|
-
*/
|
|
743
|
-
triggerEventOnPort(eventPort, payload) {
|
|
744
|
-
if (eventPort) {
|
|
745
|
-
try {
|
|
746
|
-
eventPort.postMessage({
|
|
747
|
-
type: payload.type,
|
|
748
|
-
data: payload.data,
|
|
749
|
-
});
|
|
750
|
-
}
|
|
751
|
-
catch (e) {
|
|
752
|
-
eventPort.postMessage({ error: e });
|
|
753
|
-
console.log(e);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
else {
|
|
757
|
-
console.log('Event Port is not defined');
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
/**
|
|
761
|
-
* Triggers an event to the embedded app
|
|
762
|
-
*
|
|
763
|
-
* @param messageType The event type
|
|
764
|
-
* @param data The payload to send with the message
|
|
765
|
-
*/
|
|
766
|
-
trigger(messageType, data = {}) {
|
|
767
|
-
uploadMixpanelEvent(`${MIXPANEL_EVENT.VISUAL_SDK_TRIGGER}-${messageType}`);
|
|
768
|
-
return processTrigger(this.iFrame, messageType, this.thoughtSpotHost, data);
|
|
769
|
-
}
|
|
770
|
-
/**
|
|
771
|
-
* Marks the ThoughtSpot object to have been rendered
|
|
772
|
-
* Needs to be overridden by subclasses to do the actual
|
|
773
|
-
* rendering of the iframe.
|
|
774
|
-
*
|
|
775
|
-
* @param args
|
|
776
|
-
*/
|
|
777
|
-
render() {
|
|
778
|
-
this.isRendered = true;
|
|
779
|
-
return this;
|
|
780
|
-
}
|
|
781
|
-
/**
|
|
782
|
-
* Creates the preRender shell
|
|
783
|
-
*
|
|
784
|
-
* @param showPreRenderByDefault
|
|
785
|
-
*/
|
|
786
|
-
preRender(showPreRenderByDefault = false) {
|
|
787
|
-
this.isPreRendered = true;
|
|
788
|
-
return this;
|
|
789
|
-
}
|
|
790
|
-
/**
|
|
791
|
-
* Get the Post Url Params for THOUGHTSPOT from the current
|
|
792
|
-
* host app URL.
|
|
793
|
-
* THOUGHTSPOT URL params starts with a prefix "ts-"
|
|
794
|
-
*
|
|
795
|
-
* @version SDK: 1.14.0 | ThoughtSpot: 8.4.0.cl, 8.4.1-sw
|
|
796
|
-
*/
|
|
797
|
-
getThoughtSpotPostUrlParams() {
|
|
798
|
-
const urlHash = window.location.hash;
|
|
799
|
-
const queryParams = window.location.search;
|
|
800
|
-
const postHashParams = urlHash.split('?');
|
|
801
|
-
const postURLParams = postHashParams[postHashParams.length - 1];
|
|
802
|
-
const queryParamsObj = new URLSearchParams(queryParams);
|
|
803
|
-
const postURLParamsObj = new URLSearchParams(postURLParams);
|
|
804
|
-
const params = new URLSearchParams();
|
|
805
|
-
const addKeyValuePairCb = (value, key) => {
|
|
806
|
-
if (key.startsWith(THOUGHTSPOT_PARAM_PREFIX)) {
|
|
807
|
-
params.append(key, value);
|
|
808
|
-
}
|
|
809
|
-
};
|
|
810
|
-
queryParamsObj.forEach(addKeyValuePairCb);
|
|
811
|
-
postURLParamsObj.forEach(addKeyValuePairCb);
|
|
812
|
-
let tsParams = params.toString();
|
|
813
|
-
tsParams = tsParams ? `?${tsParams}` : '';
|
|
814
|
-
return tsParams;
|
|
815
|
-
}
|
|
816
|
-
/**
|
|
817
|
-
* Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
|
|
818
|
-
*
|
|
819
|
-
* @version SDK: 1.19.1 | ThoughtSpot: *
|
|
820
|
-
*/
|
|
821
|
-
destroy() {
|
|
822
|
-
var _a;
|
|
823
|
-
try {
|
|
824
|
-
(_a = this.insertedDomEl) === null || _a === void 0 ? void 0 : _a.parentNode.removeChild(this.insertedDomEl);
|
|
825
|
-
this.unsubscribeToEvents();
|
|
826
|
-
}
|
|
827
|
-
catch (e) {
|
|
828
|
-
console.log('Error destroying TS Embed', e);
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
getUnderlyingFrameElement() {
|
|
832
|
-
return this.iFrame;
|
|
833
|
-
}
|
|
834
|
-
/**
|
|
835
|
-
* Prerenders a generic instance of the TS component.
|
|
836
|
-
* This means without the path but with the flags already applied.
|
|
837
|
-
* This is useful for prerendering the component in the background.
|
|
838
|
-
*
|
|
839
|
-
* @version SDK: 1.22.0
|
|
840
|
-
* @returns
|
|
841
|
-
*/
|
|
842
|
-
async prerenderGeneric() {
|
|
843
|
-
const prerenderFrameSrc = this.getRootIframeSrc();
|
|
844
|
-
return this.renderIFrame(prerenderFrameSrc);
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
//# sourceMappingURL=TsEmbed.js.map
|