@thoughtspot/visual-embed-sdk 1.35.14 → 1.36.1
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 +2 -3
- package/cjs/src/auth.d.ts +5 -0
- package/cjs/src/auth.d.ts.map +1 -1
- package/cjs/src/auth.js +7 -0
- package/cjs/src/auth.js.map +1 -1
- package/cjs/src/css-variables.d.ts +8 -0
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.js +8 -3
- package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js +54 -0
- package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +6 -0
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +27 -0
- 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 +73 -1
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/react/index.spec.js +2 -2
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/types.d.ts +82 -7
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +81 -7
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/authService/authService.d.ts +1 -0
- package/cjs/src/utils/authService/authService.d.ts.map +1 -1
- package/cjs/src/utils/authService/authService.js +1 -0
- package/cjs/src/utils/authService/authService.js.map +1 -1
- package/cjs/src/utils/authService/index.d.ts +1 -1
- package/cjs/src/utils/authService/index.d.ts.map +1 -1
- package/cjs/src/utils/authService/index.js +2 -1
- package/cjs/src/utils/authService/index.js.map +1 -1
- package/cjs/src/utils/authService/tokenizedAuthService.d.ts +10 -0
- package/cjs/src/utils/authService/tokenizedAuthService.d.ts.map +1 -1
- package/cjs/src/utils/authService/tokenizedAuthService.js +27 -1
- package/cjs/src/utils/authService/tokenizedAuthService.js.map +1 -1
- package/cjs/src/utils/authService/tokenizedAuthService.spec.js +58 -1
- package/cjs/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
- package/cjs/src/utils/sessionInfoService.d.ts +30 -0
- package/cjs/src/utils/sessionInfoService.d.ts.map +1 -1
- package/cjs/src/utils/sessionInfoService.js +59 -1
- package/cjs/src/utils/sessionInfoService.js.map +1 -1
- package/dist/index-CR5u7BMC.js +7370 -0
- package/dist/src/auth.d.ts +5 -0
- package/dist/src/auth.d.ts.map +1 -1
- package/dist/src/css-variables.d.ts +8 -0
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +6 -0
- 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/types.d.ts +82 -7
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/authService/authService.d.ts +1 -0
- package/dist/src/utils/authService/authService.d.ts.map +1 -1
- package/dist/src/utils/authService/index.d.ts +1 -1
- package/dist/src/utils/authService/index.d.ts.map +1 -1
- package/dist/src/utils/authService/tokenizedAuthService.d.ts +10 -0
- package/dist/src/utils/authService/tokenizedAuthService.d.ts.map +1 -1
- package/dist/src/utils/sessionInfoService.d.ts +30 -0
- package/dist/src/utils/sessionInfoService.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +206 -13
- package/dist/tsembed-react.js +205 -12
- package/dist/tsembed.es.js +207 -13
- package/dist/tsembed.js +206 -12
- package/dist/visual-embed-sdk-react-full.d.ts +125 -7
- package/dist/visual-embed-sdk-react.d.ts +125 -7
- package/dist/visual-embed-sdk.d.ts +125 -7
- package/lib/package.json +2 -3
- package/lib/src/auth.d.ts +5 -0
- package/lib/src/auth.d.ts.map +1 -1
- package/lib/src/auth.js +8 -1
- package/lib/src/auth.js.map +1 -1
- package/lib/src/css-variables.d.ts +8 -0
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.js +8 -3
- package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
- package/lib/src/embed/hostEventClient/host-event-client.spec.js +54 -0
- package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +6 -0
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +27 -0
- 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 +73 -1
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/react/index.spec.js +2 -2
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/types.d.ts +82 -7
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +81 -7
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/authService/authService.d.ts +1 -0
- package/lib/src/utils/authService/authService.d.ts.map +1 -1
- package/lib/src/utils/authService/authService.js +1 -0
- package/lib/src/utils/authService/authService.js.map +1 -1
- package/lib/src/utils/authService/index.d.ts +1 -1
- package/lib/src/utils/authService/index.d.ts.map +1 -1
- package/lib/src/utils/authService/index.js +1 -1
- package/lib/src/utils/authService/index.js.map +1 -1
- package/lib/src/utils/authService/tokenizedAuthService.d.ts +10 -0
- package/lib/src/utils/authService/tokenizedAuthService.d.ts.map +1 -1
- package/lib/src/utils/authService/tokenizedAuthService.js +25 -0
- package/lib/src/utils/authService/tokenizedAuthService.js.map +1 -1
- package/lib/src/utils/authService/tokenizedAuthService.spec.js +59 -2
- package/lib/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
- package/lib/src/utils/sessionInfoService.d.ts +30 -0
- package/lib/src/utils/sessionInfoService.d.ts.map +1 -1
- package/lib/src/utils/sessionInfoService.js +57 -1
- package/lib/src/utils/sessionInfoService.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +125 -7
- package/package.json +2 -3
- package/src/auth.ts +8 -1
- package/src/css-variables.ts +10 -0
- package/src/embed/hostEventClient/host-event-client.spec.ts +61 -0
- package/src/embed/hostEventClient/host-event-client.ts +8 -3
- package/src/embed/ts-embed.spec.ts +95 -1
- package/src/embed/ts-embed.ts +31 -0
- package/src/react/index.spec.tsx +2 -2
- package/src/types.ts +83 -7
- package/src/utils/authService/authService.ts +1 -0
- package/src/utils/authService/index.ts +5 -1
- package/src/utils/authService/tokenizedAuthService.spec.ts +66 -2
- package/src/utils/authService/tokenizedAuthService.ts +26 -0
- package/src/utils/sessionInfoService.ts +64 -1
|
@@ -1698,6 +1698,11 @@ declare module '@thoughtspot/visual-embed-sdk/auth' {
|
|
|
1698
1698
|
* Emits when the SDK authenticates successfully
|
|
1699
1699
|
*/
|
|
1700
1700
|
SDK_SUCCESS = "SDK_SUCCESS",
|
|
1701
|
+
/**
|
|
1702
|
+
* @hidden
|
|
1703
|
+
* Emits when iframe is loaded and session info is available
|
|
1704
|
+
*/
|
|
1705
|
+
SESSION_INFO_SUCCESS = "SESSION_INFO_SUCCESS",
|
|
1701
1706
|
/**
|
|
1702
1707
|
* Emits when the app sends an authentication success message
|
|
1703
1708
|
*/
|
|
@@ -1852,6 +1857,36 @@ declare module '@thoughtspot/visual-embed-sdk/utils/sessionInfoService' {
|
|
|
1852
1857
|
clusterName: string;
|
|
1853
1858
|
[key: string]: any;
|
|
1854
1859
|
};
|
|
1860
|
+
export type PreauthInfo = {
|
|
1861
|
+
info?: SessionInfo;
|
|
1862
|
+
headers: Record<string, string>;
|
|
1863
|
+
status: number;
|
|
1864
|
+
[key: string]: any;
|
|
1865
|
+
};
|
|
1866
|
+
/**
|
|
1867
|
+
* Processes the session info response and returns the session info object.
|
|
1868
|
+
* @param preauthInfoResp {any} Response from the session info API.
|
|
1869
|
+
* @returns {PreauthInfo} The session info object.
|
|
1870
|
+
* @example ```js
|
|
1871
|
+
* const preauthInfoResp = await fetch(sessionInfoPath);
|
|
1872
|
+
* const sessionInfo = await formatPreauthInfo(preauthInfoResp);
|
|
1873
|
+
* console.log(sessionInfo);
|
|
1874
|
+
* ```
|
|
1875
|
+
* @version SDK: 1.28.3 | ThoughtSpot: *
|
|
1876
|
+
*/
|
|
1877
|
+
export const formatPreauthInfo: (preauthInfoResp: any) => Promise<PreauthInfo>;
|
|
1878
|
+
/**
|
|
1879
|
+
* Returns the session info object and caches it for future use.
|
|
1880
|
+
* Once fetched the session info object is cached and returned from the cache on
|
|
1881
|
+
* subsequent calls.
|
|
1882
|
+
* @example ```js
|
|
1883
|
+
* const preauthInfo = await getPreauthInfo();
|
|
1884
|
+
* console.log(preauthInfo);
|
|
1885
|
+
* ```
|
|
1886
|
+
* @version SDK: 1.28.3 | ThoughtSpot: *
|
|
1887
|
+
* @returns {Promise<SessionInfo>} The session info object.
|
|
1888
|
+
*/
|
|
1889
|
+
export function getPreauthInfo(allowCache?: boolean): Promise<PreauthInfo>;
|
|
1855
1890
|
/**
|
|
1856
1891
|
* Returns the session info object and caches it for future use.
|
|
1857
1892
|
* Once fetched the session info object is cached and returned from the cache on
|
|
@@ -2510,6 +2545,7 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
2510
2545
|
* @version SDK 1.37.0 | ThoughtSpot: 10.7.0.cl
|
|
2511
2546
|
*/
|
|
2512
2547
|
customVariablesForThirdPartyTools?: Record<string, any>;
|
|
2548
|
+
disablePreauthCache?: boolean;
|
|
2513
2549
|
}
|
|
2514
2550
|
export interface LayoutConfig {
|
|
2515
2551
|
}
|
|
@@ -4469,16 +4505,63 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
4469
4505
|
*/
|
|
4470
4506
|
getExportRequestForCurrentPinboard = "getExportRequestForCurrentPinboard",
|
|
4471
4507
|
/**
|
|
4472
|
-
* Trigger
|
|
4473
|
-
*
|
|
4474
|
-
*
|
|
4475
|
-
* a
|
|
4508
|
+
* Trigger **Pin** action on an embedded object.
|
|
4509
|
+
* If no parameters are defined, the pin action is triggered
|
|
4510
|
+
* for the Answer that the user is currently on
|
|
4511
|
+
* and a modal opens for Liveboard selection.
|
|
4512
|
+
* To add an Answer or visualization to a Liveboard programmatically without
|
|
4513
|
+
* showing requiring additional user input via *Pin to Liveboard* modal, define
|
|
4514
|
+
* the following parameters:
|
|
4515
|
+
*
|
|
4516
|
+
* @param
|
|
4517
|
+
* `vizId`- GUID of the saved Answer or visualization to pin to a Liveboard.
|
|
4518
|
+
* Optional when pinning a new chart or table generated from a Search query.
|
|
4519
|
+
* @param
|
|
4520
|
+
* `liveboardID` - GUID of the Liveboard to pin an Answer. If there is no Liveboard,
|
|
4521
|
+
* specify the `newLiveboardName` parameter to create a new Liveboard.
|
|
4522
|
+
* @param
|
|
4523
|
+
* `tabId` - GUID of the Liveboard tab. Adds the Answer to the Liveboard tab
|
|
4524
|
+
* specified in the code.
|
|
4525
|
+
* @param
|
|
4526
|
+
* `newVizName` - Name string for the Answer or visualization. If defined,
|
|
4527
|
+
* this parameter adds a new visualization object or creates a copy of the
|
|
4528
|
+
* Answer or visualization specified in `vizId`.
|
|
4529
|
+
* Required attribute.
|
|
4530
|
+
* @param
|
|
4531
|
+
* `newLiveboardName` - Name string for the Liveboard.
|
|
4532
|
+
* Creates a new Liveboard object with the specified name.
|
|
4533
|
+
* @param
|
|
4534
|
+
* `newTabName` - Name of the tab. Adds a new tab Liveboard specified
|
|
4535
|
+
* in the code.
|
|
4536
|
+
*
|
|
4476
4537
|
* @example
|
|
4477
4538
|
* ```js
|
|
4478
|
-
* appEmbed.trigger(HostEvent.Pin
|
|
4539
|
+
* const pinResponse = await appEmbed.trigger(HostEvent.Pin, {
|
|
4540
|
+
* vizId: "123",
|
|
4541
|
+
* newVizName: "Sales by region",
|
|
4542
|
+
* liveboardId: "123",
|
|
4543
|
+
* tabId: "123"
|
|
4544
|
+
* });
|
|
4479
4545
|
* ```
|
|
4546
|
+
* @example
|
|
4547
|
+
* ```js
|
|
4548
|
+
* const pinResponse = await appEmbed.trigger(HostEvent.Pin, {
|
|
4549
|
+
* newVizName: "Total sales of Jackets",
|
|
4550
|
+
* liveboardId: "123"
|
|
4551
|
+
* });
|
|
4552
|
+
* ```
|
|
4553
|
+
*
|
|
4554
|
+
* @example
|
|
4480
4555
|
* ```js
|
|
4481
|
-
* searchEmbed.trigger(HostEvent.Pin
|
|
4556
|
+
* const pinResponse = await searchEmbed.trigger(HostEvent.Pin, {
|
|
4557
|
+
* newVizName: "Sales by state",
|
|
4558
|
+
* newLiveboardName: "Sales",
|
|
4559
|
+
* newTabName: "Products"
|
|
4560
|
+
* });
|
|
4561
|
+
* ```
|
|
4562
|
+
* @example
|
|
4563
|
+
* ```js
|
|
4564
|
+
* appEmbed.trigger(HostEvent.Pin)
|
|
4482
4565
|
* ```
|
|
4483
4566
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
|
|
4484
4567
|
*/
|
|
@@ -5125,7 +5208,33 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
5125
5208
|
*/
|
|
5126
5209
|
UpdatePersonalisedView = "UpdatePersonalisedView",
|
|
5127
5210
|
/**
|
|
5128
|
-
*
|
|
5211
|
+
* @hidden
|
|
5212
|
+
* Notify when info call is completed successfully
|
|
5213
|
+
* ```js
|
|
5214
|
+
* liveboardEmbed.trigger(HostEvent.InfoSuccess, data);
|
|
5215
|
+
*```
|
|
5216
|
+
* @version SDK: 1.36.0 | Thoughtspot: 10.6.0.cl
|
|
5217
|
+
*/
|
|
5218
|
+
InfoSuccess = "InfoSuccess",
|
|
5219
|
+
/**
|
|
5220
|
+
* Trigger the save action for an Answer.
|
|
5221
|
+
* To programmatically save an answer without opening the
|
|
5222
|
+
* *Describe your Answer* modal, define the `name` and `description`
|
|
5223
|
+
* properties.
|
|
5224
|
+
* If no parameters are specified, the save action is
|
|
5225
|
+
* triggered with a modal to prompt users to
|
|
5226
|
+
* add a name and description for the Answer.
|
|
5227
|
+
* @param - optional attributes to set Answer properties.
|
|
5228
|
+
* `name` - Name string for the Answer.
|
|
5229
|
+
* `description` - Description text for the Answer.
|
|
5230
|
+
*
|
|
5231
|
+
* @example
|
|
5232
|
+
* ```js
|
|
5233
|
+
* const saveAnswerResponse = await searchEmbed.trigger(HostEvent.SaveAnswer, {
|
|
5234
|
+
* name: "Sales by states",
|
|
5235
|
+
* description: "Total sales by states in MidWest"
|
|
5236
|
+
* });
|
|
5237
|
+
* ```
|
|
5129
5238
|
* @version SDK: 1.36.0 | ThoughtSpot: 10.6.0.cl
|
|
5130
5239
|
*/
|
|
5131
5240
|
SaveAnswer = "saveAnswer",
|
|
@@ -5273,6 +5382,7 @@ declare module '@thoughtspot/visual-embed-sdk/types' {
|
|
|
5273
5382
|
OauthPollingInterval = "oAuthPollingInterval",
|
|
5274
5383
|
IsForceRedirect = "isForceRedirect",
|
|
5275
5384
|
DataSourceId = "dataSourceId",
|
|
5385
|
+
preAuthCache = "preAuthCache",
|
|
5276
5386
|
ShowSpotterLimitations = "showSpotterLimitations"
|
|
5277
5387
|
}
|
|
5278
5388
|
/**
|
|
@@ -6710,6 +6820,14 @@ declare module '@thoughtspot/visual-embed-sdk/css-variables' {
|
|
|
6710
6820
|
* panel.
|
|
6711
6821
|
*/
|
|
6712
6822
|
'--ts-var-search-auto-complete-subtext-font-color'?: string;
|
|
6823
|
+
/**
|
|
6824
|
+
* Background color of the input box in the Spotter page.
|
|
6825
|
+
*/
|
|
6826
|
+
'--ts-var-spotter-input-background'?: string;
|
|
6827
|
+
/**
|
|
6828
|
+
* Background color of the previously asked prompt message in the Spotter page.
|
|
6829
|
+
*/
|
|
6830
|
+
'--ts-var-spotter-prompt-background': string;
|
|
6713
6831
|
/**
|
|
6714
6832
|
* Background color of the data panel.
|
|
6715
6833
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thoughtspot/visual-embed-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.36.1",
|
|
4
4
|
"description": "ThoughtSpot Embed SDK",
|
|
5
5
|
"module": "lib/src/index.js",
|
|
6
6
|
"main": "dist/tsembed.js",
|
|
@@ -72,7 +72,6 @@
|
|
|
72
72
|
"classnames": "^2.3.1",
|
|
73
73
|
"eventemitter3": "^4.0.7",
|
|
74
74
|
"gatsby-plugin-vercel": "^1.0.3",
|
|
75
|
-
"html-react-parser": "^1.4.12",
|
|
76
75
|
"lodash": "^4.17.21",
|
|
77
76
|
"mixpanel-browser": "2.47.0",
|
|
78
77
|
"ts-deepmerge": "^6.0.2",
|
|
@@ -117,7 +116,7 @@
|
|
|
117
116
|
"eslint-plugin-comment-length": "1.7.3",
|
|
118
117
|
"eslint-plugin-jsdoc": "^46.9.0",
|
|
119
118
|
"fs-extra": "^10.0.0",
|
|
120
|
-
"gh-pages": "
|
|
119
|
+
"gh-pages": "6.3.0",
|
|
121
120
|
"highlight.js": "^10.6.0",
|
|
122
121
|
"html-to-text": "^8.0.0",
|
|
123
122
|
"identity-obj-proxy": "^3.0.0",
|
package/src/auth.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from './utils/authService';
|
|
16
16
|
import { isActiveService } from './utils/authService/tokenizedAuthService';
|
|
17
17
|
import { logger } from './utils/logger';
|
|
18
|
-
import { getSessionInfo } from './utils/sessionInfoService';
|
|
18
|
+
import { getSessionInfo, getPreauthInfo } from './utils/sessionInfoService';
|
|
19
19
|
import { ERROR_MESSAGE } from './errors';
|
|
20
20
|
|
|
21
21
|
// eslint-disable-next-line import/no-mutable-exports
|
|
@@ -55,6 +55,11 @@ export enum AuthStatus {
|
|
|
55
55
|
* Emits when the SDK authenticates successfully
|
|
56
56
|
*/
|
|
57
57
|
SDK_SUCCESS = 'SDK_SUCCESS',
|
|
58
|
+
/**
|
|
59
|
+
* @hidden
|
|
60
|
+
* Emits when iframe is loaded and session info is available
|
|
61
|
+
*/
|
|
62
|
+
SESSION_INFO_SUCCESS = 'SESSION_INFO_SUCCESS',
|
|
58
63
|
/**
|
|
59
64
|
* Emits when the app sends an authentication success message
|
|
60
65
|
*/
|
|
@@ -168,6 +173,7 @@ export async function notifyAuthSuccess(): Promise<void> {
|
|
|
168
173
|
return;
|
|
169
174
|
}
|
|
170
175
|
try {
|
|
176
|
+
getPreauthInfo();
|
|
171
177
|
const sessionInfo = await getSessionInfo();
|
|
172
178
|
authEE.emit(AuthStatus.SUCCESS, sessionInfo);
|
|
173
179
|
} catch (e) {
|
|
@@ -224,6 +230,7 @@ async function isLoggedIn(thoughtSpotHost: string): Promise<boolean> {
|
|
|
224
230
|
*/
|
|
225
231
|
export async function postLoginService(): Promise<void> {
|
|
226
232
|
try {
|
|
233
|
+
getPreauthInfo();
|
|
227
234
|
const sessionInfo = await getSessionInfo();
|
|
228
235
|
releaseVersion = sessionInfo.releaseVersion;
|
|
229
236
|
const embedConfig = getEmbedConfig();
|
package/src/css-variables.ts
CHANGED
|
@@ -111,6 +111,16 @@ export interface CustomCssVariables {
|
|
|
111
111
|
*/
|
|
112
112
|
'--ts-var-search-auto-complete-subtext-font-color'?: string;
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Background color of the input box in the Spotter page.
|
|
116
|
+
*/
|
|
117
|
+
'--ts-var-spotter-input-background'?: string;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Background color of the previously asked prompt message in the Spotter page.
|
|
121
|
+
*/
|
|
122
|
+
'--ts-var-spotter-prompt-background': string;
|
|
123
|
+
|
|
114
124
|
/**
|
|
115
125
|
* Background color of the data panel.
|
|
116
126
|
*/
|
|
@@ -133,6 +133,7 @@ describe('HostEventClient', () => {
|
|
|
133
133
|
const mockResponse = {
|
|
134
134
|
value: {
|
|
135
135
|
pinboardId: 'testPinboard',
|
|
136
|
+
liveboardId: 'testPinboard',
|
|
136
137
|
tabId: 'testTab',
|
|
137
138
|
vizId: 'testVizId',
|
|
138
139
|
},
|
|
@@ -250,5 +251,65 @@ describe('HostEventClient', () => {
|
|
|
250
251
|
);
|
|
251
252
|
expect(result).toEqual([mockResponse]);
|
|
252
253
|
});
|
|
254
|
+
|
|
255
|
+
it('Pin response support pinboardId as well', async () => {
|
|
256
|
+
const { client, mockIframe } = createHostEventClient();
|
|
257
|
+
const hostEvent = HostEvent.Pin;
|
|
258
|
+
const payload: HostEventRequest<typeof hostEvent> = {
|
|
259
|
+
newVizDescription: 'Test Description',
|
|
260
|
+
vizId: 'testVizId',
|
|
261
|
+
newVizName: 'Test Answer',
|
|
262
|
+
newLiveboardName: 'testLiveboard',
|
|
263
|
+
} as any;
|
|
264
|
+
const mockResponse = [{
|
|
265
|
+
value: {
|
|
266
|
+
pinboardId: 'testLiveboard',
|
|
267
|
+
liveboardId: 'testPinboard',
|
|
268
|
+
tabId: 'testTab',
|
|
269
|
+
vizId: 'testVizId',
|
|
270
|
+
},
|
|
271
|
+
refId: 'testVizId',
|
|
272
|
+
}];
|
|
273
|
+
mockProcessTrigger.mockResolvedValue(mockResponse);
|
|
274
|
+
const result = await client.triggerHostEvent(hostEvent, payload);
|
|
275
|
+
expect(result.liveboardId).toBe('testLiveboard');
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it('should request liveboardId as well', async () => {
|
|
279
|
+
const { client, mockIframe } = createHostEventClient();
|
|
280
|
+
const hostEvent = HostEvent.Pin;
|
|
281
|
+
const payload: HostEventRequest<typeof hostEvent> = {
|
|
282
|
+
liveboardId: 'test',
|
|
283
|
+
newVizName: 'Test Answer',
|
|
284
|
+
newPinboardName: 'testLiveboard1',
|
|
285
|
+
newLiveboardName: 'testLiveboard',
|
|
286
|
+
} as any;
|
|
287
|
+
const mockResponse = [{
|
|
288
|
+
value: {
|
|
289
|
+
pinboardId: 'testLiveboard',
|
|
290
|
+
tabId: 'testTab',
|
|
291
|
+
vizId: 'testVizId',
|
|
292
|
+
},
|
|
293
|
+
refId: 'testVizId',
|
|
294
|
+
}];
|
|
295
|
+
mockProcessTrigger.mockResolvedValue(mockResponse);
|
|
296
|
+
const result = await client.triggerHostEvent(hostEvent, payload);
|
|
297
|
+
expect(result.liveboardId).toBe('testLiveboard');
|
|
298
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(
|
|
299
|
+
mockIframe,
|
|
300
|
+
HostEvent.UIPassthrough,
|
|
301
|
+
mockThoughtSpotHost,
|
|
302
|
+
{
|
|
303
|
+
parameters: { ...payload, pinboardId: 'test', newPinboardName: 'testLiveboard' },
|
|
304
|
+
type: 'addVizToPinboard',
|
|
305
|
+
},
|
|
306
|
+
);
|
|
307
|
+
expect(result).toEqual({
|
|
308
|
+
pinboardId: 'testLiveboard',
|
|
309
|
+
tabId: 'testTab',
|
|
310
|
+
vizId: 'testVizId',
|
|
311
|
+
liveboardId: 'testLiveboard',
|
|
312
|
+
});
|
|
313
|
+
});
|
|
253
314
|
});
|
|
254
315
|
});
|
|
@@ -98,13 +98,18 @@ export class HostEventClient {
|
|
|
98
98
|
|
|
99
99
|
const formattedPayload = {
|
|
100
100
|
...payload,
|
|
101
|
-
pinboardId: payload.liveboardId,
|
|
102
|
-
newPinboardName: payload.newLiveboardName,
|
|
101
|
+
pinboardId: payload.liveboardId ?? (payload as any).pinboardId,
|
|
102
|
+
newPinboardName: payload.newLiveboardName ?? (payload as any).newPinboardName,
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
const data = await this.handleHostEventWithParam(
|
|
106
106
|
UIPassthroughEvent.PinAnswerToLiveboard, formattedPayload,
|
|
107
107
|
);
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
...data,
|
|
111
|
+
liveboardId: (data as any).pinboardId,
|
|
112
|
+
};
|
|
108
113
|
}
|
|
109
114
|
|
|
110
115
|
protected async handleSaveAnswerEvent(
|
|
@@ -51,12 +51,13 @@ import * as mixpanelInstance from '../mixpanel-service';
|
|
|
51
51
|
import * as authInstance from '../auth';
|
|
52
52
|
import * as baseInstance from './base';
|
|
53
53
|
import { MIXPANEL_EVENT } from '../mixpanel-service';
|
|
54
|
-
import * as authService from '../utils/authService
|
|
54
|
+
import * as authService from '../utils/authService';
|
|
55
55
|
import { logger } from '../utils/logger';
|
|
56
56
|
import { version } from '../../package.json';
|
|
57
57
|
import { HiddenActionItemByDefaultForSearchEmbed } from './search';
|
|
58
58
|
import { processTrigger } from '../utils/processTrigger';
|
|
59
59
|
import { UIPassthroughEvent } from './hostEventClient/contracts';
|
|
60
|
+
import * as sessionInfoService from '../utils/sessionInfoService';
|
|
60
61
|
|
|
61
62
|
jest.mock('../utils/processTrigger');
|
|
62
63
|
|
|
@@ -1147,6 +1148,99 @@ describe('Unit test case for ts embed', () => {
|
|
|
1147
1148
|
});
|
|
1148
1149
|
});
|
|
1149
1150
|
|
|
1151
|
+
describe('Trigger infoSuccess event on iframe load', () => {
|
|
1152
|
+
beforeAll(() => {
|
|
1153
|
+
jest.clearAllMocks();
|
|
1154
|
+
init({
|
|
1155
|
+
thoughtSpotHost,
|
|
1156
|
+
authType: AuthType.None,
|
|
1157
|
+
loginFailedMessage: 'Failed to Login',
|
|
1158
|
+
});
|
|
1159
|
+
});
|
|
1160
|
+
|
|
1161
|
+
const setup = async (isLoggedIn = false, overrideOrgId: number | undefined = undefined) => {
|
|
1162
|
+
jest.spyOn(window, 'addEventListener').mockImplementationOnce(
|
|
1163
|
+
(event, handler, options) => {
|
|
1164
|
+
handler({
|
|
1165
|
+
data: {
|
|
1166
|
+
type: 'xyz',
|
|
1167
|
+
},
|
|
1168
|
+
ports: [3000],
|
|
1169
|
+
source: null,
|
|
1170
|
+
});
|
|
1171
|
+
},
|
|
1172
|
+
);
|
|
1173
|
+
mockProcessTrigger.mockResolvedValueOnce({ session: 'test' });
|
|
1174
|
+
// resetCachedPreauthInfo();
|
|
1175
|
+
let mockGetPreauthInfo = null;
|
|
1176
|
+
|
|
1177
|
+
if (overrideOrgId) {
|
|
1178
|
+
mockGetPreauthInfo = jest.spyOn(sessionInfoService, 'getPreauthInfo').mockImplementation(jest.fn());
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
const mockPreauthInfoFetch = jest.spyOn(authService, 'fetchPreauthInfoService').mockResolvedValueOnce({
|
|
1182
|
+
ok: true,
|
|
1183
|
+
headers: new Headers({ 'content-type': 'application/json' }), // Mock headers correctly
|
|
1184
|
+
json: async () => ({
|
|
1185
|
+
info: {
|
|
1186
|
+
configInfo: {
|
|
1187
|
+
mixpanelConfig: {
|
|
1188
|
+
devSdkKey: 'devSdkKey',
|
|
1189
|
+
},
|
|
1190
|
+
},
|
|
1191
|
+
userGUID: 'userGUID',
|
|
1192
|
+
},
|
|
1193
|
+
}), // Mock JSON response
|
|
1194
|
+
});
|
|
1195
|
+
const iFrame: any = document.createElement('div');
|
|
1196
|
+
jest.spyOn(baseInstance, 'getAuthPromise').mockResolvedValueOnce(isLoggedIn);
|
|
1197
|
+
const tsEmbed = new SearchEmbed(getRootEl(), {
|
|
1198
|
+
overrideOrgId,
|
|
1199
|
+
});
|
|
1200
|
+
iFrame.contentWindow = {
|
|
1201
|
+
postMessage: jest.fn(),
|
|
1202
|
+
};
|
|
1203
|
+
tsEmbed.on(EmbedEvent.CustomAction, jest.fn());
|
|
1204
|
+
jest.spyOn(iFrame, 'addEventListener').mockImplementationOnce(
|
|
1205
|
+
(event, handler, options) => {
|
|
1206
|
+
handler({});
|
|
1207
|
+
},
|
|
1208
|
+
);
|
|
1209
|
+
jest.spyOn(document, 'createElement').mockReturnValueOnce(iFrame);
|
|
1210
|
+
await tsEmbed.render();
|
|
1211
|
+
|
|
1212
|
+
return {
|
|
1213
|
+
mockPreauthInfoFetch,
|
|
1214
|
+
mockGetPreauthInfo,
|
|
1215
|
+
iFrame,
|
|
1216
|
+
};
|
|
1217
|
+
};
|
|
1218
|
+
|
|
1219
|
+
test('should call InfoSuccess Event on preauth call success', async () => {
|
|
1220
|
+
const {
|
|
1221
|
+
mockPreauthInfoFetch,
|
|
1222
|
+
iFrame,
|
|
1223
|
+
} = await setup(true);
|
|
1224
|
+
expect(mockPreauthInfoFetch).toHaveBeenCalledTimes(1);
|
|
1225
|
+
|
|
1226
|
+
await executeAfterWait(() => {
|
|
1227
|
+
expect(mockProcessTrigger).toHaveBeenCalledWith(
|
|
1228
|
+
iFrame,
|
|
1229
|
+
HostEvent.InfoSuccess,
|
|
1230
|
+
'http://tshost',
|
|
1231
|
+
expect.objectContaining({ info: expect.any(Object) }),
|
|
1232
|
+
);
|
|
1233
|
+
});
|
|
1234
|
+
});
|
|
1235
|
+
|
|
1236
|
+
test('should not call InfoSuccess Event if overrideOrgId is true', async () => {
|
|
1237
|
+
const {
|
|
1238
|
+
mockGetPreauthInfo,
|
|
1239
|
+
} = await setup(true, 123);
|
|
1240
|
+
expect(mockGetPreauthInfo).toHaveBeenCalledTimes(0);
|
|
1241
|
+
});
|
|
1242
|
+
});
|
|
1243
|
+
|
|
1150
1244
|
describe('when thoughtSpotHost have value and authPromise return error', () => {
|
|
1151
1245
|
beforeAll(() => {
|
|
1152
1246
|
init({
|
package/src/embed/ts-embed.ts
CHANGED
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
import { AuthFailureType } from '../auth';
|
|
71
71
|
import { getEmbedConfig } from './embedConfig';
|
|
72
72
|
import { ERROR_MESSAGE } from '../errors';
|
|
73
|
+
import { getPreauthInfo } from '../utils/sessionInfoService';
|
|
73
74
|
import { HostEventClient } from './hostEventClient/host-event-client';
|
|
74
75
|
|
|
75
76
|
const { version } = pkgInfo;
|
|
@@ -244,6 +245,24 @@ export class TsEmbed {
|
|
|
244
245
|
return null;
|
|
245
246
|
}
|
|
246
247
|
|
|
248
|
+
/**
|
|
249
|
+
* Checks if preauth cache is enabled
|
|
250
|
+
* from the view config and embed config
|
|
251
|
+
* @returns boolean
|
|
252
|
+
*/
|
|
253
|
+
private isPreAuthCacheEnabled() {
|
|
254
|
+
// Disable preauth cache when:
|
|
255
|
+
// 1. overrideOrgId is present since:
|
|
256
|
+
// - cached auth info would be for wrong org
|
|
257
|
+
// - info call response changes for each different overrideOrgId
|
|
258
|
+
// 2. disablePreauthCache is explicitly set to true
|
|
259
|
+
const isDisabled = (
|
|
260
|
+
this.viewConfig.overrideOrgId !== undefined
|
|
261
|
+
|| this.embedConfig.disablePreauthCache === true
|
|
262
|
+
);
|
|
263
|
+
return !isDisabled;
|
|
264
|
+
}
|
|
265
|
+
|
|
247
266
|
/**
|
|
248
267
|
* fix for ts7.sep.cl
|
|
249
268
|
* will be removed for ts7.oct.cl
|
|
@@ -586,6 +605,10 @@ export class TsEmbed {
|
|
|
586
605
|
queryParams[Param.OverrideOrgId] = overrideOrgId;
|
|
587
606
|
}
|
|
588
607
|
|
|
608
|
+
if (this.isPreAuthCacheEnabled()) {
|
|
609
|
+
queryParams[Param.preAuthCache] = true;
|
|
610
|
+
}
|
|
611
|
+
|
|
589
612
|
queryParams[Param.OverrideNativeConsole] = true;
|
|
590
613
|
queryParams[Param.ClientLogLevel] = this.embedConfig.logLevel;
|
|
591
614
|
|
|
@@ -722,6 +745,14 @@ export class TsEmbed {
|
|
|
722
745
|
elHeight: this.iFrame.clientHeight,
|
|
723
746
|
timeTookToLoad: loadTimestamp - initTimestamp,
|
|
724
747
|
});
|
|
748
|
+
// Send info event if preauth cache is enabled
|
|
749
|
+
if (this.isPreAuthCacheEnabled()) {
|
|
750
|
+
getPreauthInfo().then((data) => {
|
|
751
|
+
if (data?.info) {
|
|
752
|
+
this.trigger(HostEvent.InfoSuccess, data);
|
|
753
|
+
}
|
|
754
|
+
});
|
|
755
|
+
}
|
|
725
756
|
});
|
|
726
757
|
this.iFrame.addEventListener('error', () => {
|
|
727
758
|
nextInQueue();
|
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}/?embedApp=true&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=false&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true&collapseSearchBarInitially=true&enableCustomColumnGroups=false&dataPanelCustomGroupsAccordionInitialState=EXPAND_ALL#/embed/answer`,
|
|
59
|
+
`http://${thoughtSpotHost}/?embedApp=true&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]&preAuthCache=true&overrideConsoleLogs=true&clientLogLevel=ERROR&enableDataPanelV2=false&dataSourceMode=hide&useLastSelectedSources=false&isSearchEmbed=true&collapseSearchBarInitially=true&enableCustomColumnGroups=false&dataPanelCustomGroupsAccordionInitialState=EXPAND_ALL#/embed/answer`,
|
|
60
60
|
);
|
|
61
61
|
});
|
|
62
62
|
|
|
@@ -230,7 +230,7 @@ describe('React Components', () => {
|
|
|
230
230
|
),
|
|
231
231
|
).toBe(true);
|
|
232
232
|
expect(getIFrameSrc(container)).toBe(
|
|
233
|
-
`http://${thoughtSpotHost}/?embedApp=true&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22]&overrideConsoleLogs=true&clientLogLevel=ERROR&dataSources=[%22test%22]&searchTokenString=%5Brevenue%5D&executeSearch=true&useLastSelectedSources=false&isSearchEmbed=true#/embed/search-bar-embed`,
|
|
233
|
+
`http://${thoughtSpotHost}/?embedApp=true&hostAppUrl=local-host&viewPortHeight=768&viewPortWidth=1024&sdkVersion=${version}&authType=None&blockNonEmbedFullAppAccess=true&hideAction=[%22${Action.ReportError}%22]&preAuthCache=true&overrideConsoleLogs=true&clientLogLevel=ERROR&dataSources=[%22test%22]&searchTokenString=%5Brevenue%5D&executeSearch=true&useLastSelectedSources=false&isSearchEmbed=true#/embed/search-bar-embed`,
|
|
234
234
|
);
|
|
235
235
|
});
|
|
236
236
|
});
|
package/src/types.ts
CHANGED
|
@@ -629,6 +629,8 @@ export interface EmbedConfig {
|
|
|
629
629
|
* @version SDK 1.37.0 | ThoughtSpot: 10.7.0.cl
|
|
630
630
|
*/
|
|
631
631
|
customVariablesForThirdPartyTools?: Record< string, any >;
|
|
632
|
+
|
|
633
|
+
disablePreauthCache?: boolean;
|
|
632
634
|
}
|
|
633
635
|
|
|
634
636
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
@@ -2613,16 +2615,63 @@ export enum HostEvent {
|
|
|
2613
2615
|
*/
|
|
2614
2616
|
getExportRequestForCurrentPinboard = 'getExportRequestForCurrentPinboard',
|
|
2615
2617
|
/**
|
|
2616
|
-
* Trigger
|
|
2617
|
-
*
|
|
2618
|
-
*
|
|
2619
|
-
* a
|
|
2618
|
+
* Trigger **Pin** action on an embedded object.
|
|
2619
|
+
* If no parameters are defined, the pin action is triggered
|
|
2620
|
+
* for the Answer that the user is currently on
|
|
2621
|
+
* and a modal opens for Liveboard selection.
|
|
2622
|
+
* To add an Answer or visualization to a Liveboard programmatically without
|
|
2623
|
+
* showing requiring additional user input via *Pin to Liveboard* modal, define
|
|
2624
|
+
* the following parameters:
|
|
2625
|
+
*
|
|
2626
|
+
* @param
|
|
2627
|
+
* `vizId`- GUID of the saved Answer or visualization to pin to a Liveboard.
|
|
2628
|
+
* Optional when pinning a new chart or table generated from a Search query.
|
|
2629
|
+
* @param
|
|
2630
|
+
* `liveboardID` - GUID of the Liveboard to pin an Answer. If there is no Liveboard,
|
|
2631
|
+
* specify the `newLiveboardName` parameter to create a new Liveboard.
|
|
2632
|
+
* @param
|
|
2633
|
+
* `tabId` - GUID of the Liveboard tab. Adds the Answer to the Liveboard tab
|
|
2634
|
+
* specified in the code.
|
|
2635
|
+
* @param
|
|
2636
|
+
* `newVizName` - Name string for the Answer or visualization. If defined,
|
|
2637
|
+
* this parameter adds a new visualization object or creates a copy of the
|
|
2638
|
+
* Answer or visualization specified in `vizId`.
|
|
2639
|
+
* Required attribute.
|
|
2640
|
+
* @param
|
|
2641
|
+
* `newLiveboardName` - Name string for the Liveboard.
|
|
2642
|
+
* Creates a new Liveboard object with the specified name.
|
|
2643
|
+
* @param
|
|
2644
|
+
* `newTabName` - Name of the tab. Adds a new tab Liveboard specified
|
|
2645
|
+
* in the code.
|
|
2646
|
+
*
|
|
2620
2647
|
* @example
|
|
2621
2648
|
* ```js
|
|
2622
|
-
* appEmbed.trigger(HostEvent.Pin
|
|
2649
|
+
* const pinResponse = await appEmbed.trigger(HostEvent.Pin, {
|
|
2650
|
+
* vizId: "123",
|
|
2651
|
+
* newVizName: "Sales by region",
|
|
2652
|
+
* liveboardId: "123",
|
|
2653
|
+
* tabId: "123"
|
|
2654
|
+
* });
|
|
2655
|
+
* ```
|
|
2656
|
+
* @example
|
|
2657
|
+
* ```js
|
|
2658
|
+
* const pinResponse = await appEmbed.trigger(HostEvent.Pin, {
|
|
2659
|
+
* newVizName: "Total sales of Jackets",
|
|
2660
|
+
* liveboardId: "123"
|
|
2661
|
+
* });
|
|
2623
2662
|
* ```
|
|
2663
|
+
*
|
|
2664
|
+
* @example
|
|
2624
2665
|
* ```js
|
|
2625
|
-
* searchEmbed.trigger(HostEvent.Pin
|
|
2666
|
+
* const pinResponse = await searchEmbed.trigger(HostEvent.Pin, {
|
|
2667
|
+
* newVizName: "Sales by state",
|
|
2668
|
+
* newLiveboardName: "Sales",
|
|
2669
|
+
* newTabName: "Products"
|
|
2670
|
+
* });
|
|
2671
|
+
* ```
|
|
2672
|
+
* @example
|
|
2673
|
+
* ```js
|
|
2674
|
+
* appEmbed.trigger(HostEvent.Pin)
|
|
2626
2675
|
* ```
|
|
2627
2676
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
|
|
2628
2677
|
*/
|
|
@@ -3269,7 +3318,33 @@ export enum HostEvent {
|
|
|
3269
3318
|
*/
|
|
3270
3319
|
UpdatePersonalisedView = 'UpdatePersonalisedView',
|
|
3271
3320
|
/**
|
|
3272
|
-
*
|
|
3321
|
+
* @hidden
|
|
3322
|
+
* Notify when info call is completed successfully
|
|
3323
|
+
* ```js
|
|
3324
|
+
* liveboardEmbed.trigger(HostEvent.InfoSuccess, data);
|
|
3325
|
+
*```
|
|
3326
|
+
* @version SDK: 1.36.0 | Thoughtspot: 10.6.0.cl
|
|
3327
|
+
*/
|
|
3328
|
+
InfoSuccess = 'InfoSuccess',
|
|
3329
|
+
/**
|
|
3330
|
+
* Trigger the save action for an Answer.
|
|
3331
|
+
* To programmatically save an answer without opening the
|
|
3332
|
+
* *Describe your Answer* modal, define the `name` and `description`
|
|
3333
|
+
* properties.
|
|
3334
|
+
* If no parameters are specified, the save action is
|
|
3335
|
+
* triggered with a modal to prompt users to
|
|
3336
|
+
* add a name and description for the Answer.
|
|
3337
|
+
* @param - optional attributes to set Answer properties.
|
|
3338
|
+
* `name` - Name string for the Answer.
|
|
3339
|
+
* `description` - Description text for the Answer.
|
|
3340
|
+
*
|
|
3341
|
+
* @example
|
|
3342
|
+
* ```js
|
|
3343
|
+
* const saveAnswerResponse = await searchEmbed.trigger(HostEvent.SaveAnswer, {
|
|
3344
|
+
* name: "Sales by states",
|
|
3345
|
+
* description: "Total sales by states in MidWest"
|
|
3346
|
+
* });
|
|
3347
|
+
* ```
|
|
3273
3348
|
* @version SDK: 1.36.0 | ThoughtSpot: 10.6.0.cl
|
|
3274
3349
|
*/
|
|
3275
3350
|
SaveAnswer = 'saveAnswer',
|
|
@@ -3427,6 +3502,7 @@ export enum Param {
|
|
|
3427
3502
|
OauthPollingInterval = 'oAuthPollingInterval',
|
|
3428
3503
|
IsForceRedirect = 'isForceRedirect',
|
|
3429
3504
|
DataSourceId = 'dataSourceId',
|
|
3505
|
+
preAuthCache = 'preAuthCache',
|
|
3430
3506
|
ShowSpotterLimitations = 'showSpotterLimitations',
|
|
3431
3507
|
}
|
|
3432
3508
|
|