@thoughtspot/visual-embed-sdk 1.44.0 → 1.44.1-test
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/api-intercept.d.ts.map +1 -1
- package/cjs/src/api-intercept.js +8 -3
- package/cjs/src/api-intercept.js.map +1 -1
- package/cjs/src/api-intercept.spec.js +19 -3
- package/cjs/src/api-intercept.spec.js.map +1 -1
- package/cjs/src/embed/app.d.ts +17 -0
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +6 -4
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +84 -1
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/base.d.ts +7 -0
- package/cjs/src/embed/base.d.ts.map +1 -1
- package/cjs/src/embed/base.js +16 -1
- package/cjs/src/embed/base.js.map +1 -1
- package/cjs/src/embed/base.spec.js +21 -0
- package/cjs/src/embed/base.spec.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +6 -1
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +6 -1
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +18 -0
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +10 -5
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +86 -0
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +3 -2
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +51 -17
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +93 -5
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/errors.d.ts +7 -0
- package/cjs/src/errors.d.ts.map +1 -1
- package/cjs/src/errors.js +7 -0
- package/cjs/src/errors.js.map +1 -1
- package/cjs/src/index.d.ts +2 -2
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +2 -1
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/react/all-types-export.d.ts +1 -1
- package/cjs/src/react/all-types-export.d.ts.map +1 -1
- package/cjs/src/react/all-types-export.js +2 -1
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/types.d.ts +248 -6
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +134 -2
- package/cjs/src/types.js.map +1 -1
- package/dist/{index-B2QPwxuL.js → index-BXCUJ09L.js} +1 -1
- package/dist/src/api-intercept.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts +17 -0
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts +7 -0
- package/dist/src/embed/base.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +18 -0
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +3 -2
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/dist/src/errors.d.ts +7 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/react/all-types-export.d.ts +1 -1
- package/dist/src/react/all-types-export.d.ts.map +1 -1
- package/dist/src/types.d.ts +248 -6
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +293 -104
- package/dist/tsembed-react.js +292 -103
- package/dist/tsembed.es.js +307 -105
- package/dist/tsembed.js +306 -103
- package/dist/visual-embed-sdk-react-full.d.ts +245 -7
- package/dist/visual-embed-sdk-react.d.ts +238 -7
- package/dist/visual-embed-sdk.d.ts +245 -7
- package/lib/package.json +1 -1
- package/lib/src/api-intercept.d.ts.map +1 -1
- package/lib/src/api-intercept.js +9 -4
- package/lib/src/api-intercept.js.map +1 -1
- package/lib/src/api-intercept.spec.js +20 -4
- package/lib/src/api-intercept.spec.js.map +1 -1
- package/lib/src/embed/app.d.ts +17 -0
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +6 -4
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +84 -1
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts +7 -0
- package/lib/src/embed/base.d.ts.map +1 -1
- package/lib/src/embed/base.js +14 -0
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/base.spec.js +21 -0
- package/lib/src/embed/base.spec.js.map +1 -1
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js +7 -2
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +7 -2
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +18 -0
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +11 -6
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +86 -0
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +3 -2
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +52 -18
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +94 -6
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/errors.d.ts +7 -0
- package/lib/src/errors.d.ts.map +1 -1
- package/lib/src/errors.js +7 -0
- package/lib/src/errors.js.map +1 -1
- package/lib/src/index.d.ts +2 -2
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -2
- package/lib/src/index.js.map +1 -1
- package/lib/src/react/all-types-export.d.ts +1 -1
- package/lib/src/react/all-types-export.d.ts.map +1 -1
- package/lib/src/react/all-types-export.js +1 -1
- package/lib/src/react/all-types-export.js.map +1 -1
- package/lib/src/types.d.ts +248 -6
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +133 -1
- package/lib/src/types.js.map +1 -1
- package/package.json +1 -1
- package/src/api-intercept.spec.ts +23 -10
- package/src/api-intercept.ts +9 -4
- package/src/embed/app.spec.ts +116 -2
- package/src/embed/app.ts +26 -2
- package/src/embed/base.spec.ts +28 -0
- package/src/embed/base.ts +15 -0
- package/src/embed/conversation.spec.ts +7 -2
- package/src/embed/conversation.ts +7 -2
- package/src/embed/liveboard.spec.ts +107 -0
- package/src/embed/liveboard.ts +32 -4
- package/src/embed/ts-embed.spec.ts +107 -15
- package/src/embed/ts-embed.ts +56 -19
- package/src/errors.ts +7 -0
- package/src/index.ts +2 -0
- package/src/react/all-types-export.ts +1 -0
- package/src/types.ts +259 -6
package/src/embed/base.ts
CHANGED
|
@@ -35,6 +35,7 @@ import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
|
|
|
35
35
|
import { getEmbedConfig, setEmbedConfig } from './embedConfig';
|
|
36
36
|
import { getQueryParamString, getValueFromWindow, storeValueInWindow } from '../utils';
|
|
37
37
|
import { resetAllCachedServices } from '../utils/resetServices';
|
|
38
|
+
import { reload } from '../utils/processTrigger';
|
|
38
39
|
|
|
39
40
|
const CONFIG_DEFAULTS: Partial<EmbedConfig> = {
|
|
40
41
|
loginFailedMessage: 'Not logged in',
|
|
@@ -459,3 +460,17 @@ export function reset(): void {
|
|
|
459
460
|
setAuthEE(null);
|
|
460
461
|
authPromise = null;
|
|
461
462
|
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Reloads the ThoughtSpot iframe.
|
|
466
|
+
* @param iFrame
|
|
467
|
+
* @group Global methods
|
|
468
|
+
* @version SDK: 1.43.1
|
|
469
|
+
*/
|
|
470
|
+
export const reloadIframe = (iFrame: HTMLIFrameElement) => {
|
|
471
|
+
if (!iFrame) {
|
|
472
|
+
logger.warn('reloadIframe called with no iFrame element.');
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
reload(iFrame);
|
|
476
|
+
};
|
|
@@ -2,7 +2,7 @@ import { SpotterEmbed, SpotterEmbedViewConfig, ConversationEmbed } from './conve
|
|
|
2
2
|
import { TsEmbed } from './ts-embed';
|
|
3
3
|
import * as authInstance from '../auth';
|
|
4
4
|
import { Action, init } from '../index';
|
|
5
|
-
import { AuthType, Param, RuntimeFilterOp } from '../types';
|
|
5
|
+
import { AuthType, Param, RuntimeFilterOp, ErrorDetailsTypes, EmbedErrorCodes } from '../types';
|
|
6
6
|
import {
|
|
7
7
|
getDocumentBody,
|
|
8
8
|
getIFrameSrc,
|
|
@@ -120,7 +120,12 @@ describe('ConversationEmbed', () => {
|
|
|
120
120
|
(conversationEmbed as any).handleError = jest.fn();
|
|
121
121
|
await conversationEmbed.render();
|
|
122
122
|
expect((conversationEmbed as any).handleError).toHaveBeenCalledWith(
|
|
123
|
-
|
|
123
|
+
{
|
|
124
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
125
|
+
message: ERROR_MESSAGE.SPOTTER_EMBED_WORKSHEED_ID_NOT_FOUND,
|
|
126
|
+
code: EmbedErrorCodes.WORKSHEET_ID_NOT_FOUND,
|
|
127
|
+
error: ERROR_MESSAGE.SPOTTER_EMBED_WORKSHEED_ID_NOT_FOUND,
|
|
128
|
+
},
|
|
124
129
|
);
|
|
125
130
|
});
|
|
126
131
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import isUndefined from 'lodash/isUndefined';
|
|
2
2
|
import { ERROR_MESSAGE } from '../errors';
|
|
3
|
-
import { Param, BaseViewConfig, RuntimeFilter, RuntimeParameter } from '../types';
|
|
3
|
+
import { Param, BaseViewConfig, RuntimeFilter, RuntimeParameter, ErrorDetailsTypes, EmbedErrorCodes } from '../types';
|
|
4
4
|
import { TsEmbed } from './ts-embed';
|
|
5
5
|
import { getQueryParamString, getFilterQuery, getRuntimeParameters } from '../utils';
|
|
6
6
|
|
|
@@ -246,7 +246,12 @@ export class SpotterEmbed extends TsEmbed {
|
|
|
246
246
|
} = this.viewConfig;
|
|
247
247
|
|
|
248
248
|
if (!worksheetId) {
|
|
249
|
-
this.handleError(
|
|
249
|
+
this.handleError({
|
|
250
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
251
|
+
message: ERROR_MESSAGE.SPOTTER_EMBED_WORKSHEED_ID_NOT_FOUND,
|
|
252
|
+
code: EmbedErrorCodes.WORKSHEET_ID_NOT_FOUND,
|
|
253
|
+
error: ERROR_MESSAGE.SPOTTER_EMBED_WORKSHEED_ID_NOT_FOUND,
|
|
254
|
+
});
|
|
250
255
|
}
|
|
251
256
|
const queryParams = this.getBaseQueryParams();
|
|
252
257
|
queryParams[Param.SpotterEnabled] = true;
|
|
@@ -407,6 +407,70 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
407
407
|
});
|
|
408
408
|
});
|
|
409
409
|
|
|
410
|
+
test('Should add showMaskedFilterChip flag set to true to the iframe src', async () => {
|
|
411
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
412
|
+
...defaultViewConfig,
|
|
413
|
+
liveboardId,
|
|
414
|
+
showMaskedFilterChip: true,
|
|
415
|
+
} as LiveboardViewConfig);
|
|
416
|
+
|
|
417
|
+
liveboardEmbed.render();
|
|
418
|
+
await executeAfterWait(() => {
|
|
419
|
+
expectUrlMatchesWithParams(
|
|
420
|
+
getIFrameSrc(),
|
|
421
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&showMaskedFilterChip=true${prefixParams}#/embed/viz/${liveboardId}`,
|
|
422
|
+
);
|
|
423
|
+
});
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
test('Should add showMaskedFilterChip flag set to false to the iframe src', async () => {
|
|
427
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
428
|
+
...defaultViewConfig,
|
|
429
|
+
liveboardId,
|
|
430
|
+
showMaskedFilterChip: false,
|
|
431
|
+
} as LiveboardViewConfig);
|
|
432
|
+
|
|
433
|
+
liveboardEmbed.render();
|
|
434
|
+
await executeAfterWait(() => {
|
|
435
|
+
expectUrlMatchesWithParams(
|
|
436
|
+
getIFrameSrc(),
|
|
437
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&showMaskedFilterChip=false${prefixParams}#/embed/viz/${liveboardId}`,
|
|
438
|
+
);
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
test('Should add isLiveboardMasterpiecesEnabled flag set to true to the iframe src', async () => {
|
|
443
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
444
|
+
...defaultViewConfig,
|
|
445
|
+
liveboardId,
|
|
446
|
+
isLiveboardMasterpiecesEnabled: true,
|
|
447
|
+
} as LiveboardViewConfig);
|
|
448
|
+
|
|
449
|
+
liveboardEmbed.render();
|
|
450
|
+
await executeAfterWait(() => {
|
|
451
|
+
expectUrlMatchesWithParams(
|
|
452
|
+
getIFrameSrc(),
|
|
453
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLiveboardMasterpiecesEnabled=true${prefixParams}#/embed/viz/${liveboardId}`,
|
|
454
|
+
);
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
test('Should add isLiveboardMasterpiecesEnabled flag set to false to the iframe src', async () => {
|
|
459
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
460
|
+
...defaultViewConfig,
|
|
461
|
+
liveboardId,
|
|
462
|
+
isLiveboardMasterpiecesEnabled: false,
|
|
463
|
+
} as LiveboardViewConfig);
|
|
464
|
+
|
|
465
|
+
liveboardEmbed.render();
|
|
466
|
+
await executeAfterWait(() => {
|
|
467
|
+
expectUrlMatchesWithParams(
|
|
468
|
+
getIFrameSrc(),
|
|
469
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLiveboardMasterpiecesEnabled=false${prefixParams}#/embed/viz/${liveboardId}`,
|
|
470
|
+
);
|
|
471
|
+
});
|
|
472
|
+
});
|
|
473
|
+
|
|
410
474
|
test('Should add hideIrrelevantFiltersAtTabLevel flag to the iframe src', async () => {
|
|
411
475
|
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
412
476
|
...defaultViewConfig,
|
|
@@ -1587,4 +1651,47 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
1587
1651
|
expect(navigateToLiveboardSpy).toHaveBeenCalledWith(liveboardId, undefined, undefined);
|
|
1588
1652
|
});
|
|
1589
1653
|
});
|
|
1654
|
+
|
|
1655
|
+
describe('Liveboard Embed Default Height and Minimum Height Handling', () => {
|
|
1656
|
+
test('should set default height to 800 when minimum height is provided', async () => {
|
|
1657
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1658
|
+
liveboardId,
|
|
1659
|
+
...defaultViewConfig,
|
|
1660
|
+
fullHeight: true,
|
|
1661
|
+
defaultHeight: 700,
|
|
1662
|
+
minimumHeight: 800,
|
|
1663
|
+
});
|
|
1664
|
+
await liveboardEmbed.render();
|
|
1665
|
+
expect(liveboardEmbed['defaultHeight']).toBe(800);
|
|
1666
|
+
});
|
|
1667
|
+
test('should set default height to 700 when default height is provided', async () => {
|
|
1668
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1669
|
+
liveboardId,
|
|
1670
|
+
...defaultViewConfig,
|
|
1671
|
+
fullHeight: true,
|
|
1672
|
+
defaultHeight: 700,
|
|
1673
|
+
});
|
|
1674
|
+
await liveboardEmbed.render();
|
|
1675
|
+
expect(liveboardEmbed['defaultHeight']).toBe(700);
|
|
1676
|
+
});
|
|
1677
|
+
test('should set default height to 800 when minimum height is provided but default height is not', async () => {
|
|
1678
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1679
|
+
liveboardId,
|
|
1680
|
+
...defaultViewConfig,
|
|
1681
|
+
fullHeight: true,
|
|
1682
|
+
minimumHeight: 800,
|
|
1683
|
+
});
|
|
1684
|
+
await liveboardEmbed.render();
|
|
1685
|
+
expect(liveboardEmbed['defaultHeight']).toBe(800);
|
|
1686
|
+
});
|
|
1687
|
+
test('should set default height to 500 when neither default height nor minimum height is provided', async () => {
|
|
1688
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1689
|
+
liveboardId,
|
|
1690
|
+
...defaultViewConfig,
|
|
1691
|
+
fullHeight: true,
|
|
1692
|
+
});
|
|
1693
|
+
await liveboardEmbed.render();
|
|
1694
|
+
expect(liveboardEmbed['defaultHeight']).toBe(500);
|
|
1695
|
+
});
|
|
1696
|
+
});
|
|
1590
1697
|
});
|
package/src/embed/liveboard.ts
CHANGED
|
@@ -20,6 +20,8 @@ import {
|
|
|
20
20
|
SearchLiveboardCommonViewConfig as LiveboardOtherViewConfig,
|
|
21
21
|
BaseViewConfig,
|
|
22
22
|
LiveboardAppEmbedViewConfig,
|
|
23
|
+
ErrorDetailsTypes,
|
|
24
|
+
EmbedErrorCodes,
|
|
23
25
|
} from '../types';
|
|
24
26
|
import { calculateVisibleElementData, getQueryParamString, isUndefined } from '../utils';
|
|
25
27
|
import { getAuthPromise } from './base';
|
|
@@ -65,6 +67,7 @@ export interface LiveboardViewConfig extends BaseViewConfig, LiveboardOtherViewC
|
|
|
65
67
|
* Supported embed types: `LiveboardEmbed`
|
|
66
68
|
* @version SDK: 1.5.0 | ThoughtSpot: ts7.oct.cl, 7.2.1
|
|
67
69
|
* @default 500
|
|
70
|
+
* @deprecated Use `minimumHeight` instead.
|
|
68
71
|
* @example
|
|
69
72
|
* ```js
|
|
70
73
|
* const embed = new LiveboardEmbed('#embed', {
|
|
@@ -75,6 +78,23 @@ export interface LiveboardViewConfig extends BaseViewConfig, LiveboardOtherViewC
|
|
|
75
78
|
* ```
|
|
76
79
|
*/
|
|
77
80
|
defaultHeight?: number;
|
|
81
|
+
/**
|
|
82
|
+
* This is the minimum height (in pixels) for a full-height Liveboard.
|
|
83
|
+
* Setting this height helps resolve issues with empty Liveboards and
|
|
84
|
+
* other screens navigable from a Liveboard.
|
|
85
|
+
*
|
|
86
|
+
* @version SDK: 1.44.2 | ThoughtSpot: 26.0.2.cl
|
|
87
|
+
* @default 500
|
|
88
|
+
* @example
|
|
89
|
+
* ```js
|
|
90
|
+
* const embed = new LiveboardEmbed('#embed', {
|
|
91
|
+
* ... // other liveboard view config
|
|
92
|
+
* fullHeight: true,
|
|
93
|
+
* minimumHeight: 600,
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
minimumHeight?: number;
|
|
78
98
|
/**
|
|
79
99
|
* @Deprecated If set to true, the context menu in visualizations will be enabled.
|
|
80
100
|
* @example
|
|
@@ -467,6 +487,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
467
487
|
enableVizTransformations,
|
|
468
488
|
fullHeight,
|
|
469
489
|
defaultHeight,
|
|
490
|
+
minimumHeight,
|
|
470
491
|
visibleVizs,
|
|
471
492
|
liveboardV2,
|
|
472
493
|
vizId,
|
|
@@ -480,6 +501,8 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
480
501
|
showLiveboardVerifiedBadge = true,
|
|
481
502
|
showLiveboardReverifyBanner = true,
|
|
482
503
|
hideIrrelevantChipsInLiveboardTabs = false,
|
|
504
|
+
showMaskedFilterChip = false,
|
|
505
|
+
isLiveboardMasterpiecesEnabled = false,
|
|
483
506
|
isEnhancedFilterInteractivityEnabled = false,
|
|
484
507
|
enableAskSage,
|
|
485
508
|
enable2ColumnLayout,
|
|
@@ -508,9 +531,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
508
531
|
params[Param.RootMarginForLazyLoad] = this.viewConfig.lazyLoadingMargin;
|
|
509
532
|
}
|
|
510
533
|
}
|
|
511
|
-
|
|
512
|
-
this.defaultHeight = defaultHeight;
|
|
513
|
-
}
|
|
534
|
+
this.defaultHeight = minimumHeight || defaultHeight || this.defaultHeight;
|
|
514
535
|
if (enableVizTransformations !== undefined) {
|
|
515
536
|
params[Param.EnableVizTransformations] = enableVizTransformations.toString();
|
|
516
537
|
}
|
|
@@ -589,6 +610,8 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
589
610
|
params[Param.ShowLiveboardVerifiedBadge] = showLiveboardVerifiedBadge;
|
|
590
611
|
params[Param.ShowLiveboardReverifyBanner] = showLiveboardReverifyBanner;
|
|
591
612
|
params[Param.HideIrrelevantFiltersInTab] = hideIrrelevantChipsInLiveboardTabs;
|
|
613
|
+
params[Param.ShowMaskedFilterChip] = showMaskedFilterChip;
|
|
614
|
+
params[Param.IsLiveboardMasterpiecesEnabled] = isLiveboardMasterpiecesEnabled;
|
|
592
615
|
params[Param.IsEnhancedFilterInteractivityEnabled] = isEnhancedFilterInteractivityEnabled;
|
|
593
616
|
params[Param.DataPanelV2Enabled] = dataPanelV2;
|
|
594
617
|
params[Param.EnableCustomColumnGroups] = enableCustomColumnGroups;
|
|
@@ -642,7 +665,12 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
642
665
|
const liveboardId = this.viewConfig.liveboardId ?? this.viewConfig.pinboardId;
|
|
643
666
|
|
|
644
667
|
if (!liveboardId) {
|
|
645
|
-
this.handleError(
|
|
668
|
+
this.handleError({
|
|
669
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
670
|
+
message: ERROR_MESSAGE.LIVEBOARD_VIZ_ID_VALIDATION,
|
|
671
|
+
code: EmbedErrorCodes.LIVEBOARD_ID_MISSING,
|
|
672
|
+
error: ERROR_MESSAGE.LIVEBOARD_VIZ_ID_VALIDATION,
|
|
673
|
+
});
|
|
646
674
|
}
|
|
647
675
|
return `${this.getRootIframeSrc()}${this.getIframeSuffixSrc(
|
|
648
676
|
liveboardId,
|
|
@@ -29,6 +29,8 @@ import {
|
|
|
29
29
|
CustomActionTarget,
|
|
30
30
|
CustomActionsPosition,
|
|
31
31
|
DefaultAppInitData,
|
|
32
|
+
ErrorDetailsTypes,
|
|
33
|
+
EmbedErrorCodes,
|
|
32
34
|
} from '../types';
|
|
33
35
|
import {
|
|
34
36
|
executeAfterWait,
|
|
@@ -1613,9 +1615,12 @@ describe('Unit test case for ts embed', () => {
|
|
|
1613
1615
|
} as LiveboardViewConfig);
|
|
1614
1616
|
await pinboardEmbed.render();
|
|
1615
1617
|
expect(pinboardEmbed['isError']).toBe(true);
|
|
1616
|
-
expect(logger.error).toHaveBeenCalledWith(
|
|
1617
|
-
|
|
1618
|
-
|
|
1618
|
+
expect(logger.error).toHaveBeenCalledWith({
|
|
1619
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1620
|
+
message: ERROR_MESSAGE.CONFLICTING_ACTIONS_CONFIG,
|
|
1621
|
+
code: EmbedErrorCodes.CONFLICTING_ACTIONS_CONFIG,
|
|
1622
|
+
error: ERROR_MESSAGE.CONFLICTING_ACTIONS_CONFIG,
|
|
1623
|
+
});
|
|
1619
1624
|
});
|
|
1620
1625
|
test('should not throw error when there are only visible or hidden actions - pinboard', async () => {
|
|
1621
1626
|
const pinboardEmbed = new PinboardEmbed(getRootEl(), {
|
|
@@ -1645,9 +1650,12 @@ describe('Unit test case for ts embed', () => {
|
|
|
1645
1650
|
} as LiveboardViewConfig);
|
|
1646
1651
|
await liveboardEmbed.render();
|
|
1647
1652
|
expect(liveboardEmbed['isError']).toBe(true);
|
|
1648
|
-
expect(logger.error).toHaveBeenCalledWith(
|
|
1649
|
-
|
|
1650
|
-
|
|
1653
|
+
expect(logger.error).toHaveBeenCalledWith({
|
|
1654
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1655
|
+
message: ERROR_MESSAGE.CONFLICTING_ACTIONS_CONFIG,
|
|
1656
|
+
code: EmbedErrorCodes.CONFLICTING_ACTIONS_CONFIG,
|
|
1657
|
+
error: ERROR_MESSAGE.CONFLICTING_ACTIONS_CONFIG,
|
|
1658
|
+
});
|
|
1651
1659
|
}
|
|
1652
1660
|
test('should throw error when there are both visible and hidden action arrays', async () => {
|
|
1653
1661
|
await testActionsForLiveboards([Action.DownloadAsCsv], [Action.DownloadAsCsv]);
|
|
@@ -1690,9 +1698,12 @@ describe('Unit test case for ts embed', () => {
|
|
|
1690
1698
|
} as LiveboardViewConfig);
|
|
1691
1699
|
await pinboardEmbed.render();
|
|
1692
1700
|
expect(pinboardEmbed['isError']).toBe(true);
|
|
1693
|
-
expect(logger.error).toHaveBeenCalledWith(
|
|
1694
|
-
|
|
1695
|
-
|
|
1701
|
+
expect(logger.error).toHaveBeenCalledWith({
|
|
1702
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1703
|
+
message: ERROR_MESSAGE.CONFLICTING_TABS_CONFIG,
|
|
1704
|
+
code: EmbedErrorCodes.CONFLICTING_TABS_CONFIG,
|
|
1705
|
+
error: ERROR_MESSAGE.CONFLICTING_TABS_CONFIG,
|
|
1706
|
+
});
|
|
1696
1707
|
});
|
|
1697
1708
|
test('should not throw error when there are only visible or hidden Tabs - pinboard', async () => {
|
|
1698
1709
|
const pinboardEmbed = new PinboardEmbed(getRootEl(), {
|
|
@@ -1722,9 +1733,12 @@ describe('Unit test case for ts embed', () => {
|
|
|
1722
1733
|
} as LiveboardViewConfig);
|
|
1723
1734
|
await liveboardEmbed.render();
|
|
1724
1735
|
expect(liveboardEmbed['isError']).toBe(true);
|
|
1725
|
-
expect(logger.error).toHaveBeenCalledWith(
|
|
1726
|
-
|
|
1727
|
-
|
|
1736
|
+
expect(logger.error).toHaveBeenCalledWith({
|
|
1737
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1738
|
+
message: ERROR_MESSAGE.CONFLICTING_TABS_CONFIG,
|
|
1739
|
+
code: EmbedErrorCodes.CONFLICTING_TABS_CONFIG,
|
|
1740
|
+
error: ERROR_MESSAGE.CONFLICTING_TABS_CONFIG,
|
|
1741
|
+
});
|
|
1728
1742
|
}
|
|
1729
1743
|
test('should throw error when there are both visible and hidden Tab arrays', async () => {
|
|
1730
1744
|
await testTabsForLiveboards([tabId1], [tabId2]);
|
|
@@ -1770,9 +1784,12 @@ describe('Unit test case for ts embed', () => {
|
|
|
1770
1784
|
const tsEmbed = new SearchEmbed(getRootEl(), {});
|
|
1771
1785
|
await tsEmbed.render();
|
|
1772
1786
|
expect(tsEmbed['isError']).toBe(true);
|
|
1773
|
-
expect(logger.error).toHaveBeenCalledWith(
|
|
1774
|
-
|
|
1775
|
-
|
|
1787
|
+
expect(logger.error).toHaveBeenCalledWith({
|
|
1788
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1789
|
+
message: ERROR_MESSAGE.INIT_SDK_REQUIRED,
|
|
1790
|
+
code: EmbedErrorCodes.INIT_ERROR,
|
|
1791
|
+
error: ERROR_MESSAGE.INIT_SDK_REQUIRED,
|
|
1792
|
+
});
|
|
1776
1793
|
});
|
|
1777
1794
|
});
|
|
1778
1795
|
|
|
@@ -3829,3 +3846,78 @@ describe('Unit test case for ts embed', () => {
|
|
|
3829
3846
|
});
|
|
3830
3847
|
});
|
|
3831
3848
|
});
|
|
3849
|
+
|
|
3850
|
+
|
|
3851
|
+
describe('Additional Coverage Tests', () => {
|
|
3852
|
+
beforeAll(() => {
|
|
3853
|
+
init({
|
|
3854
|
+
thoughtSpotHost: 'tshost',
|
|
3855
|
+
authType: AuthType.None,
|
|
3856
|
+
});
|
|
3857
|
+
});
|
|
3858
|
+
|
|
3859
|
+
test('should handle getAuthTokenForCookielessInit with non-cookieless auth', async () => {
|
|
3860
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3861
|
+
const token = await searchEmbed['getAuthTokenForCookielessInit']();
|
|
3862
|
+
expect(token).toBe('');
|
|
3863
|
+
});
|
|
3864
|
+
|
|
3865
|
+
test('should call setIFrameHeight', async () => {
|
|
3866
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3867
|
+
await searchEmbed.render();
|
|
3868
|
+
await executeAfterWait(() => {
|
|
3869
|
+
searchEmbed['setIFrameHeight'](500);
|
|
3870
|
+
expect(getIFrameEl().style.height).toBe('500px');
|
|
3871
|
+
});
|
|
3872
|
+
});
|
|
3873
|
+
|
|
3874
|
+
test('should test getIframeCenter calculation', async () => {
|
|
3875
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3876
|
+
await searchEmbed.render();
|
|
3877
|
+
await executeAfterWait(() => {
|
|
3878
|
+
const center = searchEmbed['getIframeCenter']();
|
|
3879
|
+
expect(center).toHaveProperty('iframeCenter');
|
|
3880
|
+
expect(center).toHaveProperty('iframeHeight');
|
|
3881
|
+
expect(center).toHaveProperty('viewPortHeight');
|
|
3882
|
+
});
|
|
3883
|
+
});
|
|
3884
|
+
|
|
3885
|
+
test('should handle preRender with replaceExistingPreRender=true', async () => {
|
|
3886
|
+
createRootEleForEmbed();
|
|
3887
|
+
const embed1 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
3888
|
+
preRenderId: 'test-replace',
|
|
3889
|
+
liveboardId: 'lb1',
|
|
3890
|
+
});
|
|
3891
|
+
await embed1.preRender();
|
|
3892
|
+
const embed2 = new LiveboardEmbed('#tsEmbedDiv', {
|
|
3893
|
+
preRenderId: 'test-replace',
|
|
3894
|
+
liveboardId: 'lb2',
|
|
3895
|
+
});
|
|
3896
|
+
await embed2.preRender(false, true);
|
|
3897
|
+
expect(document.getElementById('tsEmbed-pre-render-wrapper-test-replace')).toBeTruthy();
|
|
3898
|
+
});
|
|
3899
|
+
|
|
3900
|
+
test('should test getIframeSrc base implementation', () => {
|
|
3901
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3902
|
+
expect(searchEmbed.getIframeSrc()).toBe('');
|
|
3903
|
+
});
|
|
3904
|
+
|
|
3905
|
+
test('should handle createEmbedEventResponder with OnBeforeGetVizDataIntercept', async () => {
|
|
3906
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3907
|
+
const mockPort: any = { postMessage: jest.fn() };
|
|
3908
|
+
const responder = searchEmbed['createEmbedEventResponder'](
|
|
3909
|
+
mockPort,
|
|
3910
|
+
EmbedEvent.OnBeforeGetVizDataIntercept,
|
|
3911
|
+
);
|
|
3912
|
+
responder({ data: 'test' });
|
|
3913
|
+
expect(mockPort.postMessage).toHaveBeenCalled();
|
|
3914
|
+
});
|
|
3915
|
+
|
|
3916
|
+
test('should clean up message event listeners', async () => {
|
|
3917
|
+
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
|
|
3918
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3919
|
+
await searchEmbed.render();
|
|
3920
|
+
searchEmbed['unsubscribeToMessageEvents']();
|
|
3921
|
+
expect(removeEventListenerSpy).toHaveBeenCalledWith('message', expect.any(Function));
|
|
3922
|
+
});
|
|
3923
|
+
});
|
package/src/embed/ts-embed.ts
CHANGED
|
@@ -57,6 +57,9 @@ import {
|
|
|
57
57
|
ContextMenuTriggerOptions,
|
|
58
58
|
DefaultAppInitData,
|
|
59
59
|
AllEmbedViewConfig as ViewConfig,
|
|
60
|
+
EmbedErrorDetailsEvent,
|
|
61
|
+
ErrorDetailsTypes,
|
|
62
|
+
EmbedErrorCodes,
|
|
60
63
|
} from '../types';
|
|
61
64
|
import { uploadMixpanelEvent, MIXPANEL_EVENT } from '../mixpanel-service';
|
|
62
65
|
import { processEventData, processAuthFailure } from '../utils/processData';
|
|
@@ -218,20 +221,24 @@ export class TsEmbed {
|
|
|
218
221
|
* Throws error encountered during initialization.
|
|
219
222
|
*/
|
|
220
223
|
private throwInitError() {
|
|
221
|
-
this.handleError(
|
|
224
|
+
this.handleError({
|
|
225
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
226
|
+
message: ERROR_MESSAGE.INIT_SDK_REQUIRED,
|
|
227
|
+
code: EmbedErrorCodes.INIT_ERROR,
|
|
228
|
+
error : ERROR_MESSAGE.INIT_SDK_REQUIRED,
|
|
229
|
+
});
|
|
222
230
|
}
|
|
223
231
|
|
|
224
232
|
/**
|
|
225
233
|
* Handles errors within the SDK
|
|
226
234
|
* @param error The error message or object
|
|
235
|
+
* @param errorDetails The error details
|
|
227
236
|
*/
|
|
228
|
-
protected handleError(
|
|
237
|
+
protected handleError(errorDetails: EmbedErrorDetailsEvent) {
|
|
229
238
|
this.isError = true;
|
|
230
|
-
this.executeCallbacks(EmbedEvent.Error,
|
|
231
|
-
error,
|
|
232
|
-
});
|
|
239
|
+
this.executeCallbacks(EmbedEvent.Error, errorDetails);
|
|
233
240
|
// Log error
|
|
234
|
-
logger.error(
|
|
241
|
+
logger.error(errorDetails);
|
|
235
242
|
}
|
|
236
243
|
|
|
237
244
|
/**
|
|
@@ -325,11 +332,14 @@ export class TsEmbed {
|
|
|
325
332
|
window.addEventListener('online', onlineEventListener);
|
|
326
333
|
|
|
327
334
|
const offlineEventListener = (e: Event) => {
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
335
|
+
const errorDetails = {
|
|
336
|
+
errorType: ErrorDetailsTypes.NETWORK,
|
|
337
|
+
message: ERROR_MESSAGE.OFFLINE_WARNING,
|
|
338
|
+
code: EmbedErrorCodes.NETWORK_ERROR,
|
|
339
|
+
offlineWarning : ERROR_MESSAGE.OFFLINE_WARNING,
|
|
340
|
+
};
|
|
341
|
+
this.executeCallbacks(EmbedEvent.Error, errorDetails);
|
|
342
|
+
logger.warn(errorDetails);
|
|
333
343
|
};
|
|
334
344
|
window.addEventListener('offline', offlineEventListener);
|
|
335
345
|
|
|
@@ -444,9 +454,11 @@ export class TsEmbed {
|
|
|
444
454
|
]);
|
|
445
455
|
if (customActionsResult.errors.length > 0) {
|
|
446
456
|
this.handleError({
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
457
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
458
|
+
message: customActionsResult.errors,
|
|
459
|
+
code: EmbedErrorCodes.CUSTOM_ACTION_VALIDATION,
|
|
460
|
+
error : { type: EmbedErrorCodes.CUSTOM_ACTION_VALIDATION, message: customActionsResult.errors }
|
|
461
|
+
});
|
|
450
462
|
}
|
|
451
463
|
const baseInitData = {
|
|
452
464
|
customisations: getCustomisations(this.embedConfig, this.viewConfig),
|
|
@@ -658,12 +670,22 @@ export class TsEmbed {
|
|
|
658
670
|
};
|
|
659
671
|
|
|
660
672
|
if (Array.isArray(visibleActions) && Array.isArray(hiddenActions)) {
|
|
661
|
-
this.handleError(
|
|
673
|
+
this.handleError({
|
|
674
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
675
|
+
message: ERROR_MESSAGE.CONFLICTING_ACTIONS_CONFIG,
|
|
676
|
+
code: EmbedErrorCodes.CONFLICTING_ACTIONS_CONFIG,
|
|
677
|
+
error : ERROR_MESSAGE.CONFLICTING_ACTIONS_CONFIG,
|
|
678
|
+
});
|
|
662
679
|
return queryParams;
|
|
663
680
|
}
|
|
664
681
|
|
|
665
682
|
if (Array.isArray(visibleTabs) && Array.isArray(hiddenTabs)) {
|
|
666
|
-
this.handleError(
|
|
683
|
+
this.handleError({
|
|
684
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
685
|
+
message: ERROR_MESSAGE.CONFLICTING_TABS_CONFIG,
|
|
686
|
+
code: EmbedErrorCodes.CONFLICTING_TABS_CONFIG,
|
|
687
|
+
error : ERROR_MESSAGE.CONFLICTING_TABS_CONFIG,
|
|
688
|
+
});
|
|
667
689
|
return queryParams;
|
|
668
690
|
}
|
|
669
691
|
if (primaryAction) {
|
|
@@ -916,7 +938,12 @@ export class TsEmbed {
|
|
|
916
938
|
error: JSON.stringify(error),
|
|
917
939
|
});
|
|
918
940
|
this.handleInsertionIntoDOM(this.embedConfig.loginFailedMessage);
|
|
919
|
-
this.handleError(
|
|
941
|
+
this.handleError({
|
|
942
|
+
errorType: ErrorDetailsTypes.API,
|
|
943
|
+
message: error.message || ERROR_MESSAGE.LOGIN_FAILED,
|
|
944
|
+
code: EmbedErrorCodes.LOGIN_FAILED,
|
|
945
|
+
error : error,
|
|
946
|
+
});
|
|
920
947
|
});
|
|
921
948
|
});
|
|
922
949
|
}
|
|
@@ -1323,12 +1350,22 @@ export class TsEmbed {
|
|
|
1323
1350
|
uploadMixpanelEvent(`${MIXPANEL_EVENT.VISUAL_SDK_TRIGGER}-${messageType}`);
|
|
1324
1351
|
|
|
1325
1352
|
if (!this.isRendered) {
|
|
1326
|
-
this.handleError(
|
|
1353
|
+
this.handleError({
|
|
1354
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1355
|
+
message: ERROR_MESSAGE.RENDER_BEFORE_EVENTS_REQUIRED,
|
|
1356
|
+
code: EmbedErrorCodes.RENDER_NOT_CALLED,
|
|
1357
|
+
error: ERROR_MESSAGE.RENDER_BEFORE_EVENTS_REQUIRED,
|
|
1358
|
+
});
|
|
1327
1359
|
return null;
|
|
1328
1360
|
}
|
|
1329
1361
|
|
|
1330
1362
|
if (!messageType) {
|
|
1331
|
-
this.handleError(
|
|
1363
|
+
this.handleError({
|
|
1364
|
+
errorType: ErrorDetailsTypes.VALIDATION_ERROR,
|
|
1365
|
+
message: ERROR_MESSAGE.HOST_EVENT_TYPE_UNDEFINED,
|
|
1366
|
+
code: EmbedErrorCodes.HOST_EVENT_TYPE_UNDEFINED,
|
|
1367
|
+
error: ERROR_MESSAGE.HOST_EVENT_TYPE_UNDEFINED,
|
|
1368
|
+
});
|
|
1332
1369
|
return null;
|
|
1333
1370
|
}
|
|
1334
1371
|
|
package/src/errors.ts
CHANGED
|
@@ -20,6 +20,13 @@ export const ERROR_MESSAGE = {
|
|
|
20
20
|
RENDER_CALLED_BEFORE_INIT: 'Looks like render was called before calling init, the render won\'t start until init is called.\nFor more info check\n1. https://developers.thoughtspot.com/docs/Function_init#_init\n2.https://developers.thoughtspot.com/docs/getting-started#initSdk',
|
|
21
21
|
SPOTTER_AGENT_NOT_INITIALIZED: 'SpotterAgent not initialized',
|
|
22
22
|
OFFLINE_WARNING : 'Network not Detected. Embed is offline. Please reconnect and refresh',
|
|
23
|
+
INIT_SDK_REQUIRED: 'You need to init the ThoughtSpot SDK module first',
|
|
24
|
+
CONFLICTING_ACTIONS_CONFIG: 'You cannot have both hidden actions and visible actions',
|
|
25
|
+
CONFLICTING_TABS_CONFIG: 'You cannot have both hidden Tabs and visible Tabs',
|
|
26
|
+
RENDER_BEFORE_EVENTS_REQUIRED: 'Please call render before triggering events',
|
|
27
|
+
HOST_EVENT_TYPE_UNDEFINED: 'Host event type is undefined',
|
|
28
|
+
LOGIN_FAILED: 'Login failed',
|
|
29
|
+
ERROR_PARSING_API_INTERCEPT_BODY: 'Error parsing api intercept body',
|
|
23
30
|
};
|
|
24
31
|
|
|
25
32
|
export const CUSTOM_ACTIONS_ERROR_MESSAGE = {
|
package/src/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
exportTML,
|
|
27
27
|
executeTMLInput,
|
|
28
28
|
exportTMLInput,
|
|
29
|
+
reloadIframe,
|
|
29
30
|
} from './embed/base';
|
|
30
31
|
import { PinboardEmbed, LiveboardViewConfig, LiveboardEmbed } from './embed/liveboard';
|
|
31
32
|
import { SearchEmbed, SearchViewConfig } from './embed/search';
|
|
@@ -83,6 +84,7 @@ export {
|
|
|
83
84
|
executeTML,
|
|
84
85
|
exportTML,
|
|
85
86
|
executeTMLInput,
|
|
87
|
+
reloadIframe,
|
|
86
88
|
exportTMLInput,
|
|
87
89
|
getEmbedConfig as getInitConfig,
|
|
88
90
|
getSessionInfo,
|