@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.
Files changed (153) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/embed/app.d.ts +0 -1
  3. package/cjs/src/embed/app.d.ts.map +1 -1
  4. package/cjs/src/embed/app.js +1 -1
  5. package/cjs/src/embed/app.js.map +1 -1
  6. package/cjs/src/embed/liveboard.d.ts +0 -1
  7. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  8. package/cjs/src/embed/liveboard.js +1 -1
  9. package/cjs/src/embed/liveboard.js.map +1 -1
  10. package/cjs/src/embed/sage.d.ts +0 -1
  11. package/cjs/src/embed/sage.d.ts.map +1 -1
  12. package/cjs/src/embed/sage.js +1 -1
  13. package/cjs/src/embed/sage.js.map +1 -1
  14. package/cjs/src/embed/search.d.ts +0 -1
  15. package/cjs/src/embed/search.d.ts.map +1 -1
  16. package/cjs/src/embed/search.js +2 -3
  17. package/cjs/src/embed/search.js.map +1 -1
  18. package/cjs/src/embed/ts-embed.d.ts +0 -1
  19. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  20. package/cjs/src/embed/ts-embed.js +1 -3
  21. package/cjs/src/embed/ts-embed.js.map +1 -1
  22. package/cjs/src/types.d.ts +6 -0
  23. package/cjs/src/types.d.ts.map +1 -1
  24. package/cjs/src/types.js.map +1 -1
  25. package/dist/src/embed/app.d.ts +0 -1
  26. package/dist/src/embed/app.d.ts.map +1 -1
  27. package/dist/src/embed/liveboard.d.ts +0 -1
  28. package/dist/src/embed/liveboard.d.ts.map +1 -1
  29. package/dist/src/embed/sage.d.ts +0 -1
  30. package/dist/src/embed/sage.d.ts.map +1 -1
  31. package/dist/src/embed/search.d.ts +0 -1
  32. package/dist/src/embed/search.d.ts.map +1 -1
  33. package/dist/src/embed/ts-embed.d.ts +0 -1
  34. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  35. package/dist/src/types.d.ts +6 -0
  36. package/dist/src/types.d.ts.map +1 -1
  37. package/dist/tsembed-react.es.js +7 -10
  38. package/dist/tsembed-react.js +7 -10
  39. package/dist/tsembed.es.js +7 -10
  40. package/dist/tsembed.js +7 -10
  41. package/dist/visual-embed-sdk-react-full.d.ts +6 -5
  42. package/dist/visual-embed-sdk-react.d.ts +6 -5
  43. package/dist/visual-embed-sdk.d.ts +6 -5
  44. package/lib/package.json +1 -1
  45. package/lib/src/embed/app.d.ts +0 -1
  46. package/lib/src/embed/app.d.ts.map +1 -1
  47. package/lib/src/embed/app.js +1 -1
  48. package/lib/src/embed/app.js.map +1 -1
  49. package/lib/src/embed/liveboard.d.ts +0 -1
  50. package/lib/src/embed/liveboard.d.ts.map +1 -1
  51. package/lib/src/embed/liveboard.js +1 -1
  52. package/lib/src/embed/liveboard.js.map +1 -1
  53. package/lib/src/embed/sage.d.ts +0 -1
  54. package/lib/src/embed/sage.d.ts.map +1 -1
  55. package/lib/src/embed/sage.js +1 -1
  56. package/lib/src/embed/sage.js.map +1 -1
  57. package/lib/src/embed/search.d.ts +0 -1
  58. package/lib/src/embed/search.d.ts.map +1 -1
  59. package/lib/src/embed/search.js +2 -3
  60. package/lib/src/embed/search.js.map +1 -1
  61. package/lib/src/embed/ts-embed.d.ts +0 -1
  62. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  63. package/lib/src/embed/ts-embed.js +1 -3
  64. package/lib/src/embed/ts-embed.js.map +1 -1
  65. package/lib/src/types.d.ts +6 -0
  66. package/lib/src/types.d.ts.map +1 -1
  67. package/lib/src/types.js.map +1 -1
  68. package/lib/src/visual-embed-sdk.d.ts +6 -5
  69. package/package.json +1 -1
  70. package/src/embed/app.ts +1 -2
  71. package/src/embed/liveboard.ts +1 -2
  72. package/src/embed/sage.ts +1 -2
  73. package/src/embed/search.ts +2 -4
  74. package/src/embed/ts-embed.ts +6 -9
  75. package/src/types.ts +16 -10
  76. package/cjs/src/embed/TsEmbed.d.ts +0 -302
  77. package/cjs/src/embed/TsEmbed.d.ts.map +0 -1
  78. package/cjs/src/embed/TsEmbed.js +0 -851
  79. package/cjs/src/embed/TsEmbed.js.map +0 -1
  80. package/cjs/src/utils/answerService.d.ts +0 -10
  81. package/cjs/src/utils/answerService.d.ts.map +0 -1
  82. package/cjs/src/utils/answerService.js +0 -61
  83. package/cjs/src/utils/answerService.js.map +0 -1
  84. package/cjs/src/utils/answerService.spec.d.ts +0 -2
  85. package/cjs/src/utils/answerService.spec.d.ts.map +0 -1
  86. package/cjs/src/utils/answerService.spec.js +0 -31
  87. package/cjs/src/utils/answerService.spec.js.map +0 -1
  88. package/cjs/src/utils/authService/tokenisedAuthSerice.d.ts +0 -11
  89. package/cjs/src/utils/authService/tokenisedAuthSerice.d.ts.map +0 -1
  90. package/cjs/src/utils/authService/tokenisedAuthSerice.js +0 -44
  91. package/cjs/src/utils/authService/tokenisedAuthSerice.js.map +0 -1
  92. package/cjs/src/utils/authService.d.ts +0 -55
  93. package/cjs/src/utils/authService.d.ts.map +0 -1
  94. package/cjs/src/utils/authService.js +0 -139
  95. package/cjs/src/utils/authService.js.map +0 -1
  96. package/cjs/src/utils/authService.spec.d.ts +0 -2
  97. package/cjs/src/utils/authService.spec.d.ts.map +0 -1
  98. package/cjs/src/utils/authService.spec.js +0 -82
  99. package/cjs/src/utils/authService.spec.js.map +0 -1
  100. package/cjs/src/utils/graphql/graphql-request.spec.d.ts +0 -2
  101. package/cjs/src/utils/graphql/graphql-request.spec.d.ts.map +0 -1
  102. package/cjs/src/utils/graphql/graphql-request.spec.js +0 -39
  103. package/cjs/src/utils/graphql/graphql-request.spec.js.map +0 -1
  104. package/cjs/src/utils/logger.d.ts +0 -28
  105. package/cjs/src/utils/logger.d.ts.map +0 -1
  106. package/cjs/src/utils/logger.js +0 -82
  107. package/cjs/src/utils/logger.js.map +0 -1
  108. package/dist/src/utils/answerService.d.ts +0 -10
  109. package/dist/src/utils/answerService.d.ts.map +0 -1
  110. package/dist/src/utils/answerService.spec.d.ts +0 -2
  111. package/dist/src/utils/answerService.spec.d.ts.map +0 -1
  112. package/dist/src/utils/authService/tokenisedAuthSerice.d.ts +0 -11
  113. package/dist/src/utils/authService/tokenisedAuthSerice.d.ts.map +0 -1
  114. package/dist/src/utils/authService.d.ts +0 -55
  115. package/dist/src/utils/authService.d.ts.map +0 -1
  116. package/dist/src/utils/authService.spec.d.ts +0 -2
  117. package/dist/src/utils/authService.spec.d.ts.map +0 -1
  118. package/dist/src/utils/graphql/graphql-request.spec.d.ts +0 -2
  119. package/dist/src/utils/graphql/graphql-request.spec.d.ts.map +0 -1
  120. package/dist/src/utils/logger.d.ts +0 -28
  121. package/dist/src/utils/logger.d.ts.map +0 -1
  122. package/lib/src/embed/TsEmbed.d.ts +0 -302
  123. package/lib/src/embed/TsEmbed.d.ts.map +0 -1
  124. package/lib/src/embed/TsEmbed.js +0 -847
  125. package/lib/src/embed/TsEmbed.js.map +0 -1
  126. package/lib/src/utils/answerService.d.ts +0 -10
  127. package/lib/src/utils/answerService.d.ts.map +0 -1
  128. package/lib/src/utils/answerService.js +0 -57
  129. package/lib/src/utils/answerService.js.map +0 -1
  130. package/lib/src/utils/answerService.spec.d.ts +0 -2
  131. package/lib/src/utils/answerService.spec.d.ts.map +0 -1
  132. package/lib/src/utils/answerService.spec.js +0 -29
  133. package/lib/src/utils/answerService.spec.js.map +0 -1
  134. package/lib/src/utils/authService/tokenisedAuthSerice.d.ts +0 -11
  135. package/lib/src/utils/authService/tokenisedAuthSerice.d.ts.map +0 -1
  136. package/lib/src/utils/authService/tokenisedAuthSerice.js +0 -39
  137. package/lib/src/utils/authService/tokenisedAuthSerice.js.map +0 -1
  138. package/lib/src/utils/authService.d.ts +0 -55
  139. package/lib/src/utils/authService.d.ts.map +0 -1
  140. package/lib/src/utils/authService.js +0 -129
  141. package/lib/src/utils/authService.js.map +0 -1
  142. package/lib/src/utils/authService.spec.d.ts +0 -2
  143. package/lib/src/utils/authService.spec.d.ts.map +0 -1
  144. package/lib/src/utils/authService.spec.js +0 -80
  145. package/lib/src/utils/authService.spec.js.map +0 -1
  146. package/lib/src/utils/graphql/graphql-request.spec.d.ts +0 -2
  147. package/lib/src/utils/graphql/graphql-request.spec.d.ts.map +0 -1
  148. package/lib/src/utils/graphql/graphql-request.spec.js +0 -36
  149. package/lib/src/utils/graphql/graphql-request.spec.js.map +0 -1
  150. package/lib/src/utils/logger.d.ts +0 -28
  151. package/lib/src/utils/logger.d.ts.map +0 -1
  152. package/lib/src/utils/logger.js +0 -75
  153. package/lib/src/utils/logger.js.map +0 -1
@@ -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