@thoughtspot/visual-embed-sdk 1.43.0 → 1.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/api-intercept.d.ts +51 -0
  3. package/cjs/src/api-intercept.d.ts.map +1 -0
  4. package/cjs/src/api-intercept.js +180 -0
  5. package/cjs/src/api-intercept.js.map +1 -0
  6. package/cjs/src/api-intercept.spec.d.ts +2 -0
  7. package/cjs/src/api-intercept.spec.d.ts.map +1 -0
  8. package/cjs/src/api-intercept.spec.js +672 -0
  9. package/cjs/src/api-intercept.spec.js.map +1 -0
  10. package/cjs/src/css-variables.d.ts +4 -0
  11. package/cjs/src/css-variables.d.ts.map +1 -1
  12. package/cjs/src/embed/app.d.ts +15 -5
  13. package/cjs/src/embed/app.d.ts.map +1 -1
  14. package/cjs/src/embed/app.js +7 -5
  15. package/cjs/src/embed/app.js.map +1 -1
  16. package/cjs/src/embed/app.spec.js +30 -0
  17. package/cjs/src/embed/app.spec.js.map +1 -1
  18. package/cjs/src/embed/conversation.d.ts +17 -2
  19. package/cjs/src/embed/conversation.d.ts.map +1 -1
  20. package/cjs/src/embed/conversation.js +5 -2
  21. package/cjs/src/embed/conversation.js.map +1 -1
  22. package/cjs/src/embed/conversation.spec.js +41 -0
  23. package/cjs/src/embed/conversation.spec.js.map +1 -1
  24. package/cjs/src/embed/hostEventClient/contracts.d.ts +11 -1
  25. package/cjs/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  26. package/cjs/src/embed/hostEventClient/contracts.js +1 -0
  27. package/cjs/src/embed/hostEventClient/contracts.js.map +1 -1
  28. package/cjs/src/embed/liveboard.d.ts +15 -0
  29. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  30. package/cjs/src/embed/liveboard.js +7 -2
  31. package/cjs/src/embed/liveboard.js.map +1 -1
  32. package/cjs/src/embed/liveboard.spec.js +33 -0
  33. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  34. package/cjs/src/embed/search.d.ts +0 -7
  35. package/cjs/src/embed/search.d.ts.map +1 -1
  36. package/cjs/src/embed/search.js +1 -4
  37. package/cjs/src/embed/search.js.map +1 -1
  38. package/cjs/src/embed/ts-embed.d.ts +10 -0
  39. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  40. package/cjs/src/embed/ts-embed.js +56 -15
  41. package/cjs/src/embed/ts-embed.js.map +1 -1
  42. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  43. package/cjs/src/embed/ts-embed.spec.js +412 -238
  44. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  45. package/cjs/src/index.d.ts +2 -2
  46. package/cjs/src/index.d.ts.map +1 -1
  47. package/cjs/src/index.js +2 -1
  48. package/cjs/src/index.js.map +1 -1
  49. package/cjs/src/react/all-types-export.d.ts +1 -1
  50. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  51. package/cjs/src/react/all-types-export.js +2 -1
  52. package/cjs/src/react/all-types-export.js.map +1 -1
  53. package/cjs/src/types.d.ts +246 -89
  54. package/cjs/src/types.d.ts.map +1 -1
  55. package/cjs/src/types.js +182 -70
  56. package/cjs/src/types.js.map +1 -1
  57. package/cjs/src/utils/logger.d.ts.map +1 -1
  58. package/cjs/src/utils/logger.js +1 -2
  59. package/cjs/src/utils/logger.js.map +1 -1
  60. package/cjs/src/utils/processData.d.ts +1 -1
  61. package/cjs/src/utils/processData.d.ts.map +1 -1
  62. package/cjs/src/utils/processData.js +8 -8
  63. package/cjs/src/utils/processData.js.map +1 -1
  64. package/cjs/src/utils/processData.spec.js.map +1 -1
  65. package/dist/{index-HZ94j9Ey.js → index-B2QPwxuL.js} +1 -1
  66. package/dist/src/api-intercept.d.ts +51 -0
  67. package/dist/src/api-intercept.d.ts.map +1 -0
  68. package/dist/src/api-intercept.spec.d.ts +2 -0
  69. package/dist/src/api-intercept.spec.d.ts.map +1 -0
  70. package/dist/src/css-variables.d.ts +4 -0
  71. package/dist/src/css-variables.d.ts.map +1 -1
  72. package/dist/src/embed/app.d.ts +15 -5
  73. package/dist/src/embed/app.d.ts.map +1 -1
  74. package/dist/src/embed/conversation.d.ts +17 -2
  75. package/dist/src/embed/conversation.d.ts.map +1 -1
  76. package/dist/src/embed/hostEventClient/contracts.d.ts +11 -1
  77. package/dist/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  78. package/dist/src/embed/liveboard.d.ts +15 -0
  79. package/dist/src/embed/liveboard.d.ts.map +1 -1
  80. package/dist/src/embed/search.d.ts +0 -7
  81. package/dist/src/embed/search.d.ts.map +1 -1
  82. package/dist/src/embed/ts-embed.d.ts +10 -0
  83. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  84. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  85. package/dist/src/index.d.ts +2 -2
  86. package/dist/src/index.d.ts.map +1 -1
  87. package/dist/src/react/all-types-export.d.ts +1 -1
  88. package/dist/src/react/all-types-export.d.ts.map +1 -1
  89. package/dist/src/types.d.ts +246 -89
  90. package/dist/src/types.d.ts.map +1 -1
  91. package/dist/src/utils/logger.d.ts.map +1 -1
  92. package/dist/src/utils/processData.d.ts +1 -1
  93. package/dist/src/utils/processData.d.ts.map +1 -1
  94. package/dist/tsembed-react.es.js +446 -119
  95. package/dist/tsembed-react.js +445 -118
  96. package/dist/tsembed.es.js +3588 -3261
  97. package/dist/tsembed.js +3586 -3259
  98. package/dist/visual-embed-sdk-react-full.d.ts +316 -103
  99. package/dist/visual-embed-sdk-react.d.ts +313 -103
  100. package/dist/visual-embed-sdk.d.ts +316 -103
  101. package/lib/package.json +1 -1
  102. package/lib/src/api-intercept.d.ts +51 -0
  103. package/lib/src/api-intercept.d.ts.map +1 -0
  104. package/lib/src/api-intercept.js +173 -0
  105. package/lib/src/api-intercept.js.map +1 -0
  106. package/lib/src/api-intercept.spec.d.ts +2 -0
  107. package/lib/src/api-intercept.spec.d.ts.map +1 -0
  108. package/lib/src/api-intercept.spec.js +669 -0
  109. package/lib/src/api-intercept.spec.js.map +1 -0
  110. package/lib/src/css-variables.d.ts +4 -0
  111. package/lib/src/css-variables.d.ts.map +1 -1
  112. package/lib/src/embed/app.d.ts +15 -5
  113. package/lib/src/embed/app.d.ts.map +1 -1
  114. package/lib/src/embed/app.js +8 -6
  115. package/lib/src/embed/app.js.map +1 -1
  116. package/lib/src/embed/app.spec.js +30 -0
  117. package/lib/src/embed/app.spec.js.map +1 -1
  118. package/lib/src/embed/conversation.d.ts +17 -2
  119. package/lib/src/embed/conversation.d.ts.map +1 -1
  120. package/lib/src/embed/conversation.js +5 -2
  121. package/lib/src/embed/conversation.js.map +1 -1
  122. package/lib/src/embed/conversation.spec.js +41 -0
  123. package/lib/src/embed/conversation.spec.js.map +1 -1
  124. package/lib/src/embed/hostEventClient/contracts.d.ts +11 -1
  125. package/lib/src/embed/hostEventClient/contracts.d.ts.map +1 -1
  126. package/lib/src/embed/hostEventClient/contracts.js +1 -0
  127. package/lib/src/embed/hostEventClient/contracts.js.map +1 -1
  128. package/lib/src/embed/liveboard.d.ts +15 -0
  129. package/lib/src/embed/liveboard.d.ts.map +1 -1
  130. package/lib/src/embed/liveboard.js +7 -2
  131. package/lib/src/embed/liveboard.js.map +1 -1
  132. package/lib/src/embed/liveboard.spec.js +33 -0
  133. package/lib/src/embed/liveboard.spec.js.map +1 -1
  134. package/lib/src/embed/search.d.ts +0 -7
  135. package/lib/src/embed/search.d.ts.map +1 -1
  136. package/lib/src/embed/search.js +1 -4
  137. package/lib/src/embed/search.js.map +1 -1
  138. package/lib/src/embed/ts-embed.d.ts +10 -0
  139. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  140. package/lib/src/embed/ts-embed.js +56 -15
  141. package/lib/src/embed/ts-embed.js.map +1 -1
  142. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  143. package/lib/src/embed/ts-embed.spec.js +412 -238
  144. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  145. package/lib/src/index.d.ts +2 -2
  146. package/lib/src/index.d.ts.map +1 -1
  147. package/lib/src/index.js +2 -2
  148. package/lib/src/index.js.map +1 -1
  149. package/lib/src/react/all-types-export.d.ts +1 -1
  150. package/lib/src/react/all-types-export.d.ts.map +1 -1
  151. package/lib/src/react/all-types-export.js +1 -1
  152. package/lib/src/react/all-types-export.js.map +1 -1
  153. package/lib/src/types.d.ts +246 -89
  154. package/lib/src/types.d.ts.map +1 -1
  155. package/lib/src/types.js +181 -69
  156. package/lib/src/types.js.map +1 -1
  157. package/lib/src/utils/logger.d.ts.map +1 -1
  158. package/lib/src/utils/logger.js +1 -2
  159. package/lib/src/utils/logger.js.map +1 -1
  160. package/lib/src/utils/processData.d.ts +1 -1
  161. package/lib/src/utils/processData.d.ts.map +1 -1
  162. package/lib/src/utils/processData.js +8 -8
  163. package/lib/src/utils/processData.js.map +1 -1
  164. package/lib/src/utils/processData.spec.js.map +1 -1
  165. package/package.json +1 -1
  166. package/src/api-intercept.spec.ts +856 -0
  167. package/src/api-intercept.ts +204 -0
  168. package/src/css-variables.ts +5 -0
  169. package/src/embed/app.spec.ts +41 -2
  170. package/src/embed/app.ts +48 -38
  171. package/src/embed/conversation.spec.ts +54 -0
  172. package/src/embed/conversation.ts +24 -3
  173. package/src/embed/hostEventClient/contracts.ts +10 -0
  174. package/src/embed/liveboard.spec.ts +41 -0
  175. package/src/embed/liveboard.ts +25 -2
  176. package/src/embed/search.ts +1 -14
  177. package/src/embed/ts-embed.spec.ts +498 -250
  178. package/src/embed/ts-embed.ts +80 -32
  179. package/src/index.ts +2 -0
  180. package/src/react/all-types-export.ts +1 -0
  181. package/src/types.ts +328 -165
  182. package/src/utils/logger.ts +1 -2
  183. package/src/utils/processData.spec.ts +0 -1
  184. package/src/utils/processData.ts +10 -11
@@ -0,0 +1,204 @@
1
+ import { getThoughtSpotHost } from "./config";
2
+ import { getEmbedConfig } from "./embed/embedConfig";
3
+ import { InterceptedApiType, BaseViewConfig, ApiInterceptFlags, EmbedEvent } from "./types";
4
+ import { embedEventStatus } from "./utils";
5
+ import { logger } from "./utils/logger";
6
+
7
+ const DefaultInterceptUrlsMap: Record<Exclude<InterceptedApiType, InterceptedApiType.ALL>, string[]> = {
8
+ [InterceptedApiType.AnswerData]: [
9
+ '/prism/?op=GetChartWithData',
10
+ '/prism/?op=GetTableWithHeadlineData',
11
+ '/prism/?op=GetTableWithData',
12
+ ] as string[],
13
+ [InterceptedApiType.LiveboardData]: [
14
+ '/prism/?op=LoadContextBook'
15
+ ] as string[],
16
+ };
17
+
18
+ const formatInterceptUrl = (url: string) => {
19
+ const host = getThoughtSpotHost(getEmbedConfig());
20
+ if (url.startsWith('/')) return `${host}${url}`;
21
+ return url;
22
+ }
23
+
24
+ interface LegacyInterceptFlags {
25
+ isOnBeforeGetVizDataInterceptEnabled: boolean;
26
+ }
27
+ /**
28
+ * Converts user passed url values to proper urls
29
+ * [ANSER_DATA] => ['https://host/pris/op?=op']
30
+ * @param interceptUrls
31
+ * @returns
32
+ */
33
+ const processInterceptUrls = (interceptUrls: (string | InterceptedApiType)[]) => {
34
+ let processedUrls = [...interceptUrls];
35
+ Object.entries(DefaultInterceptUrlsMap).forEach(([apiType, apiTypeUrls]) => {
36
+ if (!processedUrls.includes(apiType)) return;
37
+ processedUrls = processedUrls.filter(url => url !== apiType);
38
+ processedUrls = [...processedUrls, ...apiTypeUrls];
39
+ })
40
+ return processedUrls.map(url => formatInterceptUrl(url));
41
+ }
42
+
43
+ /**
44
+ * Returns the data to be sent to embed to setup intercepts
45
+ * the urls to intercept, timeout etc
46
+ * @param viewConfig
47
+ * @returns
48
+ */
49
+ export const getInterceptInitData = (viewConfig: BaseViewConfig): Required<Omit<ApiInterceptFlags, 'isOnBeforeGetVizDataInterceptEnabled'>> => {
50
+ const combinedUrls = [...(viewConfig.interceptUrls || [])];
51
+
52
+ if ((viewConfig as LegacyInterceptFlags).isOnBeforeGetVizDataInterceptEnabled) {
53
+ combinedUrls.push(InterceptedApiType.AnswerData);
54
+ }
55
+
56
+ const shouldInterceptAll = combinedUrls.includes(InterceptedApiType.ALL);
57
+ const interceptUrls = shouldInterceptAll ? [InterceptedApiType.ALL] : processInterceptUrls(combinedUrls);
58
+
59
+ const interceptTimeout = viewConfig.interceptTimeout;
60
+
61
+ return {
62
+ interceptUrls,
63
+ interceptTimeout,
64
+ };
65
+ }
66
+
67
+ const parseJson = (jsonString: string): [any, Error | null] => {
68
+ try {
69
+ const json = JSON.parse(jsonString);
70
+ return [json, null];
71
+ } catch (error) {
72
+ return [null, error];
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Parse the api intercept data and return the parsed data and error if any
78
+ * Embed returns the input and init from the fetch call
79
+ */
80
+ const parseInterceptData = (eventDataString: any) => {
81
+
82
+ try {
83
+ const [parsedData, error] = parseJson(eventDataString);
84
+ if (error) {
85
+ return [null, error];
86
+ }
87
+
88
+ const { input, init } = parsedData;
89
+
90
+ const [parsedBody, bodyParseError] = parseJson(init.body);
91
+ if (!bodyParseError) {
92
+ init.body = parsedBody;
93
+ }
94
+
95
+ const parsedInit = { input, init };
96
+ return [parsedInit, null];
97
+ } catch (error) {
98
+ return [null, error];
99
+ }
100
+ }
101
+
102
+ const getUrlType = (url: string) => {
103
+ for (const [apiType, apiTypeUrls] of Object.entries(DefaultInterceptUrlsMap)) {
104
+ if (apiTypeUrls.includes(url)) return apiType as InterceptedApiType;
105
+ }
106
+ // TODO: have a unknown type maybe ??
107
+ return InterceptedApiType.ALL;
108
+ }
109
+
110
+ /**
111
+ * Handle Api intercept event and simulate legacy onBeforeGetVizDataIntercept event
112
+ *
113
+ * embed sends -> ApiIntercept -> we send
114
+ * ApiIntercept
115
+ * OnBeforeGetVizDataIntercept (if url is part of DefaultUrlMap.AnswerData)
116
+ *
117
+ * @param params
118
+ * @returns
119
+ */
120
+ export const handleInterceptEvent = async (params: {
121
+ eventData: any,
122
+ executeEvent: (eventType: EmbedEvent, data: any) => void,
123
+ viewConfig: BaseViewConfig,
124
+ getUnsavedAnswerTml: (props: { sessionId?: string, vizId?: string }) => Promise<{ tml: string }>
125
+ }) => {
126
+
127
+ const { eventData, executeEvent, viewConfig, getUnsavedAnswerTml } = params;
128
+
129
+ const [interceptData, bodyParseError] = parseInterceptData(eventData.data);
130
+
131
+ if (bodyParseError) {
132
+ executeEvent(EmbedEvent.Error, {
133
+ error: 'Error parsing api intercept body',
134
+ });
135
+ logger.error('Error parsing request body', bodyParseError);
136
+ return;
137
+ }
138
+
139
+
140
+ const { input: requestUrl, init } = interceptData;
141
+
142
+ const sessionId = init?.body?.variables?.session?.sessionId;
143
+ const vizId = init?.body?.variables?.contextBookId;
144
+
145
+ const answerDataUrls = DefaultInterceptUrlsMap[InterceptedApiType.AnswerData];
146
+ const legacyInterceptEnabled = viewConfig.isOnBeforeGetVizDataInterceptEnabled;
147
+ const isAnswerDataUrl = answerDataUrls.includes(requestUrl);
148
+ const sendLegacyIntercept = isAnswerDataUrl && legacyInterceptEnabled;
149
+ if (sendLegacyIntercept) {
150
+ const answerTml = await getUnsavedAnswerTml({ sessionId, vizId });
151
+ // Build the legacy payload for backwards compatibility
152
+ const legacyPayload = {
153
+ data: {
154
+ data: answerTml,
155
+ status: embedEventStatus.END,
156
+ type: EmbedEvent.OnBeforeGetVizDataIntercept
157
+ }
158
+ }
159
+ executeEvent(EmbedEvent.OnBeforeGetVizDataIntercept, legacyPayload);
160
+ }
161
+
162
+ const urlType = getUrlType(requestUrl);
163
+ executeEvent(EmbedEvent.ApiIntercept, { ...interceptData, urlType });
164
+ }
165
+
166
+ /**
167
+ * Support both the legacy and new format of the api intercept response
168
+ * @param payload
169
+ * @returns
170
+ */
171
+ export const processApiInterceptResponse = (payload: any) => {
172
+ const isLegacyFormat = payload?.data?.error;
173
+
174
+ if (isLegacyFormat) {
175
+ return processLegacyInterceptResponse(payload);
176
+ }
177
+
178
+ return payload;
179
+ }
180
+
181
+ export const processLegacyInterceptResponse = (payload: any) => {
182
+
183
+ const errorText = payload?.data?.error?.errorText;
184
+ const errorDescription = payload?.data?.error?.errorDescription;
185
+
186
+ const payloadToSend = {
187
+ execute: payload?.data?.execute,
188
+ response: {
189
+ body: {
190
+ errors: [
191
+ {
192
+ title: errorText,
193
+ description: errorDescription,
194
+ isUserError: true,
195
+ },
196
+ ],
197
+ data: {},
198
+ },
199
+ },
200
+ };
201
+
202
+
203
+ return { data: payloadToSend };
204
+ }
@@ -847,4 +847,9 @@ export interface CustomCssVariables {
847
847
  * Background color of the summary header in the CCA modal.
848
848
  */
849
849
  '--ts-var-cca-modal-summary-header-background'?: string;
850
+
851
+ /**
852
+ * Width of the Spotter chat window.
853
+ */
854
+ '--ts-var-spotter-chat-width'?: string;
850
855
  }
@@ -371,7 +371,7 @@ describe('App embed tests', () => {
371
371
  );
372
372
  });
373
373
  });
374
-
374
+
375
375
  test('should set isLinkParametersEnabled to false in url', async () => {
376
376
  const appEmbed = new AppEmbed(getRootEl(), {
377
377
  ...defaultViewConfig,
@@ -400,6 +400,34 @@ describe('App embed tests', () => {
400
400
  });
401
401
  });
402
402
 
403
+ test('should set updatedSpotterChatPrompt to true in url', async () => {
404
+ const appEmbed = new AppEmbed(getRootEl(), {
405
+ ...defaultViewConfig,
406
+ updatedSpotterChatPrompt: true,
407
+ } as AppViewConfig);
408
+ appEmbed.render();
409
+ await executeAfterWait(() => {
410
+ expectUrlMatchesWithParams(
411
+ getIFrameSrc(),
412
+ `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&updatedSpotterChatPrompt=true${defaultParamsPost}#/home`,
413
+ );
414
+ });
415
+ });
416
+
417
+ test('should set updatedSpotterChatPrompt to false in url', async () => {
418
+ const appEmbed = new AppEmbed(getRootEl(), {
419
+ ...defaultViewConfig,
420
+ updatedSpotterChatPrompt: false,
421
+ } as AppViewConfig);
422
+ appEmbed.render();
423
+ await executeAfterWait(() => {
424
+ expectUrlMatchesWithParams(
425
+ getIFrameSrc(),
426
+ `http://${thoughtSpotHost}/?embedApp=true&profileAndHelpInNavBarHidden=false&updatedSpotterChatPrompt=false${defaultParamsPost}#/home`,
427
+ );
428
+ });
429
+ });
430
+
403
431
  test('should set liveboardXLSXCSVDownload to false in url', async () => {
404
432
  const appEmbed = new AppEmbed(getRootEl(), {
405
433
  ...defaultViewConfig,
@@ -414,6 +442,17 @@ describe('App embed tests', () => {
414
442
  });
415
443
  });
416
444
 
445
+ test('should not set liveboardXLSXCSVDownload in url when undefined', async () => {
446
+ const appEmbed = new AppEmbed(getRootEl(), {
447
+ ...defaultViewConfig,
448
+ } as AppViewConfig);
449
+ appEmbed.render();
450
+ await executeAfterWait(() => {
451
+ const iframeSrc = getIFrameSrc();
452
+ expect(iframeSrc).not.toContain('isLiveboardXLSXCSVDownloadEnabled');
453
+ });
454
+ });
455
+
417
456
  test('should set isCentralizedLiveboardFilterUXEnabled to true in url', async () => {
418
457
  const appEmbed = new AppEmbed(getRootEl(), {
419
458
  ...defaultViewConfig,
@@ -473,7 +512,7 @@ describe('App embed tests', () => {
473
512
  );
474
513
  });
475
514
  });
476
-
515
+
477
516
  test('Should add the hideTagFilterChips false to the iframe src', async () => {
478
517
  const appEmbed = new AppEmbed(getRootEl(), {
479
518
  ...defaultViewConfig,
package/src/embed/app.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import { logger } from '../utils/logger';
12
- import { calculateVisibleElementData, getQueryParamString } from '../utils';
12
+ import { calculateVisibleElementData, getQueryParamString, isUndefined } from '../utils';
13
13
  import {
14
14
  Param,
15
15
  DOMSelector,
@@ -158,7 +158,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
158
158
  * If true, the top navigation bar within the ThoughtSpot app
159
159
  * is displayed. By default, the navigation bar is hidden.
160
160
  * This flag also controls the homepage left navigation bar.
161
- *
161
+ *
162
162
  * Supported embed types: `AppEmbed`
163
163
  * @default true
164
164
  * @version SDK: 1.2.0 | ThoughtSpot: 8.4.0.cl
@@ -180,7 +180,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
180
180
  * **Note**: This option does not apply to the classic homepage.
181
181
  * To access the updated modular homepage, set
182
182
  * `modularHomeExperience` to `true` (available as Early Access feature in 9.12.5.cl).
183
- *
183
+ *
184
184
  * Supported embed types: `AppEmbed`
185
185
  * @default false
186
186
  * @version SDK: 1.28.0 | ThoughtSpot: 9.12.5.cl
@@ -196,7 +196,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
196
196
  /**
197
197
  * Control the visibility of the help (?) and profile buttons on the
198
198
  * Global nav-bar. By default, these buttons are visible on the nav-bar.
199
- *
199
+ *
200
200
  * Supported embed types: `AppEmbed`
201
201
  * @default false
202
202
  * @version SDK: 1.2.0 | ThoughtSpot: 8.4.0.cl
@@ -214,7 +214,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
214
214
  * @default true
215
215
  * Whether the help menu in the top nav bar should be served
216
216
  * from Pendo or ThoughtSpot's internal help items.
217
- *
217
+ *
218
218
  * Supported embed types: `AppEmbed`
219
219
  * @example
220
220
  * ```js
@@ -371,7 +371,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
371
371
  * Hide tag filter chips that appear when content is filtered by tags.
372
372
  * When enabled, this automatically:
373
373
  * - Hides tag filter indicators/chips from the UI
374
- *
374
+ *
375
375
  * This provides a clean interface without tag-related UI elements.
376
376
  *
377
377
  * Supported embed types: `AppEmbed`
@@ -389,7 +389,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
389
389
  hideTagFilterChips?: boolean;
390
390
  /**
391
391
  * The array of GUIDs to be hidden
392
- *
392
+ *
393
393
  * Supported embed types: `AppEmbed`
394
394
  * @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1-sw
395
395
  * @example
@@ -407,7 +407,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
407
407
  /**
408
408
  * Render liveboards using the new v2 rendering mode
409
409
  * This is a transient flag which is primarily meant for internal use
410
- *
410
+ *
411
411
  * Supported embed types: `AppEmbed`
412
412
  * @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1-sw
413
413
  * @hidden
@@ -415,7 +415,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
415
415
  liveboardV2?: boolean;
416
416
  /**
417
417
  * If set to true, the Search Assist feature is enabled.
418
- *
418
+ *
419
419
  * Supported embed types: `AppEmbed`
420
420
  * @default true
421
421
  * @version SDK: 1.13.0 | ThoughtSpot: 8.5.0.cl, 8.8.1-sw
@@ -453,7 +453,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
453
453
  fullHeight?: boolean;
454
454
  /**
455
455
  * Flag to control new Modular Home experience.
456
- *
456
+ *
457
457
  * Supported embed types: `AppEmbed`
458
458
  * @default false
459
459
  * @version SDK: 1.28.0 | ThoughtSpot: 9.12.5.cl
@@ -498,10 +498,10 @@ export interface AppViewConfig extends AllEmbedViewConfig {
498
498
  * - EXPAND_ALL: Expand all the accordion initially in data panel v2.
499
499
  * - COLLAPSE_ALL: Collapse all the accordions initially in data panel v2.
500
500
  * - EXPAND_FIRST: Expand the first accordion and collapse the rest.
501
- *
501
+ *
502
502
  * Supported embed types: `AppEmbed`
503
503
  * @version SDK: 1.32.0 | ThoughtSpot: 10.0.0.cl
504
- * @default DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL
504
+ * @default DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL
505
505
  * @example
506
506
  * ```js
507
507
  * const embed = new AppEmbed('#embed', {
@@ -512,21 +512,16 @@ export interface AppViewConfig extends AllEmbedViewConfig {
512
512
  * ```
513
513
  */
514
514
  dataPanelCustomGroupsAccordionInitialState?: DataPanelCustomColumnGroupsAccordionState;
515
- /**
516
- * Flag that allows using `EmbedEvent.OnBeforeGetVizDataIntercept`.
517
- * @version SDK : 1.29.0 | ThoughtSpot: 10.1.0.cl
518
- */
519
- isOnBeforeGetVizDataInterceptEnabled?: boolean;
520
515
  /**
521
516
  * Flag to use home page search bar mode
522
- *
517
+ *
523
518
  * Supported embed types: `AppEmbed`
524
519
  * @version SDK : 1.33.0 | ThoughtSpot: 10.3.0.cl
525
520
  */
526
521
  homePageSearchBarMode?: HomePageSearchBarMode;
527
522
  /**
528
523
  * This flag is used to enable unified search experience for full app embed.
529
- *
524
+ *
530
525
  * Supported embed types: `AppEmbed`
531
526
  * @version SDK: 1.34.0 | ThoughtSpot:10.5.0.cl
532
527
  * @default true
@@ -542,7 +537,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
542
537
 
543
538
  /**
544
539
  * This flag is used to enable/disable the styling and grouping in a Liveboard
545
- *
540
+ *
546
541
  * Supported embed types: `AppEmbed`, `LiveboardEmbed`
547
542
  * @type {boolean}
548
543
  * @version SDK: 1.40.0 | ThoughtSpot: 10.11.0.cl
@@ -559,7 +554,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
559
554
 
560
555
  /**
561
556
  * This flag is used to enable/disable the png embedding of liveboard in scheduled mails
562
- *
557
+ *
563
558
  * Supported embed types: `AppEmbed`, `LiveboardEmbed`
564
559
  * @type {boolean}
565
560
  * @version SDK: 1.42.0 | ThoughtSpot: 10.14.0.cl
@@ -576,7 +571,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
576
571
 
577
572
  /**
578
573
  * This flag is used to enable the full height lazy load data.
579
- *
574
+ *
580
575
  * @example
581
576
  * ```js
582
577
  * const embed = new AppEmbed('#embed-container', {
@@ -585,7 +580,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
585
580
  * lazyLoadingForFullHeight: true,
586
581
  * })
587
582
  * ```
588
- *
583
+ *
589
584
  * @type {boolean}
590
585
  * @default false
591
586
  * @version SDK: 1.40.0 | ThoughtSpot:10.12.0.cl
@@ -594,13 +589,13 @@ export interface AppViewConfig extends AllEmbedViewConfig {
594
589
 
595
590
  /**
596
591
  * The margin to be used for lazy loading.
597
- *
592
+ *
598
593
  * For example, if the margin is set to '10px',
599
594
  * the visualization will be loaded 10px before the its top edge is visible in the
600
595
  * viewport.
601
- *
596
+ *
602
597
  * The format is similar to CSS margin.
603
- *
598
+ *
604
599
  * @example
605
600
  * ```js
606
601
  * const embed = new AppEmbed('#embed-container', {
@@ -615,6 +610,22 @@ export interface AppViewConfig extends AllEmbedViewConfig {
615
610
  * @version SDK: 1.40.0 | ThoughtSpot:10.12.0.cl
616
611
  */
617
612
  lazyLoadingMargin?: string;
613
+
614
+ /**
615
+ * updatedSpotterChatPrompt : Controls the updated spotter chat prompt.
616
+ *
617
+ * Supported embed types: `AppEmbed`
618
+ * @default false
619
+ * @example
620
+ * ```js
621
+ * const embed = new AppEmbed('#tsEmbed', {
622
+ * ... //other embed view config
623
+ * updatedSpotterChatPrompt : true,
624
+ * })
625
+ * ```
626
+ * @version SDK: 1.45.0 | ThoughtSpot: 26.2.0.cl
627
+ */
628
+ updatedSpotterChatPrompt?: boolean;
618
629
  }
619
630
 
620
631
  /**
@@ -668,8 +679,6 @@ export class AppEmbed extends V1Embed {
668
679
  collapseSearchBarInitially = false,
669
680
  enable2ColumnLayout,
670
681
  enableCustomColumnGroups = false,
671
- isOnBeforeGetVizDataInterceptEnabled = false,
672
-
673
682
  dataPanelCustomGroupsAccordionInitialState = DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL,
674
683
  collapseSearchBar = true,
675
684
  isLiveboardCompactHeaderEnabled = false,
@@ -682,11 +691,12 @@ export class AppEmbed extends V1Embed {
682
691
  enablePendoHelp = true,
683
692
  discoveryExperience,
684
693
  coverAndFilterOptionInPDF = false,
685
- liveboardXLSXCSVDownload = false,
694
+ liveboardXLSXCSVDownload,
686
695
  isLiveboardStylingAndGroupingEnabled,
687
696
  isPNGInScheduledEmailsEnabled = false,
688
697
  isCentralizedLiveboardFilterUXEnabled = false,
689
698
  isLinkParametersEnabled,
699
+ updatedSpotterChatPrompt,
690
700
  } = this.viewConfig;
691
701
 
692
702
  let params: any = {};
@@ -706,10 +716,13 @@ export class AppEmbed extends V1Embed {
706
716
  params[Param.HideIrrelevantFiltersInTab] = hideIrrelevantChipsInLiveboardTabs;
707
717
  params[Param.IsUnifiedSearchExperienceEnabled] = isUnifiedSearchExperienceEnabled;
708
718
  params[Param.CoverAndFilterOptionInPDF] = !!coverAndFilterOptionInPDF;
709
- params[Param.LiveboardXLSXCSVDownload] = !!liveboardXLSXCSVDownload;
710
719
 
711
720
  params = this.getBaseQueryParams(params);
712
721
 
722
+ if (!isUndefined(updatedSpotterChatPrompt)) {
723
+ params[Param.UpdatedSpotterChatPrompt] = !!updatedSpotterChatPrompt;
724
+ }
725
+
713
726
  if (hideObjectSearch) {
714
727
  params[Param.HideObjectSearch] = !!hideObjectSearch;
715
728
  }
@@ -752,13 +765,6 @@ export class AppEmbed extends V1Embed {
752
765
  params[Param.enableAskSage] = enableAskSage;
753
766
  }
754
767
 
755
- if (isOnBeforeGetVizDataInterceptEnabled) {
756
-
757
- params[
758
- Param.IsOnBeforeGetVizDataInterceptEnabled
759
- ] = isOnBeforeGetVizDataInterceptEnabled;
760
- }
761
-
762
768
  if (homePageSearchBarMode) {
763
769
  params[Param.HomePageSearchBarMode] = homePageSearchBarMode;
764
770
  }
@@ -771,10 +777,14 @@ export class AppEmbed extends V1Embed {
771
777
  params[Param.IsLiveboardStylingAndGroupingEnabled] = isLiveboardStylingAndGroupingEnabled;
772
778
  }
773
779
 
780
+ if (liveboardXLSXCSVDownload !== undefined) {
781
+ params[Param.LiveboardXLSXCSVDownload] = !!liveboardXLSXCSVDownload;
782
+ }
783
+
774
784
  if (isPNGInScheduledEmailsEnabled !== undefined) {
775
785
  params[Param.isPNGInScheduledEmailsEnabled] = isPNGInScheduledEmailsEnabled;
776
786
  }
777
-
787
+
778
788
  if (hideTagFilterChips !== undefined) {
779
789
  params[Param.HideTagFilterChips] = hideTagFilterChips;
780
790
  }
@@ -316,6 +316,28 @@ describe('ConversationEmbed', () => {
316
316
  );
317
317
  });
318
318
 
319
+ it('should render the conversation embed with all boolean flags set', async () => {
320
+ const viewConfig: SpotterEmbedViewConfig = {
321
+ worksheetId: 'worksheetId',
322
+ searchOptions: {
323
+ searchQuery: 'searchQuery',
324
+ },
325
+ disableSourceSelection: true,
326
+ hideSourceSelection: true,
327
+ dataPanelV2: true,
328
+ showSpotterLimitations: true,
329
+ hideSampleQuestions: true,
330
+ enablePastConversationsSidebar: true,
331
+ };
332
+
333
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
334
+ await conversationEmbed.render();
335
+ expectUrlMatchesWithParams(
336
+ getIFrameSrc(),
337
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&disableSourceSelection=true&hideSourceSelection=true&enableDataPanelV2=true&showSpotterLimitations=true&hideSampleQuestions=true&enablePastConversationsSidebar=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
338
+ );
339
+ });
340
+
319
341
  it('should ensure deprecated ConversationEmbed class maintains same functionality as SpotterEmbed', async () => {
320
342
  const viewConfig: SpotterEmbedViewConfig = {
321
343
  worksheetId: 'worksheetId',
@@ -340,4 +362,36 @@ describe('ConversationEmbed', () => {
340
362
  `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&param1=Date%20Range&paramVal1=30#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
341
363
  );
342
364
  });
365
+
366
+ it('should render the conversation embed with updated spotter chat prompt', async () => {
367
+ const viewConfig: SpotterEmbedViewConfig = {
368
+ worksheetId: 'worksheetId',
369
+ searchOptions: {
370
+ searchQuery: 'searchQuery',
371
+ },
372
+ updatedSpotterChatPrompt: true,
373
+ };
374
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
375
+ await conversationEmbed.render();
376
+ expectUrlMatchesWithParams(
377
+ getIFrameSrc(),
378
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&updatedSpotterChatPrompt=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
379
+ );
380
+ });
381
+
382
+ it('should render the conversation embed with updated spotter chat prompt disabled', async () => {
383
+ const viewConfig: SpotterEmbedViewConfig = {
384
+ worksheetId: 'worksheetId',
385
+ searchOptions: {
386
+ searchQuery: 'searchQuery',
387
+ },
388
+ updatedSpotterChatPrompt: false,
389
+ };
390
+ const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
391
+ await conversationEmbed.render();
392
+ expectUrlMatchesWithParams(
393
+ getIFrameSrc(),
394
+ `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&updatedSpotterChatPrompt=false#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
395
+ );
396
+ });
343
397
  });
@@ -62,7 +62,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
62
62
  *
63
63
  * Supported embed types: `SageEmbed`, `AppEmbed`, `SearchBarEmbed`, `LiveboardEmbed`, `SearchEmbed`
64
64
  * @default true
65
- * @version SDK: 1.43.0 | ThoughtSpot Cloud: 10.14.0.cl
65
+ * @version SDK: 1.41.1 | ThoughtSpot Cloud: 10.14.0.cl
66
66
  * @example
67
67
  * ```js
68
68
  * // Replace <EmbedComponent> with embed component name. For example, SageEmbed, AppEmbed, or SearchBarEmbed
@@ -177,9 +177,25 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
177
177
  * enablePastConversationsSidebar : true,
178
178
  * })
179
179
  * ```
180
- * @version SDK: 1.43.0 | ThoughtSpot: 10.14.0.cl
180
+ * @version SDK: 1.45.0 | ThoughtSpot: 26.2.0.cl
181
181
  */
182
182
  enablePastConversationsSidebar?: boolean;
183
+
184
+ /**
185
+ * updatedSpotterChatPrompt : Controls the updated spotter chat prompt.
186
+ *
187
+ * Supported embed types: `SpotterEmbed`
188
+ * @default false
189
+ * @example
190
+ * ```js
191
+ * const embed = new SpotterEmbed('#tsEmbed', {
192
+ * ... //other embed view config
193
+ * updatedSpotterChatPrompt : true,
194
+ * })
195
+ * ```
196
+ * @version SDK: 1.45.0 | ThoughtSpot: 26.2.0.cl
197
+ */
198
+ updatedSpotterChatPrompt?: boolean;
183
199
  }
184
200
 
185
201
  /**
@@ -226,6 +242,7 @@ export class SpotterEmbed extends TsEmbed {
226
242
  excludeRuntimeFiltersfromURL,
227
243
  runtimeParameters,
228
244
  excludeRuntimeParametersfromURL,
245
+ updatedSpotterChatPrompt,
229
246
  } = this.viewConfig;
230
247
 
231
248
  if (!worksheetId) {
@@ -252,6 +269,10 @@ export class SpotterEmbed extends TsEmbed {
252
269
  queryParams[Param.HideSampleQuestions] = !!hideSampleQuestions;
253
270
  }
254
271
 
272
+ if (!isUndefined(updatedSpotterChatPrompt)) {
273
+ queryParams[Param.UpdatedSpotterChatPrompt] = !!updatedSpotterChatPrompt;
274
+ }
275
+
255
276
  return queryParams;
256
277
  }
257
278
 
@@ -263,7 +284,7 @@ export class SpotterEmbed extends TsEmbed {
263
284
  excludeRuntimeFiltersfromURL,
264
285
  runtimeParameters,
265
286
  excludeRuntimeParametersfromURL,
266
- enablePastConversationsSidebar
287
+ enablePastConversationsSidebar,
267
288
  } = this.viewConfig;
268
289
  const path = 'insights/conv-assist';
269
290
  const queryParams = this.getEmbedParamsObject();