@thoughtspot/visual-embed-sdk 1.52.1 → 1.52.2-beta.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 (217) hide show
  1. package/cjs/package.json +10 -3
  2. package/cjs/src/contracts/host-event-contracts.d.ts +49 -11
  3. package/cjs/src/contracts/host-event-contracts.d.ts.map +1 -1
  4. package/cjs/src/embed/app.d.ts +4 -3
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js.map +1 -1
  7. package/cjs/src/embed/app.spec.js +10 -0
  8. package/cjs/src/embed/app.spec.js.map +1 -1
  9. package/cjs/src/embed/auto-frame-renderer.spec.js +24 -13
  10. package/cjs/src/embed/auto-frame-renderer.spec.js.map +1 -1
  11. package/cjs/src/embed/conversation.d.ts +1 -0
  12. package/cjs/src/embed/conversation.d.ts.map +1 -1
  13. package/cjs/src/embed/conversation.js +3 -3
  14. package/cjs/src/embed/conversation.js.map +1 -1
  15. package/cjs/src/embed/conversation.spec.js +35 -24
  16. package/cjs/src/embed/conversation.spec.js.map +1 -1
  17. package/cjs/src/embed/embedConfig.spec.js +2 -1
  18. package/cjs/src/embed/embedConfig.spec.js.map +1 -1
  19. package/cjs/src/embed/hostEventClient/host-event-client.d.ts +2 -2
  20. package/cjs/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  21. package/cjs/src/embed/hostEventClient/host-event-client.js +16 -10
  22. package/cjs/src/embed/hostEventClient/host-event-client.js.map +1 -1
  23. package/cjs/src/embed/hostEventClient/host-event-client.spec.js +14 -8
  24. package/cjs/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  25. package/cjs/src/embed/hostEventClient/utils.d.ts +9 -0
  26. package/cjs/src/embed/hostEventClient/utils.d.ts.map +1 -1
  27. package/cjs/src/embed/hostEventClient/utils.js +49 -3
  28. package/cjs/src/embed/hostEventClient/utils.js.map +1 -1
  29. package/cjs/src/embed/hostEventClient/utils.spec.js +151 -0
  30. package/cjs/src/embed/hostEventClient/utils.spec.js.map +1 -1
  31. package/cjs/src/embed/liveboard.d.ts +4 -3
  32. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  33. package/cjs/src/embed/liveboard.js +17 -12
  34. package/cjs/src/embed/liveboard.js.map +1 -1
  35. package/cjs/src/embed/liveboard.spec.js +2 -1
  36. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  37. package/cjs/src/embed/spotter-utils.d.ts +8 -1
  38. package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
  39. package/cjs/src/embed/spotter-utils.js +14 -1
  40. package/cjs/src/embed/spotter-utils.js.map +1 -1
  41. package/cjs/src/embed/spotter-utils.spec.js +26 -0
  42. package/cjs/src/embed/spotter-utils.spec.js.map +1 -1
  43. package/cjs/src/embed/ts-embed.d.ts +35 -10
  44. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  45. package/cjs/src/embed/ts-embed.js +108 -73
  46. package/cjs/src/embed/ts-embed.js.map +1 -1
  47. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  48. package/cjs/src/embed/ts-embed.spec.js +203 -30
  49. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  50. package/cjs/src/errors.js +1 -1
  51. package/cjs/src/errors.js.map +1 -1
  52. package/cjs/src/index.d.ts +2 -1
  53. package/cjs/src/index.d.ts.map +1 -1
  54. package/cjs/src/index.js +3 -1
  55. package/cjs/src/index.js.map +1 -1
  56. package/cjs/src/react/all-types-export.d.ts +1 -1
  57. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  58. package/cjs/src/react/all-types-export.js +2 -1
  59. package/cjs/src/react/all-types-export.js.map +1 -1
  60. package/cjs/src/types.d.ts +45 -22
  61. package/cjs/src/types.d.ts.map +1 -1
  62. package/cjs/src/types.js +44 -21
  63. package/cjs/src/types.js.map +1 -1
  64. package/cjs/src/utils/authService/tokenizedAuthService.spec.js +2 -1
  65. package/cjs/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
  66. package/cjs/src/utils/custom-actions.spec.js +4 -2
  67. package/cjs/src/utils/custom-actions.spec.js.map +1 -1
  68. package/cjs/src/utils/filterConverter.d.ts +106 -0
  69. package/cjs/src/utils/filterConverter.d.ts.map +1 -0
  70. package/cjs/src/utils/filterConverter.js +215 -0
  71. package/cjs/src/utils/filterConverter.js.map +1 -0
  72. package/cjs/src/utils/filterConverter.spec.d.ts +2 -0
  73. package/cjs/src/utils/filterConverter.spec.d.ts.map +1 -0
  74. package/cjs/src/utils/filterConverter.spec.js +709 -0
  75. package/cjs/src/utils/filterConverter.spec.js.map +1 -0
  76. package/cjs/src/utils/processData.spec.js +2 -1
  77. package/cjs/src/utils/processData.spec.js.map +1 -1
  78. package/dist/{index-C1pmYb5H.js → index-BrJMbt8r.js} +1 -1
  79. package/dist/src/contracts/host-event-contracts.d.ts +49 -11
  80. package/dist/src/contracts/host-event-contracts.d.ts.map +1 -1
  81. package/dist/src/embed/app.d.ts +4 -3
  82. package/dist/src/embed/app.d.ts.map +1 -1
  83. package/dist/src/embed/conversation.d.ts +1 -0
  84. package/dist/src/embed/conversation.d.ts.map +1 -1
  85. package/dist/src/embed/hostEventClient/host-event-client.d.ts +2 -2
  86. package/dist/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  87. package/dist/src/embed/hostEventClient/utils.d.ts +9 -0
  88. package/dist/src/embed/hostEventClient/utils.d.ts.map +1 -1
  89. package/dist/src/embed/liveboard.d.ts +4 -3
  90. package/dist/src/embed/liveboard.d.ts.map +1 -1
  91. package/dist/src/embed/spotter-utils.d.ts +8 -1
  92. package/dist/src/embed/spotter-utils.d.ts.map +1 -1
  93. package/dist/src/embed/ts-embed.d.ts +35 -10
  94. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  95. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  96. package/dist/src/index.d.ts +2 -1
  97. package/dist/src/index.d.ts.map +1 -1
  98. package/dist/src/react/all-types-export.d.ts +1 -1
  99. package/dist/src/react/all-types-export.d.ts.map +1 -1
  100. package/dist/src/types.d.ts +45 -22
  101. package/dist/src/types.d.ts.map +1 -1
  102. package/dist/src/utils/filterConverter.d.ts +106 -0
  103. package/dist/src/utils/filterConverter.d.ts.map +1 -0
  104. package/dist/src/utils/filterConverter.spec.d.ts +2 -0
  105. package/dist/src/utils/filterConverter.spec.d.ts.map +1 -0
  106. package/dist/tsembed-react.es.js +252 -126
  107. package/dist/tsembed-react.js +251 -125
  108. package/dist/tsembed.es.js +460 -127
  109. package/dist/tsembed.js +459 -125
  110. package/dist/visual-embed-sdk-react-full.d.ts +233 -49
  111. package/dist/visual-embed-sdk-react.d.ts +139 -49
  112. package/dist/visual-embed-sdk.d.ts +233 -49
  113. package/lib/package.json +10 -3
  114. package/lib/src/contracts/host-event-contracts.d.ts +49 -11
  115. package/lib/src/contracts/host-event-contracts.d.ts.map +1 -1
  116. package/lib/src/embed/app.d.ts +4 -3
  117. package/lib/src/embed/app.d.ts.map +1 -1
  118. package/lib/src/embed/app.js.map +1 -1
  119. package/lib/src/embed/app.spec.js +10 -0
  120. package/lib/src/embed/app.spec.js.map +1 -1
  121. package/lib/src/embed/auto-frame-renderer.spec.js +24 -13
  122. package/lib/src/embed/auto-frame-renderer.spec.js.map +1 -1
  123. package/lib/src/embed/conversation.d.ts +1 -0
  124. package/lib/src/embed/conversation.d.ts.map +1 -1
  125. package/lib/src/embed/conversation.js +4 -4
  126. package/lib/src/embed/conversation.js.map +1 -1
  127. package/lib/src/embed/conversation.spec.js +35 -24
  128. package/lib/src/embed/conversation.spec.js.map +1 -1
  129. package/lib/src/embed/embedConfig.spec.js +2 -1
  130. package/lib/src/embed/embedConfig.spec.js.map +1 -1
  131. package/lib/src/embed/hostEventClient/host-event-client.d.ts +2 -2
  132. package/lib/src/embed/hostEventClient/host-event-client.d.ts.map +1 -1
  133. package/lib/src/embed/hostEventClient/host-event-client.js +17 -11
  134. package/lib/src/embed/hostEventClient/host-event-client.js.map +1 -1
  135. package/lib/src/embed/hostEventClient/host-event-client.spec.js +14 -8
  136. package/lib/src/embed/hostEventClient/host-event-client.spec.js.map +1 -1
  137. package/lib/src/embed/hostEventClient/utils.d.ts +9 -0
  138. package/lib/src/embed/hostEventClient/utils.d.ts.map +1 -1
  139. package/lib/src/embed/hostEventClient/utils.js +47 -2
  140. package/lib/src/embed/hostEventClient/utils.js.map +1 -1
  141. package/lib/src/embed/hostEventClient/utils.spec.js +152 -1
  142. package/lib/src/embed/hostEventClient/utils.spec.js.map +1 -1
  143. package/lib/src/embed/liveboard.d.ts +4 -3
  144. package/lib/src/embed/liveboard.d.ts.map +1 -1
  145. package/lib/src/embed/liveboard.js +17 -12
  146. package/lib/src/embed/liveboard.js.map +1 -1
  147. package/lib/src/embed/liveboard.spec.js +2 -1
  148. package/lib/src/embed/liveboard.spec.js.map +1 -1
  149. package/lib/src/embed/spotter-utils.d.ts +8 -1
  150. package/lib/src/embed/spotter-utils.d.ts.map +1 -1
  151. package/lib/src/embed/spotter-utils.js +12 -0
  152. package/lib/src/embed/spotter-utils.js.map +1 -1
  153. package/lib/src/embed/spotter-utils.spec.js +27 -1
  154. package/lib/src/embed/spotter-utils.spec.js.map +1 -1
  155. package/lib/src/embed/ts-embed.d.ts +35 -10
  156. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  157. package/lib/src/embed/ts-embed.js +109 -74
  158. package/lib/src/embed/ts-embed.js.map +1 -1
  159. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  160. package/lib/src/embed/ts-embed.spec.js +203 -30
  161. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  162. package/lib/src/errors.js +1 -1
  163. package/lib/src/errors.js.map +1 -1
  164. package/lib/src/index.d.ts +2 -1
  165. package/lib/src/index.d.ts.map +1 -1
  166. package/lib/src/index.js +2 -1
  167. package/lib/src/index.js.map +1 -1
  168. package/lib/src/react/all-types-export.d.ts +1 -1
  169. package/lib/src/react/all-types-export.d.ts.map +1 -1
  170. package/lib/src/react/all-types-export.js +1 -1
  171. package/lib/src/react/all-types-export.js.map +1 -1
  172. package/lib/src/types.d.ts +45 -22
  173. package/lib/src/types.d.ts.map +1 -1
  174. package/lib/src/types.js +44 -21
  175. package/lib/src/types.js.map +1 -1
  176. package/lib/src/utils/authService/tokenizedAuthService.spec.js +2 -1
  177. package/lib/src/utils/authService/tokenizedAuthService.spec.js.map +1 -1
  178. package/lib/src/utils/custom-actions.spec.js +4 -2
  179. package/lib/src/utils/custom-actions.spec.js.map +1 -1
  180. package/lib/src/utils/filterConverter.d.ts +106 -0
  181. package/lib/src/utils/filterConverter.d.ts.map +1 -0
  182. package/lib/src/utils/filterConverter.js +210 -0
  183. package/lib/src/utils/filterConverter.js.map +1 -0
  184. package/lib/src/utils/filterConverter.spec.d.ts +2 -0
  185. package/lib/src/utils/filterConverter.spec.d.ts.map +1 -0
  186. package/lib/src/utils/filterConverter.spec.js +707 -0
  187. package/lib/src/utils/filterConverter.spec.js.map +1 -0
  188. package/lib/src/utils/processData.spec.js +2 -1
  189. package/lib/src/utils/processData.spec.js.map +1 -1
  190. package/lib/src/visual-embed-sdk.d.ts +233 -49
  191. package/package.json +10 -3
  192. package/src/contracts/host-event-contracts.ts +55 -11
  193. package/src/embed/app.spec.ts +15 -0
  194. package/src/embed/app.ts +4 -3
  195. package/src/embed/auto-frame-renderer.spec.ts +24 -13
  196. package/src/embed/conversation.spec.ts +38 -27
  197. package/src/embed/conversation.ts +4 -4
  198. package/src/embed/embedConfig.spec.ts +2 -1
  199. package/src/embed/hostEventClient/host-event-client.spec.ts +14 -8
  200. package/src/embed/hostEventClient/host-event-client.ts +18 -10
  201. package/src/embed/hostEventClient/utils.spec.ts +176 -1
  202. package/src/embed/hostEventClient/utils.ts +51 -2
  203. package/src/embed/liveboard.spec.ts +4 -3
  204. package/src/embed/liveboard.ts +21 -15
  205. package/src/embed/spotter-utils.spec.ts +29 -0
  206. package/src/embed/spotter-utils.ts +16 -0
  207. package/src/embed/ts-embed.spec.ts +245 -30
  208. package/src/embed/ts-embed.ts +107 -74
  209. package/src/errors.ts +1 -1
  210. package/src/index.ts +10 -0
  211. package/src/react/all-types-export.ts +4 -0
  212. package/src/types.ts +44 -21
  213. package/src/utils/authService/tokenizedAuthService.spec.ts +2 -1
  214. package/src/utils/custom-actions.spec.ts +4 -2
  215. package/src/utils/filterConverter.spec.ts +801 -0
  216. package/src/utils/filterConverter.ts +304 -0
  217. package/src/utils/processData.spec.ts +2 -1
@@ -1,4 +1,4 @@
1
- /* @thoughtspot/visual-embed-sdk version 1.52.1 */
1
+ /* @thoughtspot/visual-embed-sdk version 1.52.2-beta.0 */
2
2
  'use client';
3
3
  function _mergeNamespaces(n, m) {
4
4
  m.forEach(function (e) {
@@ -3766,6 +3766,12 @@ var HostEvent;
3766
3766
  * ```js
3767
3767
  * const data = await liveboardEmbed.trigger(HostEvent.GetFilters);
3768
3768
  * console.log('data', data);
3769
+ * // {
3770
+ * // liveboardFilters: [ ... ],
3771
+ * // runtimeFilters: [
3772
+ * // { columnName: "Region", operator: "IN", values: ["West"] }
3773
+ * // ]
3774
+ * // }
3769
3775
  * ```
3770
3776
  * @example
3771
3777
  * ```js
@@ -3790,9 +3796,9 @@ var HostEvent;
3790
3796
  *
3791
3797
  * Each filter object must include the following attributes:
3792
3798
  *
3793
- * `column` - Name of the column to filter on.
3799
+ * `columnName` - Name of the column to filter on.
3794
3800
  *
3795
- * `oper` - Filter operator, for example, EQ, IN, CONTAINS.
3801
+ * `operator` - Filter operator, for example, EQ, IN, CONTAINS.
3796
3802
  * For information about the supported filter operators,
3797
3803
  * see link:https://developers.thoughtspot.com/docs/runtime-filters#rtOperator[Developer Documentation].
3798
3804
  *
@@ -3819,8 +3825,8 @@ var HostEvent;
3819
3825
  *
3820
3826
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3821
3827
  * filter: {
3822
- * column: "item type",
3823
- * oper: "IN",
3828
+ * columnName: "item type",
3829
+ * operator: "IN",
3824
3830
  * values: ["bags","shirts"]
3825
3831
  * }
3826
3832
  * });
@@ -3830,8 +3836,8 @@ var HostEvent;
3830
3836
  *
3831
3837
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3832
3838
  * filter: {
3833
- * column: "date",
3834
- * oper: "EQ",
3839
+ * columnName: "date",
3840
+ * operator: "EQ",
3835
3841
  * values: ["JULY","2023"],
3836
3842
  * type: "MONTH_YEAR"
3837
3843
  * }
@@ -3842,18 +3848,18 @@ var HostEvent;
3842
3848
  * ```js
3843
3849
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3844
3850
  * filters: [{
3845
- * column: "Item Type",
3846
- * oper: 'IN',
3851
+ * columnName: "Item Type",
3852
+ * operator: 'IN',
3847
3853
  * values: ["bags","shirts"]
3848
3854
  * },
3849
3855
  * {
3850
- * column: "Region",
3851
- * oper: 'IN',
3856
+ * columnName: "Region",
3857
+ * operator: 'IN',
3852
3858
  * values: ["West","Midwest"]
3853
3859
  * },
3854
3860
  * {
3855
- * column: "Date",
3856
- * oper: 'EQ',
3861
+ * columnName: "Date",
3862
+ * operator: 'EQ',
3857
3863
  * values: ["2023-07-31"],
3858
3864
  * type: "EXACT_DATE"
3859
3865
  * }]
@@ -3867,13 +3873,13 @@ var HostEvent;
3867
3873
  * ```js
3868
3874
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3869
3875
  * filters: [{
3870
- * column: "(Sample) Retail - Apparel::city",
3871
- * oper: 'IN',
3876
+ * columnName: "(Sample) Retail - Apparel::city",
3877
+ * operator: 'IN',
3872
3878
  * values: ["atlanta"]
3873
3879
  * },
3874
3880
  * {
3875
- * column: "(Sample) Retail - Apparel::Region",
3876
- * oper: 'IN',
3881
+ * columnName: "(Sample) Retail - Apparel::Region",
3882
+ * operator: 'IN',
3877
3883
  * values: ["West","Midwest"]
3878
3884
  * }]
3879
3885
  * });
@@ -3884,8 +3890,8 @@ var HostEvent;
3884
3890
  * import { ContextType } from '@thoughtspot/visual-embed-sdk';
3885
3891
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3886
3892
  * filter: {
3887
- * column: "item type",
3888
- * oper: "IN",
3893
+ * columnName: "item type",
3894
+ * operator: "IN",
3889
3895
  * values: ["shoes", "boots"]
3890
3896
  * }
3891
3897
  * }, ContextType.Liveboard);
@@ -3895,8 +3901,8 @@ var HostEvent;
3895
3901
  * // Scope the filter to a specific Liveboard tab
3896
3902
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3897
3903
  * filter: {
3898
- * column: "item type",
3899
- * oper: "IN",
3904
+ * columnName: "item type",
3905
+ * operator: "IN",
3900
3906
  * values: ["bags", "shirts"],
3901
3907
  * applicability: {
3902
3908
  * level: "TAB",
@@ -3905,6 +3911,12 @@ var HostEvent;
3905
3911
  * }
3906
3912
  * });
3907
3913
  * ```
3914
+ * Use `columnName` and `operator` - the same spelling as
3915
+ * {@link RuntimeFilter}. The older `column` and `oper` spellings are
3916
+ * deprecated; they are still accepted, but pass only one spelling of each
3917
+ * field, never both. To reapply the filter state captured from
3918
+ * {@link EmbedEvent.FilterChanged}, use `convertFilterChangedToUpdateFiltersPayload`
3919
+ * to convert its payload into the shape expected here.
3908
3920
  * @version SDK: 1.23.0 | ThoughtSpot: 9.4.0.cl
3909
3921
  */
3910
3922
  HostEvent["UpdateFilters"] = "updateFilters";
@@ -4890,7 +4902,6 @@ var Param;
4890
4902
  Param["IsStarterPromptsEnabled"] = "enableStarterPrompts";
4891
4903
  Param["UpdatedSpotterExperience"] = "updatedSpotterExperience";
4892
4904
  Param["SpotterDataSources"] = "spotterDataSources";
4893
- Param["AnalystId"] = "analystId";
4894
4905
  Param["OpenSpotterOnLiveboardByDefault"] = "openSpotterOnLiveboardByDefault";
4895
4906
  Param["ShowAnswerEditPanel"] = "showAnswerEditPanel";
4896
4907
  })(Param || (Param = {}));
@@ -7116,6 +7127,18 @@ var Action;
7116
7127
  * ```
7117
7128
  */
7118
7129
  Action["DeleteCollection"] = "deleteCollection";
7130
+ /**
7131
+ * Controls the visibility of the "Customize homepage" button on the
7132
+ * embedded home page.
7133
+ * @version SDK: 1.55.0 | ThoughtSpot Cloud: 26.12.0.cl
7134
+ * @example
7135
+ * ```js
7136
+ * {
7137
+ * hiddenActions: [Action.CustomizeHomepage],
7138
+ * }
7139
+ * ```
7140
+ */
7141
+ Action["CustomizeHomepage"] = "customizeHomepage";
7119
7142
  })(Action || (Action = {}));
7120
7143
  var PrefetchFeatures;
7121
7144
  (function (PrefetchFeatures) {
@@ -7620,7 +7643,7 @@ var TableContentDensity;
7620
7643
  TableContentDensity["Compact"] = "COMPACT";
7621
7644
  })(TableContentDensity || (TableContentDensity = {}));
7622
7645
 
7623
- var version$1="1.52.1";var pkg = {version:version$1};
7646
+ var version$1="1.52.2-beta.0";var pkg = {version:version$1};
7624
7647
 
7625
7648
  const { version } = pkg;
7626
7649
 
@@ -7793,7 +7816,7 @@ const ERROR_MESSAGE = {
7793
7816
  SSR_ENVIRONMENT_ERROR: 'SSR environment detected. This function cannot be called in SSR environment.',
7794
7817
  UPDATE_PARAMS_FAILED: 'Failed to update embed parameters',
7795
7818
  INVALID_SPOTTER_DOCUMENTATION_URL: 'Invalid spotterDocumentationUrl. Please provide a valid http or https URL.',
7796
- UPDATEFILTERS_INVALID_PAYLOAD: 'UpdateFilters requires a valid filter or filters array. Expected: { filter: { column, oper, values } } or { filters: [{ column, oper, values }, ...] }',
7819
+ UPDATEFILTERS_INVALID_PAYLOAD: 'UpdateFilters requires a valid filter or filters array. Expected: { filter: { columnName, operator, values } } or { filters: [{ columnName, operator, values }, ...] }',
7797
7820
  DRILLDOWN_INVALID_PAYLOAD: 'DrillDown requires a valid points object. Expected: { points: { clickedPoint?, selectedPoints? }, autoDrillDown?, vizId? }',
7798
7821
  UPDATEPARAMETERS_INVALID_PAYLOAD: 'UpdateParameters received an invalid applicability. Expected: { level: LIVEBOARD | TAB | GROUP, targetId } where targetId is required for TAB and GROUP levels',
7799
7822
  };
@@ -10756,7 +10779,7 @@ class AnswerService {
10756
10779
  async getTML() {
10757
10780
  const { object } = await this.executeQuery(getAnswerTML, {});
10758
10781
  const edoc = object[0].edoc;
10759
- const YAML = await import('./index-C1pmYb5H.js');
10782
+ const YAML = await import('./index-BrJMbt8r.js');
10760
10783
  const parsedDoc = YAML.parse(edoc);
10761
10784
  return {
10762
10785
  answer: {
@@ -21665,7 +21688,8 @@ var isUndefined_1 = isUndefined;
21665
21688
  const isValidApplicability = (a) => {
21666
21689
  if (isUndefined_1(a))
21667
21690
  return true;
21668
- // targetId is not required at LIVEBOARD level, since the filter applies to the whole Liveboard
21691
+ // targetId is not required at LIVEBOARD level, since the filter applies to
21692
+ // the whole Liveboard
21669
21693
  return isPlainObject_1(a)
21670
21694
  && Object.values(ApplicabilityLevel).includes(a.level)
21671
21695
  && (a.level === ApplicabilityLevel.Liveboard || (isString_1(a.targetId) && a.targetId.trim().length > 0));
@@ -21684,8 +21708,52 @@ function isValidUpdateFiltersPayload(payload) {
21684
21708
  const hasValidFilters = Array.isArray(payload.filters) && payload.filters.length > 0 && payload.filters.every(isValidFilter);
21685
21709
  return !!(hasValidFilter || hasValidFilters);
21686
21710
  }
21711
+ /**
21712
+ * Rewrites one filter's `columnName`/`operator` to `column`/`oper`.
21713
+ *
21714
+ * Callers may use either spelling: `columnName`/`operator` match
21715
+ * {@link RuntimeFilter} and the `EmbedEvent.FilterChanged` payload, so a
21716
+ * converted payload can be replayed as-is. But the payload is forwarded to the
21717
+ * embedded app unchanged, and only `column`/`oper` are known to be understood
21718
+ * there - so the alias must be swapped here, or it would pass validation and
21719
+ * then be silently ignored.
21720
+ *
21721
+ * If a caller supplies both spellings of a field - which TypeScript rejects,
21722
+ * but JavaScript callers can still do - the documented `columnName`/`operator`
21723
+ * wins. Deferring to the deprecated spelling would quietly discard the value
21724
+ * the rest of the SDK tells people to use.
21725
+ * @param filter One entry from the UpdateFilters payload.
21726
+ */
21727
+ function resolveFilterAliases(filter) {
21728
+ var _a, _b;
21729
+ if (!isPlainObject_1(filter))
21730
+ return filter;
21731
+ const column = (_a = filter.columnName) !== null && _a !== void 0 ? _a : filter.column;
21732
+ const oper = (_b = filter.operator) !== null && _b !== void 0 ? _b : filter.oper;
21733
+ const { columnName, operator, ...rest } = filter;
21734
+ return {
21735
+ ...rest,
21736
+ ...(isUndefined_1(column) ? {} : { column }),
21737
+ ...(isUndefined_1(oper) ? {} : { oper }),
21738
+ };
21739
+ }
21740
+ /**
21741
+ * Rewrites every filter in an UpdateFilters payload to use `column`/`oper`,
21742
+ * whichever spelling the caller supplied. Call after validation.
21743
+ * @param payload The UpdateFilters host event payload.
21744
+ */
21745
+ function resolveUpdateFiltersAliases(payload) {
21746
+ if (!isPlainObject_1(payload))
21747
+ return payload;
21748
+ return {
21749
+ ...payload,
21750
+ ...(payload.filter ? { filter: resolveFilterAliases(payload.filter) } : {}),
21751
+ ...(Array.isArray(payload.filters) ? { filters: payload.filters.map(resolveFilterAliases) } : {}),
21752
+ };
21753
+ }
21687
21754
  function isValidUpdateParametersPayload(payload) {
21688
- // Only validates the applicability of each parameter (null treated as absent); the rest is forwarded as-is for backward compatibility.
21755
+ // Only validates the applicability of each parameter (null treated as
21756
+ // absent); the rest is forwarded as-is for backward compatibility.
21689
21757
  if (!Array.isArray(payload))
21690
21758
  return true;
21691
21759
  return payload.every((p) => {
@@ -21733,7 +21801,8 @@ function throwUpdateParametersValidationError() {
21733
21801
  /**
21734
21802
  * Maps HostEvent to its corresponding UIPassthroughEvent.
21735
21803
  * Includes both custom-handler events (Pin, SaveAnswer, UpdateFilters, DrillDown)
21736
- * and getter events (GetAnswerSession, GetFilters, etc.) that use getDataWithPassthroughFallback.
21804
+ * and getter events (GetAnswerSession, GetFilters, etc.) that use
21805
+ * getDataWithPassthroughFallback.
21737
21806
  */
21738
21807
  const PASSTHROUGH_MAP = {
21739
21808
  // Custom handlers (setters with special logic)
@@ -21884,17 +21953,21 @@ class HostEventClient {
21884
21953
  throwUpdateFiltersValidationError();
21885
21954
  }
21886
21955
  // The shared contract accepts both current (columnName/operator) and
21887
- // legacy (column/oper) filter field names — as does the validation
21888
- // above and the app at runtime. The UIPassthrough FilterUpdate type
21889
- // still requires the legacy names; bridge until that contract is
21890
- // audited.
21891
- return this.handleHostEventWithParam(UIPassthroughEvent.UpdateFilters, payload, context);
21956
+ // legacy (column/oper) filter field names, but only the legacy pair is
21957
+ // understood downstream, so the payload is rewritten before it is
21958
+ // forwarded — otherwise a columnName/operator filter passes validation
21959
+ // here and is then silently ignored by the app. The cast bridges the
21960
+ // UIPassthrough FilterUpdate type, which still declares only the legacy
21961
+ // names.
21962
+ const resolvedPayload = resolveUpdateFiltersAliases(payload);
21963
+ return this.handleHostEventWithParam(UIPassthroughEvent.UpdateFilters, resolvedPayload, context);
21892
21964
  }
21893
21965
  handleUpdateParametersEvent(payload, context) {
21894
21966
  if (!isValidUpdateParametersPayload(payload)) {
21895
21967
  throwUpdateParametersValidationError();
21896
21968
  }
21897
- // UpdateParameters has no UI passthrough contract; dispatch over the legacy channel
21969
+ // UpdateParameters has no UI passthrough contract; dispatch over the
21970
+ // legacy channel
21898
21971
  return this.hostEventFallback(HostEvent.UpdateParameters, payload, context);
21899
21972
  }
21900
21973
  handleDrillDownEvent(payload, context) {
@@ -21905,8 +21978,8 @@ class HostEventClient {
21905
21978
  }
21906
21979
  /**
21907
21980
  * Dispatches a host event using the appropriate channel:
21908
- * 1. If the embedded app supports UI passthrough for this event, use it (custom handler or getter).
21909
- * 2. Otherwise fall back to the legacy host event channel.
21981
+ * 1. If the embedded app supports UI passthrough for this event, use it (custom
21982
+ * handler or getter). 2. Otherwise fall back to the legacy host event channel.
21910
21983
  *
21911
21984
  * @param hostEvent - The host event to trigger
21912
21985
  * @param payload - Optional payload for the event
@@ -21915,7 +21988,8 @@ class HostEventClient {
21915
21988
  async triggerHostEvent(hostEvent, payload, context) {
21916
21989
  const customHandler = this.customHandlers[hostEvent];
21917
21990
  const passthroughEvent = PASSTHROUGH_MAP[hostEvent];
21918
- // If embedded app supports passthrough but not this event, use legacy channel
21991
+ // If embedded app supports passthrough but not this event, use legacy
21992
+ // channel
21919
21993
  const keys = passthroughEvent ? await this.getAvailableUIPassthroughKeys(context) : [];
21920
21994
  if (passthroughEvent && keys.length > 0 && !keys.includes(passthroughEvent)) {
21921
21995
  return this.hostEventFallback(hostEvent, payload, context);
@@ -22122,11 +22196,15 @@ const TS_EMBED_ID = '_thoughtspot-embed';
22122
22196
  */
22123
22197
  const PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY = 'tsEmbedOriginalPosition';
22124
22198
  const PRERENDER_WRAPPER_ID_PREFIX = 'tsEmbed-pre-render-wrapper-';
22199
+ const PRERENDER_PARKED_TRANSFORM = 'translateY(-100%)';
22200
+ /** The height createPreRenderWrapper() seeds before anything is measured. */
22201
+ const UNMEASURED_WRAPPER_HEIGHT = '100vh';
22125
22202
  // The container applies UpdateEmbedParams through React state, so a delivered
22126
22203
  // post is not the same as the params being in effect.
22127
22204
  const UPDATE_EMBED_PARAMS_SETTLE_MS = 200;
22128
- // The container ignores runtimeFilterParams/runtimeParameterParams unless truthy, so
22129
- // null or '' leaves the previous embed's values in place. '&' is truthy and parses to {}.
22205
+ // The container ignores runtimeFilterParams/runtimeParameterParams unless
22206
+ // truthy, so null or '' leaves the previous embed's values in place. '&' is
22207
+ // truthy and parses to {}.
22130
22208
  const NO_RUNTIME_PARAMS = '&';
22131
22209
  /**
22132
22210
  * The event id map from v2 event names to v1 event id
@@ -22165,7 +22243,6 @@ class TsEmbed {
22165
22243
  this.shouldEncodeUrlQueryParams = false;
22166
22244
  this.defaultHiddenActions = [Action.ReportError];
22167
22245
  this.preRenderContainerEl = document.body;
22168
- this.containerScrollListener = null;
22169
22246
  /**
22170
22247
  * Handler for fullscreen change events
22171
22248
  */
@@ -22324,7 +22401,8 @@ class TsEmbed {
22324
22401
  const AUTH_INIT_FALLBACK_DELAY = 1000;
22325
22402
  // Wait for 1 second to ensure the embed container is loaded
22326
22403
  // This is a workaround to ensure the embed container is loaded
22327
- // this is needed until all clusters have EmbedListenerReady event
22404
+ // this is needed until all clusters have EmbedListenerReady
22405
+ // event
22328
22406
  setTimeout(processEmbedContainerReady, AUTH_INIT_FALLBACK_DELAY);
22329
22407
  }
22330
22408
  else if (source === EmbedEvent.EmbedListenerReady) {
@@ -22332,7 +22410,8 @@ class TsEmbed {
22332
22410
  }
22333
22411
  };
22334
22412
  // Subclasses that navigate the pre-render on show must await this before
22335
- // triggering Navigate. Resolves even on failure, so navigation is never blocked.
22413
+ // triggering Navigate. Resolves even on failure, so navigation is never
22414
+ // blocked.
22336
22415
  this.preRenderParamsApplied = Promise.resolve();
22337
22416
  this.hostElement = getDOMNode(domSelector);
22338
22417
  this.eventHandlerMap = new Map();
@@ -22662,8 +22741,9 @@ class TsEmbed {
22662
22741
  ...this.viewConfig,
22663
22742
  ...queryParams,
22664
22743
  ...appInitData,
22665
- // A show cycle has no URL to carry these, so the payload always states them
22666
- // — including "none", which is the case that leaks the previous filters.
22744
+ // A show cycle has no URL to carry these, so the payload always
22745
+ // states them — including "none", which is the case that leaks the
22746
+ // previous filters.
22667
22747
  runtimeFilterParams: getFilterQuery((_a = this.viewConfig.runtimeFilters) !== null && _a !== void 0 ? _a : []) || NO_RUNTIME_PARAMS,
22668
22748
  runtimeParameterParams: getRuntimeParameters((_b = this.viewConfig.runtimeParameters) !== null && _b !== void 0 ? _b : [])
22669
22749
  || NO_RUNTIME_PARAMS,
@@ -23008,7 +23088,7 @@ class TsEmbed {
23008
23088
  top: '0',
23009
23089
  left: '0',
23010
23090
  width: '100vw',
23011
- height: '100vh',
23091
+ height: UNMEASURED_WRAPPER_HEIGHT,
23012
23092
  };
23013
23093
  setStyleProperties(preRenderWrapper, initialPreRenderWrapperStyle);
23014
23094
  return preRenderWrapper;
@@ -23076,10 +23156,26 @@ class TsEmbed {
23076
23156
  return placeholder;
23077
23157
  }
23078
23158
  /**
23079
- * Resolves the configured preRenderContainer to a live element, falling
23080
- * back to `document.body`. A string selector is re-queried on every call so
23081
- * a remounted container (E.g.: React replacing the node) resolves to the
23082
- * fresh element; an element passed directly cannot be re-resolved.
23159
+ * Resolves the configured preRenderContainer to a live element. A string
23160
+ * selector is re-queried on every call so a remounted container (E.g.: React
23161
+ * replacing the node) resolves to the fresh element; an element passed
23162
+ * directly cannot be re-resolved.
23163
+ *
23164
+ * With nothing configured the frame goes into the host element's nearest
23165
+ * scrolling ancestor, falling back to `document.body`.
23166
+ *
23167
+ * The wrapper is absolutely positioned, so it follows the page for free —
23168
+ * but only while it sits inside whatever scrolls. `document.body` is right
23169
+ * only when the document itself is the scroller; an app that scrolls an
23170
+ * inner element instead left the frame pinned to the viewport while the page
23171
+ * moved under it (SCAL-338563). Being inside the scroller also lets wheel
23172
+ * events chain out of the frame into it, which they cannot do from
23173
+ * `document.body`.
23174
+ *
23175
+ * A scrolling ancestor is layout chrome rather than route content, so it
23176
+ * outlives the embed in practice; and if it does go, the host element goes
23177
+ * with it and this instance is remounting anyway.
23178
+ * `reconcilePreRenderContainer` re-runs this on a detached container.
23083
23179
  */
23084
23180
  resolvePreRenderContainerTarget() {
23085
23181
  var _a;
@@ -23099,7 +23195,13 @@ class TsEmbed {
23099
23195
  else if (containerConfig) {
23100
23196
  container = containerConfig;
23101
23197
  }
23102
- return (_a = container) !== null && _a !== void 0 ? _a : document.body;
23198
+ if (container) {
23199
+ return container;
23200
+ }
23201
+ if (!this.hostElement) {
23202
+ return document.body;
23203
+ }
23204
+ return (_a = getScrollableAncestors(this.hostElement)[0]) !== null && _a !== void 0 ? _a : document.body;
23103
23205
  }
23104
23206
  inheritPreRenderContainer() {
23105
23207
  var _a;
@@ -23144,8 +23246,9 @@ class TsEmbed {
23144
23246
  * Re-attaches the wrapper to a live container when the previously resolved
23145
23247
  * one has been detached or no longer holds the wrapper — e.g. the host app
23146
23248
  * remounted a custom preRenderContainer, which would otherwise leave a stale
23147
- * reference and collapse the wrapper. Only string selectors can be
23148
- * re-resolved; a container passed as an element is left untouched.
23249
+ * reference and collapse the wrapper. Selectors and the auto-resolved
23250
+ * scrolling ancestor are both re-resolved; a container passed as an element
23251
+ * is left untouched, as there is nothing to re-query.
23149
23252
  */
23150
23253
  reconcilePreRenderContainer() {
23151
23254
  const wrapper = this.preRenderWrapper;
@@ -23164,14 +23267,6 @@ class TsEmbed {
23164
23267
  if (resolved === stored && stored.contains(wrapper)) {
23165
23268
  return;
23166
23269
  }
23167
- if (this.containerScrollListener && stored !== resolved) {
23168
- if (stored !== document.body) {
23169
- stored.removeEventListener('scroll', this.containerScrollListener);
23170
- }
23171
- if (resolved !== document.body) {
23172
- resolved.addEventListener('scroll', this.containerScrollListener);
23173
- }
23174
- }
23175
23270
  this.preRenderContainerEl = resolved;
23176
23271
  this.applyPreRenderContainerPositioning();
23177
23272
  if (wrapper.parentNode !== resolved) {
@@ -23233,11 +23328,12 @@ class TsEmbed {
23233
23328
  */
23234
23329
  setIFrameHeight(height) {
23235
23330
  if (this.isPreRendered) {
23331
+ const next = getCssDimension(height);
23236
23332
  if (this.insertedDomEl) {
23237
- this.insertedDomEl.style.height = getCssDimension(height);
23333
+ this.insertedDomEl.style.height = next;
23238
23334
  }
23239
23335
  else if (this.preRenderWrapper) {
23240
- this.preRenderWrapper.style.height = getCssDimension(height);
23336
+ this.preRenderWrapper.style.height = next;
23241
23337
  }
23242
23338
  }
23243
23339
  else {
@@ -23390,8 +23486,9 @@ class TsEmbed {
23390
23486
  return;
23391
23487
  this.preRenderWrapper[this.embedNodeKey] = this;
23392
23488
  }
23393
- // The flag lives on the wrapper because it describes the iframe: an instance
23394
- // hidden when the container announced itself would otherwise report false forever.
23489
+ // The flag lives on the wrapper because it describes the iframe: an
23490
+ // instance hidden when the container announced itself would otherwise
23491
+ // report false forever.
23395
23492
  markEmbedContainerLoaded() {
23396
23493
  this.isEmbedContainerLoaded = true;
23397
23494
  if (this.preRenderWrapper) {
@@ -23671,34 +23768,47 @@ class TsEmbed {
23671
23768
  delete container.dataset[PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY];
23672
23769
  }
23673
23770
  /**
23674
- * Detaches and clears the container scroll listener, if one is attached.
23675
- */
23676
- removeContainerScrollListener() {
23677
- if (!this.containerScrollListener) {
23771
+ * Re-sizes the wrapper when its placeholder changes size.
23772
+ *
23773
+ * Position deliberately has no equivalent. An absolutely positioned wrapper
23774
+ * follows its containing block for free, so a correctly placed frame is the
23775
+ * browser's job and costs nothing; repositioning it on scroll would mean a
23776
+ * layout read and a style write per frame to compensate for placing it in
23777
+ * the wrong box. Size is the one thing the browser will not do for us: the
23778
+ * placeholder grows when the embedded app reports a new height, and the
23779
+ * wrapper has to be told.
23780
+ */
23781
+ observePreRenderSize() {
23782
+ var _a;
23783
+ if (this.getPreRenderConfig().doNotTrackSize || typeof ResizeObserver === 'undefined') {
23784
+ return;
23785
+ }
23786
+ const placeholder = this.getPreRenderPlaceHolderElement();
23787
+ if (!placeholder) {
23678
23788
  return;
23679
23789
  }
23680
- const customContainer = this.getCustomPreRenderContainer();
23681
- customContainer === null || customContainer === void 0 ? void 0 : customContainer.removeEventListener('scroll', this.containerScrollListener);
23682
- this.containerScrollListener = null;
23790
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23791
+ this.resizeObserver = new ResizeObserver(() => this.syncPreRenderStyle());
23792
+ this.resizeObserver.observe(placeholder);
23683
23793
  }
23684
23794
  /**
23685
23795
  * Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
23686
23796
  * @version SDK: 1.19.1 | ThoughtSpot: *
23687
23797
  */
23688
23798
  destroy() {
23689
- var _a, _b, _c;
23799
+ var _a, _b, _c, _d;
23690
23800
  try {
23691
23801
  this.removeFullscreenChangeHandler();
23692
- this.removeContainerScrollListener();
23802
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23693
23803
  this.unsubscribeToEvents();
23694
- (_a = this.preRenderWrapper) === null || _a === void 0 ? void 0 : _a.remove();
23804
+ (_b = this.preRenderWrapper) === null || _b === void 0 ? void 0 : _b.remove();
23695
23805
  this.restorePreRenderContainerPosition();
23696
23806
  if (!this.isRendered) {
23697
23807
  return;
23698
23808
  }
23699
23809
  if (!getEmbedConfig().waitForCleanupOnDestroy) {
23700
23810
  this.trigger(HostEvent.DestroyEmbed);
23701
- (_c = (_b = this.insertedDomEl) === null || _b === void 0 ? void 0 : _b.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(this.insertedDomEl);
23811
+ (_d = (_c = this.insertedDomEl) === null || _c === void 0 ? void 0 : _c.parentNode) === null || _d === void 0 ? void 0 : _d.removeChild(this.insertedDomEl);
23702
23812
  }
23703
23813
  else {
23704
23814
  const cleanupTimeout = getEmbedConfig().cleanupTimeout;
@@ -23779,7 +23889,7 @@ class TsEmbed {
23779
23889
  * wrapper to overlay it.
23780
23890
  */
23781
23891
  async showPreRender() {
23782
- var _a, _b;
23892
+ var _a;
23783
23893
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_SHOW_PRE_RENDER, {
23784
23894
  preRenderId: this.getPreRenderConfig().id,
23785
23895
  embedComponentType: this.viewConfig.embedComponentType,
@@ -23798,54 +23908,49 @@ class TsEmbed {
23798
23908
  this.beforePrerenderVisible();
23799
23909
  if (this.hostElement) {
23800
23910
  this.insertedDomEl = this.createPreRenderPlaceholder();
23801
- if (this.viewConfig.fullHeight) {
23802
- // If fullHeight has already sized the wrapper, seed the placeholder
23803
- // with the same height so syncPreRenderStyle gets an accurate rect.
23804
- const existingHeight = this.preRenderWrapper.style.height;
23805
- if (existingHeight) {
23806
- this.insertedDomEl.style.height = existingHeight;
23807
- }
23911
+ // Carry a height fullHeight has already measured onto the fresh
23912
+ // placeholder, so a re-show does not flash at frameParams height.
23913
+ // UNMEASURED_WRAPPER_HEIGHT is what createPreRenderWrapper() seeds
23914
+ // before anything has been measured; treating that as a measurement
23915
+ // is what made a first reveal overshoot to a full viewport.
23916
+ const wrapperHeight = this.preRenderWrapper.style.height;
23917
+ if (this.viewConfig.fullHeight
23918
+ && wrapperHeight
23919
+ && wrapperHeight !== UNMEASURED_WRAPPER_HEIGHT) {
23920
+ this.insertedDomEl.style.height = wrapperHeight;
23808
23921
  }
23809
23922
  const placeHolderId = this.getPreRenderIds().placeHolder;
23810
23923
  // Remove any stale placeholder from a previous cycle. It is located
23811
- // via a subtree-wide querySelector, so it may be nested deeper than a
23812
- // direct child (E.g.: with fullHeight the host app can wrap it). Use
23813
- // Element.remove() — which detaches from whatever the real parent is —
23814
- // rather than hostElement.removeChild(), which throws NotFoundError
23815
- // when the match is not a direct child. Mirrors the wrapper/child
23816
- // cleanup in createPreRenderWrapper()/createPreRenderChild().
23924
+ // via a subtree-wide querySelector, so it may be nested deeper
23925
+ // than a direct child (E.g.: with fullHeight the host app can wrap
23926
+ // it). Use Element.remove() — which detaches from whatever the real
23927
+ // parent is — rather than hostElement.removeChild(), which throws
23928
+ // NotFoundError when the match is not a direct child. Mirrors the
23929
+ // wrapper/child cleanup in
23930
+ // createPreRenderWrapper()/createPreRenderChild().
23817
23931
  (_a = this.hostElement.querySelector(`#${placeHolderId}`)) === null || _a === void 0 ? void 0 : _a.remove();
23818
23932
  this.hostElement.appendChild(this.insertedDomEl);
23819
23933
  this.syncPreRenderStyle();
23820
- const customContainer = this.getCustomPreRenderContainer();
23821
- if (customContainer && !this.containerScrollListener) {
23822
- this.containerScrollListener = () => this.syncPreRenderStyle();
23823
- customContainer.addEventListener('scroll', this.containerScrollListener);
23824
- }
23825
- if (!this.getPreRenderConfig().doNotTrackSize) {
23826
- const observeTarget = (_b = this.insertedDomEl) !== null && _b !== void 0 ? _b : this.hostElement;
23827
- this.resizeObserver = new ResizeObserver((entries) => {
23828
- entries.forEach((entry) => {
23829
- if (entry.target === observeTarget) {
23830
- this.syncPreRenderStyle();
23831
- }
23832
- });
23833
- });
23834
- this.resizeObserver.observe(observeTarget);
23835
- }
23934
+ this.observePreRenderSize();
23836
23935
  }
23837
23936
  removeStyleProperties(this.preRenderWrapper, [
23838
23937
  'z-index',
23839
23938
  'opacity',
23840
- 'pointer-events',
23841
23939
  'overflow',
23940
+ 'transform',
23842
23941
  ]);
23942
+ // Set rather than removed: a container that carries `pointer-events:
23943
+ // none` — the usual styling for a parking root that must not swallow
23944
+ // clicks — passes it down, and dropping the property here would leave
23945
+ // the inherited `none` in force and the frame dead to input.
23946
+ setStyleProperties(this.preRenderWrapper, { pointerEvents: 'auto' });
23843
23947
  this.subscribeToEvents();
23844
23948
  // Setup fullscreen change handler for prerendered components
23845
23949
  if (this.iFrame) {
23846
23950
  this.setupFullscreenChangeHandler();
23847
23951
  }
23848
- // Last, so everything above still sees the instance being taken over from.
23952
+ // Last, so everything above still sees the instance being taken over
23953
+ // from.
23849
23954
  this.takeOverPreRender();
23850
23955
  return this;
23851
23956
  }
@@ -23891,6 +23996,7 @@ class TsEmbed {
23891
23996
  * If the component is not preRendered, it issues a warning.
23892
23997
  */
23893
23998
  hidePreRender() {
23999
+ var _a;
23894
24000
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_HIDE_PRE_RENDER, {
23895
24001
  preRenderId: this.getPreRenderConfig().id,
23896
24002
  embedComponentType: this.viewConfig.embedComponentType,
@@ -23910,12 +24016,15 @@ class TsEmbed {
23910
24016
  top: '0',
23911
24017
  left: '0',
23912
24018
  overflow: 'hidden',
24019
+ // Keeps the measured size — so the next show needs no resize, which
24020
+ // is the point of pre-rendering — while lifting the box out of
24021
+ // the container's scrollable area. Overflow only extends
24022
+ // downwards, so a hidden frame parked above the top edge adds
24023
+ // none, where one left at full height shows as blank scroll space.
24024
+ transform: PRERENDER_PARKED_TRANSFORM,
23913
24025
  };
23914
24026
  setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
23915
- this.removeContainerScrollListener();
23916
- if (this.resizeObserver) {
23917
- this.resizeObserver.disconnect();
23918
- }
24027
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23919
24028
  const placeHolderEle = this.getPreRenderPlaceHolderElement();
23920
24029
  if (placeHolderEle) {
23921
24030
  placeHolderEle.parentElement.removeChild(placeHolderEle);
@@ -24132,6 +24241,18 @@ function buildStarterPromptsAppInitData(initData, viewConfig) {
24132
24241
  starterPrompts,
24133
24242
  },
24134
24243
  };
24244
+ }
24245
+ function buildSpotterAnalystAppInitData(initData, viewConfig) {
24246
+ const { spotterAnalystConfig } = viewConfig;
24247
+ if (!(spotterAnalystConfig === null || spotterAnalystConfig === void 0 ? void 0 : spotterAnalystConfig.analystId))
24248
+ return initData;
24249
+ return {
24250
+ ...initData,
24251
+ embedParams: {
24252
+ ...(initData.embedParams || {}),
24253
+ spotterAnalystConfig,
24254
+ },
24255
+ };
24135
24256
  }
24136
24257
 
24137
24258
  function buildSpotterVizAppInitData(initData, viewConfig) {
@@ -24725,8 +24846,9 @@ const addPreviewStylesIfNotPresent = () => {
24725
24846
  * @summary Liveboard & visualization embed
24726
24847
  * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
24727
24848
  */
24728
- // Home unmounts the liveboard container, which is how its state gets cleared. The
24729
- // settle window gives the container time to do it before we ask for the liveboard back.
24849
+ // Home unmounts the liveboard container, which is how its state gets cleared.
24850
+ // The settle window gives the container time to do it before we ask for the
24851
+ // liveboard back.
24730
24852
  const HOME_ROUTE = 'home';
24731
24853
  const HOME_SETTLE_MS = 200;
24732
24854
  /**
@@ -25024,21 +25146,24 @@ class LiveboardEmbed extends V1Embed {
25024
25146
  }
25025
25147
  beforePrerenderVisible() {
25026
25148
  super.beforePrerenderVisible();
25027
- // Captured before showPreRender() hands the wrapper over to this instance.
25028
- // Itself means a hide/show, not a hand-over, so there is nothing stale to clear.
25149
+ // Captured before showPreRender() hands the wrapper over to this
25150
+ // instance. Itself means a hide/show, not a hand-over, so there is
25151
+ // nothing stale to clear.
25029
25152
  const previous = this.getPreRenderObj();
25030
25153
  const showing = previous === this ? undefined : previous === null || previous === void 0 ? void 0 : previous.currentLiveboardState;
25031
25154
  this.executeAfterEmbedContainerLoaded(async () => {
25032
- // Without this the params callback suspends on its await and Navigate
25033
- // goes out first, so the container loads with the previous config's filters.
25155
+ // Without this the params callback suspends on its await and
25156
+ // Navigate goes out first, so the container loads with the previous
25157
+ // config's filters.
25034
25158
  await this.preRenderParamsApplied;
25035
25159
  if (this.isShowingLiveboardRoute(showing)) {
25036
- // Navigate to the route we are already on is a no-op, so the liveboard
25037
- // keeps its state. Home unmounts the container, which clears it.
25160
+ // Navigate to the route we are already on is a no-op, so the
25161
+ // liveboard keeps its state. Home unmounts the container, which
25162
+ // clears it.
25038
25163
  this.trigger(HostEvent.Navigate, HOME_ROUTE)
25039
25164
  .catch((error) => logger$3.warn('Could not route via home', error));
25040
- // Not awaited above: the container never acks Navigate, so that promise
25041
- // only settles on the 30s trigger timeout.
25165
+ // Not awaited above: the container never acks Navigate, so
25166
+ // that promise only settles on the 30s trigger timeout.
25042
25167
  await new Promise((resolve) => {
25043
25168
  setTimeout(resolve, HOME_SETTLE_MS);
25044
25169
  });
@@ -25052,8 +25177,9 @@ class LiveboardEmbed extends V1Embed {
25052
25177
  };
25053
25178
  });
25054
25179
  }
25055
- // The whole route, not just the liveboard id: the path is built from the viz, tab
25056
- // and view too, so a same-liveboard show onto another tab is a real navigation.
25180
+ // The whole route, not just the liveboard id: the path is built from the
25181
+ // viz, tab and view too, so a same-liveboard show onto another tab is a
25182
+ // real navigation.
25057
25183
  isShowingLiveboardRoute(showing) {
25058
25184
  if (!(showing === null || showing === void 0 ? void 0 : showing.liveboardId))
25059
25185
  return false;
@@ -26003,10 +26129,11 @@ class SpotterEmbed extends TsEmbed {
26003
26129
  const defaultAppInitData = await super.getAppInitData();
26004
26130
  const sidebarInitData = buildSpotterSidebarAppInitData(defaultAppInitData, this.viewConfig, this.handleError.bind(this));
26005
26131
  const shareInitData = buildSpotterShareConversationAppInitData(sidebarInitData, this.viewConfig);
26006
- return buildStarterPromptsAppInitData(shareInitData, this.viewConfig);
26132
+ const starterPromptsInitData = buildStarterPromptsAppInitData(shareInitData, this.viewConfig);
26133
+ return buildSpotterAnalystAppInitData(starterPromptsInitData, this.viewConfig);
26007
26134
  }
26008
26135
  getEmbedParamsObject() {
26009
- const { searchOptions, disableSourceSelection, hideSourceSelection, dataPanelV2, updatedSpotterExperience, showSpotterLimitations, hideSampleQuestions, runtimeFilters, excludeRuntimeFiltersfromURL, runtimeParameters, excludeRuntimeParametersfromURL, updatedSpotterChatPrompt, showSpotterRadiance, defaultQueryMode, enableStopAnswerGenerationEmbed, spotterChatConfig, spotterAnalystConfig, } = this.viewConfig;
26136
+ const { searchOptions, disableSourceSelection, hideSourceSelection, dataPanelV2, updatedSpotterExperience, showSpotterLimitations, hideSampleQuestions, runtimeFilters, excludeRuntimeFiltersfromURL, runtimeParameters, excludeRuntimeParametersfromURL, updatedSpotterChatPrompt, showSpotterRadiance, defaultQueryMode, enableStopAnswerGenerationEmbed, spotterChatConfig, } = this.viewConfig;
26010
26137
  const queryParams = this.getBaseQueryParams();
26011
26138
  queryParams[Param.SpotterEnabled] = true;
26012
26139
  // Boolean params
@@ -26019,7 +26146,6 @@ class SpotterEmbed extends TsEmbed {
26019
26146
  setParamIfDefined(queryParams, Param.ShowSpotterRadiance, showSpotterRadiance, true);
26020
26147
  setParamIfDefined(queryParams, Param.DefaultQueryMode, defaultQueryMode);
26021
26148
  setParamIfDefined(queryParams, Param.EnableStopAnswerGenerationEmbed, enableStopAnswerGenerationEmbed, true);
26022
- setParamIfDefined(queryParams, Param.AnalystId, spotterAnalystConfig === null || spotterAnalystConfig === void 0 ? void 0 : spotterAnalystConfig.analystId);
26023
26149
  // Handle spotterChatConfig params
26024
26150
  if (spotterChatConfig) {
26025
26151
  const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, enableStarterPrompts, } = spotterChatConfig;
@@ -26626,6 +26752,213 @@ const createLiveboardWithAnswers = async (answers, name) => {
26626
26752
  return result;
26627
26753
  };
26628
26754
 
26755
+ /**
26756
+ * Copyright (c) 2026
26757
+ *
26758
+ * Utility to convert the payload emitted by `EmbedEvent.FilterChanged`
26759
+ * into the payload shape expected by `HostEvent.UpdateFilters`, so that
26760
+ * the current filter state of a Liveboard can be captured and re-applied
26761
+ * later without having to hand-parse the event payload.
26762
+ * @summary Filter payload converter
26763
+ */
26764
+ /**
26765
+ * Coerces an epoch/count field to a number, returning `null` when the value is
26766
+ * absent or not a finite number. The payload arrives as JSON from the iframe,
26767
+ * so a missing field can be `null` as well as `undefined`, and `Number(null)`
26768
+ * or `Number('')` would otherwise silently become a valid-looking `0`
26769
+ * (i.e. the Unix epoch, or a zero-length period).
26770
+ * @param value Raw value from the date filter payload.
26771
+ */
26772
+ function toFiniteNumber(value) {
26773
+ if (isNil_1(value) || value === '')
26774
+ return null;
26775
+ const numericValue = Number(value);
26776
+ return Number.isFinite(numericValue) ? numericValue : null;
26777
+ }
26778
+ const DATE_FILTER_VALUE_EXTRACTORS = {
26779
+ EXACT_DATE: (dateFilter) => {
26780
+ const epoch = toFiniteNumber(dateFilter.epoch);
26781
+ return epoch === null ? [] : [epoch];
26782
+ },
26783
+ EXACT_DATE_RANGE: (dateFilter) => {
26784
+ var _a;
26785
+ const { lowEpoch, highEpoch } = (_a = dateFilter.dateRange) !== null && _a !== void 0 ? _a : {};
26786
+ const low = toFiniteNumber(lowEpoch);
26787
+ const high = toFiniteNumber(highEpoch);
26788
+ return low === null || high === null ? [] : [low, high];
26789
+ },
26790
+ MONTH_YEAR: (dateFilter) => (dateFilter.monthName && dateFilter.yearName
26791
+ ? [dateFilter.monthName, dateFilter.yearName]
26792
+ : []),
26793
+ QUARTER_YEAR: (dateFilter) => (dateFilter.quarterName && dateFilter.yearName
26794
+ ? [dateFilter.quarterName, dateFilter.yearName]
26795
+ : []),
26796
+ YEAR_ONLY: (dateFilter) => (dateFilter.yearName ? [dateFilter.yearName] : []),
26797
+ LAST_N_PERIOD: (dateFilter) => {
26798
+ const count = toFiniteNumber(dateFilter.number);
26799
+ return count === null ? [] : [count];
26800
+ },
26801
+ NEXT_N_PERIOD: (dateFilter) => {
26802
+ const count = toFiniteNumber(dateFilter.number);
26803
+ return count === null ? [] : [count];
26804
+ },
26805
+ };
26806
+ // Date filter types with no `values` (e.g. TODAY needs no operand).
26807
+ const PERIOD_ONLY_DATE_FILTER_TYPES = new Set([
26808
+ 'THIS_PERIOD', 'PERIOD_TO_DATE', 'TODAY', 'YESTERDAY', 'TOMORROW',
26809
+ ]);
26810
+ function convertDateFilterToParam(columnName, dateFilterContent) {
26811
+ var _a;
26812
+ const dateFilter = dateFilterContent === null || dateFilterContent === void 0 ? void 0 : dateFilterContent.dateFilter;
26813
+ if (!(dateFilter === null || dateFilter === void 0 ? void 0 : dateFilter.type))
26814
+ return null;
26815
+ let values;
26816
+ const getValues = DATE_FILTER_VALUE_EXTRACTORS[dateFilter.type];
26817
+ if (getValues) {
26818
+ values = getValues(dateFilter);
26819
+ // Required fields (e.g. epoch, yearName) are missing - the source data
26820
+ // can't be reconstructed faithfully, so skip rather than emit a filter
26821
+ // that would clear/corrupt this column when re-applied.
26822
+ if (values.length === 0)
26823
+ return null;
26824
+ }
26825
+ else if (PERIOD_ONLY_DATE_FILTER_TYPES.has(dateFilter.type)) {
26826
+ values = [];
26827
+ }
26828
+ else {
26829
+ // Unrecognized date filter type - skip rather than guess.
26830
+ return null;
26831
+ }
26832
+ const param = {
26833
+ columnName,
26834
+ operator: (_a = dateFilter.op) !== null && _a !== void 0 ? _a : RuntimeFilterOp.EQ,
26835
+ values,
26836
+ type: dateFilter.type,
26837
+ };
26838
+ if (dateFilter.datePeriod) {
26839
+ param.datePeriod = dateFilter.datePeriod;
26840
+ }
26841
+ if (!isNil_1(dateFilter.includeCurrentPeriod)) {
26842
+ param.includeCurrentPeriod = dateFilter.includeCurrentPeriod;
26843
+ }
26844
+ if (dateFilterContent.negate) {
26845
+ param.negate = true;
26846
+ }
26847
+ return param;
26848
+ }
26849
+ function convertFilterContentToParam(columnName, filterContent) {
26850
+ var _a;
26851
+ if (!(filterContent === null || filterContent === void 0 ? void 0 : filterContent.filterType))
26852
+ return null;
26853
+ const values = ((_a = filterContent.value) !== null && _a !== void 0 ? _a : [])
26854
+ .map((value) => value === null || value === void 0 ? void 0 : value.key)
26855
+ .filter((value) => !isNil_1(value));
26856
+ const param = {
26857
+ columnName,
26858
+ operator: filterContent.filterType,
26859
+ values,
26860
+ };
26861
+ if (filterContent.negate) {
26862
+ param.negate = true;
26863
+ }
26864
+ return param;
26865
+ }
26866
+ function convertFilterToParams(columnName, filter) {
26867
+ var _a, _b;
26868
+ const dateParams = ((_a = filter === null || filter === void 0 ? void 0 : filter.dateFilterContent) !== null && _a !== void 0 ? _a : [])
26869
+ .map((dateFilterContent) => convertDateFilterToParam(columnName, dateFilterContent));
26870
+ const contentParams = ((_b = filter === null || filter === void 0 ? void 0 : filter.filterContent) !== null && _b !== void 0 ? _b : [])
26871
+ .map((filterContent) => convertFilterContentToParam(columnName, filterContent));
26872
+ return [...dateParams, ...contentParams]
26873
+ .filter((param) => param !== null);
26874
+ }
26875
+ /**
26876
+ * Runtime filters need no reshaping, but they still come off the wire as JSON,
26877
+ * so a malformed entry is possible. Skip it rather than pass it through: an
26878
+ * entry missing a column, operator or values array fails
26879
+ * `isValidUpdateFiltersPayload`, and that rejects the *whole* `filters` array,
26880
+ * so one bad runtime filter would drop every other converted filter with it.
26881
+ * @param runtimeFilter A runtime filter from the `FilterChanged` payload.
26882
+ */
26883
+ function convertRuntimeFilterToParam(runtimeFilter) {
26884
+ const { columnName, operator, values } = runtimeFilter !== null && runtimeFilter !== void 0 ? runtimeFilter : {};
26885
+ if (typeof columnName !== 'string' || !columnName)
26886
+ return null;
26887
+ if (typeof operator !== 'string' || !operator)
26888
+ return null;
26889
+ if (!Array.isArray(values))
26890
+ return null;
26891
+ return { columnName, operator, values };
26892
+ }
26893
+ /**
26894
+ * Mirrors `isValidApplicability` in `hostEventClient/utils`: a `TAB` or `GROUP`
26895
+ * scope is meaningless without a `targetId`, and `UpdateFilters` rejects the
26896
+ * whole `filters` array when any entry carries a malformed `applicability`.
26897
+ * @param applicability Scope taken from the `FilterChanged` payload.
26898
+ */
26899
+ function isUsableApplicability(applicability) {
26900
+ const levels = Object.values(ApplicabilityLevel);
26901
+ if (!levels.includes(applicability.level))
26902
+ return false;
26903
+ if (applicability.level === ApplicabilityLevel.Liveboard)
26904
+ return true;
26905
+ return typeof applicability.targetId === 'string' && applicability.targetId.trim().length > 0;
26906
+ }
26907
+ function convertFilterGroupToParams(filterGroup) {
26908
+ var _a, _b;
26909
+ const columnName = (_a = filterGroup === null || filterGroup === void 0 ? void 0 : filterGroup.columnInfo) === null || _a === void 0 ? void 0 : _a.name;
26910
+ if (!columnName)
26911
+ return [];
26912
+ const { applicability } = filterGroup;
26913
+ // A filter scoped to a tab or group has to keep that scope. Replaying it
26914
+ // without `applicability` would silently widen it to the whole Liveboard,
26915
+ // changing what every other tab shows. If a scope is present but unusable,
26916
+ // skip the filter: widening is worse than dropping, and a malformed
26917
+ // applicability would fail validation for every other filter alongside it.
26918
+ if (!isNil_1(applicability) && !isUsableApplicability(applicability))
26919
+ return [];
26920
+ const params = ((_b = filterGroup.filters) !== null && _b !== void 0 ? _b : [])
26921
+ .flatMap((filter) => convertFilterToParams(columnName, filter));
26922
+ return isNil_1(applicability) ? params : params.map((param) => ({ ...param, applicability }));
26923
+ }
26924
+ /**
26925
+ * Converts the payload emitted by {@link EmbedEvent.FilterChanged} into the
26926
+ * payload shape expected by {@link HostEvent.UpdateFilters}, so the same
26927
+ * filter state can be captured and re-applied later, for example on a
26928
+ * subsequent page load.
26929
+ *
26930
+ * Both the Liveboard filters and the runtime filters present in the
26931
+ * `FilterChanged` payload are included in the returned `filters` array.
26932
+ *
26933
+ * Note: a column with multiple date-filter conditions (e.g. an OR of two
26934
+ * date ranges) is not guaranteed to round-trip losslessly - `HostEvent.UpdateFilters`
26935
+ * treats date filters as replace-not-merge per column, so only the last
26936
+ * converted entry for such a column will apply.
26937
+ * @param filterChangedPayload The filter state carried by the
26938
+ * `EmbedEvent.FilterChanged` callback, which is `payload.data` - the
26939
+ * callback argument is the event envelope, and the filters sit under its
26940
+ * `data` key.
26941
+ * @example
26942
+ * ```js
26943
+ * let savedFilters;
26944
+ * liveboardEmbed.on(EmbedEvent.FilterChanged, (payload) => {
26945
+ * savedFilters = convertFilterChangedToUpdateFiltersPayload(payload.data);
26946
+ * });
26947
+ *
26948
+ * // later, e.g. after a fresh page load
26949
+ * liveboardEmbed.trigger(HostEvent.UpdateFilters, savedFilters);
26950
+ * ```
26951
+ */
26952
+ function convertFilterChangedToUpdateFiltersPayload(filterChangedPayload) {
26953
+ var _a, _b;
26954
+ const liveboardFilterParams = ((_a = filterChangedPayload === null || filterChangedPayload === void 0 ? void 0 : filterChangedPayload.liveboardFilters) !== null && _a !== void 0 ? _a : [])
26955
+ .flatMap(convertFilterGroupToParams);
26956
+ const runtimeFilterParams = ((_b = filterChangedPayload === null || filterChangedPayload === void 0 ? void 0 : filterChangedPayload.runtimeFilters) !== null && _b !== void 0 ? _b : [])
26957
+ .map(convertRuntimeFilterToParam)
26958
+ .filter((param) => param !== null);
26959
+ return { filters: [...liveboardFilterParams, ...runtimeFilterParams] };
26960
+ }
26961
+
26629
26962
  /**
26630
26963
  * Starts an automatic renderer that watches the DOM for iframes containing
26631
26964
  * the `tsmcp=true` query parameter and replaces them with fully configured
@@ -26769,4 +27102,4 @@ class AutoFrameRenderer extends TsEmbed {
26769
27102
  }
26770
27103
  }
26771
27104
 
26772
- export { Action, AnswerService, AppEmbed, ApplicabilityLevel, AuthEvent, AuthFailureType, AuthStatus, AuthType, BackgroundFormatType, BodylessConversation, ConditionalFormattingComparisonType, ConditionalFormattingOperator, ContextMenuTriggerOptions, ContextType, ConversationEmbed, CustomActionTarget, CustomActionsPosition, DataLabelFilterOperator, DataPanelCustomColumnGroupsAccordionState$1 as DataPanelCustomColumnGroupsAccordionState, DataSourceVisualMode, EmbedErrorCodes, EmbedErrorSeverity, EmbedEvent, ErrorDetailsTypes, HomeLeftNavItem, HomePage, HomePageSearchBarMode, HomepageModule, HostEvent, InterceptedApiType, LegendPosition, ListPage, ListPageColumns, LiveboardEmbed, LogLevel, MIXPANEL_EVENT, Page, PinboardEmbed, PrefetchFeatures, PrimaryNavbarVersion, RuntimeFilterOp, SearchBarEmbed, SearchEmbed, SpotterAgentEmbed, SpotterEmbed, SpotterQueryMode, TableContentDensity, TableTheme, UIPassthroughEvent, createLiveboardWithAnswers, executeTML, exportTML, getAnswerFromQuery, getEmbedConfig as getInitConfig, getSessionInfo, init, logout, prefetch, reloadIframe, resetCachedAuthToken, startAutoMCPFrameRenderer, tokenizedFetch, uploadMixpanelEvent };
27105
+ export { Action, AnswerService, AppEmbed, ApplicabilityLevel, AuthEvent, AuthFailureType, AuthStatus, AuthType, BackgroundFormatType, BodylessConversation, ConditionalFormattingComparisonType, ConditionalFormattingOperator, ContextMenuTriggerOptions, ContextType, ConversationEmbed, CustomActionTarget, CustomActionsPosition, DataLabelFilterOperator, DataPanelCustomColumnGroupsAccordionState$1 as DataPanelCustomColumnGroupsAccordionState, DataSourceVisualMode, EmbedErrorCodes, EmbedErrorSeverity, EmbedEvent, ErrorDetailsTypes, HomeLeftNavItem, HomePage, HomePageSearchBarMode, HomepageModule, HostEvent, InterceptedApiType, LegendPosition, ListPage, ListPageColumns, LiveboardEmbed, LogLevel, MIXPANEL_EVENT, Page, PinboardEmbed, PrefetchFeatures, PrimaryNavbarVersion, RuntimeFilterOp, SearchBarEmbed, SearchEmbed, SpotterAgentEmbed, SpotterEmbed, SpotterQueryMode, TableContentDensity, TableTheme, UIPassthroughEvent, convertFilterChangedToUpdateFiltersPayload, createLiveboardWithAnswers, executeTML, exportTML, getAnswerFromQuery, getEmbedConfig as getInitConfig, getSessionInfo, init, logout, prefetch, reloadIframe, resetCachedAuthToken, startAutoMCPFrameRenderer, tokenizedFetch, uploadMixpanelEvent };