@thoughtspot/visual-embed-sdk 1.39.2-alpha.1 → 1.39.2-alpha.2

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 (170) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/config.spec.js +9 -0
  3. package/cjs/src/config.spec.js.map +1 -1
  4. package/cjs/src/embed/app.d.ts +75 -15
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js +68 -9
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +356 -4
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/bodyless-conversation.d.ts +19 -7
  11. package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
  12. package/cjs/src/embed/bodyless-conversation.js +24 -4
  13. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  14. package/cjs/src/embed/bodyless-conversation.spec.js +8 -190
  15. package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
  16. package/cjs/src/embed/conversation.d.ts +2 -60
  17. package/cjs/src/embed/conversation.d.ts.map +1 -1
  18. package/cjs/src/embed/conversation.js +1 -9
  19. package/cjs/src/embed/conversation.js.map +1 -1
  20. package/cjs/src/embed/conversation.spec.js +0 -102
  21. package/cjs/src/embed/conversation.spec.js.map +1 -1
  22. package/cjs/src/embed/liveboard.d.ts +56 -0
  23. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  24. package/cjs/src/embed/liveboard.js +46 -0
  25. package/cjs/src/embed/liveboard.js.map +1 -1
  26. package/cjs/src/embed/liveboard.spec.js +203 -0
  27. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  28. package/cjs/src/errors.d.ts +1 -0
  29. package/cjs/src/errors.d.ts.map +1 -1
  30. package/cjs/src/errors.js +1 -0
  31. package/cjs/src/errors.js.map +1 -1
  32. package/cjs/src/index.d.ts +2 -2
  33. package/cjs/src/index.d.ts.map +1 -1
  34. package/cjs/src/index.js +2 -1
  35. package/cjs/src/index.js.map +1 -1
  36. package/cjs/src/react/all-types-export.d.ts +1 -1
  37. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  38. package/cjs/src/react/all-types-export.js +3 -2
  39. package/cjs/src/react/all-types-export.js.map +1 -1
  40. package/cjs/src/react/index.d.ts +71 -20
  41. package/cjs/src/react/index.d.ts.map +1 -1
  42. package/cjs/src/react/index.js +79 -42
  43. package/cjs/src/react/index.js.map +1 -1
  44. package/cjs/src/react/index.spec.js +436 -100
  45. package/cjs/src/react/index.spec.js.map +1 -1
  46. package/cjs/src/types.d.ts +46 -4
  47. package/cjs/src/types.d.ts.map +1 -1
  48. package/cjs/src/types.js +28 -0
  49. package/cjs/src/types.js.map +1 -1
  50. package/cjs/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
  51. package/cjs/src/utils/graphql/nlsService/conversation-service.js +2 -0
  52. package/cjs/src/utils/graphql/nlsService/conversation-service.js.map +1 -1
  53. package/cjs/src/utils/processTrigger.js +2 -1
  54. package/cjs/src/utils/processTrigger.js.map +1 -1
  55. package/cjs/src/utils.d.ts +6 -0
  56. package/cjs/src/utils.d.ts.map +1 -1
  57. package/cjs/src/utils.js +23 -3
  58. package/cjs/src/utils.js.map +1 -1
  59. package/cjs/src/utils.spec.js +237 -1
  60. package/cjs/src/utils.spec.js.map +1 -1
  61. package/dist/index-e3Uw3YFO.js +7371 -0
  62. package/dist/src/embed/app.d.ts +75 -15
  63. package/dist/src/embed/app.d.ts.map +1 -1
  64. package/dist/src/embed/bodyless-conversation.d.ts +19 -7
  65. package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
  66. package/dist/src/embed/conversation.d.ts +2 -60
  67. package/dist/src/embed/conversation.d.ts.map +1 -1
  68. package/dist/src/embed/liveboard.d.ts +56 -0
  69. package/dist/src/embed/liveboard.d.ts.map +1 -1
  70. package/dist/src/errors.d.ts +1 -0
  71. package/dist/src/errors.d.ts.map +1 -1
  72. package/dist/src/index.d.ts +2 -2
  73. package/dist/src/index.d.ts.map +1 -1
  74. package/dist/src/react/all-types-export.d.ts +1 -1
  75. package/dist/src/react/all-types-export.d.ts.map +1 -1
  76. package/dist/src/react/index.d.ts +71 -20
  77. package/dist/src/react/index.d.ts.map +1 -1
  78. package/dist/src/types.d.ts +46 -4
  79. package/dist/src/types.d.ts.map +1 -1
  80. package/dist/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
  81. package/dist/src/utils.d.ts +6 -0
  82. package/dist/src/utils.d.ts.map +1 -1
  83. package/dist/tsembed-react.es.js +276 -74
  84. package/dist/tsembed-react.js +276 -72
  85. package/dist/tsembed.es.js +194 -27
  86. package/dist/tsembed.js +192 -25
  87. package/dist/visual-embed-sdk-react-full.d.ts +246 -105
  88. package/dist/visual-embed-sdk-react.d.ts +246 -105
  89. package/dist/visual-embed-sdk.d.ts +176 -86
  90. package/lib/package.json +1 -1
  91. package/lib/src/config.spec.js +9 -0
  92. package/lib/src/config.spec.js.map +1 -1
  93. package/lib/src/embed/app.d.ts +75 -15
  94. package/lib/src/embed/app.d.ts.map +1 -1
  95. package/lib/src/embed/app.js +68 -9
  96. package/lib/src/embed/app.js.map +1 -1
  97. package/lib/src/embed/app.spec.js +357 -5
  98. package/lib/src/embed/app.spec.js.map +1 -1
  99. package/lib/src/embed/bodyless-conversation.d.ts +19 -7
  100. package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
  101. package/lib/src/embed/bodyless-conversation.js +23 -4
  102. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  103. package/lib/src/embed/bodyless-conversation.spec.js +9 -191
  104. package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
  105. package/lib/src/embed/conversation.d.ts +2 -60
  106. package/lib/src/embed/conversation.d.ts.map +1 -1
  107. package/lib/src/embed/conversation.js +2 -10
  108. package/lib/src/embed/conversation.js.map +1 -1
  109. package/lib/src/embed/conversation.spec.js +2 -104
  110. package/lib/src/embed/conversation.spec.js.map +1 -1
  111. package/lib/src/embed/liveboard.d.ts +56 -0
  112. package/lib/src/embed/liveboard.d.ts.map +1 -1
  113. package/lib/src/embed/liveboard.js +47 -1
  114. package/lib/src/embed/liveboard.js.map +1 -1
  115. package/lib/src/embed/liveboard.spec.js +203 -0
  116. package/lib/src/embed/liveboard.spec.js.map +1 -1
  117. package/lib/src/errors.d.ts +1 -0
  118. package/lib/src/errors.d.ts.map +1 -1
  119. package/lib/src/errors.js +1 -0
  120. package/lib/src/errors.js.map +1 -1
  121. package/lib/src/index.d.ts +2 -2
  122. package/lib/src/index.d.ts.map +1 -1
  123. package/lib/src/index.js +2 -2
  124. package/lib/src/index.js.map +1 -1
  125. package/lib/src/react/all-types-export.d.ts +1 -1
  126. package/lib/src/react/all-types-export.d.ts.map +1 -1
  127. package/lib/src/react/all-types-export.js +1 -1
  128. package/lib/src/react/all-types-export.js.map +1 -1
  129. package/lib/src/react/index.d.ts +71 -20
  130. package/lib/src/react/index.d.ts.map +1 -1
  131. package/lib/src/react/index.js +79 -43
  132. package/lib/src/react/index.js.map +1 -1
  133. package/lib/src/react/index.spec.js +439 -103
  134. package/lib/src/react/index.spec.js.map +1 -1
  135. package/lib/src/types.d.ts +46 -4
  136. package/lib/src/types.d.ts.map +1 -1
  137. package/lib/src/types.js +28 -0
  138. package/lib/src/types.js.map +1 -1
  139. package/lib/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
  140. package/lib/src/utils/graphql/nlsService/conversation-service.js +2 -0
  141. package/lib/src/utils/graphql/nlsService/conversation-service.js.map +1 -1
  142. package/lib/src/utils/processTrigger.js +2 -1
  143. package/lib/src/utils/processTrigger.js.map +1 -1
  144. package/lib/src/utils.d.ts +6 -0
  145. package/lib/src/utils.d.ts.map +1 -1
  146. package/lib/src/utils.js +21 -2
  147. package/lib/src/utils.js.map +1 -1
  148. package/lib/src/utils.spec.js +238 -2
  149. package/lib/src/utils.spec.js.map +1 -1
  150. package/lib/src/visual-embed-sdk.d.ts +178 -88
  151. package/package.json +1 -1
  152. package/src/config.spec.ts +11 -0
  153. package/src/embed/app.spec.ts +444 -4
  154. package/src/embed/app.ts +131 -27
  155. package/src/embed/bodyless-conversation.spec.ts +9 -203
  156. package/src/embed/bodyless-conversation.ts +24 -10
  157. package/src/embed/conversation.spec.ts +5 -131
  158. package/src/embed/conversation.ts +10 -82
  159. package/src/embed/liveboard.spec.ts +251 -1
  160. package/src/embed/liveboard.ts +97 -5
  161. package/src/errors.ts +1 -0
  162. package/src/index.ts +2 -0
  163. package/src/react/all-types-export.ts +2 -1
  164. package/src/react/index.spec.tsx +556 -157
  165. package/src/react/index.tsx +117 -51
  166. package/src/types.ts +42 -0
  167. package/src/utils/graphql/nlsService/conversation-service.ts +2 -0
  168. package/src/utils/processTrigger.ts +1 -1
  169. package/src/utils.spec.ts +279 -2
  170. package/src/utils.ts +28 -2
package/src/embed/app.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import { logger } from '../utils/logger';
12
- import { getQueryParamString } from '../utils';
12
+ import { calculateVisibleElementData, getQueryParamString } from '../utils';
13
13
  import {
14
14
  Param,
15
15
  DOMSelector,
@@ -23,7 +23,7 @@ import { V1Embed } from './ts-embed';
23
23
  /**
24
24
  * Pages within the ThoughtSpot app that can be embedded.
25
25
  */
26
- // eslint-disable-next-line no-shadow
26
+
27
27
  export enum Page {
28
28
  /**
29
29
  * Home page
@@ -93,7 +93,7 @@ export enum PrimaryNavbarVersion {
93
93
  * Sliding (v3) introduces a new left-side navigation hub featuring a tab switcher,
94
94
  * along with updates to the top navigation bar.
95
95
  * It serves as the foundational version of the PrimaryNavBar.
96
-  */
96
+ */
97
97
  Sliding = 'v3',
98
98
  }
99
99
 
@@ -103,12 +103,28 @@ export enum PrimaryNavbarVersion {
103
103
  */
104
104
  export enum HomePage {
105
105
  /**
106
-  * Modular (v2) introduces the updated Modular Home Experience.
107
-  * It serves as the foundational version of the home page.
108
-  */
106
+ * Modular (v2) introduces the updated Modular Home Experience.
107
+ * It serves as the foundational version of the home page.
108
+ */
109
109
  Modular = 'v2',
110
110
  }
111
111
 
112
+ /**
113
+ * Define the version of the list page
114
+ * @version SDK: 1.40.0 | ThoughtSpot: 10.12.0.cl
115
+ */
116
+ export enum ListPage {
117
+ /**
118
+ * List (v2) is the traditional List Experience.
119
+ * It serves as the foundational version of the list page.
120
+ */
121
+ List = 'v2',
122
+ /**
123
+ * ListWithUXChanges (v3) introduces the new updated list page with UX changes.
124
+ */
125
+ ListWithUXChanges = 'v3',
126
+ }
127
+
112
128
  /**
113
129
  * Define the discovery experience
114
130
  * @version SDK: 1.40.0 | ThoughtSpot: 10.11.0.cl
@@ -122,6 +138,10 @@ export interface DiscoveryExperience {
122
138
  * homePage determines the version of the home page.
123
139
  */
124
140
  homePage?: HomePage;
141
+ /**
142
+ * listPageVersion determines the version of the list page.
143
+ */
144
+ listPageVersion?: ListPage;
125
145
  }
126
146
 
127
147
  /**
@@ -494,21 +514,7 @@ export interface AppViewConfig extends AllEmbedViewConfig {
494
514
  * ```
495
515
  */
496
516
  isUnifiedSearchExperienceEnabled?: boolean;
497
- /**
498
- * Show alert messages and toast messages in the embedded
499
- * view in full app embed.
500
- *
501
- * Supported embed types: `AppEmbed`
502
- * @version SDK: 1.11.0 | ThoughtSpot: 8.3.0.cl, 8.4.1.sw
503
- * @example
504
- * ```js
505
- * const embed = new AppEmbed('#tsEmbed', {
506
- * ... // other embed view config
507
- * showAlerts:true,
508
- * })
509
- * ```
510
- */
511
- showAlerts?: boolean;
517
+
512
518
  /**
513
519
  * This flag is used to enable/disable the styling and grouping in a Liveboard
514
520
  *
@@ -525,6 +531,48 @@ export interface AppViewConfig extends AllEmbedViewConfig {
525
531
  * ```
526
532
  */
527
533
  isLiveboardStylingAndGroupingEnabled?: boolean;
534
+
535
+ /**
536
+ * This flag is used to enable the full height lazy load data.
537
+ *
538
+ * @example
539
+ * ```js
540
+ * const embed = new AppEmbed('#embed-container', {
541
+ * // ...other options
542
+ * fullHeight: true,
543
+ * lazyLoadingForFullHeight: true,
544
+ * })
545
+ * ```
546
+ *
547
+ * @type {boolean}
548
+ * @default false
549
+ * @version SDK: 1.39.0 | ThoughtSpot:10.10.0.cl
550
+ */
551
+ lazyLoadingForFullHeight?: boolean;
552
+
553
+ /**
554
+ * The margin to be used for lazy loading.
555
+ *
556
+ * For example, if the margin is set to '10px',
557
+ * the visualization will be loaded 10px before the its top edge is visible in the
558
+ * viewport.
559
+ *
560
+ * The format is similar to CSS margin.
561
+ *
562
+ * @example
563
+ * ```js
564
+ * const embed = new AppEmbed('#embed-container', {
565
+ * // ...other options
566
+ * fullHeight: true,
567
+ * lazyLoadingForFullHeight: true,
568
+ * // Using 0px, the visualization will be only loaded when its visible in the viewport.
569
+ * lazyLoadingMargin: '0px',
570
+ * })
571
+ * ```
572
+ * @type {string}
573
+ * @version SDK: 1.39.0 | ThoughtSpot:10.10.0.cl
574
+ */
575
+ lazyLoadingMargin?: string;
528
576
  }
529
577
 
530
578
  /**
@@ -536,7 +584,7 @@ export class AppEmbed extends V1Embed {
536
584
 
537
585
  private defaultHeight = '100%';
538
586
 
539
- // eslint-disable-next-line no-useless-constructor
587
+
540
588
  constructor(domSelector: DOMSelector, viewConfig: AppViewConfig) {
541
589
  viewConfig.embedComponentType = 'AppEmbed';
542
590
  super(domSelector, viewConfig);
@@ -544,6 +592,7 @@ export class AppEmbed extends V1Embed {
544
592
  this.on(EmbedEvent.RouteChange, this.setIframeHeightForNonEmbedLiveboard);
545
593
  this.on(EmbedEvent.EmbedHeight, this.updateIFrameHeight);
546
594
  this.on(EmbedEvent.EmbedIframeCenter, this.embedIframeCenter);
595
+ this.on(EmbedEvent.RequestVisibleEmbedCoordinates, this.requestVisibleEmbedCoordinatesHandler);
547
596
  }
548
597
  }
549
598
 
@@ -577,7 +626,7 @@ export class AppEmbed extends V1Embed {
577
626
  enable2ColumnLayout,
578
627
  enableCustomColumnGroups = false,
579
628
  isOnBeforeGetVizDataInterceptEnabled = false,
580
- /* eslint-disable-next-line max-len */
629
+
581
630
  dataPanelCustomGroupsAccordionInitialState = DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL,
582
631
  collapseSearchBar = true,
583
632
  isLiveboardCompactHeaderEnabled = false,
@@ -592,7 +641,7 @@ export class AppEmbed extends V1Embed {
592
641
  isLiveboardStylingAndGroupingEnabled,
593
642
  } = this.viewConfig;
594
643
 
595
- let params = {};
644
+ let params: any = {};
596
645
  params[Param.PrimaryNavHidden] = !showPrimaryNavbar;
597
646
  params[Param.HideProfleAndHelp] = !!disableProfileAndHelp;
598
647
  params[Param.HideApplicationSwitcher] = !!hideApplicationSwitcher;
@@ -625,6 +674,10 @@ export class AppEmbed extends V1Embed {
625
674
 
626
675
  if (fullHeight === true) {
627
676
  params[Param.fullHeight] = true;
677
+ if (this.viewConfig.lazyLoadingForFullHeight) {
678
+ params[Param.IsLazyLoadingForEmbedEnabled] = true;
679
+ params[Param.RootMarginForLazyLoad] = this.viewConfig.lazyLoadingMargin;
680
+ }
628
681
  }
629
682
 
630
683
  if (tag) {
@@ -650,7 +703,7 @@ export class AppEmbed extends V1Embed {
650
703
  }
651
704
 
652
705
  if (isOnBeforeGetVizDataInterceptEnabled) {
653
- /* eslint-disable-next-line max-len */
706
+
654
707
  params[
655
708
  Param.IsOnBeforeGetVizDataInterceptEnabled
656
709
  ] = isOnBeforeGetVizDataInterceptEnabled;
@@ -678,12 +731,12 @@ export class AppEmbed extends V1Embed {
678
731
  || dataPanelCustomGroupsAccordionInitialState
679
732
  === DataPanelCustomColumnGroupsAccordionState.EXPAND_FIRST
680
733
  ) {
681
- /* eslint-disable-next-line max-len */
734
+
682
735
  params[
683
736
  Param.DataPanelCustomGroupsAccordionInitialState
684
737
  ] = dataPanelCustomGroupsAccordionInitialState;
685
738
  } else {
686
- /* eslint-disable-next-line max-len */
739
+
687
740
  params[Param.DataPanelCustomGroupsAccordionInitialState] = DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL;
688
741
  }
689
742
 
@@ -698,6 +751,10 @@ export class AppEmbed extends V1Embed {
698
751
  if (discoveryExperience.homePage === HomePage.Modular) {
699
752
  params[Param.ModularHomeExperienceEnabled] = true;
700
753
  }
754
+ // listPageVersion v3 will enable the new list page
755
+ if (discoveryExperience.listPageVersion === ListPage.ListWithUXChanges) {
756
+ params[Param.ListPageVersion] = discoveryExperience.listPageVersion;
757
+ }
701
758
  }
702
759
 
703
760
  const queryParams = getQueryParamString(params, true);
@@ -705,6 +762,23 @@ export class AppEmbed extends V1Embed {
705
762
  return queryParams;
706
763
  }
707
764
 
765
+ private sendFullHeightLazyLoadData = () => {
766
+ const data = calculateVisibleElementData(this.iFrame);
767
+ this.trigger(HostEvent.VisibleEmbedCoordinates, data);
768
+ }
769
+
770
+ /**
771
+ * This is a handler for the RequestVisibleEmbedCoordinates event.
772
+ * It is used to send the visible coordinates data to the host application.
773
+ * @param data The event payload
774
+ * @param responder The responder function
775
+ */
776
+ private requestVisibleEmbedCoordinatesHandler = (data: MessagePayload, responder: any) => {
777
+ logger.info('Sending RequestVisibleEmbedCoordinates', data);
778
+ const visibleCoordinatesData = calculateVisibleElementData(this.iFrame);
779
+ responder({ type: EmbedEvent.RequestVisibleEmbedCoordinates, data: visibleCoordinatesData });
780
+ }
781
+
708
782
  /**
709
783
  * Constructs the URL of the ThoughtSpot app page to be rendered.
710
784
  * @param pageId The ID of the page to be embedded.
@@ -727,6 +801,7 @@ export class AppEmbed extends V1Embed {
727
801
  */
728
802
  protected updateIFrameHeight = (data: MessagePayload) => {
729
803
  this.setIFrameHeight(Math.max(data.data, this.iFrame?.scrollHeight));
804
+ this.sendFullHeightLazyLoadData();
730
805
  };
731
806
 
732
807
  private embedIframeCenter = (data: MessagePayload, responder: any) => {
@@ -835,6 +910,34 @@ export class AppEmbed extends V1Embed {
835
910
  }
836
911
  }
837
912
 
913
+ /**
914
+ * Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
915
+ * @version SDK: 1.39.0 | ThoughtSpot: 10.10.0.cl
916
+ */
917
+ public destroy() {
918
+ super.destroy();
919
+ this.unregisterLazyLoadEvents();
920
+ }
921
+
922
+ private postRender() {
923
+ this.registerLazyLoadEvents();
924
+ }
925
+
926
+ private registerLazyLoadEvents() {
927
+ if (this.viewConfig.fullHeight && this.viewConfig.lazyLoadingForFullHeight) {
928
+ // TODO: Use passive: true, install modernizr to check for passive
929
+ window.addEventListener('resize', this.sendFullHeightLazyLoadData);
930
+ window.addEventListener('scroll', this.sendFullHeightLazyLoadData);
931
+ }
932
+ }
933
+
934
+ private unregisterLazyLoadEvents() {
935
+ if (this.viewConfig.fullHeight && this.viewConfig.lazyLoadingForFullHeight) {
936
+ window.removeEventListener('resize', this.sendFullHeightLazyLoadData);
937
+ window.removeEventListener('scroll', this.sendFullHeightLazyLoadData);
938
+ }
939
+ }
940
+
838
941
  /**
839
942
  * Renders the embedded application pages in the ThoughtSpot app.
840
943
  * @param renderOptions An object containing the page ID
@@ -846,6 +949,7 @@ export class AppEmbed extends V1Embed {
846
949
  const src = this.getIFrameSrc();
847
950
  await this.renderV1Embed(src);
848
951
 
952
+ this.postRender();
849
953
  return this;
850
954
  }
851
955
  }
@@ -1,5 +1,5 @@
1
1
  import 'jest-fetch-mock';
2
- import { SpotterAgentEmbed, SpotterAgentEmbedViewConfig } from './bodyless-conversation';
2
+ import { SpotterAgentEmbed, SpotterAgentEmbedViewConfig, ConversationMessage } from './bodyless-conversation';
3
3
  import * as authInstance from '../auth';
4
4
  import { init } from '../index';
5
5
  import { Action, AuthType, RuntimeFilterOp } from '../types';
@@ -138,7 +138,7 @@ describe('SpotterAgentEmbed', () => {
138
138
  expect(errorResult.error instanceof Error).toBeTruthy();
139
139
  });
140
140
 
141
- test('should apply containerClassName to the container element', async () => {
141
+ test('should handle hideActions parameter correctly', async () => {
142
142
  fetchMock.mockResponses(
143
143
  JSON.stringify({
144
144
  data: {
@@ -227,221 +227,27 @@ describe('SpotterAgentEmbed', () => {
227
227
 
228
228
  const viewConfig: SpotterAgentEmbedViewConfig = {
229
229
  worksheetId: 'worksheetId',
230
- containerClassName: 'custom-conversation-container',
230
+ hiddenActions: [Action.Download, Action.Save], // This should trigger the HideActions branch
231
231
  };
232
232
 
233
233
  const spotterAgentEmbed = new SpotterAgentEmbed(viewConfig);
234
234
  const result = await spotterAgentEmbed.sendMessage('userMessage');
235
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
236
+ // Verify the iframe src contains the hideActions parameter
240
237
  const iframeSrc = getIFrameSrc(result.container);
241
- expectUrlToHaveParamsWithValues(iframeSrc, {
242
- sessionId: 'sessionId',
243
- genNo: 2,
244
- acSessionId: 'transactionId',
245
- acGenNo: 1,
246
- });
238
+ expect(iframeSrc).toContain('hideAction');
247
239
  });
248
240
 
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
-
241
+ test('should have sendMessageData method', () => {
336
242
  const viewConfig: SpotterAgentEmbedViewConfig = {
337
243
  worksheetId: 'worksheetId',
338
- // No containerClassName provided
339
244
  };
340
245
 
341
246
  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('');
247
+ expect(typeof spotterAgentEmbed.sendMessageData).toBe('function');
346
248
  });
347
249
 
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');
250
+ test('should export ConversationMessage class', () => {
251
+ expect(typeof ConversationMessage).toBe('function');
446
252
  });
447
253
  });
@@ -13,11 +13,6 @@ export interface SpotterAgentEmbedViewConfig extends Omit<BaseViewConfig, 'prima
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;
21
16
  }
22
17
 
23
18
  /**
@@ -29,14 +24,14 @@ export interface SpotterAgentEmbedViewConfig extends Omit<BaseViewConfig, 'prima
29
24
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
30
25
  export interface BodylessConversationViewConfig extends SpotterAgentEmbedViewConfig {}
31
26
 
32
- interface SpotterAgentMessageViewConfig extends SpotterAgentEmbedViewConfig {
27
+ export interface SpotterAgentMessageViewConfig extends SpotterAgentEmbedViewConfig {
33
28
  sessionId: string;
34
29
  genNo: number;
35
30
  acSessionId: string;
36
31
  acGenNo: number;
37
32
  }
38
33
 
39
- class ConversationMessage extends TsEmbed {
34
+ export class ConversationMessage extends TsEmbed {
40
35
  constructor(container: HTMLElement, protected viewConfig: SpotterAgentMessageViewConfig) {
41
36
  viewConfig.embedComponentType = 'bodyless-conversation';
42
37
  super(container, viewConfig);
@@ -116,9 +111,6 @@ export class SpotterAgentEmbed {
116
111
  }
117
112
 
118
113
  const container = document.createElement('div');
119
- if (this.viewConfig.containerClassName) {
120
- container.className = this.viewConfig.containerClassName;
121
- }
122
114
 
123
115
  const embed = new ConversationMessage(container, {
124
116
  ...this.viewConfig,
@@ -130,6 +122,28 @@ export class SpotterAgentEmbed {
130
122
  await embed.render();
131
123
  return { container, viz: embed };
132
124
  }
125
+
126
+ /**
127
+ * Send a message to the conversation service and return only the data.
128
+ * @param userMessage - The message to send to the conversation service.
129
+ * @returns The data from the conversation service.
130
+ */
131
+ public async sendMessageData(userMessage: string) {
132
+ try {
133
+ const { data, error } = await this.conversationService.sendMessage(userMessage);
134
+ if (error) {
135
+ return { error };
136
+ }
137
+ return { data: {
138
+ sessionId: data.sessionId,
139
+ genNo: data.genNo,
140
+ acSessionId: data.stateKey.transactionId,
141
+ acGenNo: data.stateKey.generationNumber,
142
+ } };
143
+ } catch (error) {
144
+ return { error: error as Error };
145
+ }
146
+ }
133
147
  }
134
148
 
135
149
  /**