@thoughtspot/visual-embed-sdk 1.33.0-alpha.1 → 1.33.0-alpha.2
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/auth.d.ts.map +1 -1
- package/cjs/src/auth.js +6 -5
- package/cjs/src/auth.js.map +1 -1
- package/cjs/src/authToken.d.ts.map +1 -1
- package/cjs/src/authToken.js +5 -7
- package/cjs/src/authToken.js.map +1 -1
- package/cjs/src/embed/app.d.ts +12 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +13 -4
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +30 -0
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/base.d.ts.map +1 -1
- package/cjs/src/embed/base.js +2 -0
- package/cjs/src/embed/base.js.map +1 -1
- package/cjs/src/embed/search.d.ts +15 -1
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js +6 -4
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/search.spec.js +9 -9
- package/cjs/src/embed/search.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +1 -1
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +10 -6
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/errors.d.ts +11 -0
- package/cjs/src/errors.d.ts.map +1 -1
- package/cjs/src/errors.js +11 -0
- package/cjs/src/errors.js.map +1 -1
- package/cjs/src/mixpanel-service.d.ts.map +1 -1
- package/cjs/src/mixpanel-service.js +2 -1
- package/cjs/src/mixpanel-service.js.map +1 -1
- package/cjs/src/react/index.spec.js +1 -1
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/types.d.ts +155 -6
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +128 -3
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/processData.d.ts.map +1 -1
- package/cjs/src/utils/processData.js +2 -1
- package/cjs/src/utils/processData.js.map +1 -1
- package/cjs/src/utils/reporting.d.ts +16 -0
- package/cjs/src/utils/reporting.d.ts.map +1 -0
- package/cjs/src/utils/reporting.js +68 -0
- package/cjs/src/utils/reporting.js.map +1 -0
- package/cjs/src/utils/reporting.spec.d.ts +2 -0
- package/cjs/src/utils/reporting.spec.d.ts.map +1 -0
- package/cjs/src/utils/reporting.spec.js +76 -0
- package/cjs/src/utils/reporting.spec.js.map +1 -0
- package/dist/src/auth.d.ts.map +1 -1
- package/dist/src/authToken.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts +12 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +15 -1
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +1 -1
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/errors.d.ts +11 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/mixpanel-service.d.ts.map +1 -1
- package/dist/src/types.d.ts +155 -6
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/processData.d.ts.map +1 -1
- package/dist/src/utils/reporting.d.ts +16 -0
- package/dist/src/utils/reporting.d.ts.map +1 -0
- package/dist/src/utils/reporting.spec.d.ts +2 -0
- package/dist/src/utils/reporting.spec.d.ts.map +1 -0
- package/dist/tsembed-react.es.js +192 -38
- package/dist/tsembed-react.js +192 -38
- package/dist/tsembed.es.js +239 -39
- package/dist/tsembed.js +239 -39
- package/dist/visual-embed-sdk-react-full.d.ts +183 -9
- package/dist/visual-embed-sdk-react.d.ts +183 -9
- package/dist/visual-embed-sdk.d.ts +183 -9
- package/lib/package.json +1 -1
- package/lib/src/auth.d.ts.map +1 -1
- package/lib/src/auth.js +6 -5
- package/lib/src/auth.js.map +1 -1
- package/lib/src/authToken.d.ts.map +1 -1
- package/lib/src/authToken.js +5 -7
- package/lib/src/authToken.js.map +1 -1
- package/lib/src/embed/app.d.ts +12 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +12 -3
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +31 -1
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts.map +1 -1
- package/lib/src/embed/base.js +2 -0
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/search.d.ts +15 -1
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +6 -4
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/search.spec.js +9 -9
- package/lib/src/embed/search.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +1 -1
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +10 -6
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/errors.d.ts +11 -0
- package/lib/src/errors.d.ts.map +1 -1
- package/lib/src/errors.js +11 -0
- package/lib/src/errors.js.map +1 -1
- package/lib/src/mixpanel-service.d.ts.map +1 -1
- package/lib/src/mixpanel-service.js +2 -1
- package/lib/src/mixpanel-service.js.map +1 -1
- package/lib/src/react/index.spec.js +1 -1
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/types.d.ts +155 -6
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +128 -3
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/processData.d.ts.map +1 -1
- package/lib/src/utils/processData.js +2 -1
- package/lib/src/utils/processData.js.map +1 -1
- package/lib/src/utils/reporting.d.ts +16 -0
- package/lib/src/utils/reporting.d.ts.map +1 -0
- package/lib/src/utils/reporting.js +62 -0
- package/lib/src/utils/reporting.js.map +1 -0
- package/lib/src/utils/reporting.spec.d.ts +2 -0
- package/lib/src/utils/reporting.spec.d.ts.map +1 -0
- package/lib/src/utils/reporting.spec.js +74 -0
- package/lib/src/utils/reporting.spec.js.map +1 -0
- package/lib/src/visual-embed-sdk.d.ts +183 -9
- package/package.json +1 -1
- package/src/auth.ts +6 -5
- package/src/authToken.ts +5 -9
- package/src/embed/app.spec.ts +46 -0
- package/src/embed/app.ts +20 -3
- package/src/embed/base.ts +3 -1
- package/src/embed/search.spec.ts +9 -9
- package/src/embed/search.ts +21 -4
- package/src/embed/ts-embed.ts +13 -6
- package/src/errors.ts +11 -0
- package/src/mixpanel-service.ts +2 -1
- package/src/react/index.spec.tsx +1 -1
- package/src/types.ts +158 -3
- package/src/utils/processData.ts +2 -3
- package/src/utils/reporting.spec.ts +91 -0
- package/src/utils/reporting.ts +71 -0
package/src/embed/search.ts
CHANGED
|
@@ -88,6 +88,19 @@ export interface SearchViewConfig
|
|
|
88
88
|
* ```
|
|
89
89
|
*/
|
|
90
90
|
collapseDataSources?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* If set to true, the data panel is collapsed on load,
|
|
93
|
+
* but can be expanded manually.
|
|
94
|
+
* @version: SDK: 1.34.0 | ThoughtSpot: 10.3.0.cl
|
|
95
|
+
* @example
|
|
96
|
+
* ```js
|
|
97
|
+
* const embed = new SearchEmbed('#tsEmbed', {
|
|
98
|
+
* ... // other options
|
|
99
|
+
* collapseDataPanel:true,
|
|
100
|
+
* })
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
collapseDataPanel?: boolean;
|
|
91
104
|
/**
|
|
92
105
|
* Show or hide the data sources panel.
|
|
93
106
|
* @version: SDK: 1.2.0 | ThoughtSpot: 9.1.0.sw
|
|
@@ -216,7 +229,7 @@ export interface SearchViewConfig
|
|
|
216
229
|
hideSearchBar?: boolean;
|
|
217
230
|
/**
|
|
218
231
|
* Flag to control Data panel experience
|
|
219
|
-
* @default
|
|
232
|
+
* @default true
|
|
220
233
|
* @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
|
|
221
234
|
* @example
|
|
222
235
|
* ```js
|
|
@@ -236,6 +249,7 @@ export interface SearchViewConfig
|
|
|
236
249
|
* To set the initial state of the search bar in case of saved-answers.
|
|
237
250
|
* @default false
|
|
238
251
|
* @version SDK: 1.32.0 | Thoughtspot: 10.0.0.cl
|
|
252
|
+
* @deprecated Use {@link collapseSearchBar} instead
|
|
239
253
|
*/
|
|
240
254
|
collapseSearchBarInitially?: boolean;
|
|
241
255
|
/**
|
|
@@ -320,7 +334,8 @@ export class SearchEmbed extends TsEmbed {
|
|
|
320
334
|
*/
|
|
321
335
|
private getDataSourceMode() {
|
|
322
336
|
let dataSourceMode = DataSourceVisualMode.Expanded;
|
|
323
|
-
if (this.viewConfig.collapseDataSources === true
|
|
337
|
+
if (this.viewConfig.collapseDataSources === true
|
|
338
|
+
|| this.viewConfig.collapseDataPanel === true) {
|
|
324
339
|
dataSourceMode = DataSourceVisualMode.Collapsed;
|
|
325
340
|
}
|
|
326
341
|
if (this.viewConfig.hideDataSources === true) {
|
|
@@ -341,7 +356,7 @@ export class SearchEmbed extends TsEmbed {
|
|
|
341
356
|
dataSources,
|
|
342
357
|
excludeRuntimeFiltersfromURL,
|
|
343
358
|
hideSearchBar,
|
|
344
|
-
dataPanelV2 =
|
|
359
|
+
dataPanelV2 = true,
|
|
345
360
|
useLastSelectedSources = false,
|
|
346
361
|
runtimeParameters,
|
|
347
362
|
collapseSearchBarInitially = false,
|
|
@@ -351,6 +366,7 @@ export class SearchEmbed extends TsEmbed {
|
|
|
351
366
|
dataPanelCustomGroupsAccordionInitialState = DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL,
|
|
352
367
|
focusSearchBarOnRender = true,
|
|
353
368
|
excludeRuntimeParametersfromURL,
|
|
369
|
+
collapseSearchBar = true,
|
|
354
370
|
} = this.viewConfig;
|
|
355
371
|
const queryParams = this.getBaseQueryParams();
|
|
356
372
|
|
|
@@ -406,7 +422,8 @@ export class SearchEmbed extends TsEmbed {
|
|
|
406
422
|
}
|
|
407
423
|
|
|
408
424
|
queryParams[Param.searchEmbed] = true;
|
|
409
|
-
|
|
425
|
+
/* eslint-disable-next-line max-len */
|
|
426
|
+
queryParams[Param.CollapseSearchBarInitially] = collapseSearchBarInitially || collapseSearchBar;
|
|
410
427
|
queryParams[Param.EnableCustomColumnGroups] = enableCustomColumnGroups;
|
|
411
428
|
if (dataPanelCustomGroupsAccordionInitialState
|
|
412
429
|
=== DataPanelCustomColumnGroupsAccordionState.COLLAPSE_ALL
|
package/src/embed/ts-embed.ts
CHANGED
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
} from './base';
|
|
60
60
|
import { AuthFailureType } from '../auth';
|
|
61
61
|
import { getEmbedConfig } from './embedConfig';
|
|
62
|
+
import { ERROR_MESSAGE } from '../errors';
|
|
62
63
|
|
|
63
64
|
const { version } = pkgInfo;
|
|
64
65
|
|
|
@@ -347,7 +348,7 @@ export class TsEmbed {
|
|
|
347
348
|
data: { authToken },
|
|
348
349
|
});
|
|
349
350
|
} catch (e) {
|
|
350
|
-
logger.error(
|
|
351
|
+
logger.error(`${ERROR_MESSAGE.INVALID_TOKEN_ERROR} Error : ${e?.message}`);
|
|
351
352
|
processAuthFailure(e, this.isPreRendered ? this.preRenderWrapper : this.el);
|
|
352
353
|
}
|
|
353
354
|
} else if (autoLogin) {
|
|
@@ -387,7 +388,9 @@ export class TsEmbed {
|
|
|
387
388
|
* @param queryParams
|
|
388
389
|
* @returns queryParams
|
|
389
390
|
*/
|
|
390
|
-
protected getBaseQueryParams(
|
|
391
|
+
protected getBaseQueryParams(
|
|
392
|
+
queryParams: Record<any, any> = {},
|
|
393
|
+
) {
|
|
391
394
|
let hostAppUrl = window?.location?.host || '';
|
|
392
395
|
|
|
393
396
|
// The below check is needed because TS Cloud firewall, blocks
|
|
@@ -438,6 +441,7 @@ export class TsEmbed {
|
|
|
438
441
|
contextMenuTrigger,
|
|
439
442
|
linkOverride,
|
|
440
443
|
insertInToSlide,
|
|
444
|
+
disableRedirectionLinksInNewTab,
|
|
441
445
|
} = this.viewConfig;
|
|
442
446
|
|
|
443
447
|
if (Array.isArray(visibleActions) && Array.isArray(hiddenActions)) {
|
|
@@ -505,6 +509,9 @@ export class TsEmbed {
|
|
|
505
509
|
if (insertInToSlide) {
|
|
506
510
|
queryParams[Param.ShowInsertToSlide] = insertInToSlide;
|
|
507
511
|
}
|
|
512
|
+
if (disableRedirectionLinksInNewTab) {
|
|
513
|
+
queryParams[Param.DisableRedirectionLinksInNewTab] = disableRedirectionLinksInNewTab;
|
|
514
|
+
}
|
|
508
515
|
|
|
509
516
|
queryParams[Param.OverrideNativeConsole] = true;
|
|
510
517
|
queryParams[Param.ClientLogLevel] = this.embedConfig.logLevel;
|
|
@@ -557,7 +564,7 @@ export class TsEmbed {
|
|
|
557
564
|
iFrame.mozallowfullscreen = true;
|
|
558
565
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
559
566
|
// @ts-ignore
|
|
560
|
-
iFrame.allow = 'clipboard-read; clipboard-write';
|
|
567
|
+
iFrame.allow = 'clipboard-read; clipboard-write fullscreen';
|
|
561
568
|
|
|
562
569
|
const {
|
|
563
570
|
height: frameHeight,
|
|
@@ -1000,7 +1007,7 @@ export class TsEmbed {
|
|
|
1000
1007
|
*/
|
|
1001
1008
|
public preRender(showPreRenderByDefault = false): TsEmbed {
|
|
1002
1009
|
if (!this.viewConfig.preRenderId) {
|
|
1003
|
-
logger.error(
|
|
1010
|
+
logger.error(ERROR_MESSAGE.PRERENDER_ID_MISSING);
|
|
1004
1011
|
return this;
|
|
1005
1012
|
}
|
|
1006
1013
|
this.isPreRendered = true;
|
|
@@ -1107,7 +1114,7 @@ export class TsEmbed {
|
|
|
1107
1114
|
*/
|
|
1108
1115
|
public showPreRender(): void {
|
|
1109
1116
|
if (!this.viewConfig.preRenderId) {
|
|
1110
|
-
logger.error(
|
|
1117
|
+
logger.error(ERROR_MESSAGE.PRERENDER_ID_MISSING);
|
|
1111
1118
|
return;
|
|
1112
1119
|
}
|
|
1113
1120
|
if (!this.isPreRenderAvailable()) {
|
|
@@ -1155,7 +1162,7 @@ export class TsEmbed {
|
|
|
1155
1162
|
*/
|
|
1156
1163
|
public syncPreRenderStyle(): void {
|
|
1157
1164
|
if (!this.isPreRenderAvailable() || !this.el) {
|
|
1158
|
-
logger.error(
|
|
1165
|
+
logger.error(ERROR_MESSAGE.SYNC_STYLE_CALLED_BEFORE_RENDER);
|
|
1159
1166
|
return;
|
|
1160
1167
|
}
|
|
1161
1168
|
const elBoundingClient = this.el.getBoundingClientRect();
|
package/src/errors.ts
CHANGED
|
@@ -4,4 +4,15 @@ export const ERROR_MESSAGE = {
|
|
|
4
4
|
TRIGGER_TIMED_OUT: 'Trigger timedout in getting response',
|
|
5
5
|
SEARCHEMBED_BETA_WRANING_MESSAGE: 'Search Embed is in Beta in this release.',
|
|
6
6
|
SAGE_EMBED_BETA_WARNING_MESSAGE: 'Sage Embed is in Beta in this release.',
|
|
7
|
+
THIRD_PARTY_COOKIE_BLOCKED_ALERT: 'Third party cookie access is blocked on this browser, please allow third party cookies for this to work properly. \nYou can use `suppressNoCookieAccessAlert` to suppress this message.',
|
|
8
|
+
DUPLICATE_TOKEN_ERR: 'Duplicate token, please issue a new token every time getAuthToken callback is called. See https://developers.thoughtspot.com/docs/?pageid=embed-auth#trusted-auth-embed for more details.',
|
|
9
|
+
SDK_NOT_INITIALIZED: 'SDK not initialized',
|
|
10
|
+
SESSION_INFO_FAILED: 'Failed to get session info',
|
|
11
|
+
INVALID_TOKEN_ERROR: 'Received invalid token from getAuthToken callback or authToken endpoint.',
|
|
12
|
+
MIXPANEL_TOKEN_NOT_FOUND: 'Mixpanel token not found in session info',
|
|
13
|
+
PRERENDER_ID_MISSING: 'PreRender id is required for preRender',
|
|
14
|
+
SYNC_STYLE_CALLED_BEFORE_RENDER: 'PreRender should be called before using syncPreRenderStyle',
|
|
15
|
+
CSP_VIOLATION_ALERT: 'CSP violation detected. Please check the console errors for more details.',
|
|
16
|
+
CSP_FRAME_HOST_VIOLATION_LOG_MESSAGE: 'Please setup CSP Correctly for the Application to start working. You can know more about setting CSP Correctly here: https://developers.thoughtspot.com/docs/security-settings#csp-viz-embed-hosts. \n In case you are still facing error, please read: https://developers.thoughtspot.com/docs/security-settings#csp-viz-embed-hosts',
|
|
17
|
+
MISSING_REPORTING_OBSERVER: 'ReportingObserver not supported',
|
|
7
18
|
};
|
package/src/mixpanel-service.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as mixpanel from 'mixpanel-browser';
|
|
2
2
|
import { logger } from './utils/logger';
|
|
3
3
|
import { SessionInfo } from './utils/sessionInfoService';
|
|
4
|
+
import { ERROR_MESSAGE } from './errors';
|
|
4
5
|
|
|
5
6
|
export const EndPoints = {
|
|
6
7
|
CONFIG: '/callosum/v1/system/config',
|
|
@@ -57,7 +58,7 @@ function emptyQueue() {
|
|
|
57
58
|
*/
|
|
58
59
|
export function initMixpanel(sessionInfo: SessionInfo): void {
|
|
59
60
|
if (!sessionInfo || !sessionInfo.mixpanelToken) {
|
|
60
|
-
logger.error(
|
|
61
|
+
logger.error(ERROR_MESSAGE.MIXPANEL_TOKEN_NOT_FOUND);
|
|
61
62
|
return;
|
|
62
63
|
}
|
|
63
64
|
// On a public cluster the user is anonymous, so don't set the identify to
|
package/src/react/index.spec.tsx
CHANGED
|
@@ -56,7 +56,7 @@ describe('React Components', () => {
|
|
|
56
56
|
),
|
|
57
57
|
).toBe(true);
|
|
58
58
|
expect(getIFrameSrc(container)).toBe(
|
|
59
|
-
`http://${thoughtSpotHost}/?hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22,%22editACopy%22,%22saveAsView%22,%22updateTSL%22,%22editTSL%22,%22onDeleteAnswer%22]&overrideConsoleLogs=true&clientLogLevel=ERROR&enableDataPanelV2=
|
|
59
|
+
`http://${thoughtSpotHost}/?hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22,%22editACopy%22,%22saveAsView%22,%22updateTSL%22,%22editTSL%22,%22onDeleteAnswer%22]&overrideConsoleLogs=true&clientLogLevel=ERROR&enableDataPanelV2=true&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true&collapseSearchBarInitially=true&enableCustomColumnGroups=false&dataPanelCustomGroupsAccordionInitialState=EXPAND_ALL#/embed/answer`,
|
|
60
60
|
);
|
|
61
61
|
});
|
|
62
62
|
|
package/src/types.ts
CHANGED
|
@@ -201,6 +201,10 @@ export enum HomeLeftNavItem {
|
|
|
201
201
|
* @version SDK: 1.28.0| ThoughtSpot: 9.12.5.cl
|
|
202
202
|
*/
|
|
203
203
|
SpotIQAnalysis = 'spotiq-analysis',
|
|
204
|
+
/**
|
|
205
|
+
* @version SDK: 1.34.0| ThoughtSpot: 10.3.0.cl
|
|
206
|
+
*/
|
|
207
|
+
LiveboardSchedules = 'liveboard-schedules'
|
|
204
208
|
}
|
|
205
209
|
export type DOMSelector = string | HTMLElement;
|
|
206
210
|
|
|
@@ -1012,6 +1016,30 @@ export interface ViewConfig {
|
|
|
1012
1016
|
*/
|
|
1013
1017
|
// eslint-disable-next-line camelcase
|
|
1014
1018
|
enableV2Shell_experimental?: boolean;
|
|
1019
|
+
/**
|
|
1020
|
+
* To set the initial state of the search bar in case of saved-answers.
|
|
1021
|
+
* @default true
|
|
1022
|
+
* @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
|
|
1023
|
+
* @example
|
|
1024
|
+
* ```js
|
|
1025
|
+
* const embed = new LiveboardEmbed('#embed', {
|
|
1026
|
+
* liveboardId: '123',
|
|
1027
|
+
* collapseSearchBar: true
|
|
1028
|
+
* });
|
|
1029
|
+
*/
|
|
1030
|
+
collapseSearchBar?: boolean;
|
|
1031
|
+
/**
|
|
1032
|
+
* This flag can be used to disable links inside the embedded app,
|
|
1033
|
+
* and disables redirection of links in a new tab.
|
|
1034
|
+
* @example
|
|
1035
|
+
* ```js
|
|
1036
|
+
* const embed = new LiveboardEmbed('#embed', {
|
|
1037
|
+
* disableRedirectionLinksInNewTab: true
|
|
1038
|
+
* });
|
|
1039
|
+
* ```
|
|
1040
|
+
* @version SDK: 1.32.1 | ThoughtSpot: 10.3.0.cl
|
|
1041
|
+
*/
|
|
1042
|
+
disableRedirectionLinksInNewTab?: boolean;
|
|
1015
1043
|
}
|
|
1016
1044
|
|
|
1017
1045
|
/**
|
|
@@ -2493,13 +2521,15 @@ export enum HostEvent {
|
|
|
2493
2521
|
*
|
|
2494
2522
|
* @example
|
|
2495
2523
|
* ```js
|
|
2496
|
-
*
|
|
2524
|
+
* searchEmbed.trigger(HostEvent.CreateMonitor)
|
|
2497
2525
|
* ```
|
|
2498
2526
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
|
|
2499
2527
|
*/
|
|
2500
2528
|
CreateMonitor = 'createMonitor',
|
|
2501
2529
|
/**
|
|
2502
|
-
* Trigger the **Manage alerts** action on a
|
|
2530
|
+
* Trigger the **Manage alerts** action on a KPI chart
|
|
2531
|
+
* in a visualization or saved Answer.
|
|
2532
|
+
*
|
|
2503
2533
|
* @param - an object with `vizId` as a key
|
|
2504
2534
|
* @example
|
|
2505
2535
|
* ```js
|
|
@@ -2507,6 +2537,16 @@ export enum HostEvent {
|
|
|
2507
2537
|
* vizId: '730496d6-6903-4601-937e-2c691821af3c'
|
|
2508
2538
|
* })
|
|
2509
2539
|
* ```
|
|
2540
|
+
*
|
|
2541
|
+
* @example
|
|
2542
|
+
* ```js
|
|
2543
|
+
* searchEmbed.trigger(HostEvent.ManageMonitor)
|
|
2544
|
+
* ```
|
|
2545
|
+
*
|
|
2546
|
+
* @example
|
|
2547
|
+
* ```js
|
|
2548
|
+
* vizEmbed.trigger(HostEvent.ManageMonitor)
|
|
2549
|
+
* ```
|
|
2510
2550
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
|
|
2511
2551
|
*/
|
|
2512
2552
|
ManageMonitor = 'manageMonitor',
|
|
@@ -3084,6 +3124,8 @@ export enum Param {
|
|
|
3084
3124
|
IsFullAppEmbed = 'isFullAppEmbed',
|
|
3085
3125
|
IsOnBeforeGetVizDataInterceptEnabled = 'isOnBeforeGetVizDataInterceptEnabled',
|
|
3086
3126
|
FocusSearchBarOnRender = 'focusSearchBarOnRender',
|
|
3127
|
+
DisableRedirectionLinksInNewTab = 'disableRedirectionLinksInNewTab',
|
|
3128
|
+
HomePageSearchBarMode = 'homePageSearchBarMode',
|
|
3087
3129
|
}
|
|
3088
3130
|
|
|
3089
3131
|
/**
|
|
@@ -3234,6 +3276,7 @@ export enum Action {
|
|
|
3234
3276
|
*/
|
|
3235
3277
|
ConfigureFilter = 'configureFilter',
|
|
3236
3278
|
CollapseDataSources = 'collapseDataSources',
|
|
3279
|
+
CollapseDataPanel = 'collapseDataPanel',
|
|
3237
3280
|
/**
|
|
3238
3281
|
* The **Choose sources** button on Search page.
|
|
3239
3282
|
* Allows selecting data sources for search queries.
|
|
@@ -3630,12 +3673,15 @@ export enum Action {
|
|
|
3630
3673
|
* The Create alert action on KPI charts.
|
|
3631
3674
|
* @example
|
|
3632
3675
|
* ```js
|
|
3633
|
-
* disabledActions: [Action.CreateMonitor
|
|
3676
|
+
* disabledActions: [Action.CreateMonitor]
|
|
3634
3677
|
* ```
|
|
3635
3678
|
* @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
|
|
3636
3679
|
*/
|
|
3637
3680
|
CreateMonitor = 'createMonitor',
|
|
3638
3681
|
/**
|
|
3682
|
+
* @deprecated
|
|
3683
|
+
* Reports errors
|
|
3684
|
+
*
|
|
3639
3685
|
* @example
|
|
3640
3686
|
* ```js
|
|
3641
3687
|
* disabledActions: [Action.ReportError]
|
|
@@ -3860,35 +3906,84 @@ export enum Action {
|
|
|
3860
3906
|
*/
|
|
3861
3907
|
RenameModalTitleDescription = 'renameModalTitleDescription',
|
|
3862
3908
|
/**
|
|
3909
|
+
*
|
|
3910
|
+
* @example
|
|
3911
|
+
* ```js
|
|
3912
|
+
* disabledActions: [Action.RequestVerification]
|
|
3913
|
+
* ```
|
|
3863
3914
|
*
|
|
3864
3915
|
* @version SDK: 1.25.0 | Thoughtspot: 9.6.0.cl
|
|
3865
3916
|
*/
|
|
3866
3917
|
RequestVerification = 'requestVerification',
|
|
3867
3918
|
/**
|
|
3919
|
+
*
|
|
3920
|
+
* Allows users to mark a Liveboard as verified.
|
|
3921
|
+
*
|
|
3922
|
+
* @example
|
|
3923
|
+
* ```js
|
|
3924
|
+
* disabledActions: [Action.MarkAsVerified]
|
|
3925
|
+
* ```
|
|
3868
3926
|
* @version SDK: 1.25.0 | Thoughtspot: 9.6.0.cl
|
|
3869
3927
|
*/
|
|
3870
3928
|
MarkAsVerified = 'markAsVerified',
|
|
3871
3929
|
/**
|
|
3930
|
+
* The **Add Tab** action on a Liveboard.
|
|
3931
|
+
* Allows adding a new tab to a Liveboard view.
|
|
3932
|
+
*
|
|
3933
|
+
* @example
|
|
3934
|
+
* ```js
|
|
3935
|
+
* disabledActions: [Action.AddTab]
|
|
3936
|
+
* ```
|
|
3872
3937
|
* @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
|
|
3873
3938
|
*/
|
|
3874
3939
|
AddTab = 'addTab',
|
|
3875
3940
|
/**
|
|
3941
|
+
*
|
|
3942
|
+
* Initiates contextual change analysis on KPI charts.
|
|
3943
|
+
*
|
|
3944
|
+
* @example
|
|
3945
|
+
* ```js
|
|
3946
|
+
* disabledActions: [Action.EnableContextualChangeAnalysis]
|
|
3947
|
+
* ```
|
|
3876
3948
|
* @version SDK: 1.25.0 | Thoughtspot: 9.6.0.cl
|
|
3877
3949
|
*/
|
|
3878
3950
|
EnableContextualChangeAnalysis = 'enableContextualChangeAnalysis',
|
|
3879
3951
|
/**
|
|
3952
|
+
*
|
|
3953
|
+
* @example
|
|
3954
|
+
* ```js
|
|
3955
|
+
* disabledActions: [Action.ShowSageQuery]
|
|
3956
|
+
* ```
|
|
3957
|
+
*
|
|
3880
3958
|
* @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
|
|
3881
3959
|
*/
|
|
3882
3960
|
ShowSageQuery = 'showSageQuery',
|
|
3883
3961
|
/**
|
|
3962
|
+
*
|
|
3963
|
+
* @example
|
|
3964
|
+
* ```js
|
|
3965
|
+
* disabledActions: [Action.EditSageAnswer]
|
|
3966
|
+
* ```
|
|
3884
3967
|
* @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
|
|
3885
3968
|
*/
|
|
3886
3969
|
EditSageAnswer = 'editSageAnswer',
|
|
3887
3970
|
/**
|
|
3971
|
+
*
|
|
3972
|
+
* This action allows users to send feedback on AI-generated Answers.
|
|
3973
|
+
*
|
|
3974
|
+
* @example
|
|
3975
|
+
* ```js
|
|
3976
|
+
* disabledActions: [Action.SageAnswerFeedback]
|
|
3977
|
+
* ```
|
|
3888
3978
|
* @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
|
|
3889
3979
|
*/
|
|
3890
3980
|
SageAnswerFeedback = 'sageAnswerFeedback',
|
|
3891
3981
|
/**
|
|
3982
|
+
*
|
|
3983
|
+
* @example
|
|
3984
|
+
* ```js
|
|
3985
|
+
* disabledActions: [Action.ModifySageAnswer]
|
|
3986
|
+
* ```
|
|
3892
3987
|
* @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
|
|
3893
3988
|
*/
|
|
3894
3989
|
ModifySageAnswer = 'modifySageAnswer',
|
|
@@ -4018,6 +4113,66 @@ export enum Action {
|
|
|
4018
4113
|
* @version SDK: 1.27.10 | Thoughtspot: 9.12.5.cl
|
|
4019
4114
|
*/
|
|
4020
4115
|
AIHighlights = 'AIHighlights',
|
|
4116
|
+
|
|
4117
|
+
/**
|
|
4118
|
+
* Action ID for edit schedule action on schedule on homepage
|
|
4119
|
+
* @example
|
|
4120
|
+
* ```js
|
|
4121
|
+
* disabledActions: [Action.EditScheduleHomepage]
|
|
4122
|
+
* ```
|
|
4123
|
+
* @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
|
|
4124
|
+
*/
|
|
4125
|
+
EditScheduleHomepage = 'editScheduleHomepage',
|
|
4126
|
+
|
|
4127
|
+
/**
|
|
4128
|
+
* Action ID for pause schedule action on schedule on homepage
|
|
4129
|
+
* @example
|
|
4130
|
+
* ```js
|
|
4131
|
+
* disabledActions: [Action.PauseScheduleHomepage]
|
|
4132
|
+
* ```
|
|
4133
|
+
* @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
|
|
4134
|
+
*/
|
|
4135
|
+
PauseScheduleHomepage = 'pauseScheduleHomepage',
|
|
4136
|
+
|
|
4137
|
+
/**
|
|
4138
|
+
* Action ID for view schedule run action on schedule on homepage
|
|
4139
|
+
* @example
|
|
4140
|
+
* ```js
|
|
4141
|
+
* disabledActions: [Action.ViewScheduleRunHomepage]
|
|
4142
|
+
* ```
|
|
4143
|
+
* @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
|
|
4144
|
+
*/
|
|
4145
|
+
ViewScheduleRunHomepage = 'viewScheduleRunHomepage',
|
|
4146
|
+
|
|
4147
|
+
/**
|
|
4148
|
+
* Action ID for unsubscribe schedule action on schedule on homepage
|
|
4149
|
+
* @example
|
|
4150
|
+
* ```js
|
|
4151
|
+
* disabledActions: [Action.UnsubscribeScheduleHomepage]
|
|
4152
|
+
* ```
|
|
4153
|
+
* @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
|
|
4154
|
+
*/
|
|
4155
|
+
UnsubscribeScheduleHomepage = 'unsubscribeScheduleHomepage',
|
|
4156
|
+
|
|
4157
|
+
/**
|
|
4158
|
+
* Action ID for delete schedule action on schedule on homepage
|
|
4159
|
+
* @example
|
|
4160
|
+
* ```js
|
|
4161
|
+
* disabledActions: [Action.DeleteScheduleHomepage]
|
|
4162
|
+
* ```
|
|
4163
|
+
* @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
|
|
4164
|
+
*/
|
|
4165
|
+
DeleteScheduleHomepage = 'deleteScheduleHomepage',
|
|
4166
|
+
|
|
4167
|
+
/**
|
|
4168
|
+
* The **Analyze CTA** action on KPI chart.
|
|
4169
|
+
* @example
|
|
4170
|
+
* ```js
|
|
4171
|
+
* disabledActions: [Action.KPIAnalysisCTA]
|
|
4172
|
+
* ```
|
|
4173
|
+
* @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
|
|
4174
|
+
*/
|
|
4175
|
+
KPIAnalysisCTA = 'kpiAnalysisCTA',
|
|
4021
4176
|
}
|
|
4022
4177
|
|
|
4023
4178
|
export interface AnswerServiceType {
|
package/src/utils/processData.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { AuthFailureType } from '../auth';
|
|
|
9
9
|
import { AuthType, CustomActionPayload, EmbedEvent } from '../types';
|
|
10
10
|
import { AnswerService } from './graphql/answerService/answerService';
|
|
11
11
|
import { resetCachedAuthToken } from '../authToken';
|
|
12
|
+
import { ERROR_MESSAGE } from '../errors';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
*
|
|
@@ -62,9 +63,7 @@ function processNoCookieAccess(e: any, containerEl: Element) {
|
|
|
62
63
|
if (!ignoreNoCookieAccess) {
|
|
63
64
|
if (!suppressNoCookieAccessAlert && !suppressErrorAlerts) {
|
|
64
65
|
// eslint-disable-next-line no-alert
|
|
65
|
-
alert(
|
|
66
|
-
'Third party cookie access is blocked on this browser, please allow third party cookies for this to work properly. \nYou can use `suppressNoCookieAccessAlert` to suppress this message.',
|
|
67
|
-
);
|
|
66
|
+
alert(ERROR_MESSAGE.THIRD_PARTY_COOKIE_BLOCKED_ALERT);
|
|
68
67
|
}
|
|
69
68
|
// eslint-disable-next-line no-param-reassign
|
|
70
69
|
containerEl.innerHTML = loginFailedMessage;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { setEmbedConfig } from '../embed/embedConfig';
|
|
2
|
+
import { registerReportingObserver, getGlobalReportingObserver, resetGlobalReportingObserver } from './reporting';
|
|
3
|
+
import { logger } from './logger';
|
|
4
|
+
import { AuthType } from '../types';
|
|
5
|
+
import { ERROR_MESSAGE } from '../errors';
|
|
6
|
+
|
|
7
|
+
jest.mock('./logger');
|
|
8
|
+
|
|
9
|
+
describe('ReportingObserver', () => {
|
|
10
|
+
let mockReportingObserver: jest.Mock;
|
|
11
|
+
|
|
12
|
+
beforeAll(() => {
|
|
13
|
+
// Mock the ReportingObserver
|
|
14
|
+
mockReportingObserver = jest.fn().mockImplementation((callback: any, options: any) => ({
|
|
15
|
+
observe: jest.fn(),
|
|
16
|
+
disconnect: jest.fn(),
|
|
17
|
+
takeRecords: jest.fn(),
|
|
18
|
+
}));
|
|
19
|
+
(window as any).ReportingObserver = mockReportingObserver;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
jest.clearAllMocks();
|
|
24
|
+
resetGlobalReportingObserver();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('should warn if ReportingObserver is not supported', () => {
|
|
28
|
+
(window as any).ReportingObserver = undefined;
|
|
29
|
+
const observer = registerReportingObserver();
|
|
30
|
+
expect(observer).toBeNull();
|
|
31
|
+
expect(logger.warn).toHaveBeenCalledWith('ReportingObserver not supported');
|
|
32
|
+
(window as any).ReportingObserver = mockReportingObserver;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('should return existing globalObserver if override is false', () => {
|
|
36
|
+
const firstObserver = registerReportingObserver();
|
|
37
|
+
const secondObserver = registerReportingObserver();
|
|
38
|
+
expect(firstObserver === secondObserver).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('should override existing globalObserver if override is true', () => {
|
|
42
|
+
const firstObserver = registerReportingObserver();
|
|
43
|
+
const secondObserver = registerReportingObserver(true);
|
|
44
|
+
expect(firstObserver).not.toBe(secondObserver);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('should return globalObserver', () => {
|
|
48
|
+
const observer = registerReportingObserver();
|
|
49
|
+
const globalObserver = getGlobalReportingObserver();
|
|
50
|
+
expect(globalObserver).toBe(observer);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('Should register a global observer with callback', () => {
|
|
54
|
+
let callBackPassed: any;
|
|
55
|
+
|
|
56
|
+
// Mock the ReportingObserver
|
|
57
|
+
const NewMockRO = jest.fn().mockImplementation((callback: any, options: any) => {
|
|
58
|
+
callBackPassed = callback;
|
|
59
|
+
return ({
|
|
60
|
+
observe: jest.fn(),
|
|
61
|
+
disconnect: jest.fn(),
|
|
62
|
+
takeRecords: jest.fn(),
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
const currentObserver = (window as any).ReportingObserver;
|
|
66
|
+
(window as any).ReportingObserver = NewMockRO;
|
|
67
|
+
|
|
68
|
+
setEmbedConfig({
|
|
69
|
+
thoughtSpotHost: 'testHost',
|
|
70
|
+
authType: AuthType.None,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const mockAlert = jest.fn();
|
|
74
|
+
window.alert = mockAlert;
|
|
75
|
+
|
|
76
|
+
const observer = registerReportingObserver();
|
|
77
|
+
expect(observer).toBeDefined();
|
|
78
|
+
expect(NewMockRO).toHaveBeenCalled();
|
|
79
|
+
expect(callBackPassed).toBeDefined();
|
|
80
|
+
|
|
81
|
+
// call the callback
|
|
82
|
+
callBackPassed([{ type: 'csp-violation', url: 'testHost', body: { effectiveDirective: 'frame-ancestors' } }]);
|
|
83
|
+
|
|
84
|
+
expect(mockAlert).toHaveBeenCalledWith(ERROR_MESSAGE.CSP_VIOLATION_ALERT);
|
|
85
|
+
expect(logger.error).toHaveBeenCalledWith(
|
|
86
|
+
ERROR_MESSAGE.CSP_FRAME_HOST_VIOLATION_LOG_MESSAGE,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
(window as any).ReportingObserver = currentObserver;
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { getEmbedConfig } from '../embed/embedConfig';
|
|
2
|
+
import { logger } from './logger';
|
|
3
|
+
import { ERROR_MESSAGE } from '../errors';
|
|
4
|
+
|
|
5
|
+
enum ReportType {
|
|
6
|
+
CSP_VIOLATION = 'csp-violation',
|
|
7
|
+
DEPRECATION = 'deprecation',
|
|
8
|
+
INTERVENTION = 'intervention',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let globalObserver: ReportingObserver | null = null;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Register a global ReportingObserver to capture all unhandled errors
|
|
15
|
+
* @param overrideExisting boolean to override existing observer
|
|
16
|
+
* @returns ReportingObserver | null
|
|
17
|
+
*/
|
|
18
|
+
export function registerReportingObserver(overrideExisting = false): ReportingObserver | null {
|
|
19
|
+
if (!((window as any).ReportingObserver)) {
|
|
20
|
+
logger.warn(ERROR_MESSAGE.MISSING_REPORTING_OBSERVER);
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (overrideExisting) {
|
|
25
|
+
resetGlobalReportingObserver();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (globalObserver) {
|
|
29
|
+
return globalObserver;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const embedConfig = getEmbedConfig();
|
|
33
|
+
|
|
34
|
+
globalObserver = new ReportingObserver((reports) => {
|
|
35
|
+
reports.forEach((report) => {
|
|
36
|
+
const { type, url, body } = report;
|
|
37
|
+
const reportBody = body as any;
|
|
38
|
+
|
|
39
|
+
const isThoughtSpotHost = url
|
|
40
|
+
&& url.startsWith(embedConfig.thoughtSpotHost);
|
|
41
|
+
|
|
42
|
+
const isFrameHostError = type === ReportType.CSP_VIOLATION
|
|
43
|
+
&& reportBody.effectiveDirective === 'frame-ancestors';
|
|
44
|
+
|
|
45
|
+
if (isThoughtSpotHost && isFrameHostError) {
|
|
46
|
+
if (!embedConfig.suppressErrorAlerts) {
|
|
47
|
+
alert(ERROR_MESSAGE.CSP_VIOLATION_ALERT);
|
|
48
|
+
}
|
|
49
|
+
logger.error(ERROR_MESSAGE.CSP_FRAME_HOST_VIOLATION_LOG_MESSAGE);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}, { buffered: true });
|
|
53
|
+
globalObserver.observe();
|
|
54
|
+
return globalObserver;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get the global ReportingObserver
|
|
59
|
+
* @returns - ReportingObserver | null
|
|
60
|
+
*/
|
|
61
|
+
export function getGlobalReportingObserver(): ReportingObserver | null {
|
|
62
|
+
return globalObserver;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Resets the global ReportingObserver
|
|
67
|
+
*/
|
|
68
|
+
export function resetGlobalReportingObserver(): void {
|
|
69
|
+
if (globalObserver) globalObserver.disconnect();
|
|
70
|
+
globalObserver = null;
|
|
71
|
+
}
|