@thoughtspot/visual-embed-sdk 1.33.0-alpha.2 → 1.33.0
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 +6 -24
- package/cjs/src/css-variables.d.ts +46 -3
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/app.d.ts +47 -27
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +10 -1
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +32 -0
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/base.d.ts +35 -33
- package/cjs/src/embed/base.d.ts.map +1 -1
- package/cjs/src/embed/base.js +35 -33
- package/cjs/src/embed/base.js.map +1 -1
- package/cjs/src/embed/embed.spec.js +0 -19
- package/cjs/src/embed/embed.spec.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +42 -0
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +6 -1
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +43 -0
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/search.d.ts +0 -26
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +0 -1
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +8 -12
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +0 -9
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/mixpanel-service.d.ts +4 -0
- package/cjs/src/mixpanel-service.d.ts.map +1 -1
- package/cjs/src/mixpanel-service.js +4 -0
- package/cjs/src/mixpanel-service.js.map +1 -1
- package/cjs/src/tokenizedFetch.d.ts.map +1 -1
- package/cjs/src/tokenizedFetch.js +5 -1
- package/cjs/src/tokenizedFetch.js.map +1 -1
- package/cjs/src/types.d.ts +179 -22
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +143 -12
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/authService/authService.spec.js +3 -1
- package/cjs/src/utils/authService/authService.spec.js.map +1 -1
- package/cjs/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
- package/cjs/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
- package/cjs/src/utils/graphql/answerService/answer-queries.js +9 -2
- package/cjs/src/utils/graphql/answerService/answer-queries.js.map +1 -1
- package/cjs/src/utils/graphql/answerService/answerService.d.ts +15 -0
- package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
- package/cjs/src/utils/graphql/answerService/answerService.js +25 -0
- package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -1
- package/cjs/src/utils/graphql/answerService/answerService.spec.js +53 -0
- package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
- package/cjs/src/utils/graphql/graphql-request.spec.d.ts +2 -0
- package/cjs/src/utils/graphql/graphql-request.spec.d.ts.map +1 -0
- package/cjs/src/utils/graphql/graphql-request.spec.js +36 -0
- package/cjs/src/utils/graphql/graphql-request.spec.js.map +1 -0
- package/cjs/src/utils/processData.js +2 -2
- package/cjs/src/utils/processData.js.map +1 -1
- package/cjs/src/utils/processData.spec.js +14 -0
- package/cjs/src/utils/processData.spec.js.map +1 -1
- package/cjs/src/utils/processTrigger.d.ts +1 -0
- package/cjs/src/utils/processTrigger.d.ts.map +1 -1
- package/cjs/src/utils/processTrigger.js +3 -3
- package/cjs/src/utils/processTrigger.js.map +1 -1
- package/cjs/src/utils/processTrigger.spec.js +10 -0
- package/cjs/src/utils/processTrigger.spec.js.map +1 -1
- package/cjs/src/utils.d.ts.map +1 -1
- package/cjs/src/utils.js +1 -3
- package/cjs/src/utils.js.map +1 -1
- package/dist/src/css-variables.d.ts +46 -3
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts +47 -27
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts +35 -33
- package/dist/src/embed/base.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +42 -0
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +0 -26
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +0 -1
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/mixpanel-service.d.ts +4 -0
- package/dist/src/mixpanel-service.d.ts.map +1 -1
- package/dist/src/tokenizedFetch.d.ts.map +1 -1
- package/dist/src/types.d.ts +179 -22
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
- package/dist/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
- package/dist/src/utils/graphql/answerService/answerService.d.ts +15 -0
- package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
- package/dist/src/utils/graphql/graphql-request.spec.d.ts +2 -0
- package/dist/src/utils/graphql/graphql-request.spec.d.ts.map +1 -0
- package/dist/src/utils/processTrigger.d.ts +1 -0
- package/dist/src/utils/processTrigger.d.ts.map +1 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +442 -107
- package/dist/tsembed-react.js +385 -106
- package/dist/tsembed.es.js +477 -140
- package/dist/tsembed.js +420 -139
- package/dist/visual-embed-sdk-react-full.d.ts +368 -112
- package/dist/visual-embed-sdk-react.d.ts +368 -112
- package/dist/visual-embed-sdk.d.ts +368 -112
- package/lib/package.json +6 -24
- package/lib/src/css-variables.d.ts +46 -3
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/app.d.ts +47 -27
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +10 -1
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +32 -0
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts +35 -33
- package/lib/src/embed/base.d.ts.map +1 -1
- package/lib/src/embed/base.js +35 -33
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/embed.spec.js +0 -19
- package/lib/src/embed/embed.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +42 -0
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +6 -1
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +43 -0
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/search.d.ts +0 -26
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +0 -1
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +8 -12
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +0 -9
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/mixpanel-service.d.ts +4 -0
- package/lib/src/mixpanel-service.d.ts.map +1 -1
- package/lib/src/mixpanel-service.js +4 -0
- package/lib/src/mixpanel-service.js.map +1 -1
- package/lib/src/tokenizedFetch.d.ts.map +1 -1
- package/lib/src/tokenizedFetch.js +5 -1
- package/lib/src/tokenizedFetch.js.map +1 -1
- package/lib/src/types.d.ts +179 -22
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +143 -12
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/authService/authService.spec.js +3 -1
- package/lib/src/utils/authService/authService.spec.js.map +1 -1
- package/lib/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
- package/lib/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
- package/lib/src/utils/graphql/answerService/answer-queries.js +8 -1
- package/lib/src/utils/graphql/answerService/answer-queries.js.map +1 -1
- package/lib/src/utils/graphql/answerService/answerService.d.ts +15 -0
- package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
- package/lib/src/utils/graphql/answerService/answerService.js +25 -0
- package/lib/src/utils/graphql/answerService/answerService.js.map +1 -1
- package/lib/src/utils/graphql/answerService/answerService.spec.js +54 -1
- package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
- package/lib/src/utils/graphql/graphql-request.spec.d.ts +2 -0
- package/lib/src/utils/graphql/graphql-request.spec.d.ts.map +1 -0
- package/lib/src/utils/graphql/graphql-request.spec.js +33 -0
- package/lib/src/utils/graphql/graphql-request.spec.js.map +1 -0
- package/lib/src/utils/processData.js +2 -2
- package/lib/src/utils/processData.js.map +1 -1
- package/lib/src/utils/processData.spec.js +14 -0
- package/lib/src/utils/processData.spec.js.map +1 -1
- package/lib/src/utils/processTrigger.d.ts +1 -0
- package/lib/src/utils/processTrigger.d.ts.map +1 -1
- package/lib/src/utils/processTrigger.js +1 -1
- package/lib/src/utils/processTrigger.js.map +1 -1
- package/lib/src/utils/processTrigger.spec.js +10 -0
- package/lib/src/utils/processTrigger.spec.js.map +1 -1
- package/lib/src/utils.d.ts.map +1 -1
- package/lib/src/utils.js +1 -3
- package/lib/src/utils.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +368 -112
- package/package.json +6 -24
- package/src/css-variables.ts +49 -3
- package/src/embed/app.spec.ts +47 -0
- package/src/embed/app.ts +54 -26
- package/src/embed/base.ts +35 -33
- package/src/embed/embed.spec.ts +0 -22
- package/src/embed/liveboard.spec.ts +62 -0
- package/src/embed/liveboard.ts +52 -0
- package/src/embed/search.ts +0 -26
- package/src/embed/ts-embed.spec.ts +0 -11
- package/src/embed/ts-embed.ts +9 -12
- package/src/mixpanel-service.ts +4 -0
- package/src/tokenizedFetch.ts +5 -1
- package/src/types.ts +180 -21
- package/src/utils/authService/authService.spec.ts +3 -1
- package/src/utils/graphql/answerService/answer-queries.ts +9 -1
- package/src/utils/graphql/answerService/answerService.spec.ts +69 -0
- package/src/utils/graphql/answerService/answerService.ts +35 -0
- package/src/utils/graphql/graphql-request.spec.ts +38 -0
- package/src/utils/processData.spec.ts +16 -0
- package/src/utils/processData.ts +2 -2
- package/src/utils/processTrigger.spec.ts +19 -0
- package/src/utils/processTrigger.ts +1 -1
- package/src/utils.ts +1 -3
|
@@ -56,7 +56,6 @@ beforeAll(() => {
|
|
|
56
56
|
const customisations = {
|
|
57
57
|
style: {
|
|
58
58
|
customCSS: {},
|
|
59
|
-
customCSSUrl: 'http://localhost:3000',
|
|
60
59
|
},
|
|
61
60
|
content: {},
|
|
62
61
|
};
|
|
@@ -64,7 +63,6 @@ const customisations = {
|
|
|
64
63
|
const customisationsView = {
|
|
65
64
|
style: {
|
|
66
65
|
customCSS: {},
|
|
67
|
-
customCSSUrl: 'http://localhost:8000',
|
|
68
66
|
},
|
|
69
67
|
content: {
|
|
70
68
|
strings: {
|
|
@@ -95,7 +93,6 @@ describe('Unit test case for ts embed', () => {
|
|
|
95
93
|
init({
|
|
96
94
|
thoughtSpotHost: 'tshost',
|
|
97
95
|
customizations: customisations,
|
|
98
|
-
customCssUrl: 'http://localhost:5000',
|
|
99
96
|
authType: AuthType.TrustedAuthTokenCookieless,
|
|
100
97
|
getAuthToken: () => Promise.resolve('test_auth_token2'),
|
|
101
98
|
});
|
|
@@ -136,7 +133,6 @@ describe('Unit test case for ts embed', () => {
|
|
|
136
133
|
thoughtSpotHost: 'tshost',
|
|
137
134
|
authType: AuthType.None,
|
|
138
135
|
customizations: customisations,
|
|
139
|
-
customCssUrl: 'http://localhost:5000',
|
|
140
136
|
});
|
|
141
137
|
});
|
|
142
138
|
|
|
@@ -199,9 +195,6 @@ describe('Unit test case for ts embed', () => {
|
|
|
199
195
|
reorderedHomepageModules: [],
|
|
200
196
|
},
|
|
201
197
|
});
|
|
202
|
-
expect(getIFrameSrc()).toContain(
|
|
203
|
-
`customCssUrl=${customisationsView.style.customCSSUrl}`,
|
|
204
|
-
);
|
|
205
198
|
});
|
|
206
199
|
|
|
207
200
|
test('hide home page modules from view Config should be part of app_init payload', async () => {
|
|
@@ -601,7 +594,6 @@ describe('Unit test case for ts embed', () => {
|
|
|
601
594
|
init({
|
|
602
595
|
thoughtSpotHost: 'tshost',
|
|
603
596
|
customizations: customisations,
|
|
604
|
-
customCssUrl: 'http://localhost:5000',
|
|
605
597
|
authType: AuthType.TrustedAuthTokenCookieless,
|
|
606
598
|
getAuthToken: () => Promise.resolve('test_auth_token1'),
|
|
607
599
|
});
|
|
@@ -655,7 +647,6 @@ describe('Unit test case for ts embed', () => {
|
|
|
655
647
|
init({
|
|
656
648
|
thoughtSpotHost: 'tshost',
|
|
657
649
|
customizations: customisations,
|
|
658
|
-
customCssUrl: 'http://localhost:5000',
|
|
659
650
|
authType: AuthType.TrustedAuthTokenCookieless,
|
|
660
651
|
getAuthToken: () => Promise.reject(),
|
|
661
652
|
});
|
|
@@ -790,7 +781,6 @@ describe('Unit test case for ts embed', () => {
|
|
|
790
781
|
init({
|
|
791
782
|
thoughtSpotHost: 'tshost',
|
|
792
783
|
customizations: customisations,
|
|
793
|
-
customCssUrl: 'http://localhost:5000',
|
|
794
784
|
authType: AuthType.TrustedAuthToken,
|
|
795
785
|
username: 'tsadmin',
|
|
796
786
|
getAuthToken: () => Promise.resolve('test_auth_token3'),
|
|
@@ -819,7 +809,6 @@ describe('Unit test case for ts embed', () => {
|
|
|
819
809
|
init({
|
|
820
810
|
thoughtSpotHost: 'tshost',
|
|
821
811
|
customizations: customisations,
|
|
822
|
-
customCssUrl: 'http://localhost:5000',
|
|
823
812
|
authType: AuthType.TrustedAuthToken,
|
|
824
813
|
username: 'tsadmin',
|
|
825
814
|
getAuthToken: () => Promise.resolve('test_auth_token4'),
|
package/src/embed/ts-embed.ts
CHANGED
|
@@ -454,13 +454,6 @@ export class TsEmbed {
|
|
|
454
454
|
return queryParams;
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
-
// TODO remove embedConfig.customCssUrl
|
|
458
|
-
const cssUrlParam = customizations?.style?.customCSSUrl || this.embedConfig.customCssUrl;
|
|
459
|
-
|
|
460
|
-
if (cssUrlParam) {
|
|
461
|
-
queryParams[Param.CustomCSSUrl] = cssUrlParam;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
457
|
if (disabledActions?.length) {
|
|
465
458
|
queryParams[Param.DisableActions] = disabledActions;
|
|
466
459
|
}
|
|
@@ -500,9 +493,7 @@ export class TsEmbed {
|
|
|
500
493
|
if (locale !== undefined) {
|
|
501
494
|
queryParams[Param.Locale] = locale;
|
|
502
495
|
}
|
|
503
|
-
|
|
504
|
-
Object.assign(queryParams, additionalFlags);
|
|
505
|
-
}
|
|
496
|
+
|
|
506
497
|
if (linkOverride) {
|
|
507
498
|
queryParams[Param.LinkOverride] = linkOverride;
|
|
508
499
|
}
|
|
@@ -516,6 +507,13 @@ export class TsEmbed {
|
|
|
516
507
|
queryParams[Param.OverrideNativeConsole] = true;
|
|
517
508
|
queryParams[Param.ClientLogLevel] = this.embedConfig.logLevel;
|
|
518
509
|
|
|
510
|
+
if (additionalFlags && additionalFlags.constructor.name === 'Object') {
|
|
511
|
+
Object.assign(queryParams, additionalFlags);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Do not add any flags below this, as we want additional flags to
|
|
515
|
+
// override other flags
|
|
516
|
+
|
|
519
517
|
return queryParams;
|
|
520
518
|
}
|
|
521
519
|
|
|
@@ -1221,7 +1219,7 @@ export class TsEmbed {
|
|
|
1221
1219
|
* @version SDK: 1.25.0 / ThoughtSpot 9.10.0
|
|
1222
1220
|
*/
|
|
1223
1221
|
public async getAnswerService(vizId?: string): Promise<AnswerService> {
|
|
1224
|
-
const { session } = await this.trigger(HostEvent.GetAnswerSession, vizId);
|
|
1222
|
+
const { session } = await this.trigger(HostEvent.GetAnswerSession, vizId ? { vizId } : {});
|
|
1225
1223
|
|
|
1226
1224
|
return new AnswerService(session, null, this.embedConfig.thoughtSpotHost);
|
|
1227
1225
|
}
|
|
@@ -1298,7 +1296,6 @@ export class V1Embed extends TsEmbed {
|
|
|
1298
1296
|
|
|
1299
1297
|
/**
|
|
1300
1298
|
* Only for testing purposes.
|
|
1301
|
-
*
|
|
1302
1299
|
* @hidden
|
|
1303
1300
|
*/
|
|
1304
1301
|
// eslint-disable-next-line camelcase
|
package/src/mixpanel-service.ts
CHANGED
|
@@ -11,6 +11,10 @@ export const EndPoints = {
|
|
|
11
11
|
const mixpanelLib = mixpanel.default || mixpanel;
|
|
12
12
|
let mixpanelInstance: mixpanel.Mixpanel;
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Enum of mixpanel events
|
|
16
|
+
* @hidden
|
|
17
|
+
*/
|
|
14
18
|
export const MIXPANEL_EVENT = {
|
|
15
19
|
VISUAL_SDK_RENDER_START: 'visual-sdk-render-start',
|
|
16
20
|
VISUAL_SDK_CALLED_INIT: 'visual-sdk-called-init',
|
package/src/tokenizedFetch.ts
CHANGED
|
@@ -22,7 +22,11 @@ import { AuthType } from './types';
|
|
|
22
22
|
export const tokenizedFetch: typeof fetch = async (input, init): Promise<Response> => {
|
|
23
23
|
const embedConfig = getEmbedConfig();
|
|
24
24
|
if (embedConfig.authType !== AuthType.TrustedAuthTokenCookieless) {
|
|
25
|
-
return fetch(input,
|
|
25
|
+
return fetch(input, {
|
|
26
|
+
// ensure cookies are included for the non cookie-less api calls.
|
|
27
|
+
credentials: 'include',
|
|
28
|
+
...init,
|
|
29
|
+
});
|
|
26
30
|
}
|
|
27
31
|
|
|
28
32
|
const req = new Request(input, init);
|
package/src/types.ts
CHANGED
|
@@ -449,13 +449,6 @@ export interface EmbedConfig {
|
|
|
449
449
|
*/
|
|
450
450
|
queueMultiRenders?: boolean;
|
|
451
451
|
|
|
452
|
-
/**
|
|
453
|
-
* Dynamic CSS URL to be injected in the loaded application.
|
|
454
|
-
* You would also need to set `style-src` in the CSP settings.
|
|
455
|
-
* @version SDK: 1.6.0 | ThoughtSpot: ts8.nov.cl, 8.4.1.sw
|
|
456
|
-
* @default ''
|
|
457
|
-
*/
|
|
458
|
-
customCssUrl?: string;
|
|
459
452
|
/**
|
|
460
453
|
* [AuthServer|Basic] Detect if third-party party cookies are enabled by doing an
|
|
461
454
|
* additional call. This is slower and should be avoided. Listen to the
|
|
@@ -589,6 +582,13 @@ export interface EmbedConfig {
|
|
|
589
582
|
* @version SDK: 1.28.5 | Thoughtspot: *
|
|
590
583
|
*/
|
|
591
584
|
disableTokenVerification?: boolean;
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* This flag is used to disable showing the login failure page in the embedded app.
|
|
588
|
+
*
|
|
589
|
+
* @version SDK 1.32.3 | Thoughtspot: *
|
|
590
|
+
*/
|
|
591
|
+
disableLoginFailurePage?: boolean;
|
|
592
592
|
}
|
|
593
593
|
|
|
594
594
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
@@ -715,11 +715,12 @@ export interface ViewConfig {
|
|
|
715
715
|
*/
|
|
716
716
|
visibleActions?: Action[];
|
|
717
717
|
/**
|
|
718
|
-
* Show alert messages and toast messages in the embedded
|
|
718
|
+
* Show alert messages and toast messages in the embedded
|
|
719
|
+
* view in full app embed.
|
|
719
720
|
* @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
|
|
720
721
|
* @example
|
|
721
722
|
* ```js
|
|
722
|
-
* const embed = new
|
|
723
|
+
* const embed = new AppEmbed('#embed-container', {
|
|
723
724
|
* ... // other options
|
|
724
725
|
* showAlerts:true,
|
|
725
726
|
* })
|
|
@@ -1040,6 +1041,32 @@ export interface ViewConfig {
|
|
|
1040
1041
|
* @version SDK: 1.32.1 | ThoughtSpot: 10.3.0.cl
|
|
1041
1042
|
*/
|
|
1042
1043
|
disableRedirectionLinksInNewTab?: boolean;
|
|
1044
|
+
/**
|
|
1045
|
+
* Flag to control Data panel experience
|
|
1046
|
+
* @default true
|
|
1047
|
+
* @version SDK: 1.34.0 | Thoughtspot: 10.3.0.cl
|
|
1048
|
+
* @example
|
|
1049
|
+
* ```js
|
|
1050
|
+
* const embed = new AppEmbed('#tsEmbed', {
|
|
1051
|
+
* ... // other options
|
|
1052
|
+
* dataPanelV2: true,
|
|
1053
|
+
* })
|
|
1054
|
+
* ```
|
|
1055
|
+
*/
|
|
1056
|
+
dataPanelV2?: boolean;
|
|
1057
|
+
/**
|
|
1058
|
+
* To enable custom column groups in data panel v2
|
|
1059
|
+
* @version SDK: 1.32.0 | Thoughtspot: 10.0.0.cl
|
|
1060
|
+
* @default false
|
|
1061
|
+
* @example
|
|
1062
|
+
* ```js
|
|
1063
|
+
* const embed = new SearchEmbed('#tsEmbed', {
|
|
1064
|
+
* ... // other options
|
|
1065
|
+
* enableCustomColumnGroups: true,
|
|
1066
|
+
* });
|
|
1067
|
+
* ```
|
|
1068
|
+
*/
|
|
1069
|
+
enableCustomColumnGroups?: boolean;
|
|
1043
1070
|
}
|
|
1044
1071
|
|
|
1045
1072
|
/**
|
|
@@ -1252,6 +1279,28 @@ export interface RuntimeParameter {
|
|
|
1252
1279
|
* console.log('Drilldown event', drilldown);
|
|
1253
1280
|
* }));
|
|
1254
1281
|
* ```
|
|
1282
|
+
*
|
|
1283
|
+
* If you are using React components for embedding, you can register to any
|
|
1284
|
+
* events from the `EmbedEvent` list by using the `on<EventName>` convention.
|
|
1285
|
+
* For example,`onAlert`, `onCopyToClipboard` and so on.
|
|
1286
|
+
*
|
|
1287
|
+
* @example
|
|
1288
|
+
* ```js
|
|
1289
|
+
* // ...
|
|
1290
|
+
* const MyComponent = ({ dataSources }) => {
|
|
1291
|
+
* const onLoad = () => {
|
|
1292
|
+
* console.log(EmbedEvent.Load, {});
|
|
1293
|
+
* };
|
|
1294
|
+
*
|
|
1295
|
+
* return (
|
|
1296
|
+
* <SearchEmbed
|
|
1297
|
+
* dataSources={dataSources}
|
|
1298
|
+
* onLoad = {logEvent("Load")}
|
|
1299
|
+
* />
|
|
1300
|
+
* );
|
|
1301
|
+
* };
|
|
1302
|
+
* ```
|
|
1303
|
+
*
|
|
1255
1304
|
* @group Events
|
|
1256
1305
|
*/
|
|
1257
1306
|
// eslint-disable-next-line no-shadow
|
|
@@ -2121,21 +2170,61 @@ export enum EmbedEvent {
|
|
|
2121
2170
|
*/
|
|
2122
2171
|
Rename = 'rename',
|
|
2123
2172
|
/**
|
|
2124
|
-
* Emitted
|
|
2173
|
+
* Emitted if the user wants to intercept the search execution
|
|
2174
|
+
* and implement logic to decide whether to run the search or not
|
|
2125
2175
|
*
|
|
2126
|
-
* Set
|
|
2127
|
-
* this embed event
|
|
2176
|
+
* Prerequisite: Set isOnBeforeGetVizDataInterceptEnabled : true
|
|
2177
|
+
* for this embed event to get emitted.
|
|
2178
|
+
*
|
|
2179
|
+
* @param: payload
|
|
2180
|
+
* @param: responder
|
|
2181
|
+
* Contains elements that lets developers define whether ThoughtSpot
|
|
2182
|
+
* will run the search or not, and if not, which error message to provide.
|
|
2183
|
+
*
|
|
2184
|
+
* execute: When execute returns true, the search will be run.
|
|
2185
|
+
* When execute returns false, the search will not be executed.
|
|
2186
|
+
*
|
|
2187
|
+
* error: Developers can customize the user facing message when execute is
|
|
2188
|
+
* set to false using the error parameter in responder
|
|
2189
|
+
*
|
|
2190
|
+
* @version SDK : 1.29.0 | Thoughtspot : 10.2.0.cl
|
|
2128
2191
|
*
|
|
2192
|
+
* @example
|
|
2129
2193
|
*```js
|
|
2130
|
-
*
|
|
2194
|
+
* .on(EmbedEvent.OnBeforeGetVizDataIntercept,
|
|
2131
2195
|
* (payload, responder) => {
|
|
2132
2196
|
* responder({
|
|
2133
2197
|
* data: {
|
|
2134
|
-
* execute:
|
|
2135
|
-
*
|
|
2198
|
+
* execute:false,
|
|
2199
|
+
* error: {
|
|
2200
|
+
* //Provide a custom error message to explain to your end user
|
|
2201
|
+
* //why their search did not run
|
|
2202
|
+
* errorText: "This search query cannot be run.
|
|
2203
|
+
* Please contact your administrator for more details."
|
|
2204
|
+
* }
|
|
2205
|
+
* }})
|
|
2206
|
+
* })
|
|
2207
|
+
* ```
|
|
2208
|
+
*
|
|
2209
|
+
*```js
|
|
2210
|
+
* .on(EmbedEvent.OnBeforeGetVizDataIntercept,
|
|
2211
|
+
* (payload, responder) => {
|
|
2212
|
+
* const query = payload.data.data.answer.search_query
|
|
2213
|
+
* responder({
|
|
2214
|
+
* data: {
|
|
2215
|
+
* // returns true as long as the query does not include
|
|
2216
|
+
* // both the 'sales' AND the 'county' column
|
|
2217
|
+
* execute: !(query.includes("sales")&&query.includes("county")),
|
|
2218
|
+
* error: {
|
|
2219
|
+
* //Provide a custom error message to explain to your end user
|
|
2220
|
+
* // why their search did not run, and which searches are accepted by your custom logic.
|
|
2221
|
+
* errorText: "You can't use this query :" + query + ".
|
|
2222
|
+
* The 'sales' measures can never be used at the 'county' level.
|
|
2223
|
+
* Please try another measure, or remove 'county' from your search."
|
|
2224
|
+
* }
|
|
2225
|
+
* }})
|
|
2136
2226
|
* })
|
|
2137
2227
|
*```
|
|
2138
|
-
* @version SDK : 1.29.0 | Thoughtspot : 10.2.0.cl
|
|
2139
2228
|
*/
|
|
2140
2229
|
OnBeforeGetVizDataIntercept = 'onBeforeGetVizDataIntercept',
|
|
2141
2230
|
/**
|
|
@@ -2154,7 +2243,7 @@ export enum EmbedEvent {
|
|
|
2154
2243
|
|
|
2155
2244
|
/**
|
|
2156
2245
|
* Event types that can be triggered by the host application
|
|
2157
|
-
* to the embedded ThoughtSpot app
|
|
2246
|
+
* to the embedded ThoughtSpot app.
|
|
2158
2247
|
*
|
|
2159
2248
|
* To trigger an event use the corresponding
|
|
2160
2249
|
* {@link LiveboardEmbed.trigger} or {@link AppEmbed.trigger} or {@link
|
|
@@ -2171,6 +2260,40 @@ export enum EmbedEvent {
|
|
|
2171
2260
|
* { columnName: 'state, operator: RuntimeFilterOp.EQ, values: ['california']}
|
|
2172
2261
|
* ]);
|
|
2173
2262
|
* ```
|
|
2263
|
+
* @example
|
|
2264
|
+
* If using React components to embed, use the format shown in this example:
|
|
2265
|
+
*
|
|
2266
|
+
* ```js
|
|
2267
|
+
* const selectVizs = () => {
|
|
2268
|
+
* embedRef.current.trigger(HostEvent.SetVisibleVizs, [
|
|
2269
|
+
* "715e4613-c891-4884-be44-aa8d13701c06",
|
|
2270
|
+
* "3f84d633-e325-44b2-be25-c6650e5a49cf"
|
|
2271
|
+
* ]);
|
|
2272
|
+
* };
|
|
2273
|
+
* ```
|
|
2274
|
+
*
|
|
2275
|
+
*
|
|
2276
|
+
* You can also attach an Embed event to a Host event to trigger
|
|
2277
|
+
* a specific action as shown in this example:
|
|
2278
|
+
*
|
|
2279
|
+
* @example
|
|
2280
|
+
* ```js
|
|
2281
|
+
* const EmbeddedComponent = () => {
|
|
2282
|
+
* const embedRef = useRef(null); // import { useRef } from react
|
|
2283
|
+
* const onLiveboardRendered = () => {
|
|
2284
|
+
* embedRef.current.trigger(HostEvent.SetVisibleVizs, ['viz1', 'viz2']);
|
|
2285
|
+
* };
|
|
2286
|
+
*
|
|
2287
|
+
* return (
|
|
2288
|
+
* <LiveboardEmbed
|
|
2289
|
+
* ref={embedRef}
|
|
2290
|
+
* liveboardId="<liveboard-guid>"
|
|
2291
|
+
* onLiveboardRendered={onLiveboardRendered}
|
|
2292
|
+
* />
|
|
2293
|
+
* );
|
|
2294
|
+
* }
|
|
2295
|
+
* ```
|
|
2296
|
+
*
|
|
2174
2297
|
* @group Events
|
|
2175
2298
|
*/
|
|
2176
2299
|
// eslint-disable-next-line no-shadow
|
|
@@ -2255,6 +2378,15 @@ export enum HostEvent {
|
|
|
2255
2378
|
* @hidden
|
|
2256
2379
|
*/
|
|
2257
2380
|
Reload = 'reload',
|
|
2381
|
+
/**
|
|
2382
|
+
* Get current iframe src
|
|
2383
|
+
* @example
|
|
2384
|
+
* ```js
|
|
2385
|
+
* const frameUrl = AppEmbed.trigger(HostEvent.GetIframeUrl)
|
|
2386
|
+
* ```
|
|
2387
|
+
* @version SDK: 1.35.0 | Thoughtspot: 10.4.0.cl
|
|
2388
|
+
*/
|
|
2389
|
+
GetIframeUrl = 'GetIframeUrl',
|
|
2258
2390
|
/**
|
|
2259
2391
|
* Display specific visualizations on a Liveboard.
|
|
2260
2392
|
* @param - An array of GUIDs of the visualization to show. The visualization IDs not passed
|
|
@@ -2856,10 +2988,23 @@ export enum HostEvent {
|
|
|
2856
2988
|
* filter: {
|
|
2857
2989
|
* column: "item type",
|
|
2858
2990
|
* oper: "IN",
|
|
2859
|
-
* values: ["bags","shirts"]
|
|
2991
|
+
* values: ["bags","shirts"]
|
|
2992
|
+
* }
|
|
2993
|
+
* });
|
|
2994
|
+
* ```
|
|
2995
|
+
* @example
|
|
2996
|
+
* ```js
|
|
2997
|
+
*
|
|
2998
|
+
* liveboardEmbed.trigger(HostEvent.UpdateFilters, {
|
|
2999
|
+
* filter: {
|
|
3000
|
+
* column: "date",
|
|
3001
|
+
* oper: "EQ",
|
|
3002
|
+
* values: ["JULY","2023"],
|
|
3003
|
+
* type: "MONTH_YEAR"
|
|
2860
3004
|
* }
|
|
2861
3005
|
* });
|
|
2862
3006
|
* ```
|
|
3007
|
+
*
|
|
2863
3008
|
* @example
|
|
2864
3009
|
*
|
|
2865
3010
|
* ```js
|
|
@@ -2877,7 +3022,8 @@ export enum HostEvent {
|
|
|
2877
3022
|
* {
|
|
2878
3023
|
* column: "Date",
|
|
2879
3024
|
* oper: 'EQ',
|
|
2880
|
-
* values: ["
|
|
3025
|
+
* values: ["2023-07-31"],
|
|
3026
|
+
* types: "EXACT_DATE"
|
|
2881
3027
|
* }]
|
|
2882
3028
|
* });
|
|
2883
3029
|
* ```
|
|
@@ -3067,7 +3213,6 @@ export enum Param {
|
|
|
3067
3213
|
ViewPortHeight = 'viewPortHeight',
|
|
3068
3214
|
ViewPortWidth = 'viewPortWidth',
|
|
3069
3215
|
VisibleActions = 'visibleAction',
|
|
3070
|
-
CustomCSSUrl = 'customCssUrl',
|
|
3071
3216
|
DisableLoginRedirect = 'disableLoginRedirect',
|
|
3072
3217
|
visibleVizs = 'pinboardVisibleVizs',
|
|
3073
3218
|
LiveboardV2Enabled = 'isPinboardV2Enabled',
|
|
@@ -3126,6 +3271,9 @@ export enum Param {
|
|
|
3126
3271
|
FocusSearchBarOnRender = 'focusSearchBarOnRender',
|
|
3127
3272
|
DisableRedirectionLinksInNewTab = 'disableRedirectionLinksInNewTab',
|
|
3128
3273
|
HomePageSearchBarMode = 'homePageSearchBarMode',
|
|
3274
|
+
ShowLiveboardVerifiedBadge = 'showLiveboardVerifiedBadge',
|
|
3275
|
+
ShowLiveboardReverifyBanner = 'showLiveboardReverifyBanner',
|
|
3276
|
+
LiveboardHeaderV2 = 'isLiveboardHeaderV2Enabled',
|
|
3129
3277
|
}
|
|
3130
3278
|
|
|
3131
3279
|
/**
|
|
@@ -4052,7 +4200,7 @@ export enum Action {
|
|
|
4052
4200
|
*
|
|
4053
4201
|
* @version SDK: 1.32.0 | Thoughtspot: 10.1.0.cl
|
|
4054
4202
|
*/
|
|
4055
|
-
CreateLiveboard = '
|
|
4203
|
+
CreateLiveboard = 'createLiveboard',
|
|
4056
4204
|
|
|
4057
4205
|
/**
|
|
4058
4206
|
* Action ID for to hide Verified Liveboard Banner
|
|
@@ -4154,6 +4302,17 @@ export enum Action {
|
|
|
4154
4302
|
*/
|
|
4155
4303
|
UnsubscribeScheduleHomepage = 'unsubscribeScheduleHomepage',
|
|
4156
4304
|
|
|
4305
|
+
/**
|
|
4306
|
+
* The **Manage Tags** action on Homepage Favourite Module.
|
|
4307
|
+
*
|
|
4308
|
+
* @example
|
|
4309
|
+
* ```js
|
|
4310
|
+
* disabledActions: [Action.ManageTags]
|
|
4311
|
+
* ```
|
|
4312
|
+
* @version SDK : 1.34.0 | Thoughtspot: 10.3.0.cl
|
|
4313
|
+
*/
|
|
4314
|
+
ManageTags = 'manageTags',
|
|
4315
|
+
|
|
4157
4316
|
/**
|
|
4158
4317
|
* Action ID for delete schedule action on schedule on homepage
|
|
4159
4318
|
* @example
|
|
@@ -29,7 +29,9 @@ describe('Unit test for authService', () => {
|
|
|
29
29
|
const response = await fetchSessionInfoService(thoughtSpotHost);
|
|
30
30
|
expect(response.success).toBe(true);
|
|
31
31
|
expect(fetch).toHaveBeenCalledTimes(1);
|
|
32
|
-
expect(fetch).toBeCalledWith(`${thoughtSpotHost}${EndPoints.SESSION_INFO}`, {
|
|
32
|
+
expect(fetch).toBeCalledWith(`${thoughtSpotHost}${EndPoints.SESSION_INFO}`, {
|
|
33
|
+
credentials: 'include',
|
|
34
|
+
});
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
test('fetchAuthTokenService', async () => {
|
|
@@ -101,7 +101,6 @@ export const getAnswer = `
|
|
|
101
101
|
isDiscoverable
|
|
102
102
|
isHidden
|
|
103
103
|
modifiedAt
|
|
104
|
-
tags
|
|
105
104
|
}
|
|
106
105
|
visualizations {
|
|
107
106
|
... on TableViz {
|
|
@@ -164,3 +163,12 @@ export const addVizToLiveboard = `
|
|
|
164
163
|
}
|
|
165
164
|
}
|
|
166
165
|
`;
|
|
166
|
+
|
|
167
|
+
export const getSQLQuery = `
|
|
168
|
+
mutation GetSQLQuery($session: BachSessionIdInput!) {
|
|
169
|
+
Answer__getQuery(session: $session) {
|
|
170
|
+
${bachSessionId}
|
|
171
|
+
sql
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
`;
|
|
@@ -3,7 +3,9 @@ import { AuthType, RuntimeFilterOp, VizPoint } from '../../../types';
|
|
|
3
3
|
import { AnswerService } from './answerService';
|
|
4
4
|
import {
|
|
5
5
|
getAnswerData, removeColumns, addFilter, addColumns,
|
|
6
|
+
getSQLQuery,
|
|
6
7
|
} from './answer-queries';
|
|
8
|
+
import * as queries from './answer-queries';
|
|
7
9
|
import * as authTokenInstance from '../../../authToken';
|
|
8
10
|
import * as tokenizedFetch from '../../../tokenizedFetch';
|
|
9
11
|
import * as embedConfigInstance from '../../../embed/embedConfig';
|
|
@@ -34,6 +36,23 @@ describe('Answer service tests', () => {
|
|
|
34
36
|
beforeEach(() => {
|
|
35
37
|
fetchMock.resetMocks();
|
|
36
38
|
});
|
|
39
|
+
|
|
40
|
+
test('should call executeQuery with correct parameters to add columns', async () => {
|
|
41
|
+
const service = createAnswerService();
|
|
42
|
+
const executeQuerySpy = jest.spyOn(service, 'executeQuery').mockResolvedValue({
|
|
43
|
+
id: { genNo: 2 },
|
|
44
|
+
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const columnIds = ['col1', 'col2'];
|
|
48
|
+
const result = await service.addColumns(columnIds);
|
|
49
|
+
|
|
50
|
+
expect(executeQuerySpy).toHaveBeenCalledWith(queries.addColumns, {
|
|
51
|
+
columns: columnIds.map((colId) => ({ logicalColumnId: colId })),
|
|
52
|
+
});
|
|
53
|
+
expect(result.id.genNo).toBe(2);
|
|
54
|
+
});
|
|
55
|
+
|
|
37
56
|
test('Execute query should execute the supplied graphql on the session', async () => {
|
|
38
57
|
fetchMock.mockResponseOnce(JSON.stringify({
|
|
39
58
|
data: {
|
|
@@ -146,6 +165,30 @@ describe('Answer service tests', () => {
|
|
|
146
165
|
);
|
|
147
166
|
});
|
|
148
167
|
|
|
168
|
+
test('fetchPNGBlob should call the right API', () => {
|
|
169
|
+
const answerService = createAnswerService();
|
|
170
|
+
|
|
171
|
+
const mockEmbedConfig = {
|
|
172
|
+
thougthspotHost: '/test',
|
|
173
|
+
authType: AuthType.TrustedAuthTokenCookieless,
|
|
174
|
+
};
|
|
175
|
+
jest.spyOn(embedConfigInstance, 'getEmbedConfig').mockReturnValueOnce(mockEmbedConfig);
|
|
176
|
+
jest.spyOn(authTokenInstance, 'getAuthenticationToken').mockReturnValueOnce(Promise.resolve('token'));
|
|
177
|
+
const mockTokenizedFetch = jest.spyOn(tokenizedFetch, 'tokenizedFetch');
|
|
178
|
+
answerService.fetchPNGBlob(undefined, true);
|
|
179
|
+
|
|
180
|
+
expect(mockTokenizedFetch).toHaveBeenCalledWith(`https://tshost/prism/download/answer/png?sessionId=${defaultSession.sessionId}&deviceScaleFactor=2&omitBackground=true&genNo=${defaultSession.genNo}&userLocale=en-us&exportFileName=data`, expect.objectContaining({}));
|
|
181
|
+
|
|
182
|
+
answerService.fetchPNGBlob('en-uk', true);
|
|
183
|
+
expect(mockTokenizedFetch).toHaveBeenCalledWith(`https://tshost/prism/download/answer/png?sessionId=${defaultSession.sessionId}&deviceScaleFactor=2&omitBackground=true&genNo=${defaultSession.genNo}&userLocale=en-uk&exportFileName=data`, expect.objectContaining({}));
|
|
184
|
+
|
|
185
|
+
answerService.fetchPNGBlob(undefined, false);
|
|
186
|
+
expect(mockTokenizedFetch).toHaveBeenCalledWith(`https://tshost/prism/download/answer/png?sessionId=${defaultSession.sessionId}&deviceScaleFactor=2&omitBackground=false&genNo=${defaultSession.genNo}&userLocale=en-us&exportFileName=data`, expect.objectContaining({}));
|
|
187
|
+
|
|
188
|
+
answerService.fetchPNGBlob(undefined, true, 3);
|
|
189
|
+
expect(mockTokenizedFetch).toHaveBeenCalledWith(`https://tshost/prism/download/answer/png?sessionId=${defaultSession.sessionId}&deviceScaleFactor=3&omitBackground=true&genNo=${defaultSession.genNo}&userLocale=en-us&exportFileName=data`, expect.objectContaining({}));
|
|
190
|
+
});
|
|
191
|
+
|
|
149
192
|
test('getUnderlyingDataForPoint should call the right APIs', async () => {
|
|
150
193
|
fetchMock.mockResponses(
|
|
151
194
|
JSON.stringify({
|
|
@@ -404,4 +447,30 @@ describe('Answer service tests', () => {
|
|
|
404
447
|
}),
|
|
405
448
|
);
|
|
406
449
|
});
|
|
450
|
+
|
|
451
|
+
test('Get SQL query should call the right API', async () => {
|
|
452
|
+
fetchMock.mockResponseOnce(JSON.stringify({
|
|
453
|
+
data: {
|
|
454
|
+
Answer__getQuery: {
|
|
455
|
+
id: {},
|
|
456
|
+
sql: 'SELECT * FROM table',
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
}));
|
|
460
|
+
const answerService = createAnswerService();
|
|
461
|
+
const sql = await answerService.getSQLQuery();
|
|
462
|
+
expect(fetchMock).toHaveBeenCalledWith(
|
|
463
|
+
'https://tshost/prism/?op=GetSQLQuery',
|
|
464
|
+
expect.objectContaining({
|
|
465
|
+
body: JSON.stringify({
|
|
466
|
+
operationName: 'GetSQLQuery',
|
|
467
|
+
query: getSQLQuery,
|
|
468
|
+
variables: {
|
|
469
|
+
session: defaultSession,
|
|
470
|
+
},
|
|
471
|
+
}),
|
|
472
|
+
}),
|
|
473
|
+
);
|
|
474
|
+
expect(sql).toBe('SELECT * FROM table');
|
|
475
|
+
});
|
|
407
476
|
});
|
|
@@ -173,6 +173,14 @@ export class AnswerService {
|
|
|
173
173
|
);
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
public async getSQLQuery(): Promise<string> {
|
|
177
|
+
const { sql } = await this.executeQuery(
|
|
178
|
+
queries.getSQLQuery,
|
|
179
|
+
{},
|
|
180
|
+
);
|
|
181
|
+
return sql;
|
|
182
|
+
}
|
|
183
|
+
|
|
176
184
|
/**
|
|
177
185
|
* Fetch data from the answer.
|
|
178
186
|
* @param offset
|
|
@@ -214,6 +222,25 @@ export class AnswerService {
|
|
|
214
222
|
});
|
|
215
223
|
}
|
|
216
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Fetch the data for the answer as a PNG blob. This might be
|
|
227
|
+
* quicker for larger data.
|
|
228
|
+
* @param userLocale
|
|
229
|
+
* @param omitBackground Omit the background in the PNG
|
|
230
|
+
* @param deviceScaleFactor The scale factor for the PNG
|
|
231
|
+
* @return Response
|
|
232
|
+
*/
|
|
233
|
+
public async fetchPNGBlob(userLocale = 'en-us', omitBackground = false, deviceScaleFactor = 2): Promise<Response> {
|
|
234
|
+
const fetchUrl = this.getFetchPNGBlobUrl(
|
|
235
|
+
userLocale,
|
|
236
|
+
omitBackground,
|
|
237
|
+
deviceScaleFactor,
|
|
238
|
+
);
|
|
239
|
+
return tokenizedFetch(fetchUrl, {
|
|
240
|
+
credentials: 'include',
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
217
244
|
/**
|
|
218
245
|
* Just get the internal URL for this answer's data
|
|
219
246
|
* as a CSV blob.
|
|
@@ -225,6 +252,14 @@ export class AnswerService {
|
|
|
225
252
|
return `${this.thoughtSpotHost}/prism/download/answer/csv?sessionId=${this.session.sessionId}&genNo=${this.session.genNo}&userLocale=${userLocale}&exportFileName=data&hideCsvHeader=${!includeInfo}`;
|
|
226
253
|
}
|
|
227
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Just get the internal URL for this answer's data
|
|
257
|
+
* as a PNG blob.
|
|
258
|
+
*/
|
|
259
|
+
public getFetchPNGBlobUrl(userLocale = 'en-us', omitBackground = false, deviceScaleFactor = 2): string {
|
|
260
|
+
return `${this.thoughtSpotHost}/prism/download/answer/png?sessionId=${this.session.sessionId}&deviceScaleFactor=${deviceScaleFactor}&omitBackground=${omitBackground}&genNo=${this.session.genNo}&userLocale=${userLocale}&exportFileName=data`;
|
|
261
|
+
}
|
|
262
|
+
|
|
228
263
|
/**
|
|
229
264
|
* Get underlying data given a point and the output column names.
|
|
230
265
|
* In case of a context menu action, the selectedPoints are
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import 'jest-fetch-mock';
|
|
2
|
+
import { getSourceDetail } from './sourceService';
|
|
3
|
+
import * as tokenizedFetchUtil from '../../tokenizedFetch';
|
|
4
|
+
import { graphqlQuery } from './graphql-request';
|
|
5
|
+
|
|
6
|
+
const getSourceDetailQuery = `
|
|
7
|
+
query GetSourceDetail($ids: [GUID!]!) {
|
|
8
|
+
getSourceDetailById(ids: $ids, type: LOGICAL_TABLE) {
|
|
9
|
+
id
|
|
10
|
+
name
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
const thoughtSpotHost = 'TSHOST';
|
|
16
|
+
|
|
17
|
+
describe('graphQl tests', () => {
|
|
18
|
+
test('should call tokenizedFetch with correct parameters when graphqlQuery is called', async () => {
|
|
19
|
+
jest.spyOn(tokenizedFetchUtil, 'tokenizedFetch');
|
|
20
|
+
|
|
21
|
+
const details = await graphqlQuery({
|
|
22
|
+
query: getSourceDetailQuery,
|
|
23
|
+
variables: {
|
|
24
|
+
ids: [2],
|
|
25
|
+
},
|
|
26
|
+
thoughtSpotHost,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
expect(tokenizedFetchUtil.tokenizedFetch).toBeCalledWith('TSHOST/prism/?op=GetSourceDetail', {
|
|
30
|
+
body: '{"operationName":"GetSourceDetail","query":"\\n query GetSourceDetail($ids: [GUID!]!) {\\n getSourceDetailById(ids: $ids, type: LOGICAL_TABLE) {\\n id\\n name\\n }\\n } \\n","variables":{"ids":[2]}}',
|
|
31
|
+
credentials: 'include',
|
|
32
|
+
headers: {
|
|
33
|
+
accept: '*/*', 'accept-language': 'en-us', 'content-type': 'application/json;charset=UTF-8', 'x-requested-by': 'ThoughtSpot',
|
|
34
|
+
},
|
|
35
|
+
method: 'POST',
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
});
|