@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
@@ -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 _mergeNamespaces(n, m) {
4
4
  m.forEach(function (e) {
@@ -7643,7 +7643,7 @@ var TableContentDensity;
7643
7643
  TableContentDensity["Compact"] = "COMPACT";
7644
7644
  })(TableContentDensity || (TableContentDensity = {}));
7645
7645
 
7646
- var version$1="1.52.2-beta";var pkg = {version:version$1};
7646
+ var version$1="1.52.2-beta.1";var pkg = {version:version$1};
7647
7647
 
7648
7648
  const { version } = pkg;
7649
7649
 
@@ -10779,7 +10779,7 @@ class AnswerService {
10779
10779
  async getTML() {
10780
10780
  const { object } = await this.executeQuery(getAnswerTML, {});
10781
10781
  const edoc = object[0].edoc;
10782
- const YAML = await import('./index-CcBYlGo9.js');
10782
+ const YAML = await import('./index-Bt56pC82.js');
10783
10783
  const parsedDoc = YAML.parse(edoc);
10784
10784
  return {
10785
10785
  answer: {
@@ -22196,6 +22196,9 @@ const TS_EMBED_ID = '_thoughtspot-embed';
22196
22196
  */
22197
22197
  const PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY = 'tsEmbedOriginalPosition';
22198
22198
  const PRERENDER_WRAPPER_ID_PREFIX = 'tsEmbed-pre-render-wrapper-';
22199
+ const PRERENDER_PARKED_TRANSFORM = 'translateY(-100%)';
22200
+ /** The height createPreRenderWrapper() seeds before anything is measured. */
22201
+ const UNMEASURED_WRAPPER_HEIGHT = '100vh';
22199
22202
  // The container applies UpdateEmbedParams through React state, so a delivered
22200
22203
  // post is not the same as the params being in effect.
22201
22204
  const UPDATE_EMBED_PARAMS_SETTLE_MS = 200;
@@ -22203,56 +22206,6 @@ const UPDATE_EMBED_PARAMS_SETTLE_MS = 200;
22203
22206
  // truthy, so null or '' leaves the previous embed's values in place. '&' is
22204
22207
  // truthy and parses to {}.
22205
22208
  const NO_RUNTIME_PARAMS = '&';
22206
- /**
22207
- * Query parameters that stay on the iframe `src` while config is excluded from
22208
- * the URL, which is the default unless the embed sets the
22209
- * `excludeConfigFromURL` additional flag to `false`. These are the parameters the
22210
- * application shell needs before it can receive a postMessage at all: the
22211
- * embed marker, the host application URL used to validate the message origin,
22212
- * the SDK version, the flags that pick the authentication flow, and the
22213
- * boot-time settings that would otherwise be applied a frame late (viewport,
22214
- * log level, locale, formatting and org). Everything else is delivered over
22215
- * `HostEvent.UpdateEmbedParams`.
22216
- * @internal
22217
- */
22218
- const BOOTSTRAP_URL_PARAMS = new Set([
22219
- Param.EmbedApp,
22220
- Param.HostAppUrl,
22221
- Param.Version,
22222
- Param.AuthType,
22223
- Param.AutoLogin,
22224
- Param.DisableLoginRedirect,
22225
- Param.ForceSAMLAutoRedirect,
22226
- Param.cookieless,
22227
- Param.preAuthCache,
22228
- Param.blockNonEmbedFullAppAccess,
22229
- Param.OverrideOrgId,
22230
- Param.ViewPortHeight,
22231
- Param.ViewPortWidth,
22232
- Param.ClientLogLevel,
22233
- Param.OverrideNativeConsole,
22234
- Param.PendoTrackingKey,
22235
- Param.NumberFormatLocale,
22236
- Param.DateFormatLocale,
22237
- Param.CurrencyFormat,
22238
- Param.Locale,
22239
- Param.searchEmbed,
22240
- Param.livedBoardEmbed,
22241
- Param.isSpotterAgentEmbed,
22242
- Param.SpotterEnabled,
22243
- Param.IsFullAppEmbed,
22244
- Param.IsOnBeforeGetVizDataInterceptEnabled,
22245
- Param.LinkOverride,
22246
- Param.EnableLinkOverridesV2,
22247
- Param.DisableRedirectionLinksInNewTab,
22248
- Param.OverrideHistoryState,
22249
- Param.ForceTable,
22250
- Param.StringIDsUrl,
22251
- Param.DataSources,
22252
- Param.ExposeTranslationIDs,
22253
- Param.IconSpriteUrl,
22254
- Param.Tag,
22255
- ]);
22256
22209
  /**
22257
22210
  * The event id map from v2 event names to v1 event id
22258
22211
  * v1 events are the classic embed events implemented in Blink v1
@@ -22290,7 +22243,6 @@ class TsEmbed {
22290
22243
  this.shouldEncodeUrlQueryParams = false;
22291
22244
  this.defaultHiddenActions = [Action.ReportError];
22292
22245
  this.preRenderContainerEl = document.body;
22293
- this.containerScrollListener = null;
22294
22246
  /**
22295
22247
  * Handler for fullscreen change events
22296
22248
  */
@@ -22455,9 +22407,6 @@ class TsEmbed {
22455
22407
  }
22456
22408
  else if (source === EmbedEvent.EmbedListenerReady) {
22457
22409
  processEmbedContainerReady();
22458
- if (this.isConfigExcludedFromUrl()) {
22459
- this.triggerUpdateEmbedParams();
22460
- }
22461
22410
  }
22462
22411
  };
22463
22412
  // Subclasses that navigate the pre-render on show must await this before
@@ -22962,20 +22911,13 @@ class TsEmbed {
22962
22911
  return path;
22963
22912
  }
22964
22913
  getEmbedParams() {
22965
- const queryParams = this.getUrlQueryParamsObject();
22914
+ const queryParams = this.getEmbedParamsObject();
22966
22915
  return getQueryParamString(queryParams);
22967
22916
  }
22968
22917
  getEmbedParamsObject() {
22969
22918
  const params = this.getBaseQueryParams();
22970
22919
  return params;
22971
22920
  }
22972
- getUrlQueryParamsObject() {
22973
- const queryParams = this.getEmbedParamsObject();
22974
- if (!this.isConfigExcludedFromUrl()) {
22975
- return queryParams;
22976
- }
22977
- return Object.fromEntries(Object.entries(queryParams).filter(([key]) => BOOTSTRAP_URL_PARAMS.has(key)));
22978
- }
22979
22921
  getRootIframeSrc() {
22980
22922
  const query = this.getEmbedParams();
22981
22923
  return this.getEmbedBasePath(query);
@@ -23146,7 +23088,7 @@ class TsEmbed {
23146
23088
  top: '0',
23147
23089
  left: '0',
23148
23090
  width: '100vw',
23149
- height: '100vh',
23091
+ height: UNMEASURED_WRAPPER_HEIGHT,
23150
23092
  };
23151
23093
  setStyleProperties(preRenderWrapper, initialPreRenderWrapperStyle);
23152
23094
  return preRenderWrapper;
@@ -23214,10 +23156,26 @@ class TsEmbed {
23214
23156
  return placeholder;
23215
23157
  }
23216
23158
  /**
23217
- * Resolves the configured preRenderContainer to a live element, falling
23218
- * back to `document.body`. A string selector is re-queried on every call so
23219
- * a remounted container (E.g.: React replacing the node) resolves to the
23220
- * fresh element; an element passed directly cannot be re-resolved.
23159
+ * Resolves the configured preRenderContainer to a live element. A string
23160
+ * selector is re-queried on every call so a remounted container (E.g.: React
23161
+ * replacing the node) resolves to the fresh element; an element passed
23162
+ * directly cannot be re-resolved.
23163
+ *
23164
+ * With nothing configured the frame goes into the host element's nearest
23165
+ * scrolling ancestor, falling back to `document.body`.
23166
+ *
23167
+ * The wrapper is absolutely positioned, so it follows the page for free —
23168
+ * but only while it sits inside whatever scrolls. `document.body` is right
23169
+ * only when the document itself is the scroller; an app that scrolls an
23170
+ * inner element instead left the frame pinned to the viewport while the page
23171
+ * moved under it (SCAL-338563). Being inside the scroller also lets wheel
23172
+ * events chain out of the frame into it, which they cannot do from
23173
+ * `document.body`.
23174
+ *
23175
+ * A scrolling ancestor is layout chrome rather than route content, so it
23176
+ * outlives the embed in practice; and if it does go, the host element goes
23177
+ * with it and this instance is remounting anyway.
23178
+ * `reconcilePreRenderContainer` re-runs this on a detached container.
23221
23179
  */
23222
23180
  resolvePreRenderContainerTarget() {
23223
23181
  var _a;
@@ -23237,7 +23195,13 @@ class TsEmbed {
23237
23195
  else if (containerConfig) {
23238
23196
  container = containerConfig;
23239
23197
  }
23240
- return (_a = container) !== null && _a !== void 0 ? _a : document.body;
23198
+ if (container) {
23199
+ return container;
23200
+ }
23201
+ if (!this.hostElement) {
23202
+ return document.body;
23203
+ }
23204
+ return (_a = getScrollableAncestors(this.hostElement)[0]) !== null && _a !== void 0 ? _a : document.body;
23241
23205
  }
23242
23206
  inheritPreRenderContainer() {
23243
23207
  var _a;
@@ -23282,8 +23246,9 @@ class TsEmbed {
23282
23246
  * Re-attaches the wrapper to a live container when the previously resolved
23283
23247
  * one has been detached or no longer holds the wrapper — e.g. the host app
23284
23248
  * remounted a custom preRenderContainer, which would otherwise leave a stale
23285
- * reference and collapse the wrapper. Only string selectors can be
23286
- * re-resolved; a container passed as an element is left untouched.
23249
+ * reference and collapse the wrapper. Selectors and the auto-resolved
23250
+ * scrolling ancestor are both re-resolved; a container passed as an element
23251
+ * is left untouched, as there is nothing to re-query.
23287
23252
  */
23288
23253
  reconcilePreRenderContainer() {
23289
23254
  const wrapper = this.preRenderWrapper;
@@ -23302,14 +23267,6 @@ class TsEmbed {
23302
23267
  if (resolved === stored && stored.contains(wrapper)) {
23303
23268
  return;
23304
23269
  }
23305
- if (this.containerScrollListener && stored !== resolved) {
23306
- if (stored !== document.body) {
23307
- stored.removeEventListener('scroll', this.containerScrollListener);
23308
- }
23309
- if (resolved !== document.body) {
23310
- resolved.addEventListener('scroll', this.containerScrollListener);
23311
- }
23312
- }
23313
23270
  this.preRenderContainerEl = resolved;
23314
23271
  this.applyPreRenderContainerPositioning();
23315
23272
  if (wrapper.parentNode !== resolved) {
@@ -23371,11 +23328,12 @@ class TsEmbed {
23371
23328
  */
23372
23329
  setIFrameHeight(height) {
23373
23330
  if (this.isPreRendered) {
23331
+ const next = getCssDimension(height);
23374
23332
  if (this.insertedDomEl) {
23375
- this.insertedDomEl.style.height = getCssDimension(height);
23333
+ this.insertedDomEl.style.height = next;
23376
23334
  }
23377
23335
  else if (this.preRenderWrapper) {
23378
- this.preRenderWrapper.style.height = getCssDimension(height);
23336
+ this.preRenderWrapper.style.height = next;
23379
23337
  }
23380
23338
  }
23381
23339
  else {
@@ -23810,34 +23768,47 @@ class TsEmbed {
23810
23768
  delete container.dataset[PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY];
23811
23769
  }
23812
23770
  /**
23813
- * Detaches and clears the container scroll listener, if one is attached.
23814
- */
23815
- removeContainerScrollListener() {
23816
- if (!this.containerScrollListener) {
23771
+ * Re-sizes the wrapper when its placeholder changes size.
23772
+ *
23773
+ * Position deliberately has no equivalent. An absolutely positioned wrapper
23774
+ * follows its containing block for free, so a correctly placed frame is the
23775
+ * browser's job and costs nothing; repositioning it on scroll would mean a
23776
+ * layout read and a style write per frame to compensate for placing it in
23777
+ * the wrong box. Size is the one thing the browser will not do for us: the
23778
+ * placeholder grows when the embedded app reports a new height, and the
23779
+ * wrapper has to be told.
23780
+ */
23781
+ observePreRenderSize() {
23782
+ var _a;
23783
+ if (this.getPreRenderConfig().doNotTrackSize || typeof ResizeObserver === 'undefined') {
23784
+ return;
23785
+ }
23786
+ const placeholder = this.getPreRenderPlaceHolderElement();
23787
+ if (!placeholder) {
23817
23788
  return;
23818
23789
  }
23819
- const customContainer = this.getCustomPreRenderContainer();
23820
- customContainer === null || customContainer === void 0 ? void 0 : customContainer.removeEventListener('scroll', this.containerScrollListener);
23821
- this.containerScrollListener = null;
23790
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23791
+ this.resizeObserver = new ResizeObserver(() => this.syncPreRenderStyle());
23792
+ this.resizeObserver.observe(placeholder);
23822
23793
  }
23823
23794
  /**
23824
23795
  * Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
23825
23796
  * @version SDK: 1.19.1 | ThoughtSpot: *
23826
23797
  */
23827
23798
  destroy() {
23828
- var _a, _b, _c;
23799
+ var _a, _b, _c, _d;
23829
23800
  try {
23830
23801
  this.removeFullscreenChangeHandler();
23831
- this.removeContainerScrollListener();
23802
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
23832
23803
  this.unsubscribeToEvents();
23833
- (_a = this.preRenderWrapper) === null || _a === void 0 ? void 0 : _a.remove();
23804
+ (_b = this.preRenderWrapper) === null || _b === void 0 ? void 0 : _b.remove();
23834
23805
  this.restorePreRenderContainerPosition();
23835
23806
  if (!this.isRendered) {
23836
23807
  return;
23837
23808
  }
23838
23809
  if (!getEmbedConfig().waitForCleanupOnDestroy) {
23839
23810
  this.trigger(HostEvent.DestroyEmbed);
23840
- (_c = (_b = this.insertedDomEl) === null || _b === void 0 ? void 0 : _b.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(this.insertedDomEl);
23811
+ (_d = (_c = this.insertedDomEl) === null || _c === void 0 ? void 0 : _c.parentNode) === null || _d === void 0 ? void 0 : _d.removeChild(this.insertedDomEl);
23841
23812
  }
23842
23813
  else {
23843
23814
  const cleanupTimeout = getEmbedConfig().cleanupTimeout;
@@ -23883,27 +23854,6 @@ class TsEmbed {
23883
23854
  this.isRendered = true;
23884
23855
  return this.renderIFrame(prerenderFrameSrc);
23885
23856
  }
23886
- isConfigExcludedFromUrl() {
23887
- var _a, _b, _c;
23888
- 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;
23889
- // Enabled by default; only an explicit false opts out.
23890
- return flag !== false && flag !== 'false';
23891
- }
23892
- async triggerUpdateEmbedParams() {
23893
- try {
23894
- const params = await this.getUpdateEmbedParamsObject();
23895
- this.trigger(HostEvent.UpdateEmbedParams, params);
23896
- }
23897
- catch (error) {
23898
- logger$3.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
23899
- this.handleError({
23900
- errorType: ErrorDetailsTypes.API,
23901
- message: (error === null || error === void 0 ? void 0 : error.message) || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
23902
- code: EmbedErrorCodes.UPDATE_PARAMS_FAILED,
23903
- error: (error === null || error === void 0 ? void 0 : error.message) || error,
23904
- });
23905
- }
23906
- }
23907
23857
  beforePrerenderVisible() {
23908
23858
  // We can ignore this as its a bit expensive and the newer customers
23909
23859
  // have moved on to UpdateEmbedParams supported clusters
@@ -23914,7 +23864,17 @@ class TsEmbed {
23914
23864
  this.preRenderParamsApplied = new Promise((resolve) => {
23915
23865
  this.executeAfterEmbedContainerLoaded(async () => {
23916
23866
  try {
23917
- await this.triggerUpdateEmbedParams();
23867
+ const params = await this.getUpdateEmbedParamsObject();
23868
+ this.trigger(HostEvent.UpdateEmbedParams, params);
23869
+ }
23870
+ catch (error) {
23871
+ logger$3.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
23872
+ this.handleError({
23873
+ errorType: ErrorDetailsTypes.API,
23874
+ message: (error === null || error === void 0 ? void 0 : error.message) || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
23875
+ code: EmbedErrorCodes.UPDATE_PARAMS_FAILED,
23876
+ error: (error === null || error === void 0 ? void 0 : error.message) || error,
23877
+ });
23918
23878
  }
23919
23879
  finally {
23920
23880
  setTimeout(resolve, UPDATE_EMBED_PARAMS_SETTLE_MS);
@@ -23929,7 +23889,7 @@ class TsEmbed {
23929
23889
  * wrapper to overlay it.
23930
23890
  */
23931
23891
  async showPreRender() {
23932
- var _a, _b;
23892
+ var _a;
23933
23893
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_SHOW_PRE_RENDER, {
23934
23894
  preRenderId: this.getPreRenderConfig().id,
23935
23895
  embedComponentType: this.viewConfig.embedComponentType,
@@ -23948,14 +23908,16 @@ class TsEmbed {
23948
23908
  this.beforePrerenderVisible();
23949
23909
  if (this.hostElement) {
23950
23910
  this.insertedDomEl = this.createPreRenderPlaceholder();
23951
- if (this.viewConfig.fullHeight) {
23952
- // If fullHeight has already sized the wrapper, seed the
23953
- // placeholder with the same height so syncPreRenderStyle gets
23954
- // an accurate rect.
23955
- const existingHeight = this.preRenderWrapper.style.height;
23956
- if (existingHeight) {
23957
- this.insertedDomEl.style.height = existingHeight;
23958
- }
23911
+ // Carry a height fullHeight has already measured onto the fresh
23912
+ // placeholder, so a re-show does not flash at frameParams height.
23913
+ // UNMEASURED_WRAPPER_HEIGHT is what createPreRenderWrapper() seeds
23914
+ // before anything has been measured; treating that as a measurement
23915
+ // is what made a first reveal overshoot to a full viewport.
23916
+ const wrapperHeight = this.preRenderWrapper.style.height;
23917
+ if (this.viewConfig.fullHeight
23918
+ && wrapperHeight
23919
+ && wrapperHeight !== UNMEASURED_WRAPPER_HEIGHT) {
23920
+ this.insertedDomEl.style.height = wrapperHeight;
23959
23921
  }
23960
23922
  const placeHolderId = this.getPreRenderIds().placeHolder;
23961
23923
  // Remove any stale placeholder from a previous cycle. It is located
@@ -23969,29 +23931,19 @@ class TsEmbed {
23969
23931
  (_a = this.hostElement.querySelector(`#${placeHolderId}`)) === null || _a === void 0 ? void 0 : _a.remove();
23970
23932
  this.hostElement.appendChild(this.insertedDomEl);
23971
23933
  this.syncPreRenderStyle();
23972
- const customContainer = this.getCustomPreRenderContainer();
23973
- if (customContainer && !this.containerScrollListener) {
23974
- this.containerScrollListener = () => this.syncPreRenderStyle();
23975
- customContainer.addEventListener('scroll', this.containerScrollListener);
23976
- }
23977
- if (!this.getPreRenderConfig().doNotTrackSize) {
23978
- const observeTarget = (_b = this.insertedDomEl) !== null && _b !== void 0 ? _b : this.hostElement;
23979
- this.resizeObserver = new ResizeObserver((entries) => {
23980
- entries.forEach((entry) => {
23981
- if (entry.target === observeTarget) {
23982
- this.syncPreRenderStyle();
23983
- }
23984
- });
23985
- });
23986
- this.resizeObserver.observe(observeTarget);
23987
- }
23934
+ this.observePreRenderSize();
23988
23935
  }
23989
23936
  removeStyleProperties(this.preRenderWrapper, [
23990
23937
  'z-index',
23991
23938
  'opacity',
23992
- 'pointer-events',
23993
23939
  'overflow',
23940
+ 'transform',
23994
23941
  ]);
23942
+ // Set rather than removed: a container that carries `pointer-events:
23943
+ // none` — the usual styling for a parking root that must not swallow
23944
+ // clicks — passes it down, and dropping the property here would leave
23945
+ // the inherited `none` in force and the frame dead to input.
23946
+ setStyleProperties(this.preRenderWrapper, { pointerEvents: 'auto' });
23995
23947
  this.subscribeToEvents();
23996
23948
  // Setup fullscreen change handler for prerendered components
23997
23949
  if (this.iFrame) {
@@ -24044,6 +23996,7 @@ class TsEmbed {
24044
23996
  * If the component is not preRendered, it issues a warning.
24045
23997
  */
24046
23998
  hidePreRender() {
23999
+ var _a;
24047
24000
  uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_HIDE_PRE_RENDER, {
24048
24001
  preRenderId: this.getPreRenderConfig().id,
24049
24002
  embedComponentType: this.viewConfig.embedComponentType,
@@ -24063,12 +24016,15 @@ class TsEmbed {
24063
24016
  top: '0',
24064
24017
  left: '0',
24065
24018
  overflow: 'hidden',
24019
+ // Keeps the measured size — so the next show needs no resize, which
24020
+ // is the point of pre-rendering — while lifting the box out of
24021
+ // the container's scrollable area. Overflow only extends
24022
+ // downwards, so a hidden frame parked above the top edge adds
24023
+ // none, where one left at full height shows as blank scroll space.
24024
+ transform: PRERENDER_PARKED_TRANSFORM,
24066
24025
  };
24067
24026
  setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
24068
- this.removeContainerScrollListener();
24069
- if (this.resizeObserver) {
24070
- this.resizeObserver.disconnect();
24071
- }
24027
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
24072
24028
  const placeHolderEle = this.getPreRenderPlaceHolderElement();
24073
24029
  if (placeHolderEle) {
24074
24030
  placeHolderEle.parentElement.removeChild(placeHolderEle);
@@ -24494,7 +24450,7 @@ class AppEmbed extends V1Embed {
24494
24450
  * embedded Liveboard or visualization.
24495
24451
  */
24496
24452
  getEmbedParams() {
24497
- const params = this.getUrlQueryParamsObject();
24453
+ const params = this.getEmbedParamsObject();
24498
24454
  return getQueryParamString(params, true);
24499
24455
  }
24500
24456
  getEmbedParamsObject() {
@@ -24811,6 +24767,46 @@ class AppEmbed extends V1Embed {
24811
24767
  }
24812
24768
  }
24813
24769
 
24770
+ /**
24771
+ * This method is like `_.isEqual` except that it accepts `customizer` which
24772
+ * is invoked to compare values. If `customizer` returns `undefined`, comparisons
24773
+ * are handled by the method instead. The `customizer` is invoked with up to
24774
+ * six arguments: (objValue, othValue [, index|key, object, other, stack]).
24775
+ *
24776
+ * @static
24777
+ * @memberOf _
24778
+ * @since 4.0.0
24779
+ * @category Lang
24780
+ * @param {*} value The value to compare.
24781
+ * @param {*} other The other value to compare.
24782
+ * @param {Function} [customizer] The function to customize comparisons.
24783
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
24784
+ * @example
24785
+ *
24786
+ * function isGreeting(value) {
24787
+ * return /^h(?:i|ello)$/.test(value);
24788
+ * }
24789
+ *
24790
+ * function customizer(objValue, othValue) {
24791
+ * if (isGreeting(objValue) && isGreeting(othValue)) {
24792
+ * return true;
24793
+ * }
24794
+ * }
24795
+ *
24796
+ * var array = ['hello', 'goodbye'];
24797
+ * var other = ['hi', 'goodbye'];
24798
+ *
24799
+ * _.isEqualWith(array, other, customizer);
24800
+ * // => true
24801
+ */
24802
+ function isEqualWith(value, other, customizer) {
24803
+ customizer = typeof customizer == 'function' ? customizer : undefined;
24804
+ var result = customizer ? customizer(value, other) : undefined;
24805
+ return result === undefined ? _baseIsEqual(value, other, undefined, customizer) : !!result;
24806
+ }
24807
+
24808
+ var isEqualWith_1 = isEqualWith;
24809
+
24814
24810
  const getPreviewQuery = `
24815
24811
  query GetEurekaVizSnapshots(
24816
24812
  $vizId: String!, $liveboardId: String!) {
@@ -24952,7 +24948,7 @@ class LiveboardEmbed extends V1Embed {
24952
24948
  * embedded Liveboard or visualization.
24953
24949
  */
24954
24950
  getEmbedParams() {
24955
- const params = this.getUrlQueryParamsObject();
24951
+ const params = this.getEmbedParamsObject();
24956
24952
  const queryParams = getQueryParamString(params, true);
24957
24953
  return queryParams;
24958
24954
  }
@@ -25191,10 +25187,12 @@ class LiveboardEmbed extends V1Embed {
25191
25187
  beforePrerenderVisible() {
25192
25188
  super.beforePrerenderVisible();
25193
25189
  // Captured before showPreRender() hands the wrapper over to this
25194
- // instance. Itself means a hide/show, not a hand-over, so there is
25195
- // nothing stale to clear.
25190
+ // instance. React builds a new instance per mount, so an equal config
25191
+ // is a hide/show, not a hand-over: there is nothing stale to clear.
25196
25192
  const previous = this.getPreRenderObj();
25197
- const showing = previous === this ? undefined : previous === null || previous === void 0 ? void 0 : previous.currentLiveboardState;
25193
+ const showing = this.isSameEmbedConfig(previous)
25194
+ ? undefined
25195
+ : previous === null || previous === void 0 ? void 0 : previous.currentLiveboardState;
25198
25196
  this.executeAfterEmbedContainerLoaded(async () => {
25199
25197
  // Without this the params callback suspends on its await and
25200
25198
  // Navigate goes out first, so the container loads with the previous
@@ -25221,6 +25219,14 @@ class LiveboardEmbed extends V1Embed {
25221
25219
  };
25222
25220
  });
25223
25221
  }
25222
+ // Callbacks are compared as equal: React passes a fresh closure per render.
25223
+ isSameEmbedConfig(previous) {
25224
+ if (!previous)
25225
+ return false;
25226
+ if (previous === this)
25227
+ return true;
25228
+ return isEqualWith_1(previous.viewConfig, this.viewConfig, (a, b) => (typeof a === 'function' && typeof b === 'function' ? true : undefined));
25229
+ }
25224
25230
  // The whole route, not just the liveboard id: the path is built from the
25225
25231
  // viz, tab and view too, so a same-liveboard show onto another tab is a
25226
25232
  // real navigation.
@@ -25483,7 +25489,7 @@ class SearchEmbed extends TsEmbed {
25483
25489
  }
25484
25490
  getEmbedParams() {
25485
25491
  const { runtimeParameters, runtimeFilters, excludeRuntimeParametersfromURL, excludeRuntimeFiltersfromURL, } = this.viewConfig;
25486
- const queryParams = this.getUrlQueryParamsObject();
25492
+ const queryParams = this.getEmbedParamsObject();
25487
25493
  let query = '';
25488
25494
  const queryParamsString = getQueryParamString(queryParams, true);
25489
25495
  if (queryParamsString) {
@@ -25571,7 +25577,7 @@ class SearchBarEmbed extends TsEmbed {
25571
25577
  * @param dataSources A list of data source GUIDs
25572
25578
  */
25573
25579
  getIFrameSrc() {
25574
- const queryParams = this.getUrlQueryParamsObject();
25580
+ const queryParams = this.getEmbedParamsObject();
25575
25581
  const path = 'search-bar-embed';
25576
25582
  let query = '';
25577
25583
  const queryParamsString = getQueryParamString(queryParams, true);
@@ -26005,7 +26011,7 @@ class ConversationMessage extends TsEmbed {
26005
26011
  getIframeSrc() {
26006
26012
  const { sessionId, genNo, acSessionId, acGenNo, convId, messageId, } = this.viewConfig;
26007
26013
  const path = 'conv-assist-answer';
26008
- const queryParams = this.getUrlQueryParamsObject();
26014
+ const queryParams = this.getEmbedParamsObject();
26009
26015
  let query = '';
26010
26016
  const queryParamsString = getQueryParamString(queryParams, true);
26011
26017
  if (queryParamsString) {
@@ -26213,7 +26219,7 @@ class SpotterEmbed extends TsEmbed {
26213
26219
  const path = sharedConversationId
26214
26220
  ? `insights/conv-assist/s/${encodeURIComponent(sharedConversationId)}`
26215
26221
  : 'insights/conv-assist';
26216
- const queryParams = this.getUrlQueryParamsObject();
26222
+ const queryParams = this.getEmbedParamsObject();
26217
26223
  let query = '';
26218
26224
  const queryParamsString = getQueryParamString(queryParams, true);
26219
26225
  if (queryParamsString) {
@@ -27101,7 +27107,7 @@ class AutoFrameRenderer extends TsEmbed {
27101
27107
  * @returns The constructed URL to use for the ThoughtSpot embed iframe.
27102
27108
  */
27103
27109
  getMCPIframeSrc(sourceSrc) {
27104
- const queryParams = this.getUrlQueryParamsObject();
27110
+ const queryParams = this.getEmbedParamsObject();
27105
27111
  const sourceURL = new URL(sourceSrc);
27106
27112
  const existingQueryParams = sourceURL.searchParams;
27107
27113
  const existingQueryParamsObject = Object.fromEntries(existingQueryParams);