@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
package/dist/tsembed.js CHANGED
@@ -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 (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
@@ -3772,6 +3772,12 @@
3772
3772
  * ```js
3773
3773
  * const data = await liveboardEmbed.trigger(HostEvent.GetFilters);
3774
3774
  * console.log('data', data);
3775
+ * // {
3776
+ * // liveboardFilters: [ ... ],
3777
+ * // runtimeFilters: [
3778
+ * // { columnName: "Region", operator: "IN", values: ["West"] }
3779
+ * // ]
3780
+ * // }
3775
3781
  * ```
3776
3782
  * @example
3777
3783
  * ```js
@@ -3796,9 +3802,9 @@
3796
3802
  *
3797
3803
  * Each filter object must include the following attributes:
3798
3804
  *
3799
- * `column` - Name of the column to filter on.
3805
+ * `columnName` - Name of the column to filter on.
3800
3806
  *
3801
- * `oper` - Filter operator, for example, EQ, IN, CONTAINS.
3807
+ * `operator` - Filter operator, for example, EQ, IN, CONTAINS.
3802
3808
  * For information about the supported filter operators,
3803
3809
  * see link:https://developers.thoughtspot.com/docs/runtime-filters#rtOperator[Developer Documentation].
3804
3810
  *
@@ -3825,8 +3831,8 @@
3825
3831
  *
3826
3832
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3827
3833
  * filter: {
3828
- * column: "item type",
3829
- * oper: "IN",
3834
+ * columnName: "item type",
3835
+ * operator: "IN",
3830
3836
  * values: ["bags","shirts"]
3831
3837
  * }
3832
3838
  * });
@@ -3836,8 +3842,8 @@
3836
3842
  *
3837
3843
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3838
3844
  * filter: {
3839
- * column: "date",
3840
- * oper: "EQ",
3845
+ * columnName: "date",
3846
+ * operator: "EQ",
3841
3847
  * values: ["JULY","2023"],
3842
3848
  * type: "MONTH_YEAR"
3843
3849
  * }
@@ -3848,18 +3854,18 @@
3848
3854
  * ```js
3849
3855
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3850
3856
  * filters: [{
3851
- * column: "Item Type",
3852
- * oper: 'IN',
3857
+ * columnName: "Item Type",
3858
+ * operator: 'IN',
3853
3859
  * values: ["bags","shirts"]
3854
3860
  * },
3855
3861
  * {
3856
- * column: "Region",
3857
- * oper: 'IN',
3862
+ * columnName: "Region",
3863
+ * operator: 'IN',
3858
3864
  * values: ["West","Midwest"]
3859
3865
  * },
3860
3866
  * {
3861
- * column: "Date",
3862
- * oper: 'EQ',
3867
+ * columnName: "Date",
3868
+ * operator: 'EQ',
3863
3869
  * values: ["2023-07-31"],
3864
3870
  * type: "EXACT_DATE"
3865
3871
  * }]
@@ -3873,13 +3879,13 @@
3873
3879
  * ```js
3874
3880
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3875
3881
  * filters: [{
3876
- * column: "(Sample) Retail - Apparel::city",
3877
- * oper: 'IN',
3882
+ * columnName: "(Sample) Retail - Apparel::city",
3883
+ * operator: 'IN',
3878
3884
  * values: ["atlanta"]
3879
3885
  * },
3880
3886
  * {
3881
- * column: "(Sample) Retail - Apparel::Region",
3882
- * oper: 'IN',
3887
+ * columnName: "(Sample) Retail - Apparel::Region",
3888
+ * operator: 'IN',
3883
3889
  * values: ["West","Midwest"]
3884
3890
  * }]
3885
3891
  * });
@@ -3890,8 +3896,8 @@
3890
3896
  * import { ContextType } from '@thoughtspot/visual-embed-sdk';
3891
3897
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3892
3898
  * filter: {
3893
- * column: "item type",
3894
- * oper: "IN",
3899
+ * columnName: "item type",
3900
+ * operator: "IN",
3895
3901
  * values: ["shoes", "boots"]
3896
3902
  * }
3897
3903
  * }, ContextType.Liveboard);
@@ -3901,8 +3907,8 @@
3901
3907
  * // Scope the filter to a specific Liveboard tab
3902
3908
  * liveboardEmbed.trigger(HostEvent.UpdateFilters, {
3903
3909
  * filter: {
3904
- * column: "item type",
3905
- * oper: "IN",
3910
+ * columnName: "item type",
3911
+ * operator: "IN",
3906
3912
  * values: ["bags", "shirts"],
3907
3913
  * applicability: {
3908
3914
  * level: "TAB",
@@ -3911,6 +3917,12 @@
3911
3917
  * }
3912
3918
  * });
3913
3919
  * ```
3920
+ * Use `columnName` and `operator` - the same spelling as
3921
+ * {@link RuntimeFilter}. The older `column` and `oper` spellings are
3922
+ * deprecated; they are still accepted, but pass only one spelling of each
3923
+ * field, never both. To reapply the filter state captured from
3924
+ * {@link EmbedEvent.FilterChanged}, use `convertFilterChangedToUpdateFiltersPayload`
3925
+ * to convert its payload into the shape expected here.
3914
3926
  * @version SDK: 1.23.0 | ThoughtSpot: 9.4.0.cl
3915
3927
  */
3916
3928
  HostEvent["UpdateFilters"] = "updateFilters";
@@ -4896,7 +4908,6 @@
4896
4908
  Param["IsStarterPromptsEnabled"] = "enableStarterPrompts";
4897
4909
  Param["UpdatedSpotterExperience"] = "updatedSpotterExperience";
4898
4910
  Param["SpotterDataSources"] = "spotterDataSources";
4899
- Param["AnalystId"] = "analystId";
4900
4911
  Param["OpenSpotterOnLiveboardByDefault"] = "openSpotterOnLiveboardByDefault";
4901
4912
  Param["ShowAnswerEditPanel"] = "showAnswerEditPanel";
4902
4913
  })(Param || (Param = {}));
@@ -7122,6 +7133,18 @@
7122
7133
  * ```
7123
7134
  */
7124
7135
  Action["DeleteCollection"] = "deleteCollection";
7136
+ /**
7137
+ * Controls the visibility of the "Customize homepage" button on the
7138
+ * embedded home page.
7139
+ * @version SDK: 1.55.0 | ThoughtSpot Cloud: 26.12.0.cl
7140
+ * @example
7141
+ * ```js
7142
+ * {
7143
+ * hiddenActions: [Action.CustomizeHomepage],
7144
+ * }
7145
+ * ```
7146
+ */
7147
+ Action["CustomizeHomepage"] = "customizeHomepage";
7125
7148
  })(exports.Action || (exports.Action = {}));
7126
7149
  exports.PrefetchFeatures = void 0;
7127
7150
  (function (PrefetchFeatures) {
@@ -7626,7 +7649,7 @@
7626
7649
  TableContentDensity["Compact"] = "COMPACT";
7627
7650
  })(exports.TableContentDensity || (exports.TableContentDensity = {}));
7628
7651
 
7629
- var version$1="1.52.1";var pkg = {version:version$1};
7652
+ var version$1="1.52.2-beta.0";var pkg = {version:version$1};
7630
7653
 
7631
7654
  const { version } = pkg;
7632
7655
 
@@ -7799,7 +7822,7 @@
7799
7822
  SSR_ENVIRONMENT_ERROR: 'SSR environment detected. This function cannot be called in SSR environment.',
7800
7823
  UPDATE_PARAMS_FAILED: 'Failed to update embed parameters',
7801
7824
  INVALID_SPOTTER_DOCUMENTATION_URL: 'Invalid spotterDocumentationUrl. Please provide a valid http or https URL.',
7802
- UPDATEFILTERS_INVALID_PAYLOAD: 'UpdateFilters requires a valid filter or filters array. Expected: { filter: { column, oper, values } } or { filters: [{ column, oper, values }, ...] }',
7825
+ UPDATEFILTERS_INVALID_PAYLOAD: 'UpdateFilters requires a valid filter or filters array. Expected: { filter: { columnName, operator, values } } or { filters: [{ columnName, operator, values }, ...] }',
7803
7826
  DRILLDOWN_INVALID_PAYLOAD: 'DrillDown requires a valid points object. Expected: { points: { clickedPoint?, selectedPoints? }, autoDrillDown?, vizId? }',
7804
7827
  UPDATEPARAMETERS_INVALID_PAYLOAD: 'UpdateParameters received an invalid applicability. Expected: { level: LIVEBOARD | TAB | GROUP, targetId } where targetId is required for TAB and GROUP levels',
7805
7828
  };
@@ -21671,7 +21694,8 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21671
21694
  const isValidApplicability = (a) => {
21672
21695
  if (isUndefined_1(a))
21673
21696
  return true;
21674
- // targetId is not required at LIVEBOARD level, since the filter applies to the whole Liveboard
21697
+ // targetId is not required at LIVEBOARD level, since the filter applies to
21698
+ // the whole Liveboard
21675
21699
  return isPlainObject_1(a)
21676
21700
  && Object.values(exports.ApplicabilityLevel).includes(a.level)
21677
21701
  && (a.level === exports.ApplicabilityLevel.Liveboard || (isString_1(a.targetId) && a.targetId.trim().length > 0));
@@ -21690,8 +21714,52 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21690
21714
  const hasValidFilters = Array.isArray(payload.filters) && payload.filters.length > 0 && payload.filters.every(isValidFilter);
21691
21715
  return !!(hasValidFilter || hasValidFilters);
21692
21716
  }
21717
+ /**
21718
+ * Rewrites one filter's `columnName`/`operator` to `column`/`oper`.
21719
+ *
21720
+ * Callers may use either spelling: `columnName`/`operator` match
21721
+ * {@link RuntimeFilter} and the `EmbedEvent.FilterChanged` payload, so a
21722
+ * converted payload can be replayed as-is. But the payload is forwarded to the
21723
+ * embedded app unchanged, and only `column`/`oper` are known to be understood
21724
+ * there - so the alias must be swapped here, or it would pass validation and
21725
+ * then be silently ignored.
21726
+ *
21727
+ * If a caller supplies both spellings of a field - which TypeScript rejects,
21728
+ * but JavaScript callers can still do - the documented `columnName`/`operator`
21729
+ * wins. Deferring to the deprecated spelling would quietly discard the value
21730
+ * the rest of the SDK tells people to use.
21731
+ * @param filter One entry from the UpdateFilters payload.
21732
+ */
21733
+ function resolveFilterAliases(filter) {
21734
+ var _a, _b;
21735
+ if (!isPlainObject_1(filter))
21736
+ return filter;
21737
+ const column = (_a = filter.columnName) !== null && _a !== void 0 ? _a : filter.column;
21738
+ const oper = (_b = filter.operator) !== null && _b !== void 0 ? _b : filter.oper;
21739
+ const { columnName, operator, ...rest } = filter;
21740
+ return {
21741
+ ...rest,
21742
+ ...(isUndefined_1(column) ? {} : { column }),
21743
+ ...(isUndefined_1(oper) ? {} : { oper }),
21744
+ };
21745
+ }
21746
+ /**
21747
+ * Rewrites every filter in an UpdateFilters payload to use `column`/`oper`,
21748
+ * whichever spelling the caller supplied. Call after validation.
21749
+ * @param payload The UpdateFilters host event payload.
21750
+ */
21751
+ function resolveUpdateFiltersAliases(payload) {
21752
+ if (!isPlainObject_1(payload))
21753
+ return payload;
21754
+ return {
21755
+ ...payload,
21756
+ ...(payload.filter ? { filter: resolveFilterAliases(payload.filter) } : {}),
21757
+ ...(Array.isArray(payload.filters) ? { filters: payload.filters.map(resolveFilterAliases) } : {}),
21758
+ };
21759
+ }
21693
21760
  function isValidUpdateParametersPayload(payload) {
21694
- // Only validates the applicability of each parameter (null treated as absent); the rest is forwarded as-is for backward compatibility.
21761
+ // Only validates the applicability of each parameter (null treated as
21762
+ // absent); the rest is forwarded as-is for backward compatibility.
21695
21763
  if (!Array.isArray(payload))
21696
21764
  return true;
21697
21765
  return payload.every((p) => {
@@ -21739,7 +21807,8 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21739
21807
  /**
21740
21808
  * Maps HostEvent to its corresponding UIPassthroughEvent.
21741
21809
  * Includes both custom-handler events (Pin, SaveAnswer, UpdateFilters, DrillDown)
21742
- * and getter events (GetAnswerSession, GetFilters, etc.) that use getDataWithPassthroughFallback.
21810
+ * and getter events (GetAnswerSession, GetFilters, etc.) that use
21811
+ * getDataWithPassthroughFallback.
21743
21812
  */
21744
21813
  const PASSTHROUGH_MAP = {
21745
21814
  // Custom handlers (setters with special logic)
@@ -21890,17 +21959,21 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21890
21959
  throwUpdateFiltersValidationError();
21891
21960
  }
21892
21961
  // The shared contract accepts both current (columnName/operator) and
21893
- // legacy (column/oper) filter field names — as does the validation
21894
- // above and the app at runtime. The UIPassthrough FilterUpdate type
21895
- // still requires the legacy names; bridge until that contract is
21896
- // audited.
21897
- return this.handleHostEventWithParam(exports.UIPassthroughEvent.UpdateFilters, payload, context);
21962
+ // legacy (column/oper) filter field names, but only the legacy pair is
21963
+ // understood downstream, so the payload is rewritten before it is
21964
+ // forwarded — otherwise a columnName/operator filter passes validation
21965
+ // here and is then silently ignored by the app. The cast bridges the
21966
+ // UIPassthrough FilterUpdate type, which still declares only the legacy
21967
+ // names.
21968
+ const resolvedPayload = resolveUpdateFiltersAliases(payload);
21969
+ return this.handleHostEventWithParam(exports.UIPassthroughEvent.UpdateFilters, resolvedPayload, context);
21898
21970
  }
21899
21971
  handleUpdateParametersEvent(payload, context) {
21900
21972
  if (!isValidUpdateParametersPayload(payload)) {
21901
21973
  throwUpdateParametersValidationError();
21902
21974
  }
21903
- // UpdateParameters has no UI passthrough contract; dispatch over the legacy channel
21975
+ // UpdateParameters has no UI passthrough contract; dispatch over the
21976
+ // legacy channel
21904
21977
  return this.hostEventFallback(exports.HostEvent.UpdateParameters, payload, context);
21905
21978
  }
21906
21979
  handleDrillDownEvent(payload, context) {
@@ -21911,8 +21984,8 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21911
21984
  }
21912
21985
  /**
21913
21986
  * Dispatches a host event using the appropriate channel:
21914
- * 1. If the embedded app supports UI passthrough for this event, use it (custom handler or getter).
21915
- * 2. Otherwise fall back to the legacy host event channel.
21987
+ * 1. If the embedded app supports UI passthrough for this event, use it (custom
21988
+ * handler or getter). 2. Otherwise fall back to the legacy host event channel.
21916
21989
  *
21917
21990
  * @param hostEvent - The host event to trigger
21918
21991
  * @param payload - Optional payload for the event
@@ -21921,7 +21994,8 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
21921
21994
  async triggerHostEvent(hostEvent, payload, context) {
21922
21995
  const customHandler = this.customHandlers[hostEvent];
21923
21996
  const passthroughEvent = PASSTHROUGH_MAP[hostEvent];
21924
- // If embedded app supports passthrough but not this event, use legacy channel
21997
+ // If embedded app supports passthrough but not this event, use legacy
21998
+ // channel
21925
21999
  const keys = passthroughEvent ? await this.getAvailableUIPassthroughKeys(context) : [];
21926
22000
  if (passthroughEvent && keys.length > 0 && !keys.includes(passthroughEvent)) {
21927
22001
  return this.hostEventFallback(hostEvent, payload, context);
@@ -22128,11 +22202,15 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22128
22202
  */
22129
22203
  const PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY = 'tsEmbedOriginalPosition';
22130
22204
  const PRERENDER_WRAPPER_ID_PREFIX = 'tsEmbed-pre-render-wrapper-';
22205
+ const PRERENDER_PARKED_TRANSFORM = 'translateY(-100%)';
22206
+ /** The height createPreRenderWrapper() seeds before anything is measured. */
22207
+ const UNMEASURED_WRAPPER_HEIGHT = '100vh';
22131
22208
  // The container applies UpdateEmbedParams through React state, so a delivered
22132
22209
  // post is not the same as the params being in effect.
22133
22210
  const UPDATE_EMBED_PARAMS_SETTLE_MS = 200;
22134
- // The container ignores runtimeFilterParams/runtimeParameterParams unless truthy, so
22135
- // null or '' leaves the previous embed's values in place. '&' is truthy and parses to {}.
22211
+ // The container ignores runtimeFilterParams/runtimeParameterParams unless
22212
+ // truthy, so null or '' leaves the previous embed's values in place. '&' is
22213
+ // truthy and parses to {}.
22136
22214
  const NO_RUNTIME_PARAMS = '&';
22137
22215
  /**
22138
22216
  * The event id map from v2 event names to v1 event id
@@ -22171,7 +22249,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22171
22249
  this.shouldEncodeUrlQueryParams = false;
22172
22250
  this.defaultHiddenActions = [exports.Action.ReportError];
22173
22251
  this.preRenderContainerEl = document.body;
22174
- this.containerScrollListener = null;
22175
22252
  /**
22176
22253
  * Handler for fullscreen change events
22177
22254
  */
@@ -22330,7 +22407,8 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22330
22407
  const AUTH_INIT_FALLBACK_DELAY = 1000;
22331
22408
  // Wait for 1 second to ensure the embed container is loaded
22332
22409
  // This is a workaround to ensure the embed container is loaded
22333
- // this is needed until all clusters have EmbedListenerReady event
22410
+ // this is needed until all clusters have EmbedListenerReady
22411
+ // event
22334
22412
  setTimeout(processEmbedContainerReady, AUTH_INIT_FALLBACK_DELAY);
22335
22413
  }
22336
22414
  else if (source === exports.EmbedEvent.EmbedListenerReady) {
@@ -22338,7 +22416,8 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22338
22416
  }
22339
22417
  };
22340
22418
  // Subclasses that navigate the pre-render on show must await this before
22341
- // triggering Navigate. Resolves even on failure, so navigation is never blocked.
22419
+ // triggering Navigate. Resolves even on failure, so navigation is never
22420
+ // blocked.
22342
22421
  this.preRenderParamsApplied = Promise.resolve();
22343
22422
  this.hostElement = getDOMNode(domSelector);
22344
22423
  this.eventHandlerMap = new Map();
@@ -22668,8 +22747,9 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22668
22747
  ...this.viewConfig,
22669
22748
  ...queryParams,
22670
22749
  ...appInitData,
22671
- // A show cycle has no URL to carry these, so the payload always states them
22672
- // — including "none", which is the case that leaks the previous filters.
22750
+ // A show cycle has no URL to carry these, so the payload always
22751
+ // states them — including "none", which is the case that leaks the
22752
+ // previous filters.
22673
22753
  runtimeFilterParams: getFilterQuery((_a = this.viewConfig.runtimeFilters) !== null && _a !== void 0 ? _a : []) || NO_RUNTIME_PARAMS,
22674
22754
  runtimeParameterParams: getRuntimeParameters((_b = this.viewConfig.runtimeParameters) !== null && _b !== void 0 ? _b : [])
22675
22755
  || NO_RUNTIME_PARAMS,
@@ -23014,7 +23094,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23014
23094
  top: '0',
23015
23095
  left: '0',
23016
23096
  width: '100vw',
23017
- height: '100vh',
23097
+ height: UNMEASURED_WRAPPER_HEIGHT,
23018
23098
  };
23019
23099
  setStyleProperties(preRenderWrapper, initialPreRenderWrapperStyle);
23020
23100
  return preRenderWrapper;
@@ -23082,10 +23162,26 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23082
23162
  return placeholder;
23083
23163
  }
23084
23164
  /**
23085
- * Resolves the configured preRenderContainer to a live element, falling
23086
- * back to `document.body`. A string selector is re-queried on every call so
23087
- * a remounted container (E.g.: React replacing the node) resolves to the
23088
- * fresh element; an element passed directly cannot be re-resolved.
23165
+ * Resolves the configured preRenderContainer to a live element. A string
23166
+ * selector is re-queried on every call so a remounted container (E.g.: React
23167
+ * replacing the node) resolves to the fresh element; an element passed
23168
+ * directly cannot be re-resolved.
23169
+ *
23170
+ * With nothing configured the frame goes into the host element's nearest
23171
+ * scrolling ancestor, falling back to `document.body`.
23172
+ *
23173
+ * The wrapper is absolutely positioned, so it follows the page for free —
23174
+ * but only while it sits inside whatever scrolls. `document.body` is right
23175
+ * only when the document itself is the scroller; an app that scrolls an
23176
+ * inner element instead left the frame pinned to the viewport while the page
23177
+ * moved under it (SCAL-338563). Being inside the scroller also lets wheel
23178
+ * events chain out of the frame into it, which they cannot do from
23179
+ * `document.body`.
23180
+ *
23181
+ * A scrolling ancestor is layout chrome rather than route content, so it
23182
+ * outlives the embed in practice; and if it does go, the host element goes
23183
+ * with it and this instance is remounting anyway.
23184
+ * `reconcilePreRenderContainer` re-runs this on a detached container.
23089
23185
  */
23090
23186
  resolvePreRenderContainerTarget() {
23091
23187
  var _a;
@@ -23105,7 +23201,13 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23105
23201
  else if (containerConfig) {
23106
23202
  container = containerConfig;
23107
23203
  }
23108
- return (_a = container) !== null && _a !== void 0 ? _a : document.body;
23204
+ if (container) {
23205
+ return container;
23206
+ }
23207
+ if (!this.hostElement) {
23208
+ return document.body;
23209
+ }
23210
+ return (_a = getScrollableAncestors(this.hostElement)[0]) !== null && _a !== void 0 ? _a : document.body;
23109
23211
  }
23110
23212
  inheritPreRenderContainer() {
23111
23213
  var _a;
@@ -23150,8 +23252,9 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23150
23252
  * Re-attaches the wrapper to a live container when the previously resolved
23151
23253
  * one has been detached or no longer holds the wrapper — e.g. the host app
23152
23254
  * remounted a custom preRenderContainer, which would otherwise leave a stale
23153
- * reference and collapse the wrapper. Only string selectors can be
23154
- * re-resolved; a container passed as an element is left untouched.
23255
+ * reference and collapse the wrapper. Selectors and the auto-resolved
23256
+ * scrolling ancestor are both re-resolved; a container passed as an element
23257
+ * is left untouched, as there is nothing to re-query.
23155
23258
  */
23156
23259
  reconcilePreRenderContainer() {
23157
23260
  const wrapper = this.preRenderWrapper;
@@ -23170,14 +23273,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23170
23273
  if (resolved === stored && stored.contains(wrapper)) {
23171
23274
  return;
23172
23275
  }
23173
- if (this.containerScrollListener && stored !== resolved) {
23174
- if (stored !== document.body) {
23175
- stored.removeEventListener('scroll', this.containerScrollListener);
23176
- }
23177
- if (resolved !== document.body) {
23178
- resolved.addEventListener('scroll', this.containerScrollListener);
23179
- }
23180
- }
23181
23276
  this.preRenderContainerEl = resolved;
23182
23277
  this.applyPreRenderContainerPositioning();
23183
23278
  if (wrapper.parentNode !== resolved) {
@@ -23239,11 +23334,12 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23239
23334
  */
23240
23335
  setIFrameHeight(height) {
23241
23336
  if (this.isPreRendered) {
23337
+ const next = getCssDimension(height);
23242
23338
  if (this.insertedDomEl) {
23243
- this.insertedDomEl.style.height = getCssDimension(height);
23339
+ this.insertedDomEl.style.height = next;
23244
23340
  }
23245
23341
  else if (this.preRenderWrapper) {
23246
- this.preRenderWrapper.style.height = getCssDimension(height);
23342
+ this.preRenderWrapper.style.height = next;
23247
23343
  }
23248
23344
  }
23249
23345
  else {
@@ -23396,8 +23492,9 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23396
23492
  return;
23397
23493
  this.preRenderWrapper[this.embedNodeKey] = this;
23398
23494
  }
23399
- // The flag lives on the wrapper because it describes the iframe: an instance
23400
- // hidden when the container announced itself would otherwise report false forever.
23495
+ // The flag lives on the wrapper because it describes the iframe: an
23496
+ // instance hidden when the container announced itself would otherwise
23497
+ // report false forever.
23401
23498
  markEmbedContainerLoaded() {
23402
23499
  this.isEmbedContainerLoaded = true;
23403
23500
  if (this.preRenderWrapper) {
@@ -23677,34 +23774,47 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23677
23774
  delete container.dataset[PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY];
23678
23775
  }
23679
23776
  /**
23680
- * Detaches and clears the container scroll listener, if one is attached.
23681
- */
23682
- removeContainerScrollListener() {
23683
- if (!this.containerScrollListener) {
23777
+ * Re-sizes the wrapper when its placeholder changes size.
23778
+ *
23779
+ * Position deliberately has no equivalent. An absolutely positioned wrapper
23780
+ * follows its containing block for free, so a correctly placed frame is the
23781
+ * browser's job and costs nothing; repositioning it on scroll would mean a
23782
+ * layout read and a style write per frame to compensate for placing it in
23783
+ * the wrong box. Size is the one thing the browser will not do for us: the
23784
+ * placeholder grows when the embedded app reports a new height, and the
23785
+ * wrapper has to be told.
23786
+ */
23787
+ observePreRenderSize() {
23788
+ var _a;
23789
+ if (this.getPreRenderConfig().doNotTrackSize || typeof ResizeObserver === 'undefined') {
23790
+ return;
23791
+ }
23792
+ const placeholder = this.getPreRenderPlaceHolderElement();
23793
+ if (!placeholder) {
23684
23794
  return;
23685
23795
  }
23686
- const customContainer = this.getCustomPreRenderContainer();
23687
- customContainer === null || customContainer === void 0 ? void 0 : customContainer.removeEventListener('scroll', this.containerScrollListener);
23688
- this.containerScrollListener = null;
23796
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23797
+ this.resizeObserver = new ResizeObserver(() => this.syncPreRenderStyle());
23798
+ this.resizeObserver.observe(placeholder);
23689
23799
  }
23690
23800
  /**
23691
23801
  * Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
23692
23802
  * @version SDK: 1.19.1 | ThoughtSpot: *
23693
23803
  */
23694
23804
  destroy() {
23695
- var _a, _b, _c;
23805
+ var _a, _b, _c, _d;
23696
23806
  try {
23697
23807
  this.removeFullscreenChangeHandler();
23698
- this.removeContainerScrollListener();
23808
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23699
23809
  this.unsubscribeToEvents();
23700
- (_a = this.preRenderWrapper) === null || _a === void 0 ? void 0 : _a.remove();
23810
+ (_b = this.preRenderWrapper) === null || _b === void 0 ? void 0 : _b.remove();
23701
23811
  this.restorePreRenderContainerPosition();
23702
23812
  if (!this.isRendered) {
23703
23813
  return;
23704
23814
  }
23705
23815
  if (!getEmbedConfig().waitForCleanupOnDestroy) {
23706
23816
  this.trigger(exports.HostEvent.DestroyEmbed);
23707
- (_c = (_b = this.insertedDomEl) === null || _b === void 0 ? void 0 : _b.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(this.insertedDomEl);
23817
+ (_d = (_c = this.insertedDomEl) === null || _c === void 0 ? void 0 : _c.parentNode) === null || _d === void 0 ? void 0 : _d.removeChild(this.insertedDomEl);
23708
23818
  }
23709
23819
  else {
23710
23820
  const cleanupTimeout = getEmbedConfig().cleanupTimeout;
@@ -23785,7 +23895,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23785
23895
  * wrapper to overlay it.
23786
23896
  */
23787
23897
  async showPreRender() {
23788
- var _a, _b;
23898
+ var _a;
23789
23899
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_SHOW_PRE_RENDER, {
23790
23900
  preRenderId: this.getPreRenderConfig().id,
23791
23901
  embedComponentType: this.viewConfig.embedComponentType,
@@ -23804,54 +23914,49 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23804
23914
  this.beforePrerenderVisible();
23805
23915
  if (this.hostElement) {
23806
23916
  this.insertedDomEl = this.createPreRenderPlaceholder();
23807
- if (this.viewConfig.fullHeight) {
23808
- // If fullHeight has already sized the wrapper, seed the placeholder
23809
- // with the same height so syncPreRenderStyle gets an accurate rect.
23810
- const existingHeight = this.preRenderWrapper.style.height;
23811
- if (existingHeight) {
23812
- this.insertedDomEl.style.height = existingHeight;
23813
- }
23917
+ // Carry a height fullHeight has already measured onto the fresh
23918
+ // placeholder, so a re-show does not flash at frameParams height.
23919
+ // UNMEASURED_WRAPPER_HEIGHT is what createPreRenderWrapper() seeds
23920
+ // before anything has been measured; treating that as a measurement
23921
+ // is what made a first reveal overshoot to a full viewport.
23922
+ const wrapperHeight = this.preRenderWrapper.style.height;
23923
+ if (this.viewConfig.fullHeight
23924
+ && wrapperHeight
23925
+ && wrapperHeight !== UNMEASURED_WRAPPER_HEIGHT) {
23926
+ this.insertedDomEl.style.height = wrapperHeight;
23814
23927
  }
23815
23928
  const placeHolderId = this.getPreRenderIds().placeHolder;
23816
23929
  // Remove any stale placeholder from a previous cycle. It is located
23817
- // via a subtree-wide querySelector, so it may be nested deeper than a
23818
- // direct child (E.g.: with fullHeight the host app can wrap it). Use
23819
- // Element.remove() — which detaches from whatever the real parent is —
23820
- // rather than hostElement.removeChild(), which throws NotFoundError
23821
- // when the match is not a direct child. Mirrors the wrapper/child
23822
- // cleanup in createPreRenderWrapper()/createPreRenderChild().
23930
+ // via a subtree-wide querySelector, so it may be nested deeper
23931
+ // than a direct child (E.g.: with fullHeight the host app can wrap
23932
+ // it). Use Element.remove() — which detaches from whatever the real
23933
+ // parent is — rather than hostElement.removeChild(), which throws
23934
+ // NotFoundError when the match is not a direct child. Mirrors the
23935
+ // wrapper/child cleanup in
23936
+ // createPreRenderWrapper()/createPreRenderChild().
23823
23937
  (_a = this.hostElement.querySelector(`#${placeHolderId}`)) === null || _a === void 0 ? void 0 : _a.remove();
23824
23938
  this.hostElement.appendChild(this.insertedDomEl);
23825
23939
  this.syncPreRenderStyle();
23826
- const customContainer = this.getCustomPreRenderContainer();
23827
- if (customContainer && !this.containerScrollListener) {
23828
- this.containerScrollListener = () => this.syncPreRenderStyle();
23829
- customContainer.addEventListener('scroll', this.containerScrollListener);
23830
- }
23831
- if (!this.getPreRenderConfig().doNotTrackSize) {
23832
- const observeTarget = (_b = this.insertedDomEl) !== null && _b !== void 0 ? _b : this.hostElement;
23833
- this.resizeObserver = new ResizeObserver((entries) => {
23834
- entries.forEach((entry) => {
23835
- if (entry.target === observeTarget) {
23836
- this.syncPreRenderStyle();
23837
- }
23838
- });
23839
- });
23840
- this.resizeObserver.observe(observeTarget);
23841
- }
23940
+ this.observePreRenderSize();
23842
23941
  }
23843
23942
  removeStyleProperties(this.preRenderWrapper, [
23844
23943
  'z-index',
23845
23944
  'opacity',
23846
- 'pointer-events',
23847
23945
  'overflow',
23946
+ 'transform',
23848
23947
  ]);
23948
+ // Set rather than removed: a container that carries `pointer-events:
23949
+ // none` — the usual styling for a parking root that must not swallow
23950
+ // clicks — passes it down, and dropping the property here would leave
23951
+ // the inherited `none` in force and the frame dead to input.
23952
+ setStyleProperties(this.preRenderWrapper, { pointerEvents: 'auto' });
23849
23953
  this.subscribeToEvents();
23850
23954
  // Setup fullscreen change handler for prerendered components
23851
23955
  if (this.iFrame) {
23852
23956
  this.setupFullscreenChangeHandler();
23853
23957
  }
23854
- // Last, so everything above still sees the instance being taken over from.
23958
+ // Last, so everything above still sees the instance being taken over
23959
+ // from.
23855
23960
  this.takeOverPreRender();
23856
23961
  return this;
23857
23962
  }
@@ -23897,6 +24002,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23897
24002
  * If the component is not preRendered, it issues a warning.
23898
24003
  */
23899
24004
  hidePreRender() {
24005
+ var _a;
23900
24006
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_HIDE_PRE_RENDER, {
23901
24007
  preRenderId: this.getPreRenderConfig().id,
23902
24008
  embedComponentType: this.viewConfig.embedComponentType,
@@ -23916,12 +24022,15 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23916
24022
  top: '0',
23917
24023
  left: '0',
23918
24024
  overflow: 'hidden',
24025
+ // Keeps the measured size — so the next show needs no resize, which
24026
+ // is the point of pre-rendering — while lifting the box out of
24027
+ // the container's scrollable area. Overflow only extends
24028
+ // downwards, so a hidden frame parked above the top edge adds
24029
+ // none, where one left at full height shows as blank scroll space.
24030
+ transform: PRERENDER_PARKED_TRANSFORM,
23919
24031
  };
23920
24032
  setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
23921
- this.removeContainerScrollListener();
23922
- if (this.resizeObserver) {
23923
- this.resizeObserver.disconnect();
23924
- }
24033
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23925
24034
  const placeHolderEle = this.getPreRenderPlaceHolderElement();
23926
24035
  if (placeHolderEle) {
23927
24036
  placeHolderEle.parentElement.removeChild(placeHolderEle);
@@ -24138,6 +24247,18 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24138
24247
  starterPrompts,
24139
24248
  },
24140
24249
  };
24250
+ }
24251
+ function buildSpotterAnalystAppInitData(initData, viewConfig) {
24252
+ const { spotterAnalystConfig } = viewConfig;
24253
+ if (!(spotterAnalystConfig === null || spotterAnalystConfig === void 0 ? void 0 : spotterAnalystConfig.analystId))
24254
+ return initData;
24255
+ return {
24256
+ ...initData,
24257
+ embedParams: {
24258
+ ...(initData.embedParams || {}),
24259
+ spotterAnalystConfig,
24260
+ },
24261
+ };
24141
24262
  }
24142
24263
 
24143
24264
  function buildSpotterVizAppInitData(initData, viewConfig) {
@@ -24731,8 +24852,9 @@ query GetEurekaVizSnapshots(
24731
24852
  * @summary Liveboard & visualization embed
24732
24853
  * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
24733
24854
  */
24734
- // Home unmounts the liveboard container, which is how its state gets cleared. The
24735
- // settle window gives the container time to do it before we ask for the liveboard back.
24855
+ // Home unmounts the liveboard container, which is how its state gets cleared.
24856
+ // The settle window gives the container time to do it before we ask for the
24857
+ // liveboard back.
24736
24858
  const HOME_ROUTE = 'home';
24737
24859
  const HOME_SETTLE_MS = 200;
24738
24860
  /**
@@ -25030,21 +25152,24 @@ query GetEurekaVizSnapshots(
25030
25152
  }
25031
25153
  beforePrerenderVisible() {
25032
25154
  super.beforePrerenderVisible();
25033
- // Captured before showPreRender() hands the wrapper over to this instance.
25034
- // Itself means a hide/show, not a hand-over, so there is nothing stale to clear.
25155
+ // Captured before showPreRender() hands the wrapper over to this
25156
+ // instance. Itself means a hide/show, not a hand-over, so there is
25157
+ // nothing stale to clear.
25035
25158
  const previous = this.getPreRenderObj();
25036
25159
  const showing = previous === this ? undefined : previous === null || previous === void 0 ? void 0 : previous.currentLiveboardState;
25037
25160
  this.executeAfterEmbedContainerLoaded(async () => {
25038
- // Without this the params callback suspends on its await and Navigate
25039
- // goes out first, so the container loads with the previous config's filters.
25161
+ // Without this the params callback suspends on its await and
25162
+ // Navigate goes out first, so the container loads with the previous
25163
+ // config's filters.
25040
25164
  await this.preRenderParamsApplied;
25041
25165
  if (this.isShowingLiveboardRoute(showing)) {
25042
- // Navigate to the route we are already on is a no-op, so the liveboard
25043
- // keeps its state. Home unmounts the container, which clears it.
25166
+ // Navigate to the route we are already on is a no-op, so the
25167
+ // liveboard keeps its state. Home unmounts the container, which
25168
+ // clears it.
25044
25169
  this.trigger(exports.HostEvent.Navigate, HOME_ROUTE)
25045
25170
  .catch((error) => logger$3.warn('Could not route via home', error));
25046
- // Not awaited above: the container never acks Navigate, so that promise
25047
- // only settles on the 30s trigger timeout.
25171
+ // Not awaited above: the container never acks Navigate, so
25172
+ // that promise only settles on the 30s trigger timeout.
25048
25173
  await new Promise((resolve) => {
25049
25174
  setTimeout(resolve, HOME_SETTLE_MS);
25050
25175
  });
@@ -25058,8 +25183,9 @@ query GetEurekaVizSnapshots(
25058
25183
  };
25059
25184
  });
25060
25185
  }
25061
- // The whole route, not just the liveboard id: the path is built from the viz, tab
25062
- // and view too, so a same-liveboard show onto another tab is a real navigation.
25186
+ // The whole route, not just the liveboard id: the path is built from the
25187
+ // viz, tab and view too, so a same-liveboard show onto another tab is a
25188
+ // real navigation.
25063
25189
  isShowingLiveboardRoute(showing) {
25064
25190
  if (!(showing === null || showing === void 0 ? void 0 : showing.liveboardId))
25065
25191
  return false;
@@ -26009,10 +26135,11 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26009
26135
  const defaultAppInitData = await super.getAppInitData();
26010
26136
  const sidebarInitData = buildSpotterSidebarAppInitData(defaultAppInitData, this.viewConfig, this.handleError.bind(this));
26011
26137
  const shareInitData = buildSpotterShareConversationAppInitData(sidebarInitData, this.viewConfig);
26012
- return buildStarterPromptsAppInitData(shareInitData, this.viewConfig);
26138
+ const starterPromptsInitData = buildStarterPromptsAppInitData(shareInitData, this.viewConfig);
26139
+ return buildSpotterAnalystAppInitData(starterPromptsInitData, this.viewConfig);
26013
26140
  }
26014
26141
  getEmbedParamsObject() {
26015
- const { searchOptions, disableSourceSelection, hideSourceSelection, dataPanelV2, updatedSpotterExperience, showSpotterLimitations, hideSampleQuestions, runtimeFilters, excludeRuntimeFiltersfromURL, runtimeParameters, excludeRuntimeParametersfromURL, updatedSpotterChatPrompt, showSpotterRadiance, defaultQueryMode, enableStopAnswerGenerationEmbed, spotterChatConfig, spotterAnalystConfig, } = this.viewConfig;
26142
+ const { searchOptions, disableSourceSelection, hideSourceSelection, dataPanelV2, updatedSpotterExperience, showSpotterLimitations, hideSampleQuestions, runtimeFilters, excludeRuntimeFiltersfromURL, runtimeParameters, excludeRuntimeParametersfromURL, updatedSpotterChatPrompt, showSpotterRadiance, defaultQueryMode, enableStopAnswerGenerationEmbed, spotterChatConfig, } = this.viewConfig;
26016
26143
  const queryParams = this.getBaseQueryParams();
26017
26144
  queryParams[Param.SpotterEnabled] = true;
26018
26145
  // Boolean params
@@ -26025,7 +26152,6 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26025
26152
  setParamIfDefined(queryParams, Param.ShowSpotterRadiance, showSpotterRadiance, true);
26026
26153
  setParamIfDefined(queryParams, Param.DefaultQueryMode, defaultQueryMode);
26027
26154
  setParamIfDefined(queryParams, Param.EnableStopAnswerGenerationEmbed, enableStopAnswerGenerationEmbed, true);
26028
- setParamIfDefined(queryParams, Param.AnalystId, spotterAnalystConfig === null || spotterAnalystConfig === void 0 ? void 0 : spotterAnalystConfig.analystId);
26029
26155
  // Handle spotterChatConfig params
26030
26156
  if (spotterChatConfig) {
26031
26157
  const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, enableStarterPrompts, } = spotterChatConfig;
@@ -26632,6 +26758,213 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
26632
26758
  return result;
26633
26759
  };
26634
26760
 
26761
+ /**
26762
+ * Copyright (c) 2026
26763
+ *
26764
+ * Utility to convert the payload emitted by `EmbedEvent.FilterChanged`
26765
+ * into the payload shape expected by `HostEvent.UpdateFilters`, so that
26766
+ * the current filter state of a Liveboard can be captured and re-applied
26767
+ * later without having to hand-parse the event payload.
26768
+ * @summary Filter payload converter
26769
+ */
26770
+ /**
26771
+ * Coerces an epoch/count field to a number, returning `null` when the value is
26772
+ * absent or not a finite number. The payload arrives as JSON from the iframe,
26773
+ * so a missing field can be `null` as well as `undefined`, and `Number(null)`
26774
+ * or `Number('')` would otherwise silently become a valid-looking `0`
26775
+ * (i.e. the Unix epoch, or a zero-length period).
26776
+ * @param value Raw value from the date filter payload.
26777
+ */
26778
+ function toFiniteNumber(value) {
26779
+ if (isNil_1(value) || value === '')
26780
+ return null;
26781
+ const numericValue = Number(value);
26782
+ return Number.isFinite(numericValue) ? numericValue : null;
26783
+ }
26784
+ const DATE_FILTER_VALUE_EXTRACTORS = {
26785
+ EXACT_DATE: (dateFilter) => {
26786
+ const epoch = toFiniteNumber(dateFilter.epoch);
26787
+ return epoch === null ? [] : [epoch];
26788
+ },
26789
+ EXACT_DATE_RANGE: (dateFilter) => {
26790
+ var _a;
26791
+ const { lowEpoch, highEpoch } = (_a = dateFilter.dateRange) !== null && _a !== void 0 ? _a : {};
26792
+ const low = toFiniteNumber(lowEpoch);
26793
+ const high = toFiniteNumber(highEpoch);
26794
+ return low === null || high === null ? [] : [low, high];
26795
+ },
26796
+ MONTH_YEAR: (dateFilter) => (dateFilter.monthName && dateFilter.yearName
26797
+ ? [dateFilter.monthName, dateFilter.yearName]
26798
+ : []),
26799
+ QUARTER_YEAR: (dateFilter) => (dateFilter.quarterName && dateFilter.yearName
26800
+ ? [dateFilter.quarterName, dateFilter.yearName]
26801
+ : []),
26802
+ YEAR_ONLY: (dateFilter) => (dateFilter.yearName ? [dateFilter.yearName] : []),
26803
+ LAST_N_PERIOD: (dateFilter) => {
26804
+ const count = toFiniteNumber(dateFilter.number);
26805
+ return count === null ? [] : [count];
26806
+ },
26807
+ NEXT_N_PERIOD: (dateFilter) => {
26808
+ const count = toFiniteNumber(dateFilter.number);
26809
+ return count === null ? [] : [count];
26810
+ },
26811
+ };
26812
+ // Date filter types with no `values` (e.g. TODAY needs no operand).
26813
+ const PERIOD_ONLY_DATE_FILTER_TYPES = new Set([
26814
+ 'THIS_PERIOD', 'PERIOD_TO_DATE', 'TODAY', 'YESTERDAY', 'TOMORROW',
26815
+ ]);
26816
+ function convertDateFilterToParam(columnName, dateFilterContent) {
26817
+ var _a;
26818
+ const dateFilter = dateFilterContent === null || dateFilterContent === void 0 ? void 0 : dateFilterContent.dateFilter;
26819
+ if (!(dateFilter === null || dateFilter === void 0 ? void 0 : dateFilter.type))
26820
+ return null;
26821
+ let values;
26822
+ const getValues = DATE_FILTER_VALUE_EXTRACTORS[dateFilter.type];
26823
+ if (getValues) {
26824
+ values = getValues(dateFilter);
26825
+ // Required fields (e.g. epoch, yearName) are missing - the source data
26826
+ // can't be reconstructed faithfully, so skip rather than emit a filter
26827
+ // that would clear/corrupt this column when re-applied.
26828
+ if (values.length === 0)
26829
+ return null;
26830
+ }
26831
+ else if (PERIOD_ONLY_DATE_FILTER_TYPES.has(dateFilter.type)) {
26832
+ values = [];
26833
+ }
26834
+ else {
26835
+ // Unrecognized date filter type - skip rather than guess.
26836
+ return null;
26837
+ }
26838
+ const param = {
26839
+ columnName,
26840
+ operator: (_a = dateFilter.op) !== null && _a !== void 0 ? _a : exports.RuntimeFilterOp.EQ,
26841
+ values,
26842
+ type: dateFilter.type,
26843
+ };
26844
+ if (dateFilter.datePeriod) {
26845
+ param.datePeriod = dateFilter.datePeriod;
26846
+ }
26847
+ if (!isNil_1(dateFilter.includeCurrentPeriod)) {
26848
+ param.includeCurrentPeriod = dateFilter.includeCurrentPeriod;
26849
+ }
26850
+ if (dateFilterContent.negate) {
26851
+ param.negate = true;
26852
+ }
26853
+ return param;
26854
+ }
26855
+ function convertFilterContentToParam(columnName, filterContent) {
26856
+ var _a;
26857
+ if (!(filterContent === null || filterContent === void 0 ? void 0 : filterContent.filterType))
26858
+ return null;
26859
+ const values = ((_a = filterContent.value) !== null && _a !== void 0 ? _a : [])
26860
+ .map((value) => value === null || value === void 0 ? void 0 : value.key)
26861
+ .filter((value) => !isNil_1(value));
26862
+ const param = {
26863
+ columnName,
26864
+ operator: filterContent.filterType,
26865
+ values,
26866
+ };
26867
+ if (filterContent.negate) {
26868
+ param.negate = true;
26869
+ }
26870
+ return param;
26871
+ }
26872
+ function convertFilterToParams(columnName, filter) {
26873
+ var _a, _b;
26874
+ const dateParams = ((_a = filter === null || filter === void 0 ? void 0 : filter.dateFilterContent) !== null && _a !== void 0 ? _a : [])
26875
+ .map((dateFilterContent) => convertDateFilterToParam(columnName, dateFilterContent));
26876
+ const contentParams = ((_b = filter === null || filter === void 0 ? void 0 : filter.filterContent) !== null && _b !== void 0 ? _b : [])
26877
+ .map((filterContent) => convertFilterContentToParam(columnName, filterContent));
26878
+ return [...dateParams, ...contentParams]
26879
+ .filter((param) => param !== null);
26880
+ }
26881
+ /**
26882
+ * Runtime filters need no reshaping, but they still come off the wire as JSON,
26883
+ * so a malformed entry is possible. Skip it rather than pass it through: an
26884
+ * entry missing a column, operator or values array fails
26885
+ * `isValidUpdateFiltersPayload`, and that rejects the *whole* `filters` array,
26886
+ * so one bad runtime filter would drop every other converted filter with it.
26887
+ * @param runtimeFilter A runtime filter from the `FilterChanged` payload.
26888
+ */
26889
+ function convertRuntimeFilterToParam(runtimeFilter) {
26890
+ const { columnName, operator, values } = runtimeFilter !== null && runtimeFilter !== void 0 ? runtimeFilter : {};
26891
+ if (typeof columnName !== 'string' || !columnName)
26892
+ return null;
26893
+ if (typeof operator !== 'string' || !operator)
26894
+ return null;
26895
+ if (!Array.isArray(values))
26896
+ return null;
26897
+ return { columnName, operator, values };
26898
+ }
26899
+ /**
26900
+ * Mirrors `isValidApplicability` in `hostEventClient/utils`: a `TAB` or `GROUP`
26901
+ * scope is meaningless without a `targetId`, and `UpdateFilters` rejects the
26902
+ * whole `filters` array when any entry carries a malformed `applicability`.
26903
+ * @param applicability Scope taken from the `FilterChanged` payload.
26904
+ */
26905
+ function isUsableApplicability(applicability) {
26906
+ const levels = Object.values(exports.ApplicabilityLevel);
26907
+ if (!levels.includes(applicability.level))
26908
+ return false;
26909
+ if (applicability.level === exports.ApplicabilityLevel.Liveboard)
26910
+ return true;
26911
+ return typeof applicability.targetId === 'string' && applicability.targetId.trim().length > 0;
26912
+ }
26913
+ function convertFilterGroupToParams(filterGroup) {
26914
+ var _a, _b;
26915
+ const columnName = (_a = filterGroup === null || filterGroup === void 0 ? void 0 : filterGroup.columnInfo) === null || _a === void 0 ? void 0 : _a.name;
26916
+ if (!columnName)
26917
+ return [];
26918
+ const { applicability } = filterGroup;
26919
+ // A filter scoped to a tab or group has to keep that scope. Replaying it
26920
+ // without `applicability` would silently widen it to the whole Liveboard,
26921
+ // changing what every other tab shows. If a scope is present but unusable,
26922
+ // skip the filter: widening is worse than dropping, and a malformed
26923
+ // applicability would fail validation for every other filter alongside it.
26924
+ if (!isNil_1(applicability) && !isUsableApplicability(applicability))
26925
+ return [];
26926
+ const params = ((_b = filterGroup.filters) !== null && _b !== void 0 ? _b : [])
26927
+ .flatMap((filter) => convertFilterToParams(columnName, filter));
26928
+ return isNil_1(applicability) ? params : params.map((param) => ({ ...param, applicability }));
26929
+ }
26930
+ /**
26931
+ * Converts the payload emitted by {@link EmbedEvent.FilterChanged} into the
26932
+ * payload shape expected by {@link HostEvent.UpdateFilters}, so the same
26933
+ * filter state can be captured and re-applied later, for example on a
26934
+ * subsequent page load.
26935
+ *
26936
+ * Both the Liveboard filters and the runtime filters present in the
26937
+ * `FilterChanged` payload are included in the returned `filters` array.
26938
+ *
26939
+ * Note: a column with multiple date-filter conditions (e.g. an OR of two
26940
+ * date ranges) is not guaranteed to round-trip losslessly - `HostEvent.UpdateFilters`
26941
+ * treats date filters as replace-not-merge per column, so only the last
26942
+ * converted entry for such a column will apply.
26943
+ * @param filterChangedPayload The filter state carried by the
26944
+ * `EmbedEvent.FilterChanged` callback, which is `payload.data` - the
26945
+ * callback argument is the event envelope, and the filters sit under its
26946
+ * `data` key.
26947
+ * @example
26948
+ * ```js
26949
+ * let savedFilters;
26950
+ * liveboardEmbed.on(EmbedEvent.FilterChanged, (payload) => {
26951
+ * savedFilters = convertFilterChangedToUpdateFiltersPayload(payload.data);
26952
+ * });
26953
+ *
26954
+ * // later, e.g. after a fresh page load
26955
+ * liveboardEmbed.trigger(HostEvent.UpdateFilters, savedFilters);
26956
+ * ```
26957
+ */
26958
+ function convertFilterChangedToUpdateFiltersPayload(filterChangedPayload) {
26959
+ var _a, _b;
26960
+ const liveboardFilterParams = ((_a = filterChangedPayload === null || filterChangedPayload === void 0 ? void 0 : filterChangedPayload.liveboardFilters) !== null && _a !== void 0 ? _a : [])
26961
+ .flatMap(convertFilterGroupToParams);
26962
+ const runtimeFilterParams = ((_b = filterChangedPayload === null || filterChangedPayload === void 0 ? void 0 : filterChangedPayload.runtimeFilters) !== null && _b !== void 0 ? _b : [])
26963
+ .map(convertRuntimeFilterToParam)
26964
+ .filter((param) => param !== null);
26965
+ return { filters: [...liveboardFilterParams, ...runtimeFilterParams] };
26966
+ }
26967
+
26635
26968
  /**
26636
26969
  * Starts an automatic renderer that watches the DOM for iframes containing
26637
26970
  * the `tsmcp=true` query parameter and replaces them with fully configured
@@ -34304,6 +34637,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
34304
34637
  exports.SearchEmbed = SearchEmbed;
34305
34638
  exports.SpotterAgentEmbed = SpotterAgentEmbed;
34306
34639
  exports.SpotterEmbed = SpotterEmbed;
34640
+ exports.convertFilterChangedToUpdateFiltersPayload = convertFilterChangedToUpdateFiltersPayload;
34307
34641
  exports.createLiveboardWithAnswers = createLiveboardWithAnswers;
34308
34642
  exports.executeTML = executeTML;
34309
34643
  exports.exportTML = exportTML;