@thoughtspot/visual-embed-sdk 1.41.1 → 1.42.1-alpha.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 +9 -9
- package/cjs/src/api-intercept.d.ts +25 -0
- package/cjs/src/api-intercept.d.ts.map +1 -0
- package/cjs/src/api-intercept.js +115 -0
- package/cjs/src/api-intercept.js.map +1 -0
- package/cjs/src/css-variables.d.ts +52 -14
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +7 -2
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +20 -0
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.d.ts +1 -0
- package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/cjs/src/embed/bodyless-conversation.js +7 -3
- package/cjs/src/embed/bodyless-conversation.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts +1 -0
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +7 -2
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.d.ts +11 -1
- package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/cjs/src/embed/hostEventClient/contracts.js +1 -0
- package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +1 -0
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +10 -2
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +35 -0
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/sage.d.ts +1 -0
- package/cjs/src/embed/sage.d.ts.map +1 -1
- package/cjs/src/embed/sage.js +10 -6
- package/cjs/src/embed/sage.js.map +1 -1
- package/cjs/src/embed/search-bar.d.ts +1 -0
- package/cjs/src/embed/search-bar.d.ts.map +1 -1
- package/cjs/src/embed/search-bar.js +11 -7
- package/cjs/src/embed/search-bar.js.map +1 -1
- package/cjs/src/embed/search.d.ts +1 -0
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js +10 -9
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +21 -4
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +115 -34
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +83 -0
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/errors.d.ts +1 -0
- package/cjs/src/errors.d.ts.map +1 -1
- package/cjs/src/errors.js +1 -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/react/all-types-export.spec.js +1 -1
- package/cjs/src/react/all-types-export.spec.js.map +1 -1
- package/cjs/src/react/util.js.map +1 -1
- package/cjs/src/react/util.spec.d.ts +2 -0
- package/cjs/src/react/util.spec.d.ts.map +1 -0
- package/cjs/src/react/util.spec.js +78 -0
- package/cjs/src/react/util.spec.js.map +1 -0
- package/cjs/src/types.d.ts +135 -8
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +73 -4
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/processData.d.ts +1 -1
- package/cjs/src/utils/processData.d.ts.map +1 -1
- package/cjs/src/utils/processData.js +8 -8
- package/cjs/src/utils/processData.js.map +1 -1
- package/dist/index-BEzW4MDA.js +7371 -0
- package/dist/{index-DQueHwfQ.js → index-DvNA626T.js} +1 -1
- package/dist/src/api-intercept.d.ts +25 -0
- package/dist/src/api-intercept.d.ts.map +1 -0
- package/dist/src/css-variables.d.ts +52 -14
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/bodyless-conversation.d.ts +1 -0
- package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts +1 -0
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/hostEventClient/contracts.d.ts +11 -1
- package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +1 -0
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/sage.d.ts +1 -0
- package/dist/src/embed/sage.d.ts.map +1 -1
- package/dist/src/embed/search-bar.d.ts +1 -0
- package/dist/src/embed/search-bar.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +1 -0
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +21 -4
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/errors.d.ts +1 -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/react/util.spec.d.ts +2 -0
- package/dist/src/react/util.spec.d.ts.map +1 -0
- package/dist/src/types.d.ts +135 -8
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/processData.d.ts +1 -1
- package/dist/src/utils/processData.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +370 -90
- package/dist/tsembed-react.js +369 -89
- package/dist/tsembed.es.js +371 -91
- package/dist/tsembed.js +369 -89
- package/dist/visual-embed-sdk-react-full.d.ts +9431 -9915
- package/dist/visual-embed-sdk-react.d.ts +9301 -9922
- package/dist/visual-embed-sdk.d.ts +9470 -9532
- package/lib/package.json +9 -9
- package/lib/src/api-intercept.d.ts +25 -0
- package/lib/src/api-intercept.d.ts.map +1 -0
- package/lib/src/api-intercept.js +108 -0
- package/lib/src/api-intercept.js.map +1 -0
- package/lib/src/css-variables.d.ts +52 -14
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +7 -2
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +20 -0
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.d.ts +1 -0
- package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/lib/src/embed/bodyless-conversation.js +7 -3
- package/lib/src/embed/bodyless-conversation.js.map +1 -1
- package/lib/src/embed/conversation.d.ts +1 -0
- 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/hostEventClient/contracts.d.ts +11 -1
- package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
- package/lib/src/embed/hostEventClient/contracts.js +1 -0
- package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +1 -0
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +10 -2
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +35 -0
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/sage.d.ts +1 -0
- package/lib/src/embed/sage.d.ts.map +1 -1
- package/lib/src/embed/sage.js +10 -6
- package/lib/src/embed/sage.js.map +1 -1
- package/lib/src/embed/search-bar.d.ts +1 -0
- package/lib/src/embed/search-bar.d.ts.map +1 -1
- package/lib/src/embed/search-bar.js +11 -7
- package/lib/src/embed/search-bar.js.map +1 -1
- package/lib/src/embed/search.d.ts +1 -0
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +10 -9
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +21 -4
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +115 -34
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +83 -0
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/errors.d.ts +1 -0
- package/lib/src/errors.d.ts.map +1 -1
- package/lib/src/errors.js +1 -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/react/all-types-export.spec.js +1 -1
- package/lib/src/react/all-types-export.spec.js.map +1 -1
- package/lib/src/react/util.js.map +1 -1
- package/lib/src/react/util.spec.d.ts +2 -0
- package/lib/src/react/util.spec.d.ts.map +1 -0
- package/lib/src/react/util.spec.js +76 -0
- package/lib/src/react/util.spec.js.map +1 -0
- package/lib/src/types.d.ts +135 -8
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +72 -3
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/processData.d.ts +1 -1
- package/lib/src/utils/processData.d.ts.map +1 -1
- package/lib/src/utils/processData.js +8 -8
- package/lib/src/utils/processData.js.map +1 -1
- package/package.json +9 -9
- package/src/api-intercept.ts +134 -0
- package/src/css-variables.ts +53 -16
- package/src/embed/app.spec.ts +28 -0
- package/src/embed/app.ts +9 -1
- package/src/embed/bodyless-conversation.ts +8 -3
- package/src/embed/conversation.ts +17 -2
- package/src/embed/hostEventClient/contracts.ts +10 -0
- package/src/embed/liveboard.spec.ts +44 -0
- package/src/embed/liveboard.ts +12 -1
- package/src/embed/sage.ts +14 -9
- package/src/embed/search-bar.tsx +14 -7
- package/src/embed/search.ts +21 -8
- package/src/embed/ts-embed.spec.ts +116 -5
- package/src/embed/ts-embed.ts +152 -50
- package/src/errors.ts +1 -0
- package/src/index.ts +2 -0
- package/src/react/all-types-export.spec.ts +1 -1
- package/src/react/all-types-export.ts +1 -0
- package/src/react/util.spec.tsx +88 -0
- package/src/react/util.ts +3 -3
- package/src/types.ts +195 -64
- package/src/utils/processData.ts +11 -11
- package/lib/src/visual-embed-sdk.d.ts +0 -9779
|
@@ -7,6 +7,7 @@ export enum UIPassthroughEvent {
|
|
|
7
7
|
GetAvailableUIPassthroughs = 'getAvailableUiPassthroughs',
|
|
8
8
|
GetAnswerConfig = 'getAnswerPageConfig',
|
|
9
9
|
GetLiveboardConfig = 'getPinboardPageConfig',
|
|
10
|
+
GetUnsavedAnswerTML = 'getUnsavedAnswerTML',
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
// UI Passthrough Contract
|
|
@@ -63,6 +64,15 @@ export type UIPassthroughContractBase = {
|
|
|
63
64
|
request: any;
|
|
64
65
|
response: any;
|
|
65
66
|
};
|
|
67
|
+
[UIPassthroughEvent.GetUnsavedAnswerTML]: {
|
|
68
|
+
request: {
|
|
69
|
+
sessionId?: string;
|
|
70
|
+
vizId?: string;
|
|
71
|
+
};
|
|
72
|
+
response: {
|
|
73
|
+
tml: string;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
66
76
|
};
|
|
67
77
|
|
|
68
78
|
// UI Passthrough Request and Response
|
|
@@ -183,6 +183,36 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
183
183
|
});
|
|
184
184
|
});
|
|
185
185
|
|
|
186
|
+
test('should set isLinkParametersEnabled to true in url', async () => {
|
|
187
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
188
|
+
isLinkParametersEnabled: true,
|
|
189
|
+
...defaultViewConfig,
|
|
190
|
+
liveboardId,
|
|
191
|
+
} as LiveboardViewConfig);
|
|
192
|
+
liveboardEmbed.render();
|
|
193
|
+
await executeAfterWait(() => {
|
|
194
|
+
expectUrlMatchesWithParams(
|
|
195
|
+
getIFrameSrc(),
|
|
196
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLinkParametersEnabled=true${prefixParams}#/embed/viz/${liveboardId}`,
|
|
197
|
+
);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test('should set isLinkParametersEnabled to false in url', async () => {
|
|
202
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
203
|
+
isLinkParametersEnabled: false,
|
|
204
|
+
...defaultViewConfig,
|
|
205
|
+
liveboardId,
|
|
206
|
+
} as LiveboardViewConfig);
|
|
207
|
+
liveboardEmbed.render();
|
|
208
|
+
await executeAfterWait(() => {
|
|
209
|
+
expectUrlMatchesWithParams(
|
|
210
|
+
getIFrameSrc(),
|
|
211
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&isLinkParametersEnabled=false${prefixParams}#/embed/viz/${liveboardId}`,
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
|
|
186
216
|
test('should set visible actions as empty array', async () => {
|
|
187
217
|
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
188
218
|
visibleActions: [],
|
|
@@ -657,6 +687,7 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
657
687
|
test('navigateToLiveboard should trigger the navigate event with the correct path', async (done) => {
|
|
658
688
|
mockMessageChannel();
|
|
659
689
|
// mock getSessionInfo
|
|
690
|
+
|
|
660
691
|
mockGetSessionInfo();
|
|
661
692
|
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
662
693
|
...defaultViewConfig,
|
|
@@ -684,6 +715,13 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
684
715
|
mockMessageChannel();
|
|
685
716
|
|
|
686
717
|
// mock getSessionInfo
|
|
718
|
+
jest.spyOn(SessionInfoService, 'getSessionInfo').mockResolvedValue({
|
|
719
|
+
releaseVersion: '1.0.0',
|
|
720
|
+
userGUID: '1234567890',
|
|
721
|
+
currentOrgId: 1,
|
|
722
|
+
privileges: [],
|
|
723
|
+
mixpanelToken: '1234567890',
|
|
724
|
+
});
|
|
687
725
|
mockGetSessionInfo();
|
|
688
726
|
|
|
689
727
|
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
@@ -779,6 +817,12 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
779
817
|
});
|
|
780
818
|
|
|
781
819
|
describe('PreRender flow for liveboard embed', () => {
|
|
820
|
+
beforeAll(() => {
|
|
821
|
+
init({
|
|
822
|
+
thoughtSpotHost: "http://tshost",
|
|
823
|
+
authType: AuthType.None,
|
|
824
|
+
});
|
|
825
|
+
});
|
|
782
826
|
test('it should preRender generic with liveboard id is not passed', async (done) => {
|
|
783
827
|
const consoleSpy = jest.spyOn(console, 'error');
|
|
784
828
|
const libEmbed = new LiveboardEmbed(getRootEl(), {
|
package/src/embed/liveboard.ts
CHANGED
|
@@ -440,6 +440,12 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
440
440
|
* embedded Liveboard or visualization.
|
|
441
441
|
*/
|
|
442
442
|
protected getEmbedParams() {
|
|
443
|
+
const params = this.getEmbedParamsObject();
|
|
444
|
+
const queryParams = getQueryParamString(params, true);
|
|
445
|
+
return queryParams;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
protected getEmbedParamsObject() {
|
|
443
449
|
let params: any = {};
|
|
444
450
|
params = this.getBaseQueryParams(params);
|
|
445
451
|
const {
|
|
@@ -471,6 +477,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
471
477
|
isLiveboardStylingAndGroupingEnabled,
|
|
472
478
|
isPNGInScheduledEmailsEnabled = false,
|
|
473
479
|
showSpotterLimitations,
|
|
480
|
+
isLinkParametersEnabled,
|
|
474
481
|
} = this.viewConfig;
|
|
475
482
|
|
|
476
483
|
const preventLiveboardFilterRemoval = this.viewConfig.preventLiveboardFilterRemoval
|
|
@@ -546,6 +553,10 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
546
553
|
params[Param.ShowSpotterLimitations] = showSpotterLimitations;
|
|
547
554
|
}
|
|
548
555
|
|
|
556
|
+
if (isLinkParametersEnabled !== undefined) {
|
|
557
|
+
params[Param.isLinkParametersEnabled] = isLinkParametersEnabled;
|
|
558
|
+
}
|
|
559
|
+
|
|
549
560
|
params[Param.LiveboardHeaderSticky] = isLiveboardHeaderSticky;
|
|
550
561
|
params[Param.LiveboardHeaderV2] = isLiveboardCompactHeaderEnabled;
|
|
551
562
|
params[Param.ShowLiveboardVerifiedBadge] = showLiveboardVerifiedBadge;
|
|
@@ -557,7 +568,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
557
568
|
params[Param.LiveboardXLSXCSVDownload] = !!liveboardXLSXCSVDownload;
|
|
558
569
|
const queryParams = getQueryParamString(params, true);
|
|
559
570
|
|
|
560
|
-
return
|
|
571
|
+
return params;
|
|
561
572
|
}
|
|
562
573
|
|
|
563
574
|
private getIframeSuffixSrc(liveboardId: string, vizId: string, activeTabId: string) {
|
package/src/embed/sage.ts
CHANGED
|
@@ -153,12 +153,7 @@ export class SageEmbed extends V1Embed {
|
|
|
153
153
|
super(domSelector, viewConfig);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
* Constructs a map of parameters to be passed on to the
|
|
158
|
-
* embedded Eureka or Sage search page.
|
|
159
|
-
* @returns {string} query string
|
|
160
|
-
*/
|
|
161
|
-
protected getEmbedParams(): string {
|
|
156
|
+
protected getEmbedParamsObject() {
|
|
162
157
|
const {
|
|
163
158
|
disableWorksheetChange,
|
|
164
159
|
hideWorksheetSelector,
|
|
@@ -184,6 +179,16 @@ export class SageEmbed extends V1Embed {
|
|
|
184
179
|
params[Param.IsProductTour] = !!isProductTour;
|
|
185
180
|
params[Param.HideSageAnswerHeader] = !!hideSageAnswerHeader;
|
|
186
181
|
|
|
182
|
+
return params;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Constructs a map of parameters to be passed on to the
|
|
187
|
+
* embedded Eureka or Sage search page.
|
|
188
|
+
* @returns {string} query string
|
|
189
|
+
*/
|
|
190
|
+
protected getEmbedParams(): string {
|
|
191
|
+
const params = this.getEmbedParamsObject();
|
|
187
192
|
return getQueryParamString(params, true);
|
|
188
193
|
}
|
|
189
194
|
|
|
@@ -194,15 +199,15 @@ export class SageEmbed extends V1Embed {
|
|
|
194
199
|
*/
|
|
195
200
|
public getIFrameSrc(): string {
|
|
196
201
|
const path = 'eureka';
|
|
197
|
-
const postHashObj = {};
|
|
202
|
+
const postHashObj: Record<string, any> = {};
|
|
198
203
|
const tsPostHashParams = this.getThoughtSpotPostUrlParams();
|
|
199
204
|
const {
|
|
200
205
|
dataSource, searchOptions,
|
|
201
206
|
} = this.viewConfig;
|
|
202
207
|
|
|
203
|
-
if (dataSource) postHashObj[Param.WorksheetId] = dataSource;
|
|
208
|
+
if (dataSource) (postHashObj as any)[Param.WorksheetId] = dataSource;
|
|
204
209
|
if (searchOptions?.searchQuery && searchOptions.executeSearch) {
|
|
205
|
-
postHashObj[Param.executeSearch] = true;
|
|
210
|
+
(postHashObj as any)[Param.executeSearch] = true;
|
|
206
211
|
}
|
|
207
212
|
|
|
208
213
|
let sagePostHashParams = new URLSearchParams(postHashObj).toString();
|
package/src/embed/search-bar.tsx
CHANGED
|
@@ -118,12 +118,7 @@ export class SearchBarEmbed extends TsEmbed {
|
|
|
118
118
|
this.viewConfig = viewConfig;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
* Construct the URL of the embedded ThoughtSpot search to be
|
|
123
|
-
* loaded in the iframe
|
|
124
|
-
* @param dataSources A list of data source GUIDs
|
|
125
|
-
*/
|
|
126
|
-
private getIFrameSrc() {
|
|
121
|
+
protected getEmbedParamsObject() {
|
|
127
122
|
const {
|
|
128
123
|
searchOptions,
|
|
129
124
|
dataSource,
|
|
@@ -131,7 +126,6 @@ export class SearchBarEmbed extends TsEmbed {
|
|
|
131
126
|
useLastSelectedSources = false,
|
|
132
127
|
excludeSearchTokenStringFromURL,
|
|
133
128
|
} = this.viewConfig;
|
|
134
|
-
const path = 'search-bar-embed';
|
|
135
129
|
const queryParams = this.getBaseQueryParams();
|
|
136
130
|
|
|
137
131
|
queryParams[Param.HideActions] = [...(queryParams[Param.HideActions] ?? [])];
|
|
@@ -159,6 +153,19 @@ export class SearchBarEmbed extends TsEmbed {
|
|
|
159
153
|
queryParams[Param.UseLastSelectedDataSource] = false;
|
|
160
154
|
}
|
|
161
155
|
queryParams[Param.searchEmbed] = true;
|
|
156
|
+
|
|
157
|
+
return queryParams;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Construct the URL of the embedded ThoughtSpot search to be
|
|
162
|
+
* loaded in the iframe
|
|
163
|
+
* @param dataSources A list of data source GUIDs
|
|
164
|
+
*/
|
|
165
|
+
private getIFrameSrc() {
|
|
166
|
+
const queryParams = this.getEmbedParamsObject();
|
|
167
|
+
const path = 'search-bar-embed';
|
|
168
|
+
|
|
162
169
|
let query = '';
|
|
163
170
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
164
171
|
if (queryParamsString) {
|
package/src/embed/search.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { ERROR_MESSAGE } from '../errors';
|
|
|
26
26
|
import { getAuthPromise } from './base';
|
|
27
27
|
import { getReleaseVersion } from '../auth';
|
|
28
28
|
import { getEmbedConfig } from './embedConfig';
|
|
29
|
+
import { getInterceptInitData } from '../api-intercept';
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* Configuration for search options.
|
|
@@ -331,7 +332,7 @@ export const HiddenActionItemByDefaultForSearchEmbed = [
|
|
|
331
332
|
];
|
|
332
333
|
|
|
333
334
|
export interface SearchAppInitData extends DefaultAppInitData {
|
|
334
|
-
|
|
335
|
+
searchOptions?: SearchOptions;
|
|
335
336
|
}
|
|
336
337
|
|
|
337
338
|
/**
|
|
@@ -381,7 +382,7 @@ export class SearchEmbed extends TsEmbed {
|
|
|
381
382
|
return { ...defaultAppInitData, ...this.getSearchInitData() };
|
|
382
383
|
}
|
|
383
384
|
|
|
384
|
-
protected
|
|
385
|
+
protected getEmbedParamsObject() {
|
|
385
386
|
const {
|
|
386
387
|
hideResults,
|
|
387
388
|
enableSearchAssist,
|
|
@@ -398,7 +399,7 @@ export class SearchEmbed extends TsEmbed {
|
|
|
398
399
|
collapseSearchBarInitially = false,
|
|
399
400
|
enableCustomColumnGroups = false,
|
|
400
401
|
isOnBeforeGetVizDataInterceptEnabled = false,
|
|
401
|
-
|
|
402
|
+
|
|
402
403
|
dataPanelCustomGroupsAccordionInitialState = DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL,
|
|
403
404
|
focusSearchBarOnRender = true,
|
|
404
405
|
excludeRuntimeParametersfromURL,
|
|
@@ -442,8 +443,9 @@ export class SearchEmbed extends TsEmbed {
|
|
|
442
443
|
queryParams[Param.HideSearchBar] = true;
|
|
443
444
|
}
|
|
444
445
|
|
|
445
|
-
|
|
446
|
-
|
|
446
|
+
const { enableApiIntercept } = getInterceptInitData(this.embedConfig, this.viewConfig);
|
|
447
|
+
if (isOnBeforeGetVizDataInterceptEnabled && !enableApiIntercept) {
|
|
448
|
+
|
|
447
449
|
queryParams[Param.IsOnBeforeGetVizDataInterceptEnabled] = isOnBeforeGetVizDataInterceptEnabled;
|
|
448
450
|
}
|
|
449
451
|
|
|
@@ -460,7 +462,7 @@ export class SearchEmbed extends TsEmbed {
|
|
|
460
462
|
}
|
|
461
463
|
|
|
462
464
|
queryParams[Param.searchEmbed] = true;
|
|
463
|
-
|
|
465
|
+
|
|
464
466
|
queryParams[Param.CollapseSearchBarInitially] = collapseSearchBarInitially || collapseSearchBar;
|
|
465
467
|
queryParams[Param.EnableCustomColumnGroups] = enableCustomColumnGroups;
|
|
466
468
|
if (dataPanelCustomGroupsAccordionInitialState
|
|
@@ -468,12 +470,23 @@ export class SearchEmbed extends TsEmbed {
|
|
|
468
470
|
|| dataPanelCustomGroupsAccordionInitialState
|
|
469
471
|
=== DataPanelCustomColumnGroupsAccordionState.EXPAND_FIRST
|
|
470
472
|
) {
|
|
471
|
-
|
|
473
|
+
|
|
472
474
|
queryParams[Param.DataPanelCustomGroupsAccordionInitialState] = dataPanelCustomGroupsAccordionInitialState;
|
|
473
475
|
} else {
|
|
474
|
-
|
|
476
|
+
|
|
475
477
|
queryParams[Param.DataPanelCustomGroupsAccordionInitialState] = DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL;
|
|
476
478
|
}
|
|
479
|
+
return queryParams;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
protected getEmbedParams() {
|
|
483
|
+
const {
|
|
484
|
+
runtimeParameters,
|
|
485
|
+
runtimeFilters,
|
|
486
|
+
excludeRuntimeParametersfromURL,
|
|
487
|
+
excludeRuntimeFiltersfromURL,
|
|
488
|
+
} = this.viewConfig;
|
|
489
|
+
const queryParams = this.getEmbedParamsObject();
|
|
477
490
|
let query = '';
|
|
478
491
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
479
492
|
if (queryParamsString) {
|
|
@@ -1045,7 +1045,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
1045
1045
|
type: EmbedEvent.APP_INIT,
|
|
1046
1046
|
data: {},
|
|
1047
1047
|
};
|
|
1048
|
-
|
|
1048
|
+
|
|
1049
1049
|
// Create a SearchEmbed with valid custom actions to test
|
|
1050
1050
|
// CustomActionsValidationResult
|
|
1051
1051
|
const searchEmbed = new SearchEmbed(getRootEl(), {
|
|
@@ -1067,7 +1067,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
1067
1067
|
}
|
|
1068
1068
|
]
|
|
1069
1069
|
});
|
|
1070
|
-
|
|
1070
|
+
|
|
1071
1071
|
searchEmbed.render();
|
|
1072
1072
|
const mockPort: any = {
|
|
1073
1073
|
postMessage: jest.fn(),
|
|
@@ -1116,7 +1116,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
1116
1116
|
customVariablesForThirdPartyTools: {},
|
|
1117
1117
|
},
|
|
1118
1118
|
});
|
|
1119
|
-
|
|
1119
|
+
|
|
1120
1120
|
// Verify that CustomActionsValidationResult structure is
|
|
1121
1121
|
// correct
|
|
1122
1122
|
const appInitData = mockPort.postMessage.mock.calls[0][0].data;
|
|
@@ -1137,7 +1137,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
1137
1137
|
})
|
|
1138
1138
|
])
|
|
1139
1139
|
);
|
|
1140
|
-
|
|
1140
|
+
|
|
1141
1141
|
// Verify actions are sorted by name (alphabetically)
|
|
1142
1142
|
expect(appInitData.customActions[0].name).toBe('Another Valid Action');
|
|
1143
1143
|
expect(appInitData.customActions[1].name).toBe('Valid Action');
|
|
@@ -2488,7 +2488,7 @@ describe('Unit test case for ts embed', () => {
|
|
|
2488
2488
|
});
|
|
2489
2489
|
|
|
2490
2490
|
afterAll((): void => {
|
|
2491
|
-
window.location = location;
|
|
2491
|
+
(window.location as any) = location;
|
|
2492
2492
|
});
|
|
2493
2493
|
|
|
2494
2494
|
it('get url params for TS', () => {
|
|
@@ -3345,4 +3345,115 @@ describe('Unit test case for ts embed', () => {
|
|
|
3345
3345
|
expect(searchEmbed.isEmbedContainerLoaded).toBe(true);
|
|
3346
3346
|
});
|
|
3347
3347
|
});
|
|
3348
|
+
|
|
3349
|
+
describe('Online event listener registration after auth failure', () => {
|
|
3350
|
+
beforeAll(() => {
|
|
3351
|
+
init({
|
|
3352
|
+
thoughtSpotHost: 'tshost',
|
|
3353
|
+
authType: AuthType.None,
|
|
3354
|
+
loginFailedMessage: 'Not logged in',
|
|
3355
|
+
});
|
|
3356
|
+
});
|
|
3357
|
+
|
|
3358
|
+
test('should register online event listener when authentication fails', async () => {
|
|
3359
|
+
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
|
|
3360
|
+
jest.spyOn(baseInstance, 'getAuthPromise').mockRejectedValueOnce(
|
|
3361
|
+
new Error('Auth failed'),
|
|
3362
|
+
);
|
|
3363
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3364
|
+
addEventListenerSpy.mockClear();
|
|
3365
|
+
await searchEmbed.render();
|
|
3366
|
+
await executeAfterWait(() => {
|
|
3367
|
+
expect(getRootEl().innerHTML).toContain('Not logged in');
|
|
3368
|
+
const onlineListenerCalls = addEventListenerSpy.mock.calls.filter(
|
|
3369
|
+
(call) => call[0] === 'online',
|
|
3370
|
+
);
|
|
3371
|
+
expect(onlineListenerCalls).toHaveLength(1);
|
|
3372
|
+
const offlineListenerCalls = addEventListenerSpy.mock.calls.filter(
|
|
3373
|
+
(call) => call[0] === 'offline',
|
|
3374
|
+
);
|
|
3375
|
+
expect(offlineListenerCalls).toHaveLength(1);
|
|
3376
|
+
const messageListenerCalls = addEventListenerSpy.mock.calls.filter(
|
|
3377
|
+
(call) => call[0] === 'message',
|
|
3378
|
+
);
|
|
3379
|
+
expect(messageListenerCalls).toHaveLength(0);
|
|
3380
|
+
});
|
|
3381
|
+
|
|
3382
|
+
addEventListenerSpy.mockRestore();
|
|
3383
|
+
});
|
|
3384
|
+
|
|
3385
|
+
test('should attempt to trigger reload when online event occurs after auth failure', async () => {
|
|
3386
|
+
jest.spyOn(baseInstance, 'getAuthPromise').mockRejectedValueOnce(
|
|
3387
|
+
new Error('Auth failed'),
|
|
3388
|
+
);
|
|
3389
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3390
|
+
const triggerSpy = jest.spyOn(searchEmbed, 'trigger').mockResolvedValue(null);
|
|
3391
|
+
await searchEmbed.render();
|
|
3392
|
+
|
|
3393
|
+
await executeAfterWait(() => {
|
|
3394
|
+
expect(getRootEl().innerHTML).toContain('Not logged in');
|
|
3395
|
+
triggerSpy.mockClear();
|
|
3396
|
+
const onlineEvent = new Event('online');
|
|
3397
|
+
window.dispatchEvent(onlineEvent);
|
|
3398
|
+
expect(triggerSpy).toHaveBeenCalledWith(HostEvent.Reload);
|
|
3399
|
+
});
|
|
3400
|
+
|
|
3401
|
+
triggerSpy.mockReset();
|
|
3402
|
+
});
|
|
3403
|
+
|
|
3404
|
+
test('should handle online event gracefully when no iframe exists', async () => {
|
|
3405
|
+
jest.spyOn(baseInstance, 'getAuthPromise').mockRejectedValueOnce(
|
|
3406
|
+
new Error('Auth failed'),
|
|
3407
|
+
);
|
|
3408
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3409
|
+
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => { });
|
|
3410
|
+
await searchEmbed.render();
|
|
3411
|
+
await executeAfterWait(() => {
|
|
3412
|
+
expect(getRootEl().innerHTML).toContain('Not logged in');
|
|
3413
|
+
const onlineEvent = new Event('online');
|
|
3414
|
+
expect(() => {
|
|
3415
|
+
window.dispatchEvent(onlineEvent);
|
|
3416
|
+
}).not.toThrow();
|
|
3417
|
+
});
|
|
3418
|
+
|
|
3419
|
+
errorSpy.mockReset();
|
|
3420
|
+
});
|
|
3421
|
+
|
|
3422
|
+
test('should register all event listeners when authentication succeeds', async () => {
|
|
3423
|
+
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
|
|
3424
|
+
jest.spyOn(baseInstance, 'getAuthPromise').mockResolvedValueOnce(true);
|
|
3425
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3426
|
+
addEventListenerSpy.mockClear();
|
|
3427
|
+
await searchEmbed.render();
|
|
3428
|
+
await executeAfterWait(() => {
|
|
3429
|
+
const onlineListenerCalls = addEventListenerSpy.mock.calls.filter(
|
|
3430
|
+
(call) => call[0] === 'online',
|
|
3431
|
+
);
|
|
3432
|
+
expect(onlineListenerCalls).toHaveLength(1);
|
|
3433
|
+
const offlineListenerCalls = addEventListenerSpy.mock.calls.filter(
|
|
3434
|
+
(call) => call[0] === 'offline',
|
|
3435
|
+
);
|
|
3436
|
+
expect(offlineListenerCalls).toHaveLength(1);
|
|
3437
|
+
const messageListenerCalls = addEventListenerSpy.mock.calls.filter(
|
|
3438
|
+
(call) => call[0] === 'message',
|
|
3439
|
+
);
|
|
3440
|
+
expect(messageListenerCalls).toHaveLength(1);
|
|
3441
|
+
});
|
|
3442
|
+
|
|
3443
|
+
addEventListenerSpy.mockRestore();
|
|
3444
|
+
});
|
|
3445
|
+
test('should successfully trigger reload when online event occurs after auth success', async () => {
|
|
3446
|
+
jest.spyOn(baseInstance, 'getAuthPromise').mockResolvedValueOnce(true);
|
|
3447
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
3448
|
+
const triggerSpy = jest.spyOn(searchEmbed, 'trigger').mockResolvedValue({} as any);
|
|
3449
|
+
await searchEmbed.render();
|
|
3450
|
+
await executeAfterWait(() => {
|
|
3451
|
+
triggerSpy.mockClear();
|
|
3452
|
+
const onlineEvent = new Event('online');
|
|
3453
|
+
window.dispatchEvent(onlineEvent);
|
|
3454
|
+
expect(triggerSpy).toHaveBeenCalledWith(HostEvent.Reload);
|
|
3455
|
+
});
|
|
3456
|
+
triggerSpy.mockReset();
|
|
3457
|
+
});
|
|
3458
|
+
});
|
|
3348
3459
|
});
|