@thoughtspot/visual-embed-sdk 1.37.1 → 1.38.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 (99) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/embed/bodyless-conversation.d.ts +44 -9
  3. package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
  4. package/cjs/src/embed/bodyless-conversation.js +35 -5
  5. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  6. package/cjs/src/embed/bodyless-conversation.spec.js +290 -5
  7. package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
  8. package/cjs/src/embed/conversation.d.ts +40 -11
  9. package/cjs/src/embed/conversation.d.ts.map +1 -1
  10. package/cjs/src/embed/conversation.js +29 -4
  11. package/cjs/src/embed/conversation.js.map +1 -1
  12. package/cjs/src/embed/conversation.spec.js +7 -7
  13. package/cjs/src/embed/conversation.spec.js.map +1 -1
  14. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  15. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  16. package/cjs/src/index.d.ts +4 -4
  17. package/cjs/src/index.d.ts.map +1 -1
  18. package/cjs/src/index.js +5 -1
  19. package/cjs/src/index.js.map +1 -1
  20. package/cjs/src/react/all-types-export.d.ts +1 -1
  21. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  22. package/cjs/src/react/all-types-export.js +3 -1
  23. package/cjs/src/react/all-types-export.js.map +1 -1
  24. package/cjs/src/react/index.d.ts +53 -5
  25. package/cjs/src/react/index.d.ts.map +1 -1
  26. package/cjs/src/react/index.js +73 -4
  27. package/cjs/src/react/index.js.map +1 -1
  28. package/cjs/src/react/index.spec.js +94 -0
  29. package/cjs/src/react/index.spec.js.map +1 -1
  30. package/cjs/src/types.d.ts +2 -1
  31. package/cjs/src/types.d.ts.map +1 -1
  32. package/cjs/src/types.js +1 -0
  33. package/cjs/src/types.js.map +1 -1
  34. package/dist/{index-m9UtENc9.js → index-BIcnpmMY.js} +1 -1
  35. package/dist/src/embed/bodyless-conversation.d.ts +44 -9
  36. package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
  37. package/dist/src/embed/conversation.d.ts +40 -11
  38. package/dist/src/embed/conversation.d.ts.map +1 -1
  39. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  40. package/dist/src/index.d.ts +4 -4
  41. package/dist/src/index.d.ts.map +1 -1
  42. package/dist/src/react/all-types-export.d.ts +1 -1
  43. package/dist/src/react/all-types-export.d.ts.map +1 -1
  44. package/dist/src/react/index.d.ts +53 -5
  45. package/dist/src/react/index.d.ts.map +1 -1
  46. package/dist/src/types.d.ts +2 -1
  47. package/dist/src/types.d.ts.map +1 -1
  48. package/dist/tsembed-react.es.js +562 -10
  49. package/dist/tsembed-react.js +562 -8
  50. package/dist/tsembed.es.js +65 -11
  51. package/dist/tsembed.js +71 -15
  52. package/dist/visual-embed-sdk-react-full.d.ts +184 -72
  53. package/dist/visual-embed-sdk-react.d.ts +184 -72
  54. package/dist/visual-embed-sdk.d.ts +87 -22
  55. package/lib/package.json +1 -1
  56. package/lib/src/embed/bodyless-conversation.d.ts +44 -9
  57. package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
  58. package/lib/src/embed/bodyless-conversation.js +33 -4
  59. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  60. package/lib/src/embed/bodyless-conversation.spec.js +292 -7
  61. package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
  62. package/lib/src/embed/conversation.d.ts +40 -11
  63. package/lib/src/embed/conversation.d.ts.map +1 -1
  64. package/lib/src/embed/conversation.js +27 -3
  65. package/lib/src/embed/conversation.js.map +1 -1
  66. package/lib/src/embed/conversation.spec.js +8 -8
  67. package/lib/src/embed/conversation.spec.js.map +1 -1
  68. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  69. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  70. package/lib/src/index.d.ts +4 -4
  71. package/lib/src/index.d.ts.map +1 -1
  72. package/lib/src/index.js +4 -4
  73. package/lib/src/index.js.map +1 -1
  74. package/lib/src/react/all-types-export.d.ts +1 -1
  75. package/lib/src/react/all-types-export.d.ts.map +1 -1
  76. package/lib/src/react/all-types-export.js +1 -1
  77. package/lib/src/react/all-types-export.js.map +1 -1
  78. package/lib/src/react/index.d.ts +53 -5
  79. package/lib/src/react/index.d.ts.map +1 -1
  80. package/lib/src/react/index.js +73 -4
  81. package/lib/src/react/index.js.map +1 -1
  82. package/lib/src/react/index.spec.js +96 -2
  83. package/lib/src/react/index.spec.js.map +1 -1
  84. package/lib/src/types.d.ts +2 -1
  85. package/lib/src/types.d.ts.map +1 -1
  86. package/lib/src/types.js +1 -0
  87. package/lib/src/types.js.map +1 -1
  88. package/lib/src/visual-embed-sdk.d.ts +90 -25
  89. package/package.json +1 -1
  90. package/src/embed/bodyless-conversation.spec.ts +314 -7
  91. package/src/embed/bodyless-conversation.ts +53 -8
  92. package/src/embed/conversation.spec.ts +16 -16
  93. package/src/embed/conversation.ts +44 -11
  94. package/src/embed/ts-embed.spec.ts +0 -2
  95. package/src/index.ts +16 -5
  96. package/src/react/all-types-export.ts +2 -0
  97. package/src/react/index.spec.tsx +157 -1
  98. package/src/react/index.tsx +98 -11
  99. package/src/types.ts +1 -0
@@ -15,10 +15,10 @@ export interface SearchOptions {
15
15
  }
16
16
 
17
17
  /**
18
- * The configuration for the embedded conversationEmbed options.
18
+ * The configuration for the embedded spotterEmbed options.
19
19
  * @group Embed components
20
20
  */
21
- export interface ConversationViewConfig extends ViewConfig {
21
+ export interface SpotterEmbedViewConfig extends ViewConfig {
22
22
  /**
23
23
  * The ID of the worksheet to use for the conversation.
24
24
  */
@@ -32,7 +32,7 @@ export interface ConversationViewConfig extends ViewConfig {
32
32
  * but still display the selected data source.
33
33
  * @example
34
34
  * ```js
35
- * const embed = new ConversationEmbed('#tsEmbed', {
35
+ * const embed = new SpotterEmbed('#tsEmbed', {
36
36
  * ... // other options
37
37
  * disableSourceSelection : true,
38
38
  * })
@@ -44,7 +44,7 @@ export interface ConversationViewConfig extends ViewConfig {
44
44
  * hideSourceSelection : Hide data source selection
45
45
  * @example
46
46
  * ```js
47
- * const embed = new ConversationEmbed('#tsEmbed', {
47
+ * const embed = new SpotterEmbed('#tsEmbed', {
48
48
  * ... // other options
49
49
  * hideSourceSelection : true,
50
50
  * })
@@ -71,7 +71,7 @@ export interface ConversationViewConfig extends ViewConfig {
71
71
  * default is false.
72
72
  * @example
73
73
  * ```js
74
- * const embed = new ConversationEmbed('#tsEmbed', {
74
+ * const embed = new SpotterEmbed('#tsEmbed', {
75
75
  * ... // other options
76
76
  * showSpotterLimitations : true,
77
77
  * })
@@ -84,7 +84,7 @@ export interface ConversationViewConfig extends ViewConfig {
84
84
  * the initial screen of the conversation.
85
85
  * @example
86
86
  * ```js
87
- * const embed = new ConversationEmbed('#tsEmbed', {
87
+ * const embed = new SpotterEmbed('#tsEmbed', {
88
88
  * ... // other options
89
89
  * hideSampleQuestions : true,
90
90
  * })
@@ -94,12 +94,21 @@ export interface ConversationViewConfig extends ViewConfig {
94
94
  hideSampleQuestions?: boolean;
95
95
  }
96
96
 
97
+ /**
98
+ * The configuration for the embedded spotterEmbed options.
99
+ * @deprecated from SDK: 1.38.0 | ThoughtSpot: 10.10.0.cl
100
+ * Use {@link SpotterEmbedViewConfig} instead
101
+ * @group Embed components
102
+ */
103
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
104
+ export interface ConversationViewConfig extends SpotterEmbedViewConfig {}
105
+
97
106
  /**
98
107
  * Embed ThoughtSpot AI Conversation.
99
108
  * @group Embed components
100
109
  * @example
101
110
  * ```js
102
- * const conversation = new ConversationEmbed('#tsEmbed', {
111
+ * const conversation = new SpotterEmbed('#tsEmbed', {
103
112
  * worksheetId: 'worksheetId',
104
113
  * searchOptions: {
105
114
  * searchQuery: 'searchQuery',
@@ -107,10 +116,10 @@ export interface ConversationViewConfig extends ViewConfig {
107
116
  * });
108
117
  * conversation.render();
109
118
  * ```
110
- * @version SDK: 1.33.1 | ThoughtSpot: 10.5.0.cl
119
+ * @version SDK: 1.37.0 | ThoughtSpot: 10.9.0.cl
111
120
  */
112
- export class ConversationEmbed extends TsEmbed {
113
- constructor(container: HTMLElement, protected viewConfig: ConversationViewConfig) {
121
+ export class SpotterEmbed extends TsEmbed {
122
+ constructor(container: HTMLElement, protected viewConfig: SpotterEmbedViewConfig) {
114
123
  viewConfig.embedComponentType = 'conversation';
115
124
  super(container, viewConfig);
116
125
  }
@@ -163,7 +172,7 @@ export class ConversationEmbed extends TsEmbed {
163
172
  return `${this.getEmbedBasePath(query)}/embed/${path}${tsPostHashParams}`;
164
173
  }
165
174
 
166
- public async render(): Promise<ConversationEmbed> {
175
+ public async render(): Promise<SpotterEmbed> {
167
176
  await super.render();
168
177
 
169
178
  const src = this.getIframeSrc();
@@ -171,3 +180,27 @@ export class ConversationEmbed extends TsEmbed {
171
180
  return this;
172
181
  }
173
182
  }
183
+
184
+ /**
185
+ * Embed ThoughtSpot AI Conversation.
186
+ * @deprecated from SDK: 1.38.0 | ThoughtSpot: 10.10.0.cl
187
+ * Use {@link SpotterEmbed} instead
188
+ * @group Embed components
189
+ * @example
190
+ * ```js
191
+ * const conversation = new SpotterEmbed('#tsEmbed', {
192
+ * worksheetId: 'worksheetId',
193
+ * searchOptions: {
194
+ * searchQuery: 'searchQuery',
195
+ * },
196
+ * });
197
+ * conversation.render();
198
+ * ```
199
+ * @version SDK: 1.37.0 | ThoughtSpot: 10.9.0.cl
200
+ */
201
+ export class ConversationEmbed extends SpotterEmbed {
202
+ constructor(container: HTMLElement, protected viewConfig: ConversationViewConfig) {
203
+ viewConfig.embedComponentType = 'conversation';
204
+ super(container, viewConfig);
205
+ }
206
+ }
@@ -14,8 +14,6 @@ import {
14
14
  AppViewConfig,
15
15
  SageEmbed,
16
16
  SageViewConfig,
17
- ConversationViewConfig,
18
- ConversationEmbed,
19
17
  SearchViewConfig,
20
18
  AnswerService,
21
19
  } from '../index';
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, Page, AppViewConfig, HomePageSearchBarMode,
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 { BodylessConversation, BodylessConversationViewConfig } from './embed/bodyless-conversation';
27
- import { ConversationEmbed, ConversationViewConfig } from './embed/conversation';
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';
@@ -85,10 +90,14 @@ export {
85
90
  LiveboardEmbed,
86
91
  SageEmbed,
87
92
  AppEmbed,
88
- BodylessConversation,
93
+ SpotterAgentEmbed,
94
+ SpotterAgentEmbedViewConfig,
89
95
  BodylessConversationViewConfig,
90
- ConversationEmbed,
96
+ BodylessConversation,
97
+ SpotterEmbed,
98
+ SpotterEmbedViewConfig,
91
99
  ConversationViewConfig,
100
+ ConversationEmbed,
92
101
  AuthFailureType,
93
102
  AuthStatus,
94
103
  AuthEvent,
@@ -129,6 +138,8 @@ export {
129
138
  uploadMixpanelEvent,
130
139
  MIXPANEL_EVENT,
131
140
  HomePageSearchBarMode,
141
+ PrimaryNavbarVersion,
142
+ HomePage,
132
143
  VizPoint,
133
144
  CustomActionPayload,
134
145
  UIPassthroughEvent,
@@ -9,8 +9,10 @@ export {
9
9
  PreRenderedAppEmbed,
10
10
  SageEmbed,
11
11
  PreRenderedSageEmbed,
12
+ SpotterEmbed,
12
13
  ConversationEmbed,
13
14
  PreRenderedConversationEmbed,
15
+ SpotterAgentEmbed,
14
16
  useEmbedRef,
15
17
  useInit,
16
18
  } from './index';
@@ -16,6 +16,7 @@ import {
16
16
  } from '../test/test-utils';
17
17
  import {
18
18
  SearchEmbed, AppEmbed, LiveboardEmbed, useEmbedRef, SearchBarEmbed, PreRenderedLiveboardEmbed,
19
+ SpotterAgentEmbed
19
20
  } from './index';
20
21
  import * as allExports from './index';
21
22
  import {
@@ -235,6 +236,161 @@ describe('React Components', () => {
235
236
  });
236
237
  });
237
238
 
239
+ describe('SpotterAgentEmbed', () => {
240
+ it('Should work as a React component integrating BodylessConversation', async () => {
241
+ const mockDiv = document.createElement('div');
242
+
243
+ let conversationService: any = null;
244
+
245
+ render(
246
+ <SpotterAgentEmbed
247
+ ref={(instance: any) => {
248
+ conversationService = instance;
249
+
250
+ if (instance) {
251
+ instance.sendMessage = jest.fn().mockResolvedValue({
252
+ container: mockDiv
253
+ });
254
+ }
255
+ }}
256
+ worksheetId="test-worksheet-id"
257
+ />
258
+ );
259
+
260
+ expect(conversationService).not.toBeNull();
261
+
262
+ if (conversationService) {
263
+ expect(typeof conversationService.sendMessage).toBe('function');
264
+
265
+ const response = await conversationService.sendMessage("What are my sales this month?");
266
+ expect(response.container).toBe(mockDiv);
267
+ }
268
+ });
269
+
270
+ it('Should work as a React component with ref support', () => {
271
+ const mockSendMessage = jest.fn().mockResolvedValue({
272
+ container: document.createElement('div'),
273
+ viz: {}
274
+ });
275
+
276
+ const TestComponent = () => {
277
+ const conversationRef = React.useRef(null);
278
+
279
+ const handleClick = () => {
280
+ if (conversationRef.current) {
281
+ conversationRef.current.sendMessage = mockSendMessage;
282
+
283
+ conversationRef.current.sendMessage("Test message");
284
+ }
285
+ };
286
+
287
+ return (
288
+ <>
289
+ <SpotterAgentEmbed
290
+ ref={conversationRef}
291
+ worksheetId="test-worksheet-id"
292
+ />
293
+ <button data-testid="test-button" onClick={handleClick}>
294
+ Send Message
295
+ </button>
296
+ </>
297
+ );
298
+ };
299
+
300
+ const { getByTestId } = render(<TestComponent />);
301
+
302
+ fireEvent.click(getByTestId('test-button'));
303
+
304
+ expect(mockSendMessage).toHaveBeenCalledWith("Test message");
305
+ });
306
+
307
+ it('Should work with the useEmbedRef hook', () => {
308
+ const mockSendMessage = jest.fn().mockResolvedValue({
309
+ container: document.createElement('div'),
310
+ viz: {}
311
+ });
312
+
313
+ const TestComponent = () => {
314
+ const embedRef = useEmbedRef<typeof SpotterAgentEmbed>();
315
+
316
+ const handleClick = () => {
317
+ if (embedRef.current) {
318
+ const service = embedRef.current as unknown as {
319
+ sendMessage: typeof mockSendMessage
320
+ };
321
+
322
+ service.sendMessage = mockSendMessage;
323
+
324
+ service.sendMessage("Test with useEmbedRef");
325
+ }
326
+ };
327
+
328
+ return (
329
+ <>
330
+ <SpotterAgentEmbed
331
+ ref={embedRef}
332
+ worksheetId="test-worksheet-id"
333
+ />
334
+ <button data-testid="use-embed-ref-button" onClick={handleClick}>
335
+ Send with useEmbedRef
336
+ </button>
337
+ </>
338
+ );
339
+ };
340
+
341
+ const { getByTestId } = render(<TestComponent />);
342
+
343
+ fireEvent.click(getByTestId('use-embed-ref-button'));
344
+
345
+ expect(mockSendMessage).toHaveBeenCalledWith("Test with useEmbedRef");
346
+ });
347
+
348
+ it('Should work with the className prop', async () => {
349
+ let capturedInstance: any = null;
350
+
351
+ const TestComponent = () => {
352
+ const embedRef = useEmbedRef<typeof SpotterAgentEmbed>();
353
+
354
+ React.useEffect(() => {
355
+ capturedInstance = embedRef.current;
356
+
357
+ if (capturedInstance) {
358
+ const mockConversationService = {
359
+ sendMessage: jest.fn().mockResolvedValue({
360
+ data: {
361
+ sessionId: 'test-session',
362
+ genNo: 1,
363
+ stateKey: {
364
+ transactionId: 'test-transaction',
365
+ generationNumber: 1
366
+ }
367
+ }
368
+ })
369
+ };
370
+ (capturedInstance as any).conversationService = mockConversationService;
371
+ }
372
+ }, []);
373
+
374
+ return (
375
+ <SpotterAgentEmbed
376
+ ref={embedRef}
377
+ worksheetId="test-worksheet-id"
378
+ className="embedClass"
379
+ />
380
+ );
381
+ };
382
+
383
+ render(<TestComponent />);
384
+
385
+ expect(capturedInstance).not.toBeNull();
386
+
387
+ if (capturedInstance) {
388
+ const result = await capturedInstance.sendMessage("test");
389
+ expect(result.container.className).toBe("embedClass");
390
+ }
391
+ });
392
+ });
393
+
238
394
  describe('PreRenderedLiveboardEmbed', () => {
239
395
  it('should preRender the liveboard ', async () => {
240
396
  const preRenderId = 'tsEmbed-pre-render-wrapper-test';
@@ -285,7 +441,7 @@ describe('allExports', () => {
285
441
  it('should not have undefined exports', () => {
286
442
  Object.keys(allExports).forEach(
287
443
  (exportKey) => expect(
288
- Boolean(allExports[exportKey]),
444
+ Boolean(allExports[exportKey as keyof typeof allExports]),
289
445
  )
290
446
  .toBe(true),
291
447
  );
@@ -10,10 +10,11 @@ import { SearchEmbed as _SearchEmbed, SearchViewConfig } from '../embed/search';
10
10
  import { AppEmbed as _AppEmbed, AppViewConfig } from '../embed/app';
11
11
  import { LiveboardEmbed as _LiveboardEmbed, LiveboardViewConfig } from '../embed/liveboard';
12
12
  import { TsEmbed } from '../embed/ts-embed';
13
+ import { SpotterAgentEmbed as _SpotterAgentEmbed, SpotterAgentEmbedViewConfig } from '../embed/bodyless-conversation';
13
14
 
14
15
  import { EmbedConfig, EmbedEvent, ViewConfig } from '../types';
15
16
  import { EmbedProps, getViewPropsAndListeners } from './util';
16
- import { ConversationEmbed as _ConversationEmbed, ConversationViewConfig } from '../embed/conversation';
17
+ import { SpotterEmbed as _SpotterEmbed, SpotterEmbedViewConfig, ConversationEmbed as _ConversationEmbed, ConversationViewConfig } from '../embed/conversation';
17
18
  import { init } from '../embed/base';
18
19
 
19
20
  const componentFactory = <T extends typeof TsEmbed, U extends EmbedProps, V extends ViewConfig>(
@@ -23,7 +24,7 @@ const componentFactory = <T extends typeof TsEmbed, U extends EmbedProps, V exte
23
24
  // Embed.preRender() method instead of the usual render method, and it will
24
25
  // not be destroyed when the component is unmounted.
25
26
  isPreRenderedComponent = false,
26
- ) => React.forwardRef<InstanceType<T>, U>(
27
+ ) => React.forwardRef<InstanceType<T>, U>(
27
28
  (props: U, forwardedRef: React.MutableRefObject<InstanceType<T>>) => {
28
29
  const ref = React.useRef<HTMLDivElement>(null);
29
30
  const { className, style, ...embedProps } = props;
@@ -334,6 +335,7 @@ export const PreRenderedSageEmbed = componentFactory<
334
335
  SageViewConfig
335
336
  >(_SageEmbed, true);
336
337
 
338
+ interface SpotterEmbedProps extends EmbedProps, SpotterEmbedViewConfig { }
337
339
  interface ConversationEmbedProps extends EmbedProps, ConversationViewConfig { }
338
340
 
339
341
  /**
@@ -341,6 +343,30 @@ interface ConversationEmbedProps extends EmbedProps, ConversationViewConfig { }
341
343
  * @example
342
344
  * ```tsx
343
345
  * function Sage() {
346
+ * return <SpotterEmbed
347
+ * worksheetId="<worksheet-id-here>"
348
+ * searchOptions={{
349
+ * searchQuery: "<search query to start with>"
350
+ * }}
351
+ * ... other view config props or event listeners.
352
+ * />
353
+ * }
354
+ * ```
355
+ */
356
+ export const SpotterEmbed = componentFactory<
357
+ typeof _SpotterEmbed,
358
+ SpotterEmbedProps,
359
+ SpotterEmbedViewConfig
360
+ >(_SpotterEmbed);
361
+
362
+
363
+ /**
364
+ * React component for LLM based conversation BI.
365
+ * @deprecated from SDK: 1.38.0 | ThoughtSpot: 10.10.0.cl
366
+ * Use {@link SpotterEmbed} instead
367
+ * @example
368
+ * ```tsx
369
+ * function Sage() {
344
370
  * return <ConversationEmbed
345
371
  * worksheetId="<worksheet-id-here>"
346
372
  * searchOptions={{
@@ -352,14 +378,73 @@ interface ConversationEmbedProps extends EmbedProps, ConversationViewConfig { }
352
378
  * ```
353
379
  */
354
380
  export const ConversationEmbed = componentFactory<
355
- typeof _ConversationEmbed, ConversationEmbedProps, ConversationViewConfig>(
356
- _ConversationEmbed,
357
- );
381
+ typeof _ConversationEmbed,
382
+ ConversationEmbedProps,
383
+ ConversationViewConfig
384
+ >(_ConversationEmbed);
385
+
386
+ interface SpotterAgentEmbedProps extends EmbedProps, SpotterAgentEmbedViewConfig {}
387
+
388
+ /**
389
+ * React component for SpotterAgent embed, which can be integrated inside
390
+ * chatbots or other conversational interfaces.
391
+ * @example
392
+ * ```tsx
393
+ * function SpotterAgent() {
394
+ * const ref = useRef();
395
+ *
396
+ * const handleSendMessage = async () => {
397
+ * const { container, error } = await ref.current.sendMessage('show me sales by region');
398
+ * if (container) {
399
+ * document.body.appendChild(container);
400
+ * }
401
+ * };
402
+ *
403
+ * return (
404
+ * <div>
405
+ * <SpotterAgentEmbed ref={ref} worksheetId="worksheetId" />
406
+ * <button onClick={handleSendMessage}>Send Message</button>
407
+ * </div>
408
+ * );
409
+ * }
410
+ * ```
411
+ */
412
+ export const SpotterAgentEmbed = React.forwardRef<_SpotterAgentEmbed, SpotterAgentEmbedProps>((props, ref) => {
413
+ const { className, ...restProps } = props;
414
+ const serviceRef = useRef<_SpotterAgentEmbed | null>(null);
415
+
416
+ useDeepCompareEffect(() => {
417
+ if (serviceRef.current) {
418
+ serviceRef.current = null;
419
+ }
420
+
421
+ const configProps = {
422
+ ...restProps,
423
+ ...(className ? { containerClassName: className } : {})
424
+ };
425
+
426
+ serviceRef.current = new _SpotterAgentEmbed(configProps);
427
+
428
+ if (ref) {
429
+ if (typeof ref === 'function') {
430
+ ref(serviceRef.current);
431
+ } else {
432
+ ref.current = serviceRef.current;
433
+ }
434
+ }
435
+
436
+ return () => {
437
+ serviceRef.current = null;
438
+ };
439
+ }, [props]);
440
+
441
+ return null;
442
+ });
358
443
 
359
444
  /**
360
445
  * React component for PreRendered Conversation embed.
361
446
  *
362
- * PreRenderedConversationEmbed will preRender the ConversationEmbed and will be hidden by
447
+ * PreRenderedConversationEmbed will preRender the SpotterEmbed and will be hidden by
363
448
  * default.
364
449
  *
365
450
  * SageEmbed with preRenderId passed will call showPreRender on the embed.
@@ -370,21 +455,23 @@ export const ConversationEmbed = componentFactory<
370
455
  * }
371
456
  * ```
372
457
  * function MyComponent() {
373
- * return <ConversationEmbed preRenderId="someId" worksheetId="id" />
458
+ * return <SpotterEmbed preRenderId="someId" worksheetId="id" />
374
459
  * }
375
460
  * ```
376
461
  */
377
462
  export const PreRenderedConversationEmbed = componentFactory<
378
- typeof _ConversationEmbed,
379
- SageEmbedProps & PreRenderProps,
380
- ConversationViewConfig
381
- >(_ConversationEmbed, true);
463
+ typeof _SpotterEmbed,
464
+ SpotterEmbedProps & PreRenderProps,
465
+ SpotterEmbedViewConfig
466
+ >(_SpotterEmbed, true);
382
467
 
383
468
  type EmbedComponent = typeof SearchEmbed
384
469
  | typeof AppEmbed
385
470
  | typeof LiveboardEmbed
386
471
  | typeof SearchBarEmbed
387
472
  | typeof SageEmbed
473
+ | typeof SpotterAgentEmbed
474
+ | typeof SpotterEmbed
388
475
  | typeof ConversationEmbed;
389
476
 
390
477
  /**
package/src/types.ts CHANGED
@@ -3662,6 +3662,7 @@ export enum Param {
3662
3662
  ShowSpotterLimitations = 'showSpotterLimitations',
3663
3663
  CoverAndFilterOptionInPDF = 'coverAndFilterOptionInPDF',
3664
3664
  PrimaryAction = 'primaryAction',
3665
+ isSpotterAgentEmbed = 'isSpotterAgentEmbed',
3665
3666
  }
3666
3667
 
3667
3668
  /**