@thoughtspot/visual-embed-sdk 1.40.1-alpha.2 → 1.40.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 +7 -6
- package/cjs/src/css-variables.d.ts +316 -0
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/app.d.ts +6 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +22 -0
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +39 -2
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.d.ts +0 -1
- package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/cjs/src/embed/bodyless-conversation.js +3 -7
- package/cjs/src/embed/bodyless-conversation.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts +63 -3
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +11 -8
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +102 -0
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +11 -3
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +23 -33
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +182 -29
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/sage.d.ts +0 -1
- package/cjs/src/embed/sage.d.ts.map +1 -1
- package/cjs/src/embed/sage.js +6 -10
- package/cjs/src/embed/sage.js.map +1 -1
- package/cjs/src/embed/search-bar.d.ts +0 -1
- package/cjs/src/embed/search-bar.d.ts.map +1 -1
- package/cjs/src/embed/search-bar.js +7 -11
- package/cjs/src/embed/search-bar.js.map +1 -1
- package/cjs/src/embed/search.d.ts +0 -1
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js +8 -7
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +22 -9
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +75 -59
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +173 -1
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/types.d.ts +154 -54
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +140 -52
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/liveboardService/liveboardService.d.ts +21 -6
- package/cjs/src/utils/liveboardService/liveboardService.d.ts.map +1 -1
- package/cjs/src/utils/liveboardService/liveboardService.js +21 -6
- package/cjs/src/utils/liveboardService/liveboardService.js.map +1 -1
- package/dist/{index-CmEQfuE3.js → index-P5YjBOuJ.js} +1 -1
- package/dist/src/css-variables.d.ts +316 -0
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts +6 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/bodyless-conversation.d.ts +0 -1
- package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts +63 -3
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +11 -3
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/sage.d.ts +0 -1
- package/dist/src/embed/sage.d.ts.map +1 -1
- package/dist/src/embed/search-bar.d.ts +0 -1
- package/dist/src/embed/search-bar.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +0 -1
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +22 -9
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/types.d.ts +154 -54
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/liveboardService/liveboardService.d.ts +21 -6
- package/dist/src/utils/liveboardService/liveboardService.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +298 -190
- package/dist/tsembed-react.js +297 -189
- package/dist/tsembed.es.js +319 -196
- package/dist/tsembed.js +318 -195
- package/dist/visual-embed-sdk-react-full.d.ts +583 -76
- package/dist/visual-embed-sdk-react.d.ts +583 -76
- package/dist/visual-embed-sdk.d.ts +583 -76
- package/lib/package.json +7 -6
- package/lib/src/css-variables.d.ts +316 -0
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/app.d.ts +6 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +22 -0
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +39 -2
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.d.ts +0 -1
- package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/lib/src/embed/bodyless-conversation.js +3 -7
- package/lib/src/embed/bodyless-conversation.js.map +1 -1
- package/lib/src/embed/conversation.d.ts +63 -3
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js +12 -9
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +104 -2
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +11 -3
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +23 -33
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +182 -29
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/sage.d.ts +0 -1
- package/lib/src/embed/sage.d.ts.map +1 -1
- package/lib/src/embed/sage.js +6 -10
- package/lib/src/embed/sage.js.map +1 -1
- package/lib/src/embed/search-bar.d.ts +0 -1
- package/lib/src/embed/search-bar.d.ts.map +1 -1
- package/lib/src/embed/search-bar.js +7 -11
- package/lib/src/embed/search-bar.js.map +1 -1
- package/lib/src/embed/search.d.ts +0 -1
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +8 -7
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +22 -9
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +75 -59
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +173 -1
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/types.d.ts +154 -54
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +140 -52
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/liveboardService/liveboardService.d.ts +21 -6
- package/lib/src/utils/liveboardService/liveboardService.d.ts.map +1 -1
- package/lib/src/utils/liveboardService/liveboardService.js +21 -6
- package/lib/src/utils/liveboardService/liveboardService.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +584 -77
- package/package.json +7 -6
- package/src/css-variables.ts +396 -1
- package/src/embed/app.spec.ts +54 -2
- package/src/embed/app.ts +24 -0
- package/src/embed/bodyless-conversation.ts +3 -9
- package/src/embed/conversation.spec.ts +131 -5
- package/src/embed/conversation.ts +87 -23
- package/src/embed/liveboard.spec.ts +233 -32
- package/src/embed/liveboard.ts +24 -39
- package/src/embed/sage.ts +6 -11
- package/src/embed/search-bar.tsx +7 -14
- package/src/embed/search.ts +7 -18
- package/src/embed/ts-embed.spec.ts +344 -112
- package/src/embed/ts-embed.ts +82 -70
- package/src/types.ts +153 -54
- package/src/utils/liveboardService/liveboardService.ts +21 -6
- package/dist/index-D1pyb7RG.js +0 -7371
- package/dist/index-DeFzsyFF.js +0 -7371
- package/dist/index-Dpf0rd6w.js +0 -7371
- package/dist/index-UuEbsISo.js +0 -7447
- package/dist/index-e3Uw3YFO.js +0 -7371
- package/dist/index-k7pkZMhx.js +0 -7371
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
SpotterEmbedViewConfig,
|
|
4
|
-
} from './conversation';
|
|
1
|
+
import { SpotterEmbed, SpotterEmbedViewConfig, ConversationEmbed } from './conversation';
|
|
2
|
+
import { TsEmbed } from './ts-embed';
|
|
5
3
|
import * as authInstance from '../auth';
|
|
6
4
|
import { Action, init } from '../index';
|
|
7
|
-
import { AuthType, Param } from '../types';
|
|
5
|
+
import { AuthType, Param, RuntimeFilterOp } from '../types';
|
|
8
6
|
import {
|
|
9
7
|
getDocumentBody,
|
|
10
8
|
getIFrameSrc,
|
|
@@ -180,4 +178,132 @@ describe('ConversationEmbed', () => {
|
|
|
180
178
|
`http://${thoughtSpotHost}/v2/?${defaultParams}&${Param.DisableActions}=[%22${Action.InConversationTraining}%22]&${Param.DisableActionReason}=${disabledReason}&isSpotterExperienceEnabled=true&enableDataPanelV2=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
|
|
181
179
|
);
|
|
182
180
|
});
|
|
181
|
+
|
|
182
|
+
it('should render the conversation embed with runtime filters', async () => {
|
|
183
|
+
const viewConfig: SpotterEmbedViewConfig = {
|
|
184
|
+
worksheetId: 'worksheetId',
|
|
185
|
+
searchOptions: {
|
|
186
|
+
searchQuery: 'searchQuery',
|
|
187
|
+
},
|
|
188
|
+
runtimeFilters: [
|
|
189
|
+
{
|
|
190
|
+
columnName: 'revenue',
|
|
191
|
+
operator: RuntimeFilterOp.EQ,
|
|
192
|
+
values: [1000],
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
|
|
198
|
+
await conversationEmbed.render();
|
|
199
|
+
expectUrlMatchesWithParams(
|
|
200
|
+
getIFrameSrc(),
|
|
201
|
+
`http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&col1=revenue&op1=EQ&val1=1000#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
|
|
202
|
+
);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it('should render the conversation embed with runtime parameters', async () => {
|
|
206
|
+
const viewConfig: SpotterEmbedViewConfig = {
|
|
207
|
+
worksheetId: 'worksheetId',
|
|
208
|
+
searchOptions: {
|
|
209
|
+
searchQuery: 'searchQuery',
|
|
210
|
+
},
|
|
211
|
+
runtimeParameters: [
|
|
212
|
+
{
|
|
213
|
+
name: 'Date Range',
|
|
214
|
+
value: '30',
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
|
|
220
|
+
await conversationEmbed.render();
|
|
221
|
+
expectUrlMatchesWithParams(
|
|
222
|
+
getIFrameSrc(),
|
|
223
|
+
`http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true¶m1=Date%20Range¶mVal1=30#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
|
|
224
|
+
);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it('should render the conversation embed with runtime parameters excluded from URL', async () => {
|
|
228
|
+
const viewConfig: SpotterEmbedViewConfig = {
|
|
229
|
+
worksheetId: 'worksheetId',
|
|
230
|
+
searchOptions: {
|
|
231
|
+
searchQuery: 'searchQuery',
|
|
232
|
+
},
|
|
233
|
+
runtimeParameters: [
|
|
234
|
+
{
|
|
235
|
+
name: 'Date Range',
|
|
236
|
+
value: '30',
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: 'Region',
|
|
240
|
+
value: 'North America',
|
|
241
|
+
},
|
|
242
|
+
],
|
|
243
|
+
excludeRuntimeParametersfromURL: true,
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
|
|
247
|
+
await conversationEmbed.render();
|
|
248
|
+
expectUrlMatchesWithParams(
|
|
249
|
+
getIFrameSrc(),
|
|
250
|
+
`http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
|
|
251
|
+
);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('should render the conversation embed with both runtime filters and parameters', async () => {
|
|
255
|
+
const viewConfig: SpotterEmbedViewConfig = {
|
|
256
|
+
worksheetId: 'worksheetId',
|
|
257
|
+
searchOptions: {
|
|
258
|
+
searchQuery: 'searchQuery',
|
|
259
|
+
},
|
|
260
|
+
runtimeParameters: [
|
|
261
|
+
{
|
|
262
|
+
name: 'Date Range',
|
|
263
|
+
value: '30',
|
|
264
|
+
},
|
|
265
|
+
],
|
|
266
|
+
runtimeFilters: [
|
|
267
|
+
{
|
|
268
|
+
columnName: 'revenue',
|
|
269
|
+
operator: RuntimeFilterOp.EQ,
|
|
270
|
+
values: [1000],
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
excludeRuntimeParametersfromURL: false,
|
|
274
|
+
excludeRuntimeFiltersfromURL: false,
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
|
|
278
|
+
await conversationEmbed.render();
|
|
279
|
+
expectUrlMatchesWithParams(
|
|
280
|
+
getIFrameSrc(),
|
|
281
|
+
`http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&col1=revenue&op1=EQ&val1=1000¶m1=Date%20Range¶mVal1=30#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
|
|
282
|
+
);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('should ensure deprecated ConversationEmbed class maintains same functionality as SpotterEmbed', async () => {
|
|
286
|
+
const viewConfig: SpotterEmbedViewConfig = {
|
|
287
|
+
worksheetId: 'worksheetId',
|
|
288
|
+
searchOptions: {
|
|
289
|
+
searchQuery: 'searchQuery',
|
|
290
|
+
},
|
|
291
|
+
runtimeParameters: [
|
|
292
|
+
{
|
|
293
|
+
name: 'Date Range',
|
|
294
|
+
value: '30',
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// Test with deprecated class
|
|
300
|
+
const conversationEmbed = new ConversationEmbed(getRootEl(), viewConfig);
|
|
301
|
+
await conversationEmbed.render();
|
|
302
|
+
|
|
303
|
+
// Verify it generates the same URL structure as SpotterEmbed
|
|
304
|
+
expectUrlMatchesWithParams(
|
|
305
|
+
getIFrameSrc(),
|
|
306
|
+
`http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true¶m1=Date%20Range¶mVal1=30#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
|
|
307
|
+
);
|
|
308
|
+
});
|
|
183
309
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import isUndefined from 'lodash/isUndefined';
|
|
2
2
|
import { ERROR_MESSAGE } from '../errors';
|
|
3
|
-
import { Param, BaseViewConfig } from '../types';
|
|
3
|
+
import { Param, BaseViewConfig, RuntimeFilter, RuntimeParameter } from '../types';
|
|
4
4
|
import { TsEmbed } from './ts-embed';
|
|
5
|
-
import { getQueryParamString } from '../utils';
|
|
5
|
+
import { getQueryParamString, getFilterQuery, getRuntimeParameters } from '../utils';
|
|
6
6
|
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
8
|
* Configuration for search options
|
|
9
9
|
*/
|
|
10
10
|
export interface SearchOptions {
|
|
@@ -20,7 +20,8 @@ export interface SearchOptions {
|
|
|
20
20
|
*/
|
|
21
21
|
export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAction'> {
|
|
22
22
|
/**
|
|
23
|
-
* The ID of the data source object. For example, Model, View, or Table. Spotter uses
|
|
23
|
+
* The ID of the data source object. For example, Model, View, or Table. Spotter uses
|
|
24
|
+
* this object to query data and generate Answers.
|
|
24
25
|
*/
|
|
25
26
|
worksheetId: string;
|
|
26
27
|
/**
|
|
@@ -30,7 +31,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
|
|
|
30
31
|
/**
|
|
31
32
|
* disableSourceSelection : Disables data source selection
|
|
32
33
|
* but still display the selected data source.
|
|
33
|
-
*
|
|
34
|
+
*
|
|
34
35
|
* Supported embed types: `SpotterEmbed`
|
|
35
36
|
* @example
|
|
36
37
|
* ```js
|
|
@@ -44,7 +45,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
|
|
|
44
45
|
disableSourceSelection?: boolean;
|
|
45
46
|
/**
|
|
46
47
|
* hideSourceSelection : Hide data source selection
|
|
47
|
-
*
|
|
48
|
+
*
|
|
48
49
|
* Supported embed types: `SpotterEmbed`
|
|
49
50
|
* @example
|
|
50
51
|
* ```js
|
|
@@ -58,7 +59,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
|
|
|
58
59
|
hideSourceSelection?: boolean;
|
|
59
60
|
/**
|
|
60
61
|
* Flag to control Data panel experience
|
|
61
|
-
*
|
|
62
|
+
*
|
|
62
63
|
* Supported embed types: `SageEmbed`, `AppEmbed`, `SearchBarEmbed`, `LiveboardEmbed`, `SearchEmbed`
|
|
63
64
|
* @default false
|
|
64
65
|
* @version SDK: 1.36.0 | ThoughtSpot Cloud: 10.4.0.cl
|
|
@@ -76,7 +77,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
|
|
|
76
77
|
* showSpotterLimitations : show limitation text
|
|
77
78
|
* of the spotter underneath the chat input.
|
|
78
79
|
* default is false.
|
|
79
|
-
*
|
|
80
|
+
*
|
|
80
81
|
* Supported embed types: `SpotterEmbed`
|
|
81
82
|
* @example
|
|
82
83
|
* ```js
|
|
@@ -91,7 +92,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
|
|
|
91
92
|
/**
|
|
92
93
|
* hideSampleQuestions : Hide sample questions on
|
|
93
94
|
* the initial screen of the conversation.
|
|
94
|
-
*
|
|
95
|
+
*
|
|
95
96
|
* Supported embed types: `SpotterEmbed`
|
|
96
97
|
* @example
|
|
97
98
|
* ```js
|
|
@@ -103,6 +104,66 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
|
|
|
103
104
|
* @version SDK: 1.36.0 | ThoughtSpot: 10.6.0.cl
|
|
104
105
|
*/
|
|
105
106
|
hideSampleQuestions?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* The list of runtime filters to apply to a search Answer,
|
|
109
|
+
* visualization, or Liveboard.
|
|
110
|
+
*
|
|
111
|
+
* Supported embed types: `SpotterEmbed`
|
|
112
|
+
* @example
|
|
113
|
+
* ```js
|
|
114
|
+
* const embed = new SpotterEmbed('#tsEmbed', {
|
|
115
|
+
* // other embed view config
|
|
116
|
+
* runtimeFilters: [
|
|
117
|
+
* {
|
|
118
|
+
* columnName: 'color',
|
|
119
|
+
* operator: RuntimeFilterOp.EQ,
|
|
120
|
+
* values: ['red'],
|
|
121
|
+
* },
|
|
122
|
+
* ],
|
|
123
|
+
* })
|
|
124
|
+
* ```
|
|
125
|
+
* @version SDK: 1.41.0 | ThoughtSpot: 10.13.0.cl
|
|
126
|
+
*/
|
|
127
|
+
runtimeFilters?: RuntimeFilter[];
|
|
128
|
+
/**
|
|
129
|
+
* Flag to control whether runtime filters should be included in the URL.
|
|
130
|
+
* If true, filters will be passed via app initialization payload instead.
|
|
131
|
+
* If false/undefined, filters will be added to URL (default behavior).
|
|
132
|
+
*
|
|
133
|
+
* Supported embed types: `SpotterEmbed`
|
|
134
|
+
* @default false
|
|
135
|
+
* @version SDK: 1.41.0 | ThoughtSpot: 10.13.0.cl
|
|
136
|
+
*/
|
|
137
|
+
excludeRuntimeFiltersfromURL?: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* The list of runtime parameters to apply to the conversation.
|
|
140
|
+
*
|
|
141
|
+
* Supported embed types: `SpotterEmbed`
|
|
142
|
+
* @example
|
|
143
|
+
* ```js
|
|
144
|
+
* const embed = new SpotterEmbed('#tsEmbed', {
|
|
145
|
+
* // other embed view config
|
|
146
|
+
* runtimeParameters: [
|
|
147
|
+
* {
|
|
148
|
+
* name: 'Integer Param',
|
|
149
|
+
* value: 10,
|
|
150
|
+
* },
|
|
151
|
+
* ],
|
|
152
|
+
* })
|
|
153
|
+
* ```
|
|
154
|
+
* @version SDK: 1.41.0 | ThoughtSpot: 10.13.0.cl
|
|
155
|
+
*/
|
|
156
|
+
runtimeParameters?: RuntimeParameter[];
|
|
157
|
+
/**
|
|
158
|
+
* Flag to control whether runtime parameters should be included in the URL.
|
|
159
|
+
* If true, parameters will be passed via app initialization payload instead.
|
|
160
|
+
* If false/undefined, parameters will be added to URL (default behavior).
|
|
161
|
+
*
|
|
162
|
+
* Supported embed types: `SpotterEmbed`
|
|
163
|
+
* @default false
|
|
164
|
+
* @version SDK: 1.41.0 | ThoughtSpot: 10.13.0.cl
|
|
165
|
+
*/
|
|
166
|
+
excludeRuntimeParametersfromURL?: boolean;
|
|
106
167
|
}
|
|
107
168
|
|
|
108
169
|
/**
|
|
@@ -135,7 +196,7 @@ export class SpotterEmbed extends TsEmbed {
|
|
|
135
196
|
super(container, viewConfig);
|
|
136
197
|
}
|
|
137
198
|
|
|
138
|
-
|
|
199
|
+
public getIframeSrc(): string {
|
|
139
200
|
const {
|
|
140
201
|
worksheetId,
|
|
141
202
|
searchOptions,
|
|
@@ -144,8 +205,12 @@ export class SpotterEmbed extends TsEmbed {
|
|
|
144
205
|
dataPanelV2,
|
|
145
206
|
showSpotterLimitations,
|
|
146
207
|
hideSampleQuestions,
|
|
208
|
+
runtimeFilters,
|
|
209
|
+
excludeRuntimeFiltersfromURL,
|
|
210
|
+
runtimeParameters,
|
|
211
|
+
excludeRuntimeParametersfromURL,
|
|
147
212
|
} = this.viewConfig;
|
|
148
|
-
|
|
213
|
+
const path = 'insights/conv-assist';
|
|
149
214
|
if (!worksheetId) {
|
|
150
215
|
this.handleError(ERROR_MESSAGE.SPOTTER_EMBED_WORKSHEED_ID_NOT_FOUND);
|
|
151
216
|
}
|
|
@@ -170,27 +235,26 @@ export class SpotterEmbed extends TsEmbed {
|
|
|
170
235
|
queryParams[Param.HideSampleQuestions] = !!hideSampleQuestions;
|
|
171
236
|
}
|
|
172
237
|
|
|
173
|
-
return queryParams;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
public getIframeSrc(): string {
|
|
177
|
-
const {
|
|
178
|
-
worksheetId,
|
|
179
|
-
searchOptions,
|
|
180
|
-
} = this.viewConfig;
|
|
181
|
-
const path = 'insights/conv-assist';
|
|
182
|
-
const queryParams = this.getEmbedParamsObject();
|
|
183
|
-
|
|
184
238
|
let query = '';
|
|
185
239
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
186
240
|
if (queryParamsString) {
|
|
187
241
|
query = `?${queryParamsString}`;
|
|
188
242
|
}
|
|
243
|
+
|
|
244
|
+
const filterQuery = getFilterQuery(runtimeFilters || []);
|
|
245
|
+
if (filterQuery && !excludeRuntimeFiltersfromURL) {
|
|
246
|
+
query += `&${filterQuery}`;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const parameterQuery = getRuntimeParameters(runtimeParameters || []);
|
|
250
|
+
if (parameterQuery && !excludeRuntimeParametersfromURL) {
|
|
251
|
+
query += `&${parameterQuery}`;
|
|
252
|
+
}
|
|
253
|
+
|
|
189
254
|
const tsPostHashParams = this.getThoughtSpotPostUrlParams({
|
|
190
255
|
worksheet: worksheetId,
|
|
191
256
|
query: searchOptions?.searchQuery || '',
|
|
192
257
|
});
|
|
193
|
-
|
|
194
258
|
return `${this.getEmbedBasePath(query)}/embed/${path}${tsPostHashParams}`;
|
|
195
259
|
}
|
|
196
260
|
|
|
@@ -601,14 +601,6 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
601
601
|
|
|
602
602
|
test('navigateToLiveboard should trigger the navigate event with the correct path', async (done) => {
|
|
603
603
|
mockMessageChannel();
|
|
604
|
-
// mock getSessionInfo
|
|
605
|
-
jest.spyOn(SessionInfoService, 'getSessionInfo').mockResolvedValue({
|
|
606
|
-
releaseVersion: '1.0.0',
|
|
607
|
-
userGUID: '1234567890',
|
|
608
|
-
currentOrgId: 1,
|
|
609
|
-
privileges: [],
|
|
610
|
-
mixpanelToken: '1234567890',
|
|
611
|
-
});
|
|
612
604
|
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
613
605
|
...defaultViewConfig,
|
|
614
606
|
} as LiveboardViewConfig);
|
|
@@ -619,30 +611,16 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
619
611
|
postMessageToParent(iframe.contentWindow, {
|
|
620
612
|
type: EmbedEvent.APP_INIT,
|
|
621
613
|
});
|
|
622
|
-
postMessageToParent(iframe.contentWindow, {
|
|
623
|
-
type: EmbedEvent.AuthInit,
|
|
624
|
-
});
|
|
625
|
-
liveboardEmbed.navigateToLiveboard('lb1', 'viz1');
|
|
626
614
|
});
|
|
627
|
-
|
|
628
615
|
executeAfterWait(() => {
|
|
616
|
+
liveboardEmbed.navigateToLiveboard('lb1', 'viz1');
|
|
629
617
|
expect(onSpy).toHaveBeenCalledWith(HostEvent.Navigate, 'embed/viz/lb1/viz1');
|
|
630
618
|
done();
|
|
631
|
-
}
|
|
619
|
+
});
|
|
632
620
|
});
|
|
633
621
|
|
|
634
622
|
test('navigateToLiveboard with preRender', async (done) => {
|
|
635
623
|
mockMessageChannel();
|
|
636
|
-
|
|
637
|
-
// mock getSessionInfo
|
|
638
|
-
jest.spyOn(SessionInfoService, 'getSessionInfo').mockResolvedValue({
|
|
639
|
-
releaseVersion: '1.0.0',
|
|
640
|
-
userGUID: '1234567890',
|
|
641
|
-
currentOrgId: 1,
|
|
642
|
-
privileges: [],
|
|
643
|
-
mixpanelToken: '1234567890',
|
|
644
|
-
});
|
|
645
|
-
|
|
646
624
|
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
647
625
|
...defaultViewConfig,
|
|
648
626
|
preRenderId: 'test',
|
|
@@ -654,15 +632,12 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
654
632
|
postMessageToParent(iframe.contentWindow, {
|
|
655
633
|
type: EmbedEvent.APP_INIT,
|
|
656
634
|
});
|
|
657
|
-
postMessageToParent(iframe.contentWindow, {
|
|
658
|
-
type: EmbedEvent.AuthInit,
|
|
659
|
-
});
|
|
660
635
|
});
|
|
661
636
|
executeAfterWait(() => {
|
|
662
637
|
liveboardEmbed.navigateToLiveboard('lb1', 'viz1');
|
|
663
638
|
expect(onSpy).toHaveBeenCalledWith(HostEvent.Navigate, 'embed/viz/lb1/viz1');
|
|
664
639
|
done();
|
|
665
|
-
}
|
|
640
|
+
});
|
|
666
641
|
});
|
|
667
642
|
test('should set runtime parametere values in url params', async () => {
|
|
668
643
|
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
@@ -787,7 +762,7 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
787
762
|
});
|
|
788
763
|
});
|
|
789
764
|
|
|
790
|
-
test('it should navigateToLiveboard with liveboard id is not passed', async (done) => {
|
|
765
|
+
test('it should navigateToLiveboard with liveboard id is not passed with EmbedListenerReady event', async (done) => {
|
|
791
766
|
mockMessageChannel();
|
|
792
767
|
const consoleSpy = jest.spyOn(console, 'error');
|
|
793
768
|
const testPreRenderId = 'testPreRender';
|
|
@@ -816,12 +791,19 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
816
791
|
libEmbed,
|
|
817
792
|
);
|
|
818
793
|
|
|
794
|
+
await executeAfterWait(() => {
|
|
795
|
+
const iframe = getIFrameEl();
|
|
796
|
+
postMessageToParent(iframe.contentWindow, {
|
|
797
|
+
type: EmbedEvent.EmbedListenerReady,
|
|
798
|
+
});
|
|
799
|
+
});
|
|
800
|
+
|
|
819
801
|
const testLiveboardId = 'testLiveboardId';
|
|
820
802
|
const newLibEmbed = new LiveboardEmbed(getRootEl(), {
|
|
821
803
|
preRenderId: testPreRenderId,
|
|
822
804
|
liveboardId: testLiveboardId,
|
|
823
|
-
|
|
824
|
-
|
|
805
|
+
vizId: 'testVizId',
|
|
806
|
+
activeTabId: 'testActiveTabId',
|
|
825
807
|
});
|
|
826
808
|
const navigateToLiveboardSpy = jest.spyOn(newLibEmbed, 'navigateToLiveboard');
|
|
827
809
|
await newLibEmbed.showPreRender();
|
|
@@ -832,7 +814,7 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
832
814
|
) as HTMLIFrameElement;
|
|
833
815
|
|
|
834
816
|
// should render the generic link
|
|
835
|
-
expect(navigateToLiveboardSpy).toHaveBeenCalledWith(testLiveboardId, '
|
|
817
|
+
expect(navigateToLiveboardSpy).toHaveBeenCalledWith(testLiveboardId, 'testVizId', 'testActiveTabId');
|
|
836
818
|
expect(iFrame.src).toMatch(/http:\/\/tshost\/.*&isLiveboardEmbed=true.*#$/);
|
|
837
819
|
|
|
838
820
|
expect(consoleSpy).toHaveBeenCalledTimes(0);
|
|
@@ -840,6 +822,72 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
840
822
|
done();
|
|
841
823
|
});
|
|
842
824
|
});
|
|
825
|
+
|
|
826
|
+
test('it should navigateToLiveboard with liveboard id is not passed with AuthInit event', async (done) => {
|
|
827
|
+
mockMessageChannel();
|
|
828
|
+
const consoleSpy = jest.spyOn(console, 'error');
|
|
829
|
+
const testPreRenderId = 'testPreRender';
|
|
830
|
+
const libEmbed = new LiveboardEmbed(getRootEl(), {
|
|
831
|
+
preRenderId: testPreRenderId,
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
jest.spyOn(SessionInfoService, 'getSessionInfo').mockResolvedValue({
|
|
835
|
+
releaseVersion: '1.0.0',
|
|
836
|
+
userGUID: '1234567890',
|
|
837
|
+
currentOrgId: 1,
|
|
838
|
+
privileges: [],
|
|
839
|
+
mixpanelToken: '1234567890',
|
|
840
|
+
});
|
|
841
|
+
let resizeObserverCb: any;
|
|
842
|
+
(window as any).ResizeObserver =
|
|
843
|
+
window.ResizeObserver ||
|
|
844
|
+
jest.fn().mockImplementation((resizeObserverCbParam: any) => {
|
|
845
|
+
resizeObserverCb = resizeObserverCbParam;
|
|
846
|
+
return {
|
|
847
|
+
disconnect: jest.fn(),
|
|
848
|
+
observe: jest.fn(),
|
|
849
|
+
unobserve: jest.fn(),
|
|
850
|
+
};
|
|
851
|
+
});
|
|
852
|
+
await libEmbed.preRender();
|
|
853
|
+
await waitFor(() => !!getIFrameEl());
|
|
854
|
+
const ts = '__tsEmbed';
|
|
855
|
+
expect((document.getElementById(libEmbed.getPreRenderIds().wrapper) as any)[ts]).toEqual(
|
|
856
|
+
libEmbed,
|
|
857
|
+
);
|
|
858
|
+
const testLiveboardId = 'testLiveboardId';
|
|
859
|
+
const newLibEmbed = new LiveboardEmbed(getRootEl(), {
|
|
860
|
+
preRenderId: testPreRenderId,
|
|
861
|
+
liveboardId: testLiveboardId,
|
|
862
|
+
vizId: 'testVizId',
|
|
863
|
+
activeTabId: 'testActiveTabId',
|
|
864
|
+
});
|
|
865
|
+
const navigateToLiveboardSpy = jest.spyOn(newLibEmbed, 'navigateToLiveboard');
|
|
866
|
+
|
|
867
|
+
await newLibEmbed.showPreRender();
|
|
868
|
+
|
|
869
|
+
await executeAfterWait(() => {
|
|
870
|
+
const iFrame = document.getElementById(
|
|
871
|
+
newLibEmbed.getPreRenderIds().child,
|
|
872
|
+
) as HTMLIFrameElement;
|
|
873
|
+
postMessageToParent(iFrame.contentWindow, {
|
|
874
|
+
type: EmbedEvent.AuthInit,
|
|
875
|
+
});
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
await executeAfterWait(() => {
|
|
880
|
+
const iFrame = document.getElementById(
|
|
881
|
+
libEmbed.getPreRenderIds().child,
|
|
882
|
+
) as HTMLIFrameElement;
|
|
883
|
+
// should render the generic link
|
|
884
|
+
expect(navigateToLiveboardSpy).toHaveBeenCalledWith(testLiveboardId, 'testVizId', 'testActiveTabId');
|
|
885
|
+
expect(iFrame.src).toMatch(/http:\/\/tshost\/.*&isLiveboardEmbed=true.*#$/);
|
|
886
|
+
expect(consoleSpy).toHaveBeenCalledTimes(0);
|
|
887
|
+
done();
|
|
888
|
+
}, 1005);
|
|
889
|
+
});
|
|
890
|
+
|
|
843
891
|
});
|
|
844
892
|
|
|
845
893
|
describe('LazyLoadingForFullHeight functionality', () => {
|
|
@@ -1113,4 +1161,157 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
1113
1161
|
});
|
|
1114
1162
|
});
|
|
1115
1163
|
});
|
|
1164
|
+
|
|
1165
|
+
describe('Liveboard Embed Container Loading and PreRender', () => {
|
|
1166
|
+
beforeEach(() => {
|
|
1167
|
+
document.body.innerHTML = getDocumentBody();
|
|
1168
|
+
});
|
|
1169
|
+
|
|
1170
|
+
test('should call navigateToLiveboard after embed container is loaded in beforePrerenderVisible', async () => {
|
|
1171
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1172
|
+
liveboardId,
|
|
1173
|
+
vizId,
|
|
1174
|
+
activeTabId,
|
|
1175
|
+
...defaultViewConfig,
|
|
1176
|
+
});
|
|
1177
|
+
|
|
1178
|
+
const navigateToLiveboardSpy = jest.spyOn(liveboardEmbed, 'navigateToLiveboard').mockResolvedValue(undefined);
|
|
1179
|
+
|
|
1180
|
+
// Mock embed container as not loaded initially
|
|
1181
|
+
liveboardEmbed.isEmbedContainerLoaded = false;
|
|
1182
|
+
|
|
1183
|
+
// Call beforePrerenderVisible
|
|
1184
|
+
liveboardEmbed['beforePrerenderVisible']();
|
|
1185
|
+
|
|
1186
|
+
// navigateToLiveboard should not be called immediately
|
|
1187
|
+
expect(navigateToLiveboardSpy).not.toHaveBeenCalled();
|
|
1188
|
+
|
|
1189
|
+
// Simulate embed container becoming ready
|
|
1190
|
+
liveboardEmbed.isEmbedContainerLoaded = true;
|
|
1191
|
+
liveboardEmbed['executeEmbedContainerReadyCallbacks']();
|
|
1192
|
+
|
|
1193
|
+
// Now navigateToLiveboard should be called
|
|
1194
|
+
expect(navigateToLiveboardSpy).toHaveBeenCalledWith(liveboardId, vizId, activeTabId);
|
|
1195
|
+
});
|
|
1196
|
+
|
|
1197
|
+
test('should update currentLiveboardState for prerender object when embed container loads', async () => {
|
|
1198
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1199
|
+
liveboardId,
|
|
1200
|
+
vizId,
|
|
1201
|
+
activeTabId,
|
|
1202
|
+
...defaultViewConfig,
|
|
1203
|
+
});
|
|
1204
|
+
|
|
1205
|
+
const mockPreRenderObj = {
|
|
1206
|
+
currentLiveboardState: {},
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
jest.spyOn(liveboardEmbed as any, 'getPreRenderObj').mockReturnValue(mockPreRenderObj as any);
|
|
1210
|
+
jest.spyOn(liveboardEmbed, 'navigateToLiveboard').mockResolvedValue(undefined);
|
|
1211
|
+
|
|
1212
|
+
// Mock embed container as not loaded initially
|
|
1213
|
+
liveboardEmbed.isEmbedContainerLoaded = false;
|
|
1214
|
+
|
|
1215
|
+
// Call beforePrerenderVisible
|
|
1216
|
+
liveboardEmbed['beforePrerenderVisible']();
|
|
1217
|
+
|
|
1218
|
+
// Simulate embed container becoming ready
|
|
1219
|
+
liveboardEmbed.isEmbedContainerLoaded = true;
|
|
1220
|
+
liveboardEmbed['executeEmbedContainerReadyCallbacks']();
|
|
1221
|
+
|
|
1222
|
+
// Check that currentLiveboardState was updated
|
|
1223
|
+
expect(mockPreRenderObj.currentLiveboardState).toEqual({
|
|
1224
|
+
liveboardId,
|
|
1225
|
+
vizId,
|
|
1226
|
+
activeTabId,
|
|
1227
|
+
});
|
|
1228
|
+
});
|
|
1229
|
+
|
|
1230
|
+
test('should handle beforePrerenderVisible when embed container is already loaded', async () => {
|
|
1231
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1232
|
+
liveboardId,
|
|
1233
|
+
vizId,
|
|
1234
|
+
activeTabId,
|
|
1235
|
+
...defaultViewConfig,
|
|
1236
|
+
});
|
|
1237
|
+
|
|
1238
|
+
const navigateToLiveboardSpy = jest.spyOn(liveboardEmbed, 'navigateToLiveboard').mockResolvedValue(undefined);
|
|
1239
|
+
|
|
1240
|
+
// Mock embed container as already loaded
|
|
1241
|
+
liveboardEmbed.isEmbedContainerLoaded = true;
|
|
1242
|
+
|
|
1243
|
+
// Call beforePrerenderVisible
|
|
1244
|
+
liveboardEmbed['beforePrerenderVisible']();
|
|
1245
|
+
|
|
1246
|
+
// navigateToLiveboard should be called immediately
|
|
1247
|
+
expect(navigateToLiveboardSpy).toHaveBeenCalledWith(liveboardId, vizId, activeTabId);
|
|
1248
|
+
});
|
|
1249
|
+
|
|
1250
|
+
test('should handle beforePrerenderVisible without prerender object', async () => {
|
|
1251
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1252
|
+
liveboardId,
|
|
1253
|
+
vizId,
|
|
1254
|
+
activeTabId,
|
|
1255
|
+
...defaultViewConfig,
|
|
1256
|
+
});
|
|
1257
|
+
|
|
1258
|
+
jest.spyOn(liveboardEmbed as any, 'getPreRenderObj').mockReturnValue(null);
|
|
1259
|
+
const navigateToLiveboardSpy = jest.spyOn(liveboardEmbed, 'navigateToLiveboard').mockResolvedValue(undefined);
|
|
1260
|
+
|
|
1261
|
+
// Mock embed container as not loaded initially
|
|
1262
|
+
liveboardEmbed.isEmbedContainerLoaded = false;
|
|
1263
|
+
|
|
1264
|
+
// Call beforePrerenderVisible
|
|
1265
|
+
liveboardEmbed['beforePrerenderVisible']();
|
|
1266
|
+
|
|
1267
|
+
// Simulate embed container becoming ready
|
|
1268
|
+
liveboardEmbed.isEmbedContainerLoaded = true;
|
|
1269
|
+
liveboardEmbed['executeEmbedContainerReadyCallbacks']();
|
|
1270
|
+
|
|
1271
|
+
// navigateToLiveboard should still be called
|
|
1272
|
+
expect(navigateToLiveboardSpy).toHaveBeenCalledWith(liveboardId, vizId, activeTabId);
|
|
1273
|
+
});
|
|
1274
|
+
|
|
1275
|
+
test('should work with all liveboard parameters', async () => {
|
|
1276
|
+
const customLiveboardId = 'custom-liveboard-id';
|
|
1277
|
+
const customVizId = 'custom-viz-id';
|
|
1278
|
+
const customActiveTabId = 'custom-active-tab-id';
|
|
1279
|
+
|
|
1280
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1281
|
+
liveboardId: customLiveboardId,
|
|
1282
|
+
vizId: customVizId,
|
|
1283
|
+
activeTabId: customActiveTabId,
|
|
1284
|
+
...defaultViewConfig,
|
|
1285
|
+
});
|
|
1286
|
+
|
|
1287
|
+
const navigateToLiveboardSpy = jest.spyOn(liveboardEmbed, 'navigateToLiveboard').mockResolvedValue(undefined);
|
|
1288
|
+
|
|
1289
|
+
// Mock embed container as already loaded
|
|
1290
|
+
liveboardEmbed.isEmbedContainerLoaded = true;
|
|
1291
|
+
|
|
1292
|
+
// Call beforePrerenderVisible
|
|
1293
|
+
liveboardEmbed['beforePrerenderVisible']();
|
|
1294
|
+
|
|
1295
|
+
// Check that all parameters are passed correctly
|
|
1296
|
+
expect(navigateToLiveboardSpy).toHaveBeenCalledWith(customLiveboardId, customVizId, customActiveTabId);
|
|
1297
|
+
});
|
|
1298
|
+
|
|
1299
|
+
test('should work with minimal liveboard parameters', async () => {
|
|
1300
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1301
|
+
liveboardId,
|
|
1302
|
+
...defaultViewConfig,
|
|
1303
|
+
});
|
|
1304
|
+
|
|
1305
|
+
const navigateToLiveboardSpy = jest.spyOn(liveboardEmbed, 'navigateToLiveboard').mockResolvedValue(undefined);
|
|
1306
|
+
|
|
1307
|
+
// Mock embed container as already loaded
|
|
1308
|
+
liveboardEmbed.isEmbedContainerLoaded = true;
|
|
1309
|
+
|
|
1310
|
+
// Call beforePrerenderVisible
|
|
1311
|
+
liveboardEmbed['beforePrerenderVisible']();
|
|
1312
|
+
|
|
1313
|
+
// Check that undefined parameters are passed correctly
|
|
1314
|
+
expect(navigateToLiveboardSpy).toHaveBeenCalledWith(liveboardId, undefined, undefined);
|
|
1315
|
+
});
|
|
1316
|
+
});
|
|
1116
1317
|
});
|