@thoughtspot/visual-embed-sdk 1.52.2-beta → 1.52.2-beta.1

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 (82) hide show
  1. package/cjs/package.json +2 -2
  2. package/cjs/src/embed/app.js +1 -1
  3. package/cjs/src/embed/app.js.map +1 -1
  4. package/cjs/src/embed/auto-frame-renderer.js +1 -1
  5. package/cjs/src/embed/auto-frame-renderer.js.map +1 -1
  6. package/cjs/src/embed/bodyless-conversation.js +1 -1
  7. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  8. package/cjs/src/embed/conversation.js +1 -1
  9. package/cjs/src/embed/conversation.js.map +1 -1
  10. package/cjs/src/embed/liveboard.d.ts +1 -0
  11. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  12. package/cjs/src/embed/liveboard.js +16 -4
  13. package/cjs/src/embed/liveboard.js.map +1 -1
  14. package/cjs/src/embed/liveboard.spec.js +54 -0
  15. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  16. package/cjs/src/embed/search-bar.js +1 -1
  17. package/cjs/src/embed/search-bar.js.map +1 -1
  18. package/cjs/src/embed/search.js +1 -1
  19. package/cjs/src/embed/search.js.map +1 -1
  20. package/cjs/src/embed/search.spec.js +0 -20
  21. package/cjs/src/embed/search.spec.js.map +1 -1
  22. package/cjs/src/embed/ts-embed.d.ts +34 -12
  23. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  24. package/cjs/src/embed/ts-embed.js +98 -142
  25. package/cjs/src/embed/ts-embed.js.map +1 -1
  26. package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
  27. package/cjs/src/embed/ts-embed.spec.js +171 -138
  28. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  29. package/dist/{index-CcBYlGo9.js → index-Bt56pC82.js} +1 -1
  30. package/dist/src/embed/liveboard.d.ts +1 -0
  31. package/dist/src/embed/liveboard.d.ts.map +1 -1
  32. package/dist/src/embed/ts-embed.d.ts +34 -12
  33. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  34. package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
  35. package/dist/tsembed-react.es.js +161 -155
  36. package/dist/tsembed-react.js +160 -154
  37. package/dist/tsembed.es.js +162 -156
  38. package/dist/tsembed.js +161 -155
  39. package/dist/visual-embed-sdk-react-full.d.ts +35 -12
  40. package/dist/visual-embed-sdk-react.d.ts +35 -12
  41. package/dist/visual-embed-sdk.d.ts +35 -12
  42. package/lib/package.json +2 -2
  43. package/lib/src/embed/app.js +1 -1
  44. package/lib/src/embed/app.js.map +1 -1
  45. package/lib/src/embed/auto-frame-renderer.js +1 -1
  46. package/lib/src/embed/auto-frame-renderer.js.map +1 -1
  47. package/lib/src/embed/bodyless-conversation.js +1 -1
  48. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  49. package/lib/src/embed/conversation.js +1 -1
  50. package/lib/src/embed/conversation.js.map +1 -1
  51. package/lib/src/embed/liveboard.d.ts +1 -0
  52. package/lib/src/embed/liveboard.d.ts.map +1 -1
  53. package/lib/src/embed/liveboard.js +15 -4
  54. package/lib/src/embed/liveboard.js.map +1 -1
  55. package/lib/src/embed/liveboard.spec.js +54 -0
  56. package/lib/src/embed/liveboard.spec.js.map +1 -1
  57. package/lib/src/embed/search-bar.js +1 -1
  58. package/lib/src/embed/search-bar.js.map +1 -1
  59. package/lib/src/embed/search.js +1 -1
  60. package/lib/src/embed/search.js.map +1 -1
  61. package/lib/src/embed/search.spec.js +0 -20
  62. package/lib/src/embed/search.spec.js.map +1 -1
  63. package/lib/src/embed/ts-embed.d.ts +34 -12
  64. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  65. package/lib/src/embed/ts-embed.js +99 -143
  66. package/lib/src/embed/ts-embed.js.map +1 -1
  67. package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
  68. package/lib/src/embed/ts-embed.spec.js +172 -139
  69. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  70. package/lib/src/visual-embed-sdk.d.ts +35 -12
  71. package/package.json +2 -2
  72. package/src/embed/app.ts +1 -1
  73. package/src/embed/auto-frame-renderer.ts +1 -1
  74. package/src/embed/bodyless-conversation.ts +1 -1
  75. package/src/embed/conversation.ts +1 -1
  76. package/src/embed/liveboard.spec.ts +62 -0
  77. package/src/embed/liveboard.ts +18 -4
  78. package/src/embed/search-bar.tsx +1 -1
  79. package/src/embed/search.spec.ts +0 -23
  80. package/src/embed/search.ts +1 -1
  81. package/src/embed/ts-embed.spec.ts +213 -179
  82. package/src/embed/ts-embed.ts +96 -149
package/dist/tsembed.js CHANGED
@@ -1,4 +1,4 @@
1
- /* @thoughtspot/visual-embed-sdk version 1.52.2-beta */
1
+ /* @thoughtspot/visual-embed-sdk version 1.52.2-beta.1 */
2
2
  'use client';
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
@@ -7649,7 +7649,7 @@
7649
7649
  TableContentDensity["Compact"] = "COMPACT";
7650
7650
  })(exports.TableContentDensity || (exports.TableContentDensity = {}));
7651
7651
 
7652
- var version$1="1.52.2-beta";var pkg = {version:version$1};
7652
+ var version$1="1.52.2-beta.1";var pkg = {version:version$1};
7653
7653
 
7654
7654
  const { version } = pkg;
7655
7655
 
@@ -22202,6 +22202,9 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22202
22202
  */
22203
22203
  const PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY = 'tsEmbedOriginalPosition';
22204
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';
22205
22208
  // The container applies UpdateEmbedParams through React state, so a delivered
22206
22209
  // post is not the same as the params being in effect.
22207
22210
  const UPDATE_EMBED_PARAMS_SETTLE_MS = 200;
@@ -22209,56 +22212,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22209
22212
  // truthy, so null or '' leaves the previous embed's values in place. '&' is
22210
22213
  // truthy and parses to {}.
22211
22214
  const NO_RUNTIME_PARAMS = '&';
22212
- /**
22213
- * Query parameters that stay on the iframe `src` while config is excluded from
22214
- * the URL, which is the default unless the embed sets the
22215
- * `excludeConfigFromURL` additional flag to `false`. These are the parameters the
22216
- * application shell needs before it can receive a postMessage at all: the
22217
- * embed marker, the host application URL used to validate the message origin,
22218
- * the SDK version, the flags that pick the authentication flow, and the
22219
- * boot-time settings that would otherwise be applied a frame late (viewport,
22220
- * log level, locale, formatting and org). Everything else is delivered over
22221
- * `HostEvent.UpdateEmbedParams`.
22222
- * @internal
22223
- */
22224
- const BOOTSTRAP_URL_PARAMS = new Set([
22225
- Param.EmbedApp,
22226
- Param.HostAppUrl,
22227
- Param.Version,
22228
- Param.AuthType,
22229
- Param.AutoLogin,
22230
- Param.DisableLoginRedirect,
22231
- Param.ForceSAMLAutoRedirect,
22232
- Param.cookieless,
22233
- Param.preAuthCache,
22234
- Param.blockNonEmbedFullAppAccess,
22235
- Param.OverrideOrgId,
22236
- Param.ViewPortHeight,
22237
- Param.ViewPortWidth,
22238
- Param.ClientLogLevel,
22239
- Param.OverrideNativeConsole,
22240
- Param.PendoTrackingKey,
22241
- Param.NumberFormatLocale,
22242
- Param.DateFormatLocale,
22243
- Param.CurrencyFormat,
22244
- Param.Locale,
22245
- Param.searchEmbed,
22246
- Param.livedBoardEmbed,
22247
- Param.isSpotterAgentEmbed,
22248
- Param.SpotterEnabled,
22249
- Param.IsFullAppEmbed,
22250
- Param.IsOnBeforeGetVizDataInterceptEnabled,
22251
- Param.LinkOverride,
22252
- Param.EnableLinkOverridesV2,
22253
- Param.DisableRedirectionLinksInNewTab,
22254
- Param.OverrideHistoryState,
22255
- Param.ForceTable,
22256
- Param.StringIDsUrl,
22257
- Param.DataSources,
22258
- Param.ExposeTranslationIDs,
22259
- Param.IconSpriteUrl,
22260
- Param.Tag,
22261
- ]);
22262
22215
  /**
22263
22216
  * The event id map from v2 event names to v1 event id
22264
22217
  * v1 events are the classic embed events implemented in Blink v1
@@ -22296,7 +22249,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22296
22249
  this.shouldEncodeUrlQueryParams = false;
22297
22250
  this.defaultHiddenActions = [exports.Action.ReportError];
22298
22251
  this.preRenderContainerEl = document.body;
22299
- this.containerScrollListener = null;
22300
22252
  /**
22301
22253
  * Handler for fullscreen change events
22302
22254
  */
@@ -22461,9 +22413,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22461
22413
  }
22462
22414
  else if (source === exports.EmbedEvent.EmbedListenerReady) {
22463
22415
  processEmbedContainerReady();
22464
- if (this.isConfigExcludedFromUrl()) {
22465
- this.triggerUpdateEmbedParams();
22466
- }
22467
22416
  }
22468
22417
  };
22469
22418
  // Subclasses that navigate the pre-render on show must await this before
@@ -22968,20 +22917,13 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
22968
22917
  return path;
22969
22918
  }
22970
22919
  getEmbedParams() {
22971
- const queryParams = this.getUrlQueryParamsObject();
22920
+ const queryParams = this.getEmbedParamsObject();
22972
22921
  return getQueryParamString(queryParams);
22973
22922
  }
22974
22923
  getEmbedParamsObject() {
22975
22924
  const params = this.getBaseQueryParams();
22976
22925
  return params;
22977
22926
  }
22978
- getUrlQueryParamsObject() {
22979
- const queryParams = this.getEmbedParamsObject();
22980
- if (!this.isConfigExcludedFromUrl()) {
22981
- return queryParams;
22982
- }
22983
- return Object.fromEntries(Object.entries(queryParams).filter(([key]) => BOOTSTRAP_URL_PARAMS.has(key)));
22984
- }
22985
22927
  getRootIframeSrc() {
22986
22928
  const query = this.getEmbedParams();
22987
22929
  return this.getEmbedBasePath(query);
@@ -23152,7 +23094,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23152
23094
  top: '0',
23153
23095
  left: '0',
23154
23096
  width: '100vw',
23155
- height: '100vh',
23097
+ height: UNMEASURED_WRAPPER_HEIGHT,
23156
23098
  };
23157
23099
  setStyleProperties(preRenderWrapper, initialPreRenderWrapperStyle);
23158
23100
  return preRenderWrapper;
@@ -23220,10 +23162,26 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23220
23162
  return placeholder;
23221
23163
  }
23222
23164
  /**
23223
- * Resolves the configured preRenderContainer to a live element, falling
23224
- * back to `document.body`. A string selector is re-queried on every call so
23225
- * a remounted container (E.g.: React replacing the node) resolves to the
23226
- * 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.
23227
23185
  */
23228
23186
  resolvePreRenderContainerTarget() {
23229
23187
  var _a;
@@ -23243,7 +23201,13 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23243
23201
  else if (containerConfig) {
23244
23202
  container = containerConfig;
23245
23203
  }
23246
- 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;
23247
23211
  }
23248
23212
  inheritPreRenderContainer() {
23249
23213
  var _a;
@@ -23288,8 +23252,9 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23288
23252
  * Re-attaches the wrapper to a live container when the previously resolved
23289
23253
  * one has been detached or no longer holds the wrapper — e.g. the host app
23290
23254
  * remounted a custom preRenderContainer, which would otherwise leave a stale
23291
- * reference and collapse the wrapper. Only string selectors can be
23292
- * 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.
23293
23258
  */
23294
23259
  reconcilePreRenderContainer() {
23295
23260
  const wrapper = this.preRenderWrapper;
@@ -23308,14 +23273,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23308
23273
  if (resolved === stored && stored.contains(wrapper)) {
23309
23274
  return;
23310
23275
  }
23311
- if (this.containerScrollListener && stored !== resolved) {
23312
- if (stored !== document.body) {
23313
- stored.removeEventListener('scroll', this.containerScrollListener);
23314
- }
23315
- if (resolved !== document.body) {
23316
- resolved.addEventListener('scroll', this.containerScrollListener);
23317
- }
23318
- }
23319
23276
  this.preRenderContainerEl = resolved;
23320
23277
  this.applyPreRenderContainerPositioning();
23321
23278
  if (wrapper.parentNode !== resolved) {
@@ -23377,11 +23334,12 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23377
23334
  */
23378
23335
  setIFrameHeight(height) {
23379
23336
  if (this.isPreRendered) {
23337
+ const next = getCssDimension(height);
23380
23338
  if (this.insertedDomEl) {
23381
- this.insertedDomEl.style.height = getCssDimension(height);
23339
+ this.insertedDomEl.style.height = next;
23382
23340
  }
23383
23341
  else if (this.preRenderWrapper) {
23384
- this.preRenderWrapper.style.height = getCssDimension(height);
23342
+ this.preRenderWrapper.style.height = next;
23385
23343
  }
23386
23344
  }
23387
23345
  else {
@@ -23816,34 +23774,47 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23816
23774
  delete container.dataset[PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY];
23817
23775
  }
23818
23776
  /**
23819
- * Detaches and clears the container scroll listener, if one is attached.
23820
- */
23821
- removeContainerScrollListener() {
23822
- 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) {
23823
23794
  return;
23824
23795
  }
23825
- const customContainer = this.getCustomPreRenderContainer();
23826
- customContainer === null || customContainer === void 0 ? void 0 : customContainer.removeEventListener('scroll', this.containerScrollListener);
23827
- 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);
23828
23799
  }
23829
23800
  /**
23830
23801
  * Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
23831
23802
  * @version SDK: 1.19.1 | ThoughtSpot: *
23832
23803
  */
23833
23804
  destroy() {
23834
- var _a, _b, _c;
23805
+ var _a, _b, _c, _d;
23835
23806
  try {
23836
23807
  this.removeFullscreenChangeHandler();
23837
- this.removeContainerScrollListener();
23808
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23838
23809
  this.unsubscribeToEvents();
23839
- (_a = this.preRenderWrapper) === null || _a === void 0 ? void 0 : _a.remove();
23810
+ (_b = this.preRenderWrapper) === null || _b === void 0 ? void 0 : _b.remove();
23840
23811
  this.restorePreRenderContainerPosition();
23841
23812
  if (!this.isRendered) {
23842
23813
  return;
23843
23814
  }
23844
23815
  if (!getEmbedConfig().waitForCleanupOnDestroy) {
23845
23816
  this.trigger(exports.HostEvent.DestroyEmbed);
23846
- (_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);
23847
23818
  }
23848
23819
  else {
23849
23820
  const cleanupTimeout = getEmbedConfig().cleanupTimeout;
@@ -23889,27 +23860,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23889
23860
  this.isRendered = true;
23890
23861
  return this.renderIFrame(prerenderFrameSrc);
23891
23862
  }
23892
- isConfigExcludedFromUrl() {
23893
- var _a, _b, _c;
23894
- const flag = (_b = (_a = this.viewConfig.additionalFlags) === null || _a === void 0 ? void 0 : _a.excludeConfigFromURL) !== null && _b !== void 0 ? _b : (_c = this.embedConfig.additionalFlags) === null || _c === void 0 ? void 0 : _c.excludeConfigFromURL;
23895
- // Enabled by default; only an explicit false opts out.
23896
- return flag !== false && flag !== 'false';
23897
- }
23898
- async triggerUpdateEmbedParams() {
23899
- try {
23900
- const params = await this.getUpdateEmbedParamsObject();
23901
- this.trigger(exports.HostEvent.UpdateEmbedParams, params);
23902
- }
23903
- catch (error) {
23904
- logger$3.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
23905
- this.handleError({
23906
- errorType: exports.ErrorDetailsTypes.API,
23907
- message: (error === null || error === void 0 ? void 0 : error.message) || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
23908
- code: exports.EmbedErrorCodes.UPDATE_PARAMS_FAILED,
23909
- error: (error === null || error === void 0 ? void 0 : error.message) || error,
23910
- });
23911
- }
23912
- }
23913
23863
  beforePrerenderVisible() {
23914
23864
  // We can ignore this as its a bit expensive and the newer customers
23915
23865
  // have moved on to UpdateEmbedParams supported clusters
@@ -23920,7 +23870,17 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23920
23870
  this.preRenderParamsApplied = new Promise((resolve) => {
23921
23871
  this.executeAfterEmbedContainerLoaded(async () => {
23922
23872
  try {
23923
- await this.triggerUpdateEmbedParams();
23873
+ const params = await this.getUpdateEmbedParamsObject();
23874
+ this.trigger(exports.HostEvent.UpdateEmbedParams, params);
23875
+ }
23876
+ catch (error) {
23877
+ logger$3.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
23878
+ this.handleError({
23879
+ errorType: exports.ErrorDetailsTypes.API,
23880
+ message: (error === null || error === void 0 ? void 0 : error.message) || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
23881
+ code: exports.EmbedErrorCodes.UPDATE_PARAMS_FAILED,
23882
+ error: (error === null || error === void 0 ? void 0 : error.message) || error,
23883
+ });
23924
23884
  }
23925
23885
  finally {
23926
23886
  setTimeout(resolve, UPDATE_EMBED_PARAMS_SETTLE_MS);
@@ -23935,7 +23895,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23935
23895
  * wrapper to overlay it.
23936
23896
  */
23937
23897
  async showPreRender() {
23938
- var _a, _b;
23898
+ var _a;
23939
23899
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_SHOW_PRE_RENDER, {
23940
23900
  preRenderId: this.getPreRenderConfig().id,
23941
23901
  embedComponentType: this.viewConfig.embedComponentType,
@@ -23954,14 +23914,16 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23954
23914
  this.beforePrerenderVisible();
23955
23915
  if (this.hostElement) {
23956
23916
  this.insertedDomEl = this.createPreRenderPlaceholder();
23957
- if (this.viewConfig.fullHeight) {
23958
- // If fullHeight has already sized the wrapper, seed the
23959
- // placeholder with the same height so syncPreRenderStyle gets
23960
- // an accurate rect.
23961
- const existingHeight = this.preRenderWrapper.style.height;
23962
- if (existingHeight) {
23963
- this.insertedDomEl.style.height = existingHeight;
23964
- }
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;
23965
23927
  }
23966
23928
  const placeHolderId = this.getPreRenderIds().placeHolder;
23967
23929
  // Remove any stale placeholder from a previous cycle. It is located
@@ -23975,29 +23937,19 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
23975
23937
  (_a = this.hostElement.querySelector(`#${placeHolderId}`)) === null || _a === void 0 ? void 0 : _a.remove();
23976
23938
  this.hostElement.appendChild(this.insertedDomEl);
23977
23939
  this.syncPreRenderStyle();
23978
- const customContainer = this.getCustomPreRenderContainer();
23979
- if (customContainer && !this.containerScrollListener) {
23980
- this.containerScrollListener = () => this.syncPreRenderStyle();
23981
- customContainer.addEventListener('scroll', this.containerScrollListener);
23982
- }
23983
- if (!this.getPreRenderConfig().doNotTrackSize) {
23984
- const observeTarget = (_b = this.insertedDomEl) !== null && _b !== void 0 ? _b : this.hostElement;
23985
- this.resizeObserver = new ResizeObserver((entries) => {
23986
- entries.forEach((entry) => {
23987
- if (entry.target === observeTarget) {
23988
- this.syncPreRenderStyle();
23989
- }
23990
- });
23991
- });
23992
- this.resizeObserver.observe(observeTarget);
23993
- }
23940
+ this.observePreRenderSize();
23994
23941
  }
23995
23942
  removeStyleProperties(this.preRenderWrapper, [
23996
23943
  'z-index',
23997
23944
  'opacity',
23998
- 'pointer-events',
23999
23945
  'overflow',
23946
+ 'transform',
24000
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' });
24001
23953
  this.subscribeToEvents();
24002
23954
  // Setup fullscreen change handler for prerendered components
24003
23955
  if (this.iFrame) {
@@ -24050,6 +24002,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24050
24002
  * If the component is not preRendered, it issues a warning.
24051
24003
  */
24052
24004
  hidePreRender() {
24005
+ var _a;
24053
24006
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_HIDE_PRE_RENDER, {
24054
24007
  preRenderId: this.getPreRenderConfig().id,
24055
24008
  embedComponentType: this.viewConfig.embedComponentType,
@@ -24069,12 +24022,15 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24069
24022
  top: '0',
24070
24023
  left: '0',
24071
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,
24072
24031
  };
24073
24032
  setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
24074
- this.removeContainerScrollListener();
24075
- if (this.resizeObserver) {
24076
- this.resizeObserver.disconnect();
24077
- }
24033
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
24078
24034
  const placeHolderEle = this.getPreRenderPlaceHolderElement();
24079
24035
  if (placeHolderEle) {
24080
24036
  placeHolderEle.parentElement.removeChild(placeHolderEle);
@@ -24500,7 +24456,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24500
24456
  * embedded Liveboard or visualization.
24501
24457
  */
24502
24458
  getEmbedParams() {
24503
- const params = this.getUrlQueryParamsObject();
24459
+ const params = this.getEmbedParamsObject();
24504
24460
  return getQueryParamString(params, true);
24505
24461
  }
24506
24462
  getEmbedParamsObject() {
@@ -24817,6 +24773,46 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
24817
24773
  }
24818
24774
  }
24819
24775
 
24776
+ /**
24777
+ * This method is like `_.isEqual` except that it accepts `customizer` which
24778
+ * is invoked to compare values. If `customizer` returns `undefined`, comparisons
24779
+ * are handled by the method instead. The `customizer` is invoked with up to
24780
+ * six arguments: (objValue, othValue [, index|key, object, other, stack]).
24781
+ *
24782
+ * @static
24783
+ * @memberOf _
24784
+ * @since 4.0.0
24785
+ * @category Lang
24786
+ * @param {*} value The value to compare.
24787
+ * @param {*} other The other value to compare.
24788
+ * @param {Function} [customizer] The function to customize comparisons.
24789
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
24790
+ * @example
24791
+ *
24792
+ * function isGreeting(value) {
24793
+ * return /^h(?:i|ello)$/.test(value);
24794
+ * }
24795
+ *
24796
+ * function customizer(objValue, othValue) {
24797
+ * if (isGreeting(objValue) && isGreeting(othValue)) {
24798
+ * return true;
24799
+ * }
24800
+ * }
24801
+ *
24802
+ * var array = ['hello', 'goodbye'];
24803
+ * var other = ['hi', 'goodbye'];
24804
+ *
24805
+ * _.isEqualWith(array, other, customizer);
24806
+ * // => true
24807
+ */
24808
+ function isEqualWith(value, other, customizer) {
24809
+ customizer = typeof customizer == 'function' ? customizer : undefined;
24810
+ var result = customizer ? customizer(value, other) : undefined;
24811
+ return result === undefined ? _baseIsEqual(value, other, undefined, customizer) : !!result;
24812
+ }
24813
+
24814
+ var isEqualWith_1 = isEqualWith;
24815
+
24820
24816
  const getPreviewQuery = `
24821
24817
  query GetEurekaVizSnapshots(
24822
24818
  $vizId: String!, $liveboardId: String!) {
@@ -24958,7 +24954,7 @@ query GetEurekaVizSnapshots(
24958
24954
  * embedded Liveboard or visualization.
24959
24955
  */
24960
24956
  getEmbedParams() {
24961
- const params = this.getUrlQueryParamsObject();
24957
+ const params = this.getEmbedParamsObject();
24962
24958
  const queryParams = getQueryParamString(params, true);
24963
24959
  return queryParams;
24964
24960
  }
@@ -25197,10 +25193,12 @@ query GetEurekaVizSnapshots(
25197
25193
  beforePrerenderVisible() {
25198
25194
  super.beforePrerenderVisible();
25199
25195
  // Captured before showPreRender() hands the wrapper over to this
25200
- // instance. Itself means a hide/show, not a hand-over, so there is
25201
- // nothing stale to clear.
25196
+ // instance. React builds a new instance per mount, so an equal config
25197
+ // is a hide/show, not a hand-over: there is nothing stale to clear.
25202
25198
  const previous = this.getPreRenderObj();
25203
- const showing = previous === this ? undefined : previous === null || previous === void 0 ? void 0 : previous.currentLiveboardState;
25199
+ const showing = this.isSameEmbedConfig(previous)
25200
+ ? undefined
25201
+ : previous === null || previous === void 0 ? void 0 : previous.currentLiveboardState;
25204
25202
  this.executeAfterEmbedContainerLoaded(async () => {
25205
25203
  // Without this the params callback suspends on its await and
25206
25204
  // Navigate goes out first, so the container loads with the previous
@@ -25227,6 +25225,14 @@ query GetEurekaVizSnapshots(
25227
25225
  };
25228
25226
  });
25229
25227
  }
25228
+ // Callbacks are compared as equal: React passes a fresh closure per render.
25229
+ isSameEmbedConfig(previous) {
25230
+ if (!previous)
25231
+ return false;
25232
+ if (previous === this)
25233
+ return true;
25234
+ return isEqualWith_1(previous.viewConfig, this.viewConfig, (a, b) => (typeof a === 'function' && typeof b === 'function' ? true : undefined));
25235
+ }
25230
25236
  // The whole route, not just the liveboard id: the path is built from the
25231
25237
  // viz, tab and view too, so a same-liveboard show onto another tab is a
25232
25238
  // real navigation.
@@ -25489,7 +25495,7 @@ query GetEurekaVizSnapshots(
25489
25495
  }
25490
25496
  getEmbedParams() {
25491
25497
  const { runtimeParameters, runtimeFilters, excludeRuntimeParametersfromURL, excludeRuntimeFiltersfromURL, } = this.viewConfig;
25492
- const queryParams = this.getUrlQueryParamsObject();
25498
+ const queryParams = this.getEmbedParamsObject();
25493
25499
  let query = '';
25494
25500
  const queryParamsString = getQueryParamString(queryParams, true);
25495
25501
  if (queryParamsString) {
@@ -25577,7 +25583,7 @@ query GetEurekaVizSnapshots(
25577
25583
  * @param dataSources A list of data source GUIDs
25578
25584
  */
25579
25585
  getIFrameSrc() {
25580
- const queryParams = this.getUrlQueryParamsObject();
25586
+ const queryParams = this.getEmbedParamsObject();
25581
25587
  const path = 'search-bar-embed';
25582
25588
  let query = '';
25583
25589
  const queryParamsString = getQueryParamString(queryParams, true);
@@ -26011,7 +26017,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26011
26017
  getIframeSrc() {
26012
26018
  const { sessionId, genNo, acSessionId, acGenNo, convId, messageId, } = this.viewConfig;
26013
26019
  const path = 'conv-assist-answer';
26014
- const queryParams = this.getUrlQueryParamsObject();
26020
+ const queryParams = this.getEmbedParamsObject();
26015
26021
  let query = '';
26016
26022
  const queryParamsString = getQueryParamString(queryParams, true);
26017
26023
  if (queryParamsString) {
@@ -26219,7 +26225,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
26219
26225
  const path = sharedConversationId
26220
26226
  ? `insights/conv-assist/s/${encodeURIComponent(sharedConversationId)}`
26221
26227
  : 'insights/conv-assist';
26222
- const queryParams = this.getUrlQueryParamsObject();
26228
+ const queryParams = this.getEmbedParamsObject();
26223
26229
  let query = '';
26224
26230
  const queryParamsString = getQueryParamString(queryParams, true);
26225
26231
  if (queryParamsString) {
@@ -27107,7 +27113,7 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
27107
27113
  * @returns The constructed URL to use for the ThoughtSpot embed iframe.
27108
27114
  */
27109
27115
  getMCPIframeSrc(sourceSrc) {
27110
- const queryParams = this.getUrlQueryParamsObject();
27116
+ const queryParams = this.getEmbedParamsObject();
27111
27117
  const sourceURL = new URL(sourceSrc);
27112
27118
  const existingQueryParams = sourceURL.searchParams;
27113
27119
  const existingQueryParamsObject = Object.fromEntries(existingQueryParams);
@@ -12295,7 +12295,7 @@ declare class TsEmbed {
12295
12295
  private defaultHiddenActions;
12296
12296
  private resizeObserver;
12297
12297
  private preRenderContainerEl;
12298
- private containerScrollListener;
12298
+ /** Last height the embedded app reported, once fullHeight has measured one. */
12299
12299
  protected hostEventClient: HostEventClient;
12300
12300
  protected isReadyForRenderPromise: Promise<void>;
12301
12301
  protected shouldWaitForRenderPromise: boolean;
@@ -12510,7 +12510,6 @@ declare class TsEmbed {
12510
12510
  protected getV1EmbedBasePath(queryString: string): string;
12511
12511
  protected getEmbedParams(): string;
12512
12512
  protected getEmbedParamsObject(): Record<any, any>;
12513
- protected getUrlQueryParamsObject(): Record<any, any>;
12514
12513
  protected getRootIframeSrc(): string;
12515
12514
  protected createIframeEl(frameSrc: string): HTMLIFrameElement;
12516
12515
  /**
@@ -12552,10 +12551,26 @@ declare class TsEmbed {
12552
12551
  */
12553
12552
  private createPreRenderPlaceholder;
12554
12553
  /**
12555
- * Resolves the configured preRenderContainer to a live element, falling
12556
- * back to `document.body`. A string selector is re-queried on every call so
12557
- * a remounted container (E.g.: React replacing the node) resolves to the
12558
- * fresh element; an element passed directly cannot be re-resolved.
12554
+ * Resolves the configured preRenderContainer to a live element. A string
12555
+ * selector is re-queried on every call so a remounted container (E.g.: React
12556
+ * replacing the node) resolves to the fresh element; an element passed
12557
+ * directly cannot be re-resolved.
12558
+ *
12559
+ * With nothing configured the frame goes into the host element's nearest
12560
+ * scrolling ancestor, falling back to `document.body`.
12561
+ *
12562
+ * The wrapper is absolutely positioned, so it follows the page for free —
12563
+ * but only while it sits inside whatever scrolls. `document.body` is right
12564
+ * only when the document itself is the scroller; an app that scrolls an
12565
+ * inner element instead left the frame pinned to the viewport while the page
12566
+ * moved under it (SCAL-338563). Being inside the scroller also lets wheel
12567
+ * events chain out of the frame into it, which they cannot do from
12568
+ * `document.body`.
12569
+ *
12570
+ * A scrolling ancestor is layout chrome rather than route content, so it
12571
+ * outlives the embed in practice; and if it does go, the host element goes
12572
+ * with it and this instance is remounting anyway.
12573
+ * `reconcilePreRenderContainer` re-runs this on a detached container.
12559
12574
  */
12560
12575
  private resolvePreRenderContainerTarget;
12561
12576
  private inheritPreRenderContainer;
@@ -12572,8 +12587,9 @@ declare class TsEmbed {
12572
12587
  * Re-attaches the wrapper to a live container when the previously resolved
12573
12588
  * one has been detached or no longer holds the wrapper — e.g. the host app
12574
12589
  * remounted a custom preRenderContainer, which would otherwise leave a stale
12575
- * reference and collapse the wrapper. Only string selectors can be
12576
- * re-resolved; a container passed as an element is left untouched.
12590
+ * reference and collapse the wrapper. Selectors and the auto-resolved
12591
+ * scrolling ancestor are both re-resolved; a container passed as an element
12592
+ * is left untouched, as there is nothing to re-query.
12577
12593
  */
12578
12594
  private reconcilePreRenderContainer;
12579
12595
  protected insertIntoDOMForPreRender(child: string | Node): void;
@@ -12789,9 +12805,17 @@ declare class TsEmbed {
12789
12805
  */
12790
12806
  private restorePreRenderContainerPosition;
12791
12807
  /**
12792
- * Detaches and clears the container scroll listener, if one is attached.
12808
+ * Re-sizes the wrapper when its placeholder changes size.
12809
+ *
12810
+ * Position deliberately has no equivalent. An absolutely positioned wrapper
12811
+ * follows its containing block for free, so a correctly placed frame is the
12812
+ * browser's job and costs nothing; repositioning it on scroll would mean a
12813
+ * layout read and a style write per frame to compensate for placing it in
12814
+ * the wrong box. Size is the one thing the browser will not do for us: the
12815
+ * placeholder grows when the embedded app reports a new height, and the
12816
+ * wrapper has to be told.
12793
12817
  */
12794
- private removeContainerScrollListener;
12818
+ private observePreRenderSize;
12795
12819
  /**
12796
12820
  * Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
12797
12821
  * @version SDK: 1.19.1 | ThoughtSpot: *
@@ -12807,8 +12831,6 @@ declare class TsEmbed {
12807
12831
  */
12808
12832
  prerenderGeneric(): Promise<any>;
12809
12833
  protected preRenderParamsApplied: Promise<void>;
12810
- protected isConfigExcludedFromUrl(): boolean;
12811
- protected triggerUpdateEmbedParams(): Promise<void>;
12812
12834
  protected beforePrerenderVisible(): void;
12813
12835
  /**
12814
12836
  * Displays the pre-rendered component inside the host element.
@@ -15774,6 +15796,7 @@ declare class LiveboardEmbed extends V1Embed {
15774
15796
  personalizedViewId: string;
15775
15797
  };
15776
15798
  protected beforePrerenderVisible(): void;
15799
+ private isSameEmbedConfig;
15777
15800
  private isShowingLiveboardRoute;
15778
15801
  protected handleRenderForPrerender(): Promise<TsEmbed>;
15779
15802
  /**