@thoughtspot/visual-embed-sdk 1.37.1-spotter-embed → 1.38.0-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/README.md +1 -1
- package/cjs/package.json +2 -2
- package/cjs/src/embed/app.d.ts +43 -3
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +40 -7
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +23 -6
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/base.d.ts.map +1 -1
- package/cjs/src/embed/base.js +7 -0
- package/cjs/src/embed/base.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.d.ts +8 -3
- package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/cjs/src/embed/bodyless-conversation.js +5 -2
- package/cjs/src/embed/bodyless-conversation.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.spec.js +286 -1
- package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts +5 -3
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +3 -2
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +21 -10
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +6 -4
- 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 +105 -0
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/index.d.ts +4 -4
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +5 -3
- 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/index.d.ts +32 -3
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +54 -2
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/react/index.spec.js +94 -0
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/types.d.ts +25 -51
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +24 -50
- package/cjs/src/types.js.map +1 -1
- package/dist/{index-Cj4BVGHL.js → index-DeFzsyFF.js} +1 -1
- package/dist/{index-DnIvX1FR.js → index-NZYq1Tu3.js} +1 -2
- package/dist/src/embed/app.d.ts +43 -3
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts.map +1 -1
- package/dist/src/embed/bodyless-conversation.d.ts +8 -3
- package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts +5 -3
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- 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/index.d.ts +4 -4
- 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/index.d.ts +32 -3
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +25 -51
- package/dist/src/types.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +614 -77
- package/dist/tsembed-react.js +758 -296
- package/dist/tsembed.es.js +153 -75
- package/dist/tsembed.js +297 -295
- package/dist/visual-embed-sdk-react-full.d.ts +194 -145
- package/dist/visual-embed-sdk-react.d.ts +194 -145
- package/dist/visual-embed-sdk.d.ts +82 -61
- package/lib/package.json +2 -2
- package/lib/src/embed/app.d.ts +43 -3
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +39 -6
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +24 -7
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/base.d.ts.map +1 -1
- package/lib/src/embed/base.js +7 -0
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.d.ts +8 -3
- package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/lib/src/embed/bodyless-conversation.js +5 -2
- package/lib/src/embed/bodyless-conversation.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.spec.js +287 -2
- package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/lib/src/embed/conversation.d.ts +5 -3
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js +3 -2
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +21 -10
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +6 -4
- 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 +105 -0
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/index.d.ts +4 -4
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +4 -4
- 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/index.d.ts +32 -3
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +53 -1
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +96 -2
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/types.d.ts +25 -51
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +24 -50
- package/lib/src/types.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +85 -64
- package/package.json +2 -2
- package/src/embed/app.spec.ts +30 -6
- package/src/embed/app.ts +62 -9
- package/src/embed/base.ts +9 -0
- package/src/embed/bodyless-conversation.spec.ts +308 -1
- package/src/embed/bodyless-conversation.ts +13 -3
- package/src/embed/conversation.ts +5 -3
- package/src/embed/liveboard.ts +25 -10
- package/src/embed/ts-embed.spec.ts +130 -0
- package/src/embed/ts-embed.ts +6 -4
- package/src/index.ts +10 -3
- package/src/react/all-types-export.ts +1 -0
- package/src/react/index.spec.tsx +157 -1
- package/src/react/index.tsx +64 -3
- package/src/types.ts +24 -56
- package/cjs/src/pages/embed-test.page.d.ts +0 -8
- package/cjs/src/pages/embed-test.page.d.ts.map +0 -1
- package/cjs/src/pages/embed-test.page.js +0 -20
- package/cjs/src/pages/embed-test.page.js.map +0 -1
- package/cjs/src/pages/home.page.d.ts +0 -6
- package/cjs/src/pages/home.page.d.ts.map +0 -1
- package/cjs/src/pages/home.page.js +0 -12
- package/cjs/src/pages/home.page.js.map +0 -1
- package/cjs/src/pages/login.page.d.ts +0 -15
- package/cjs/src/pages/login.page.d.ts.map +0 -1
- package/cjs/src/pages/login.page.js +0 -22
- package/cjs/src/pages/login.page.js.map +0 -1
- package/cjs/src/tests/auth.test.d.ts +0 -1
- package/cjs/src/tests/auth.test.d.ts.map +0 -1
- package/cjs/src/tests/auth.test.js +0 -1
- package/cjs/src/tests/auth.test.js.map +0 -1
- package/cjs/src/tests/e2e/auth.spec.d.ts +0 -2
- package/cjs/src/tests/e2e/auth.spec.d.ts.map +0 -1
- package/cjs/src/tests/e2e/auth.spec.js +0 -54
- package/cjs/src/tests/e2e/auth.spec.js.map +0 -1
- package/dist/index-DUaG1OG2.js +0 -7447
- package/dist/index-Fhk1V_Gw.js +0 -7371
- package/dist/index-OuiZF3zE.js +0 -7371
|
@@ -31,7 +31,7 @@ describe('SpotterAgentEmbed', () => {
|
|
|
31
31
|
fetchMock.resetMocks();
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
test('should render the
|
|
34
|
+
test('should render the SpotterAgent embed', async () => {
|
|
35
35
|
fetchMock.mockResponses(
|
|
36
36
|
JSON.stringify({
|
|
37
37
|
data: {
|
|
@@ -137,4 +137,311 @@ describe('SpotterAgentEmbed', () => {
|
|
|
137
137
|
const errorResult = await spotterEmbed.sendMessage('userMessage');
|
|
138
138
|
expect(errorResult.error instanceof Error).toBeTruthy();
|
|
139
139
|
});
|
|
140
|
+
|
|
141
|
+
test('should apply containerClassName to the container element', async () => {
|
|
142
|
+
fetchMock.mockResponses(
|
|
143
|
+
JSON.stringify({
|
|
144
|
+
data: {
|
|
145
|
+
ConvAssist__createConversation: {
|
|
146
|
+
convId: 'conversationId',
|
|
147
|
+
initialCtx: {
|
|
148
|
+
type: 'TS_ANSWER',
|
|
149
|
+
tsAnsCtx: {
|
|
150
|
+
sessionId: 'sessionId',
|
|
151
|
+
genNo: 1,
|
|
152
|
+
stateKey: {
|
|
153
|
+
transactionId: 'transactionId',
|
|
154
|
+
generationNumber: 1,
|
|
155
|
+
},
|
|
156
|
+
worksheet: {
|
|
157
|
+
worksheetId: 'worksheetId',
|
|
158
|
+
worksheetName: 'GTM',
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
}),
|
|
165
|
+
JSON.stringify({
|
|
166
|
+
data: {
|
|
167
|
+
ConvAssist__sendMessage: {
|
|
168
|
+
responses: [
|
|
169
|
+
{
|
|
170
|
+
msgId: 'msgId',
|
|
171
|
+
data: {
|
|
172
|
+
asstRespData: {
|
|
173
|
+
tool: 'TS_NLS',
|
|
174
|
+
asstRespText: '',
|
|
175
|
+
nlsAnsData: {
|
|
176
|
+
sageQuerySuggestions: [
|
|
177
|
+
{
|
|
178
|
+
llmReasoning: {
|
|
179
|
+
assumptions: 'You want the total [COL|sales] for [COL|item_type] [VAL|jackets] for [VAL|this year].',
|
|
180
|
+
clarifications: '',
|
|
181
|
+
interpretation: '',
|
|
182
|
+
__typename: 'eureka_SageQuerySuggestion_LLMReasoning',
|
|
183
|
+
},
|
|
184
|
+
tokens: [
|
|
185
|
+
'sum sales',
|
|
186
|
+
"item type = 'jackets'",
|
|
187
|
+
"date = 'this year'",
|
|
188
|
+
],
|
|
189
|
+
tmlTokens: [
|
|
190
|
+
'sum [sales]',
|
|
191
|
+
"[date] = [date].'this year'",
|
|
192
|
+
"[item type] = [item type].'jackets'",
|
|
193
|
+
],
|
|
194
|
+
worksheetId: 'worksheetId',
|
|
195
|
+
description: '',
|
|
196
|
+
title: '',
|
|
197
|
+
cached: false,
|
|
198
|
+
sqlQuery: "SELECT SUM(sales) FROM __Sample_Retail_Apparel WHERE item_type = 'jackets' AND date = _this_year();",
|
|
199
|
+
sessionId: 'sessionId',
|
|
200
|
+
genNo: 2,
|
|
201
|
+
formulaInfo: [],
|
|
202
|
+
tmlPhrases: [],
|
|
203
|
+
stateKey: {
|
|
204
|
+
transactionId: 'transactionId',
|
|
205
|
+
generationNumber: 1,
|
|
206
|
+
__typename: 'sage_auto_complete_v2_ACStateKey',
|
|
207
|
+
},
|
|
208
|
+
__typename: 'eureka_SageQuerySuggestion',
|
|
209
|
+
},
|
|
210
|
+
],
|
|
211
|
+
responseType: 'ANSWER',
|
|
212
|
+
__typename: 'convassist_nls_tool_NLSToolAsstRespData',
|
|
213
|
+
},
|
|
214
|
+
__typename: 'convassist_AsstResponseData',
|
|
215
|
+
},
|
|
216
|
+
__typename: 'convassist_MessageData',
|
|
217
|
+
},
|
|
218
|
+
type: 'ASST_RESPONSE',
|
|
219
|
+
__typename: 'convassist_MessagePayload',
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
__typename: 'convassist_SendMessageResponse',
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
}),
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const viewConfig: SpotterAgentEmbedViewConfig = {
|
|
229
|
+
worksheetId: 'worksheetId',
|
|
230
|
+
containerClassName: 'custom-conversation-container',
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const spotterAgentEmbed = new SpotterAgentEmbed(viewConfig);
|
|
234
|
+
const result = await spotterAgentEmbed.sendMessage('userMessage');
|
|
235
|
+
|
|
236
|
+
// Verify that the container has the custom class name
|
|
237
|
+
expect(result.container.className).toBe('custom-conversation-container');
|
|
238
|
+
|
|
239
|
+
// Also verify the iframe src is correct
|
|
240
|
+
const iframeSrc = getIFrameSrc(result.container);
|
|
241
|
+
expectUrlToHaveParamsWithValues(iframeSrc, {
|
|
242
|
+
sessionId: 'sessionId',
|
|
243
|
+
genNo: 2,
|
|
244
|
+
acSessionId: 'transactionId',
|
|
245
|
+
acGenNo: 1,
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
test('should not set className when containerClassName is not provided', async () => {
|
|
250
|
+
fetchMock.mockResponses(
|
|
251
|
+
JSON.stringify({
|
|
252
|
+
data: {
|
|
253
|
+
ConvAssist__createConversation: {
|
|
254
|
+
convId: 'conversationId',
|
|
255
|
+
initialCtx: {
|
|
256
|
+
type: 'TS_ANSWER',
|
|
257
|
+
tsAnsCtx: {
|
|
258
|
+
sessionId: 'sessionId',
|
|
259
|
+
genNo: 1,
|
|
260
|
+
stateKey: {
|
|
261
|
+
transactionId: 'transactionId',
|
|
262
|
+
generationNumber: 1,
|
|
263
|
+
},
|
|
264
|
+
worksheet: {
|
|
265
|
+
worksheetId: 'worksheetId',
|
|
266
|
+
worksheetName: 'GTM',
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
}),
|
|
273
|
+
JSON.stringify({
|
|
274
|
+
data: {
|
|
275
|
+
ConvAssist__sendMessage: {
|
|
276
|
+
responses: [
|
|
277
|
+
{
|
|
278
|
+
msgId: 'msgId',
|
|
279
|
+
data: {
|
|
280
|
+
asstRespData: {
|
|
281
|
+
tool: 'TS_NLS',
|
|
282
|
+
asstRespText: '',
|
|
283
|
+
nlsAnsData: {
|
|
284
|
+
sageQuerySuggestions: [
|
|
285
|
+
{
|
|
286
|
+
llmReasoning: {
|
|
287
|
+
assumptions: 'You want the total [COL|sales] for [COL|item_type] [VAL|jackets] for [VAL|this year].',
|
|
288
|
+
clarifications: '',
|
|
289
|
+
interpretation: '',
|
|
290
|
+
__typename: 'eureka_SageQuerySuggestion_LLMReasoning',
|
|
291
|
+
},
|
|
292
|
+
tokens: [
|
|
293
|
+
'sum sales',
|
|
294
|
+
"item type = 'jackets'",
|
|
295
|
+
"date = 'this year'",
|
|
296
|
+
],
|
|
297
|
+
tmlTokens: [
|
|
298
|
+
'sum [sales]',
|
|
299
|
+
"[date] = [date].'this year'",
|
|
300
|
+
"[item type] = [item type].'jackets'",
|
|
301
|
+
],
|
|
302
|
+
worksheetId: 'worksheetId',
|
|
303
|
+
description: '',
|
|
304
|
+
title: '',
|
|
305
|
+
cached: false,
|
|
306
|
+
sqlQuery: "SELECT SUM(sales) FROM __Sample_Retail_Apparel WHERE item_type = 'jackets' AND date = _this_year();",
|
|
307
|
+
sessionId: 'sessionId',
|
|
308
|
+
genNo: 2,
|
|
309
|
+
formulaInfo: [],
|
|
310
|
+
tmlPhrases: [],
|
|
311
|
+
stateKey: {
|
|
312
|
+
transactionId: 'transactionId',
|
|
313
|
+
generationNumber: 1,
|
|
314
|
+
__typename: 'sage_auto_complete_v2_ACStateKey',
|
|
315
|
+
},
|
|
316
|
+
__typename: 'eureka_SageQuerySuggestion',
|
|
317
|
+
},
|
|
318
|
+
],
|
|
319
|
+
responseType: 'ANSWER',
|
|
320
|
+
__typename: 'convassist_nls_tool_NLSToolAsstRespData',
|
|
321
|
+
},
|
|
322
|
+
__typename: 'convassist_AsstResponseData',
|
|
323
|
+
},
|
|
324
|
+
__typename: 'convassist_MessageData',
|
|
325
|
+
},
|
|
326
|
+
type: 'ASST_RESPONSE',
|
|
327
|
+
__typename: 'convassist_MessagePayload',
|
|
328
|
+
},
|
|
329
|
+
],
|
|
330
|
+
__typename: 'convassist_SendMessageResponse',
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
}),
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
const viewConfig: SpotterAgentEmbedViewConfig = {
|
|
337
|
+
worksheetId: 'worksheetId',
|
|
338
|
+
// No containerClassName provided
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
const spotterAgentEmbed = new SpotterAgentEmbed(viewConfig);
|
|
342
|
+
const result = await spotterAgentEmbed.sendMessage('userMessage');
|
|
343
|
+
|
|
344
|
+
// Verify that the container has no class name (empty string)
|
|
345
|
+
expect(result.container.className).toBe('');
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
test('should handle hideActions parameter correctly', async () => {
|
|
349
|
+
fetchMock.mockResponses(
|
|
350
|
+
JSON.stringify({
|
|
351
|
+
data: {
|
|
352
|
+
ConvAssist__createConversation: {
|
|
353
|
+
convId: 'conversationId',
|
|
354
|
+
initialCtx: {
|
|
355
|
+
type: 'TS_ANSWER',
|
|
356
|
+
tsAnsCtx: {
|
|
357
|
+
sessionId: 'sessionId',
|
|
358
|
+
genNo: 1,
|
|
359
|
+
stateKey: {
|
|
360
|
+
transactionId: 'transactionId',
|
|
361
|
+
generationNumber: 1,
|
|
362
|
+
},
|
|
363
|
+
worksheet: {
|
|
364
|
+
worksheetId: 'worksheetId',
|
|
365
|
+
worksheetName: 'GTM',
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
}),
|
|
372
|
+
JSON.stringify({
|
|
373
|
+
data: {
|
|
374
|
+
ConvAssist__sendMessage: {
|
|
375
|
+
responses: [
|
|
376
|
+
{
|
|
377
|
+
msgId: 'msgId',
|
|
378
|
+
data: {
|
|
379
|
+
asstRespData: {
|
|
380
|
+
tool: 'TS_NLS',
|
|
381
|
+
asstRespText: '',
|
|
382
|
+
nlsAnsData: {
|
|
383
|
+
sageQuerySuggestions: [
|
|
384
|
+
{
|
|
385
|
+
llmReasoning: {
|
|
386
|
+
assumptions: 'You want the total [COL|sales] for [COL|item_type] [VAL|jackets] for [VAL|this year].',
|
|
387
|
+
clarifications: '',
|
|
388
|
+
interpretation: '',
|
|
389
|
+
__typename: 'eureka_SageQuerySuggestion_LLMReasoning',
|
|
390
|
+
},
|
|
391
|
+
tokens: [
|
|
392
|
+
'sum sales',
|
|
393
|
+
"item type = 'jackets'",
|
|
394
|
+
"date = 'this year'",
|
|
395
|
+
],
|
|
396
|
+
tmlTokens: [
|
|
397
|
+
'sum [sales]',
|
|
398
|
+
"[date] = [date].'this year'",
|
|
399
|
+
"[item type] = [item type].'jackets'",
|
|
400
|
+
],
|
|
401
|
+
worksheetId: 'worksheetId',
|
|
402
|
+
description: '',
|
|
403
|
+
title: '',
|
|
404
|
+
cached: false,
|
|
405
|
+
sqlQuery: "SELECT SUM(sales) FROM __Sample_Retail_Apparel WHERE item_type = 'jackets' AND date = _this_year();",
|
|
406
|
+
sessionId: 'sessionId',
|
|
407
|
+
genNo: 2,
|
|
408
|
+
formulaInfo: [],
|
|
409
|
+
tmlPhrases: [],
|
|
410
|
+
stateKey: {
|
|
411
|
+
transactionId: 'transactionId',
|
|
412
|
+
generationNumber: 1,
|
|
413
|
+
__typename: 'sage_auto_complete_v2_ACStateKey',
|
|
414
|
+
},
|
|
415
|
+
__typename: 'eureka_SageQuerySuggestion',
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
responseType: 'ANSWER',
|
|
419
|
+
__typename: 'convassist_nls_tool_NLSToolAsstRespData',
|
|
420
|
+
},
|
|
421
|
+
__typename: 'convassist_AsstResponseData',
|
|
422
|
+
},
|
|
423
|
+
__typename: 'convassist_MessageData',
|
|
424
|
+
},
|
|
425
|
+
type: 'ASST_RESPONSE',
|
|
426
|
+
__typename: 'convassist_MessagePayload',
|
|
427
|
+
},
|
|
428
|
+
],
|
|
429
|
+
__typename: 'convassist_SendMessageResponse',
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
}),
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
const viewConfig: SpotterAgentEmbedViewConfig = {
|
|
436
|
+
worksheetId: 'worksheetId',
|
|
437
|
+
hiddenActions: [Action.Download, Action.Save], // This should trigger the HideActions branch
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
const spotterAgentEmbed = new SpotterAgentEmbed(viewConfig);
|
|
441
|
+
const result = await spotterAgentEmbed.sendMessage('userMessage');
|
|
442
|
+
|
|
443
|
+
// Verify the iframe src contains the hideActions parameter
|
|
444
|
+
const iframeSrc = getIFrameSrc(result.container);
|
|
445
|
+
expect(iframeSrc).toContain('hideAction');
|
|
446
|
+
});
|
|
140
447
|
});
|
|
@@ -13,11 +13,17 @@ export interface SpotterAgentEmbedViewConfig extends ViewConfig {
|
|
|
13
13
|
* The ID of the worksheet to use for the conversation.
|
|
14
14
|
*/
|
|
15
15
|
worksheetId: string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Optional CSS class name to add to the container div.
|
|
19
|
+
*/
|
|
20
|
+
containerClassName?: string;
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
/**
|
|
19
24
|
* Configuration for conversation options.
|
|
20
|
-
* @deprecated
|
|
25
|
+
* @deprecated from SDK: 1.38.0 | ThoughtSpot: 10.10.0.cl
|
|
26
|
+
* Use {@link SpotterAgentEmbedViewConfig} instead
|
|
21
27
|
* @group Embed components
|
|
22
28
|
*/
|
|
23
29
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
@@ -110,6 +116,10 @@ export class SpotterAgentEmbed {
|
|
|
110
116
|
}
|
|
111
117
|
|
|
112
118
|
const container = document.createElement('div');
|
|
119
|
+
if (this.viewConfig.containerClassName) {
|
|
120
|
+
container.className = this.viewConfig.containerClassName;
|
|
121
|
+
}
|
|
122
|
+
|
|
113
123
|
const embed = new ConversationMessage(container, {
|
|
114
124
|
...this.viewConfig,
|
|
115
125
|
sessionId: data.sessionId,
|
|
@@ -125,7 +135,8 @@ export class SpotterAgentEmbed {
|
|
|
125
135
|
/**
|
|
126
136
|
* Create a conversation embed, which can be integrated inside
|
|
127
137
|
* chatbots or other conversational interfaces.
|
|
128
|
-
* @deprecated
|
|
138
|
+
* @deprecated from SDK: 1.38.0 | ThoughtSpot: 10.10.0.cl
|
|
139
|
+
* Use {@link SpotterAgentEmbed} instead
|
|
129
140
|
* @example
|
|
130
141
|
* ```js
|
|
131
142
|
* import { SpotterAgentEmbed } from '@thoughtspot/visual-embed-sdk';
|
|
@@ -140,7 +151,6 @@ export class SpotterAgentEmbed {
|
|
|
140
151
|
* document.body.appendChild(container); // or to any other element
|
|
141
152
|
* ```
|
|
142
153
|
* @group Embed components
|
|
143
|
-
* @version SDK: 1.37.0 | ThoughtSpot: 10.9.0.cl
|
|
144
154
|
*/
|
|
145
155
|
export class BodylessConversation extends SpotterAgentEmbed {
|
|
146
156
|
constructor(viewConfig: BodylessConversationViewConfig) {
|
|
@@ -96,7 +96,8 @@ export interface SpotterEmbedViewConfig extends ViewConfig {
|
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
98
|
* The configuration for the embedded spotterEmbed options.
|
|
99
|
-
* @deprecated
|
|
99
|
+
* @deprecated from SDK: 1.38.0 | ThoughtSpot: 10.10.0.cl
|
|
100
|
+
* Use {@link SpotterEmbedViewConfig} instead
|
|
100
101
|
* @group Embed components
|
|
101
102
|
*/
|
|
102
103
|
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
@@ -115,7 +116,7 @@ export interface ConversationViewConfig extends SpotterEmbedViewConfig {}
|
|
|
115
116
|
* });
|
|
116
117
|
* conversation.render();
|
|
117
118
|
* ```
|
|
118
|
-
* @version SDK: 1.
|
|
119
|
+
* @version SDK: 1.37.0 | ThoughtSpot: 10.9.0.cl
|
|
119
120
|
*/
|
|
120
121
|
export class SpotterEmbed extends TsEmbed {
|
|
121
122
|
constructor(container: HTMLElement, protected viewConfig: SpotterEmbedViewConfig) {
|
|
@@ -182,7 +183,8 @@ export class SpotterEmbed extends TsEmbed {
|
|
|
182
183
|
|
|
183
184
|
/**
|
|
184
185
|
* Embed ThoughtSpot AI Conversation.
|
|
185
|
-
* @deprecated
|
|
186
|
+
* @deprecated from SDK: 1.38.0 | ThoughtSpot: 10.10.0.cl
|
|
187
|
+
* Use {@link SpotterEmbed} instead
|
|
186
188
|
* @group Embed components
|
|
187
189
|
* @example
|
|
188
190
|
* ```js
|
package/src/embed/liveboard.ts
CHANGED
|
@@ -24,13 +24,8 @@ import { getAuthPromise } from './base';
|
|
|
24
24
|
import { TsEmbed, V1Embed } from './ts-embed';
|
|
25
25
|
import { addPreviewStylesIfNotPresent } from '../utils/global-styles';
|
|
26
26
|
import { TriggerPayload, TriggerResponse } from './hostEventClient/contracts';
|
|
27
|
+
import { logger } from '../utils/logger';
|
|
27
28
|
|
|
28
|
-
const liveboardHeightWhitelistedRoutes = [
|
|
29
|
-
'/embed/viz/',
|
|
30
|
-
'/embed/insights/viz/',
|
|
31
|
-
'/tsl-editor/PINBOARD_ANSWER_BOOK/',
|
|
32
|
-
'/import-tsl/PINBOARD_ANSWER_BOOK/',
|
|
33
|
-
];
|
|
34
29
|
|
|
35
30
|
/**
|
|
36
31
|
* The configuration for the embedded Liveboard or visualization page view.
|
|
@@ -429,11 +424,16 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
429
424
|
|
|
430
425
|
private defaultHeight = 500;
|
|
431
426
|
|
|
432
|
-
|
|
427
|
+
|
|
433
428
|
constructor(domSelector: DOMSelector, viewConfig: LiveboardViewConfig) {
|
|
434
429
|
viewConfig.embedComponentType = 'LiveboardEmbed';
|
|
435
430
|
super(domSelector, viewConfig);
|
|
436
431
|
if (this.viewConfig.fullHeight === true) {
|
|
432
|
+
if (this.viewConfig.vizId) {
|
|
433
|
+
logger.warn('Full height is currently only supported for Liveboard embeds.' +
|
|
434
|
+
'Using full height with vizId might lead to unexpected behavior.');
|
|
435
|
+
}
|
|
436
|
+
|
|
437
437
|
this.on(EmbedEvent.RouteChange, this.setIframeHeightForNonEmbedLiveboard);
|
|
438
438
|
this.on(EmbedEvent.EmbedHeight, this.updateIFrameHeight);
|
|
439
439
|
this.on(EmbedEvent.EmbedIframeCenter, this.embedIframeCenter);
|
|
@@ -592,11 +592,26 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
592
592
|
};
|
|
593
593
|
|
|
594
594
|
private setIframeHeightForNonEmbedLiveboard = (data: MessagePayload) => {
|
|
595
|
-
const
|
|
596
|
-
|
|
595
|
+
const { height: frameHeight } = this.viewConfig.frameParams || {};
|
|
596
|
+
|
|
597
|
+
const liveboardRelatedRoutes = [
|
|
598
|
+
'/pinboard/',
|
|
599
|
+
'/insights/pinboard/',
|
|
600
|
+
'/schedules/',
|
|
601
|
+
'/embed/viz/',
|
|
602
|
+
'/embed/insights/viz/',
|
|
603
|
+
'/liveboard/',
|
|
604
|
+
'/insights/liveboard/',
|
|
605
|
+
'/tsl-editor/PINBOARD_ANSWER_BOOK/',
|
|
606
|
+
'/import-tsl/PINBOARD_ANSWER_BOOK/',
|
|
607
|
+
];
|
|
608
|
+
|
|
609
|
+
if (liveboardRelatedRoutes.some((path) => data.data.currentPath.startsWith(path))) {
|
|
610
|
+
// Ignore the height reset of the frame, if the navigation is
|
|
611
|
+
// only within the liveboard page.
|
|
597
612
|
return;
|
|
598
613
|
}
|
|
599
|
-
this.setIFrameHeight(this.defaultHeight);
|
|
614
|
+
this.setIFrameHeight(frameHeight || this.defaultHeight);
|
|
600
615
|
};
|
|
601
616
|
|
|
602
617
|
private setActiveTab(data: { tabId: string }) {
|
|
@@ -58,6 +58,7 @@ import { HiddenActionItemByDefaultForSearchEmbed } from './search';
|
|
|
58
58
|
import { processTrigger } from '../utils/processTrigger';
|
|
59
59
|
import { UIPassthroughEvent } from './hostEventClient/contracts';
|
|
60
60
|
import * as sessionInfoService from '../utils/sessionInfoService';
|
|
61
|
+
import * as authToken from '../authToken';
|
|
61
62
|
|
|
62
63
|
jest.mock('../utils/processTrigger');
|
|
63
64
|
|
|
@@ -2576,4 +2577,133 @@ describe('Unit test case for ts embed', () => {
|
|
|
2576
2577
|
expect(iframeAfterInit).not.toBe(null);
|
|
2577
2578
|
});
|
|
2578
2579
|
});
|
|
2580
|
+
|
|
2581
|
+
describe('AutoLogin behavior in updateAuthToken', () => {
|
|
2582
|
+
const mockPort = { postMessage: jest.fn() };
|
|
2583
|
+
const mockEmbedEventPayload = { type: EmbedEvent.AuthExpire, data: {} };
|
|
2584
|
+
|
|
2585
|
+
beforeEach(() => {
|
|
2586
|
+
jest.clearAllMocks();
|
|
2587
|
+
document.body.innerHTML = getDocumentBody();
|
|
2588
|
+
mockPort.postMessage.mockClear();
|
|
2589
|
+
jest.spyOn(authToken, 'getAuthenticationToken').mockResolvedValue('test-token');
|
|
2590
|
+
|
|
2591
|
+
jest.spyOn(baseInstance, 'handleAuth').mockImplementation(() => Promise.resolve(true));
|
|
2592
|
+
jest.spyOn(baseInstance, 'notifyAuthFailure').mockImplementation(() => {});
|
|
2593
|
+
});
|
|
2594
|
+
|
|
2595
|
+
const renderAndTriggerAuthExpire = async () => {
|
|
2596
|
+
const searchEmbed = new SearchEmbed(getRootEl(), defaultViewConfig);
|
|
2597
|
+
await searchEmbed.render();
|
|
2598
|
+
await executeAfterWait(() => {
|
|
2599
|
+
const iframe = getIFrameEl();
|
|
2600
|
+
postMessageToParent(iframe.contentWindow, mockEmbedEventPayload, mockPort);
|
|
2601
|
+
});
|
|
2602
|
+
};
|
|
2603
|
+
|
|
2604
|
+
test('Cookieless with autoLogin undefined should default to true', async () => {
|
|
2605
|
+
init({
|
|
2606
|
+
thoughtSpotHost: 'tshost',
|
|
2607
|
+
authType: AuthType.TrustedAuthTokenCookieless,
|
|
2608
|
+
// autoLogin undefined
|
|
2609
|
+
});
|
|
2610
|
+
|
|
2611
|
+
await renderAndTriggerAuthExpire();
|
|
2612
|
+
|
|
2613
|
+
await executeAfterWait(() => {
|
|
2614
|
+
expect(authToken.getAuthenticationToken).toHaveBeenCalled();
|
|
2615
|
+
expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
|
|
2616
|
+
expect(mockPort.postMessage).toHaveBeenCalledWith({
|
|
2617
|
+
type: EmbedEvent.AuthExpire,
|
|
2618
|
+
data: { authToken: 'test-token' },
|
|
2619
|
+
});
|
|
2620
|
+
});
|
|
2621
|
+
});
|
|
2622
|
+
|
|
2623
|
+
test('Cookieless with autoLogin false should not get auth token', async () => {
|
|
2624
|
+
init({
|
|
2625
|
+
thoughtSpotHost: 'tshost',
|
|
2626
|
+
authType: AuthType.TrustedAuthTokenCookieless,
|
|
2627
|
+
autoLogin: false,
|
|
2628
|
+
});
|
|
2629
|
+
|
|
2630
|
+
await renderAndTriggerAuthExpire();
|
|
2631
|
+
|
|
2632
|
+
await executeAfterWait(() => {
|
|
2633
|
+
expect(authToken.getAuthenticationToken).not.toHaveBeenCalled();
|
|
2634
|
+
expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
|
|
2635
|
+
expect(mockPort.postMessage).not.toHaveBeenCalled();
|
|
2636
|
+
});
|
|
2637
|
+
});
|
|
2638
|
+
|
|
2639
|
+
test('Cookieless with autoLogin true should get auth token', async () => {
|
|
2640
|
+
init({
|
|
2641
|
+
thoughtSpotHost: 'tshost',
|
|
2642
|
+
authType: AuthType.TrustedAuthTokenCookieless,
|
|
2643
|
+
autoLogin: true,
|
|
2644
|
+
});
|
|
2645
|
+
|
|
2646
|
+
await renderAndTriggerAuthExpire();
|
|
2647
|
+
|
|
2648
|
+
await executeAfterWait(() => {
|
|
2649
|
+
expect(authToken.getAuthenticationToken).toHaveBeenCalled();
|
|
2650
|
+
expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
|
|
2651
|
+
expect(mockPort.postMessage).toHaveBeenCalledWith({
|
|
2652
|
+
type: EmbedEvent.AuthExpire,
|
|
2653
|
+
data: { authToken: 'test-token' },
|
|
2654
|
+
});
|
|
2655
|
+
});
|
|
2656
|
+
});
|
|
2657
|
+
|
|
2658
|
+
test('Other authType with autoLogin undefined should default to false', async () => {
|
|
2659
|
+
init({
|
|
2660
|
+
thoughtSpotHost: 'tshost',
|
|
2661
|
+
authType: AuthType.None,
|
|
2662
|
+
// autoLogin undefined
|
|
2663
|
+
});
|
|
2664
|
+
|
|
2665
|
+
await renderAndTriggerAuthExpire();
|
|
2666
|
+
|
|
2667
|
+
await executeAfterWait(() => {
|
|
2668
|
+
expect(authToken.getAuthenticationToken).not.toHaveBeenCalled();
|
|
2669
|
+
expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
|
|
2670
|
+
});
|
|
2671
|
+
});
|
|
2672
|
+
|
|
2673
|
+
test('Other authType with autoLogin true should call handleAuth', async () => {
|
|
2674
|
+
init({
|
|
2675
|
+
thoughtSpotHost: 'tshost',
|
|
2676
|
+
authType: AuthType.None,
|
|
2677
|
+
autoLogin: true,
|
|
2678
|
+
});
|
|
2679
|
+
|
|
2680
|
+
await renderAndTriggerAuthExpire();
|
|
2681
|
+
|
|
2682
|
+
await executeAfterWait(() => {
|
|
2683
|
+
expect(authToken.getAuthenticationToken).not.toHaveBeenCalled();
|
|
2684
|
+
expect(baseInstance.handleAuth).toHaveBeenCalledTimes(2);
|
|
2685
|
+
});
|
|
2686
|
+
});
|
|
2687
|
+
|
|
2688
|
+
test('Other authType with autoLogin false should not call handleAuth', async () => {
|
|
2689
|
+
init({
|
|
2690
|
+
thoughtSpotHost: 'tshost',
|
|
2691
|
+
authType: AuthType.None,
|
|
2692
|
+
autoLogin: false,
|
|
2693
|
+
});
|
|
2694
|
+
|
|
2695
|
+
await renderAndTriggerAuthExpire();
|
|
2696
|
+
|
|
2697
|
+
await executeAfterWait(() => {
|
|
2698
|
+
expect(authToken.getAuthenticationToken).not.toHaveBeenCalled();
|
|
2699
|
+
expect(baseInstance.handleAuth).toHaveBeenCalledTimes(1);
|
|
2700
|
+
});
|
|
2701
|
+
});
|
|
2702
|
+
|
|
2703
|
+
afterEach(() => {
|
|
2704
|
+
expect(baseInstance.notifyAuthFailure).toHaveBeenCalledWith(
|
|
2705
|
+
authInstance.AuthFailureType.EXPIRY
|
|
2706
|
+
);
|
|
2707
|
+
});
|
|
2708
|
+
});
|
|
2579
2709
|
});
|
package/src/embed/ts-embed.ts
CHANGED
|
@@ -409,11 +409,13 @@ export class TsEmbed {
|
|
|
409
409
|
* @param responder
|
|
410
410
|
*/
|
|
411
411
|
private updateAuthToken = async (_: any, responder: any) => {
|
|
412
|
-
const {
|
|
413
|
-
|
|
414
|
-
|
|
412
|
+
const { authType } = this.embedConfig;
|
|
413
|
+
let { autoLogin } = this.embedConfig;
|
|
414
|
+
// Default autoLogin: true for cookieless if undefined/null, otherwise false
|
|
415
|
+
autoLogin = autoLogin ?? (authType === AuthType.TrustedAuthTokenCookieless);
|
|
416
|
+
if (autoLogin && authType === AuthType.TrustedAuthTokenCookieless) {
|
|
415
417
|
try {
|
|
416
|
-
authToken = await getAuthenticationToken(this.embedConfig);
|
|
418
|
+
const authToken = await getAuthenticationToken(this.embedConfig);
|
|
417
419
|
responder({
|
|
418
420
|
type: EmbedEvent.AuthExpire,
|
|
419
421
|
data: { authToken },
|
package/src/index.ts
CHANGED
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
* @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
|
|
10
10
|
*/
|
|
11
11
|
import {
|
|
12
|
-
AppEmbed,
|
|
12
|
+
AppEmbed,
|
|
13
|
+
Page,
|
|
14
|
+
AppViewConfig,
|
|
15
|
+
HomePageSearchBarMode,
|
|
16
|
+
PrimaryNavbarVersion,
|
|
17
|
+
HomePage,
|
|
13
18
|
} from './embed/app';
|
|
14
19
|
import {
|
|
15
20
|
init,
|
|
@@ -23,8 +28,8 @@ import {
|
|
|
23
28
|
import { PinboardEmbed, LiveboardViewConfig, LiveboardEmbed } from './embed/liveboard';
|
|
24
29
|
import { SearchEmbed, SearchViewConfig } from './embed/search';
|
|
25
30
|
import { SearchBarEmbed, SearchBarViewConfig } from './embed/search-bar';
|
|
26
|
-
import { SpotterAgentEmbed, SpotterAgentEmbedViewConfig,
|
|
27
|
-
import { SpotterEmbed, SpotterEmbedViewConfig,
|
|
31
|
+
import { SpotterAgentEmbed, SpotterAgentEmbedViewConfig, BodylessConversation, BodylessConversationViewConfig} from './embed/bodyless-conversation';
|
|
32
|
+
import { SpotterEmbed, SpotterEmbedViewConfig, ConversationEmbed, ConversationViewConfig } from './embed/conversation';
|
|
28
33
|
import {
|
|
29
34
|
AuthFailureType, AuthStatus, AuthEvent, AuthEventEmitter,
|
|
30
35
|
} from './auth';
|
|
@@ -133,6 +138,8 @@ export {
|
|
|
133
138
|
uploadMixpanelEvent,
|
|
134
139
|
MIXPANEL_EVENT,
|
|
135
140
|
HomePageSearchBarMode,
|
|
141
|
+
PrimaryNavbarVersion,
|
|
142
|
+
HomePage,
|
|
136
143
|
VizPoint,
|
|
137
144
|
CustomActionPayload,
|
|
138
145
|
UIPassthroughEvent,
|