@thoughtspot/visual-embed-sdk 1.24.0-preRender.5 → 1.24.0-preRender.7

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 (174) hide show
  1. package/README.md +1 -1
  2. package/cjs/package.json +2 -2
  3. package/cjs/src/embed/app.d.ts +35 -1
  4. package/cjs/src/embed/app.d.ts.map +1 -1
  5. package/cjs/src/embed/app.js +5 -1
  6. package/cjs/src/embed/app.js.map +1 -1
  7. package/cjs/src/embed/app.spec.js +19 -0
  8. package/cjs/src/embed/app.spec.js.map +1 -1
  9. package/cjs/src/embed/liveboard.d.ts +35 -5
  10. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  11. package/cjs/src/embed/liveboard.js +14 -9
  12. package/cjs/src/embed/liveboard.js.map +1 -1
  13. package/cjs/src/embed/liveboard.spec.js +14 -3
  14. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  15. package/cjs/src/embed/sage.d.ts +45 -7
  16. package/cjs/src/embed/sage.d.ts.map +1 -1
  17. package/cjs/src/embed/sage.js +9 -3
  18. package/cjs/src/embed/sage.js.map +1 -1
  19. package/cjs/src/embed/sage.spec.js +85 -6
  20. package/cjs/src/embed/sage.spec.js.map +1 -1
  21. package/cjs/src/embed/search-bar.d.ts +1 -1
  22. package/cjs/src/embed/search-bar.d.ts.map +1 -1
  23. package/cjs/src/embed/search-bar.js.map +1 -1
  24. package/cjs/src/embed/search.d.ts +2 -6
  25. package/cjs/src/embed/search.d.ts.map +1 -1
  26. package/cjs/src/embed/search.js.map +1 -1
  27. package/cjs/src/embed/ts-embed.d.ts +1 -1
  28. package/cjs/src/embed/ts-embed.d.ts.map +1 -1
  29. package/cjs/src/embed/ts-embed.js +45 -41
  30. package/cjs/src/embed/ts-embed.js.map +1 -1
  31. package/cjs/src/embed/ts-embed.spec.js +50 -11
  32. package/cjs/src/embed/ts-embed.spec.js.map +1 -1
  33. package/cjs/src/index.d.ts +2 -2
  34. package/cjs/src/index.d.ts.map +1 -1
  35. package/cjs/src/index.js.map +1 -1
  36. package/cjs/src/react/all-types-export.d.ts +1 -1
  37. package/cjs/src/react/all-types-export.d.ts.map +1 -1
  38. package/cjs/src/react/all-types-export.js.map +1 -1
  39. package/cjs/src/react/index.d.ts +12 -0
  40. package/cjs/src/react/index.d.ts.map +1 -1
  41. package/cjs/src/react/index.js +37 -16
  42. package/cjs/src/react/index.js.map +1 -1
  43. package/cjs/src/types.d.ts +30 -33
  44. package/cjs/src/types.d.ts.map +1 -1
  45. package/cjs/src/types.js +20 -5
  46. package/cjs/src/types.js.map +1 -1
  47. package/cjs/src/utils/graphql/answerService/answerService.d.ts +2 -1
  48. package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  49. package/cjs/src/utils/graphql/answerService/answerService.js +3 -5
  50. package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -1
  51. package/cjs/src/utils/graphql/answerService/answerService.spec.js +1 -1
  52. package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  53. package/cjs/src/utils/graphql/sourceService.d.ts.map +1 -1
  54. package/cjs/src/utils/graphql/sourceService.js +3 -1
  55. package/cjs/src/utils/graphql/sourceService.js.map +1 -1
  56. package/cjs/src/utils.d.ts +1 -0
  57. package/cjs/src/utils.d.ts.map +1 -1
  58. package/cjs/src/utils.js +5 -3
  59. package/cjs/src/utils.js.map +1 -1
  60. package/cjs/src/utils.spec.js +18 -8
  61. package/cjs/src/utils.spec.js.map +1 -1
  62. package/dist/src/embed/app.d.ts +35 -1
  63. package/dist/src/embed/app.d.ts.map +1 -1
  64. package/dist/src/embed/liveboard.d.ts +35 -5
  65. package/dist/src/embed/liveboard.d.ts.map +1 -1
  66. package/dist/src/embed/sage.d.ts +45 -7
  67. package/dist/src/embed/sage.d.ts.map +1 -1
  68. package/dist/src/embed/search-bar.d.ts +1 -1
  69. package/dist/src/embed/search-bar.d.ts.map +1 -1
  70. package/dist/src/embed/search.d.ts +2 -6
  71. package/dist/src/embed/search.d.ts.map +1 -1
  72. package/dist/src/embed/ts-embed.d.ts +1 -1
  73. package/dist/src/embed/ts-embed.d.ts.map +1 -1
  74. package/dist/src/index.d.ts +2 -2
  75. package/dist/src/index.d.ts.map +1 -1
  76. package/dist/src/react/all-types-export.d.ts +1 -1
  77. package/dist/src/react/all-types-export.d.ts.map +1 -1
  78. package/dist/src/react/index.d.ts +12 -0
  79. package/dist/src/react/index.d.ts.map +1 -1
  80. package/dist/src/types.d.ts +30 -33
  81. package/dist/src/types.d.ts.map +1 -1
  82. package/dist/src/utils/graphql/answerService/answerService.d.ts +2 -1
  83. package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  84. package/dist/src/utils/graphql/sourceService.d.ts.map +1 -1
  85. package/dist/src/utils.d.ts +1 -0
  86. package/dist/src/utils.d.ts.map +1 -1
  87. package/dist/tsembed-react.es.js +3752 -19027
  88. package/dist/tsembed-react.js +3752 -19027
  89. package/dist/tsembed.es.js +7586 -23428
  90. package/dist/tsembed.js +7586 -23428
  91. package/dist/visual-embed-sdk-react-full.d.ts +161 -53
  92. package/dist/visual-embed-sdk-react.d.ts +161 -53
  93. package/dist/visual-embed-sdk.d.ts +149 -53
  94. package/lib/package.json +2 -2
  95. package/lib/src/embed/app.d.ts +35 -1
  96. package/lib/src/embed/app.d.ts.map +1 -1
  97. package/lib/src/embed/app.js +5 -1
  98. package/lib/src/embed/app.js.map +1 -1
  99. package/lib/src/embed/app.spec.js +19 -0
  100. package/lib/src/embed/app.spec.js.map +1 -1
  101. package/lib/src/embed/liveboard.d.ts +35 -5
  102. package/lib/src/embed/liveboard.d.ts.map +1 -1
  103. package/lib/src/embed/liveboard.js +15 -9
  104. package/lib/src/embed/liveboard.js.map +1 -1
  105. package/lib/src/embed/liveboard.spec.js +14 -3
  106. package/lib/src/embed/liveboard.spec.js.map +1 -1
  107. package/lib/src/embed/sage.d.ts +45 -7
  108. package/lib/src/embed/sage.d.ts.map +1 -1
  109. package/lib/src/embed/sage.js +9 -3
  110. package/lib/src/embed/sage.js.map +1 -1
  111. package/lib/src/embed/sage.spec.js +85 -6
  112. package/lib/src/embed/sage.spec.js.map +1 -1
  113. package/lib/src/embed/search-bar.d.ts +1 -1
  114. package/lib/src/embed/search-bar.d.ts.map +1 -1
  115. package/lib/src/embed/search-bar.js.map +1 -1
  116. package/lib/src/embed/search.d.ts +2 -6
  117. package/lib/src/embed/search.d.ts.map +1 -1
  118. package/lib/src/embed/search.js.map +1 -1
  119. package/lib/src/embed/ts-embed.d.ts +1 -1
  120. package/lib/src/embed/ts-embed.d.ts.map +1 -1
  121. package/lib/src/embed/ts-embed.js +46 -42
  122. package/lib/src/embed/ts-embed.js.map +1 -1
  123. package/lib/src/embed/ts-embed.spec.js +50 -11
  124. package/lib/src/embed/ts-embed.spec.js.map +1 -1
  125. package/lib/src/index.d.ts +2 -2
  126. package/lib/src/index.d.ts.map +1 -1
  127. package/lib/src/index.js.map +1 -1
  128. package/lib/src/react/all-types-export.d.ts +1 -1
  129. package/lib/src/react/all-types-export.d.ts.map +1 -1
  130. package/lib/src/react/all-types-export.js.map +1 -1
  131. package/lib/src/react/index.d.ts +12 -0
  132. package/lib/src/react/index.d.ts.map +1 -1
  133. package/lib/src/react/index.js +37 -16
  134. package/lib/src/react/index.js.map +1 -1
  135. package/lib/src/types.d.ts +30 -33
  136. package/lib/src/types.d.ts.map +1 -1
  137. package/lib/src/types.js +20 -5
  138. package/lib/src/types.js.map +1 -1
  139. package/lib/src/utils/graphql/answerService/answerService.d.ts +2 -1
  140. package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
  141. package/lib/src/utils/graphql/answerService/answerService.js +3 -5
  142. package/lib/src/utils/graphql/answerService/answerService.js.map +1 -1
  143. package/lib/src/utils/graphql/answerService/answerService.spec.js +1 -1
  144. package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
  145. package/lib/src/utils/graphql/sourceService.d.ts.map +1 -1
  146. package/lib/src/utils/graphql/sourceService.js +3 -1
  147. package/lib/src/utils/graphql/sourceService.js.map +1 -1
  148. package/lib/src/utils.d.ts +1 -0
  149. package/lib/src/utils.d.ts.map +1 -1
  150. package/lib/src/utils.js +3 -2
  151. package/lib/src/utils.js.map +1 -1
  152. package/lib/src/utils.spec.js +19 -9
  153. package/lib/src/utils.spec.js.map +1 -1
  154. package/lib/src/visual-embed-sdk.d.ts +152 -56
  155. package/package.json +2 -2
  156. package/src/embed/app.spec.ts +29 -0
  157. package/src/embed/app.ts +43 -1
  158. package/src/embed/liveboard.spec.ts +19 -3
  159. package/src/embed/liveboard.ts +53 -13
  160. package/src/embed/sage.spec.ts +119 -6
  161. package/src/embed/sage.ts +63 -13
  162. package/src/embed/search-bar.tsx +11 -1
  163. package/src/embed/search.ts +5 -6
  164. package/src/embed/ts-embed.spec.ts +57 -12
  165. package/src/embed/ts-embed.ts +55 -45
  166. package/src/index.ts +2 -0
  167. package/src/react/all-types-export.ts +1 -0
  168. package/src/react/index.tsx +54 -12
  169. package/src/types.ts +36 -39
  170. package/src/utils/graphql/answerService/answerService.spec.ts +1 -1
  171. package/src/utils/graphql/answerService/answerService.ts +3 -5
  172. package/src/utils/graphql/sourceService.ts +4 -1
  173. package/src/utils.spec.ts +23 -8
  174. package/src/utils.ts +4 -2
@@ -7,7 +7,8 @@
7
7
  * @author Ayon Ghosh <ayon.ghosh@thoughtspot.com>
8
8
  */
9
9
 
10
- import _ from 'lodash';
10
+ import isEqual from 'lodash/isEqual';
11
+
11
12
  import {
12
13
  getEncodedQueryParamsString,
13
14
  getCssDimension,
@@ -22,6 +23,7 @@ import {
22
23
  getRuntimeParameters,
23
24
  setStyleProperties,
24
25
  removeStyleProperties,
26
+ isUndefined,
25
27
  } from '../utils';
26
28
  import {
27
29
  getThoughtSpotHost,
@@ -99,7 +101,7 @@ export class TsEmbed {
99
101
  /**
100
102
  * The key to store the embed instance in the DOM node
101
103
  */
102
- protected embedNodeKey = '__tsEmbed'
104
+ protected embedNodeKey = '__tsEmbed';
103
105
 
104
106
  protected isAppInitialized = false;
105
107
 
@@ -260,7 +262,10 @@ export class TsEmbed {
260
262
  if (event.source === this.iFrame.contentWindow) {
261
263
  this.executeCallbacks(
262
264
  eventType,
263
- processEventData(eventType, eventData, this.thoughtSpotHost, this.el),
265
+ processEventData(eventType,
266
+ eventData,
267
+ this.thoughtSpotHost,
268
+ this.isPreRendered ? this.preRenderWrapper : this.el),
264
269
  eventPort,
265
270
  );
266
271
  }
@@ -419,9 +424,6 @@ export class TsEmbed {
419
424
  contextMenuTrigger,
420
425
  linkOverride,
421
426
  insertInToSlide,
422
- hideLiveboardHeader,
423
- showLiveboardDescription,
424
- showLiveboardTitle,
425
427
  } = this.viewConfig;
426
428
 
427
429
  if (Array.isArray(visibleActions) && Array.isArray(hiddenActions)) {
@@ -489,15 +491,6 @@ export class TsEmbed {
489
491
  if (insertInToSlide) {
490
492
  queryParams[Param.ShowInsertToSlide] = insertInToSlide;
491
493
  }
492
- if (hideLiveboardHeader) {
493
- queryParams[Param.HideLiveboardHeader] = hideLiveboardHeader;
494
- }
495
- if (showLiveboardDescription) {
496
- queryParams[Param.ShowLiveboardDescription] = showLiveboardDescription;
497
- }
498
- if (showLiveboardTitle) {
499
- queryParams[Param.ShowLiveboardTitle] = showLiveboardTitle;
500
- }
501
494
 
502
495
  return queryParams;
503
496
  }
@@ -648,10 +641,6 @@ export class TsEmbed {
648
641
  }
649
642
 
650
643
  protected createPreRenderWrapper(): HTMLDivElement {
651
- if (!this.viewConfig.preRenderId) {
652
- throw new Error('PreRender id is required to create PreRender wrapper');
653
- }
654
-
655
644
  const preRenderIds = this.getPreRenderIds();
656
645
 
657
646
  document.getElementById(preRenderIds.wrapper)?.remove();
@@ -1063,20 +1052,31 @@ export class TsEmbed {
1063
1052
  // Override in subclass
1064
1053
  }
1065
1054
 
1066
- private validatePreRenderProps = (viewConfig : ViewConfig) => {
1067
- const preRenderAllowedKeys = ['preRenderId', 'vizId', 'liveboardId', ...Object.keys(EmbedEvent)];
1055
+ private validatePreRenderViewConfig = (viewConfig: ViewConfig) => {
1056
+ const preRenderAllowedKeys = [
1057
+ 'preRenderId',
1058
+ 'vizId',
1059
+ 'liveboardId',
1060
+ ];
1068
1061
  const preRenderedObject = this.insertedDomEl?.[this.embedNodeKey] as TsEmbed;
1069
1062
  if (!preRenderedObject) return;
1070
1063
  if (viewConfig.preRenderId) {
1071
- const allOtherKeys = Object.keys(viewConfig)
1072
- .filter((key) => !preRenderAllowedKeys.includes(key));
1064
+ const allOtherKeys = Object.keys(viewConfig).filter(
1065
+ (key) => !preRenderAllowedKeys.includes(key) && !key.startsWith('on'),
1066
+ );
1073
1067
 
1074
1068
  allOtherKeys.forEach((key) => {
1075
- if (!_.isEqual(viewConfig[key], preRenderedObject.viewConfig[key])) {
1069
+ if (
1070
+ !isUndefined(viewConfig[key])
1071
+ && !isEqual(viewConfig[key], preRenderedObject.viewConfig[key])
1072
+ ) {
1076
1073
  console.warn(
1077
- `${this.embedComponentType} pre-rendered with ${key} as \`${JSON.stringify(viewConfig[key])}\` but a `
1078
- + `different value is set in the Embed component as \`${JSON.stringify(preRenderedObject.viewConfig?.[key]?.toString())}\`. `
1079
- + 'The new value is ignored.',
1074
+ `${this.embedComponentType} was pre-rendered with `
1075
+ + `"${key}" as "${JSON.stringify(preRenderedObject.viewConfig[key])}" `
1076
+ + `but a different value "${JSON.stringify(viewConfig[key])}" `
1077
+ + 'was passed to the Embed component. '
1078
+ + 'The new value provided is ignored, the value provided during '
1079
+ + 'preRender is used.',
1080
1080
  );
1081
1081
  }
1082
1082
  });
@@ -1090,6 +1090,10 @@ export class TsEmbed {
1090
1090
  * element.
1091
1091
  */
1092
1092
  public showPreRender(): void {
1093
+ if (!this.viewConfig.preRenderId) {
1094
+ console.error('PreRender id is required for preRender');
1095
+ return;
1096
+ }
1093
1097
  if (!this.isPreRenderAvailable()) {
1094
1098
  const isAvailable = this.connectPreRendered();
1095
1099
 
@@ -1098,23 +1102,24 @@ export class TsEmbed {
1098
1102
  this.preRender(true);
1099
1103
  return;
1100
1104
  }
1101
- this.validatePreRenderProps(this.viewConfig);
1105
+ this.validatePreRenderViewConfig(this.viewConfig);
1102
1106
  }
1103
1107
 
1104
1108
  if (this.el) {
1105
1109
  this.syncPreRenderStyle();
1106
-
1107
- this.resizeObserver = new ResizeObserver((entries) => {
1108
- entries.forEach((entry) => {
1109
- if (entry.contentRect && entry.target === this.el) {
1110
- setStyleProperties(this.preRenderWrapper, {
1111
- width: `${entry.contentRect.width}px`,
1112
- height: `${entry.contentRect.height}px`,
1113
- });
1114
- }
1110
+ if (!this.viewConfig.doNotTrackPreRenderSize) {
1111
+ this.resizeObserver = new ResizeObserver((entries) => {
1112
+ entries.forEach((entry) => {
1113
+ if (entry.contentRect && entry.target === this.el) {
1114
+ setStyleProperties(this.preRenderWrapper, {
1115
+ width: `${entry.contentRect.width}px`,
1116
+ height: `${entry.contentRect.height}px`,
1117
+ });
1118
+ }
1119
+ });
1115
1120
  });
1116
- });
1117
- this.resizeObserver.observe(this.el);
1121
+ this.resizeObserver.observe(this.el);
1122
+ }
1118
1123
  }
1119
1124
 
1120
1125
  this.beforePrerenderVisible();
@@ -1134,8 +1139,9 @@ export class TsEmbed {
1134
1139
  * is not defined or not found.
1135
1140
  */
1136
1141
  public syncPreRenderStyle(): void {
1137
- if (!this.el) {
1138
- throw new Error('Embed element is not defined');
1142
+ if (!this.isPreRenderAvailable() || !this.el) {
1143
+ console.error('PreRender should be called before using syncPreRenderStyle');
1144
+ return;
1139
1145
  }
1140
1146
  const elBoundingClient = this.el.getBoundingClientRect();
1141
1147
 
@@ -1155,7 +1161,7 @@ export class TsEmbed {
1155
1161
  if (!this.isPreRenderAvailable()) {
1156
1162
  // if the embed component is not preRendered , nothing to hide
1157
1163
  console.warn(
1158
- 'Warning: You should call PreRender before hiding it using hidePreRender.',
1164
+ 'PreRender should be called before hiding it using hidePreRender.',
1159
1165
  );
1160
1166
  return;
1161
1167
  }
@@ -1219,13 +1225,17 @@ export class V1Embed extends TsEmbed {
1219
1225
  protected getRootIframeSrc(): string {
1220
1226
  const queryParams = this.getEmbedParams();
1221
1227
  let queryString = queryParams;
1228
+ const { runtimeParameters = [] } = this.viewConfig;
1229
+ if (runtimeParameters?.length > 0) {
1230
+ const parameterQuery = getRuntimeParameters(runtimeParameters);
1231
+ queryString = [parameterQuery, queryParams].filter(Boolean).join('&');
1232
+ }
1233
+
1222
1234
  if (!this.viewConfig.excludeRuntimeFiltersfromURL) {
1223
1235
  const runtimeFilters = this.viewConfig.runtimeFilters;
1224
- const runtimeParameters = this.viewConfig.runtimeParameters;
1225
1236
 
1226
- const parameterQuery = getRuntimeParameters(runtimeParameters || []);
1227
1237
  const filterQuery = getFilterQuery(runtimeFilters || []);
1228
- queryString = [parameterQuery, filterQuery, queryParams].filter(Boolean).join('&');
1238
+ queryString = [filterQuery, queryString].filter(Boolean).join('&');
1229
1239
  }
1230
1240
  return this.getV1EmbedBasePath(queryString);
1231
1241
  }
package/src/index.ts CHANGED
@@ -39,6 +39,7 @@ import {
39
39
  CustomStyles,
40
40
  customCssInterface,
41
41
  ContextMenuTriggerOptions,
42
+ RuntimeParameter,
42
43
  } from './types';
43
44
  import { CustomCssVariables } from './css-variables';
44
45
  import { SageEmbed, SageViewConfig } from './embed/sage';
@@ -93,4 +94,5 @@ export {
93
94
  CustomStyles,
94
95
  customCssInterface,
95
96
  CustomCssVariables,
97
+ RuntimeParameter,
96
98
  };
@@ -48,4 +48,5 @@ export {
48
48
  CustomStyles,
49
49
  customCssInterface,
50
50
  CustomCssVariables,
51
+ RuntimeParameter,
51
52
  } from '../index';
@@ -13,6 +13,10 @@ import { EmbedProps, getViewPropsAndListeners } from './util';
13
13
 
14
14
  const componentFactory = <T extends typeof TsEmbed, U extends EmbedProps, V extends ViewConfig>(
15
15
  EmbedConstructor: T,
16
+ // isPreRenderedComponent: Specifies whether the component being returned is
17
+ // intended for preRendering. If set to true, the component will call the
18
+ // Embed.preRender() method instead of the usual render method, and it will
19
+ // not be destroyed when the component is unmounted.
16
20
  isPreRenderedComponent = false,
17
21
  ) => React.forwardRef<InstanceType<T>, U>(
18
22
  (props: U, forwardedRef: React.MutableRefObject<InstanceType<T>>) => {
@@ -21,6 +25,42 @@ const componentFactory = <T extends typeof TsEmbed, U extends EmbedProps, V exte
21
25
  const { viewConfig, listeners } = getViewPropsAndListeners<Omit<U, 'className'>, V>(
22
26
  embedProps,
23
27
  );
28
+
29
+ const handleDestroy = (tsEmbed: InstanceType<T>) => {
30
+ // do not destroy if it is a preRender component
31
+ if (isPreRenderedComponent) return;
32
+
33
+ // if component is connected to a preRendered component
34
+ if (props.preRenderId) {
35
+ tsEmbed.hidePreRender();
36
+ return;
37
+ }
38
+
39
+ tsEmbed.destroy();
40
+ };
41
+
42
+ const handlePreRenderRendering = (tsEmbed : InstanceType<T>) => {
43
+ tsEmbed.preRender();
44
+ };
45
+
46
+ const handleDefaultRendering = (tsEmbed : InstanceType<T>) => {
47
+ // if component is connected to a preRendered component
48
+ if (props.preRenderId) {
49
+ tsEmbed.showPreRender();
50
+ return;
51
+ }
52
+
53
+ tsEmbed.render();
54
+ };
55
+
56
+ const handleRendering = (tsEmbed : InstanceType<T>) => {
57
+ if (isPreRenderedComponent) {
58
+ handlePreRenderRendering(tsEmbed);
59
+ return;
60
+ }
61
+ handleDefaultRendering(tsEmbed);
62
+ };
63
+
24
64
  useDeepCompareEffect(() => {
25
65
  const tsEmbed = new EmbedConstructor(
26
66
  ref!.current,
@@ -37,23 +77,13 @@ const componentFactory = <T extends typeof TsEmbed, U extends EmbedProps, V exte
37
77
  Object.keys(listeners).forEach((eventName) => {
38
78
  tsEmbed.on(eventName as EmbedEvent, listeners[eventName as EmbedEvent]);
39
79
  });
40
- if (isPreRenderedComponent) {
41
- tsEmbed.preRender();
42
- } else if (props.preRenderId) {
43
- tsEmbed.showPreRender();
44
- } else {
45
- tsEmbed.render();
46
- }
47
-
80
+ handleRendering(tsEmbed);
48
81
  if (forwardedRef) {
49
82
  // eslint-disable-next-line no-param-reassign
50
83
  forwardedRef.current = tsEmbed;
51
84
  }
52
85
  return () => {
53
- if (!isPreRenderedComponent) {
54
- if (props.preRenderId) tsEmbed.hidePreRender();
55
- else tsEmbed.destroy();
56
- }
86
+ handleDestroy(tsEmbed);
57
87
  };
58
88
  }, [viewConfig, listeners]);
59
89
 
@@ -81,6 +111,18 @@ interface PreRenderProps {
81
111
  * });
82
112
  * embed.showPreRender();
83
113
  * ```
114
+ *
115
+ * Use PreRendered react component for pre rendering embed components.
116
+ * @example
117
+ * ```tsx
118
+ * function LandingPageComponent() {
119
+ * return <PreRenderedLiveboardEmbed preRenderId="someId" liveboardId="libId" />
120
+ * }
121
+ * ```
122
+ * function MyComponent() {
123
+ * return <LiveboardEmbed preRenderId="someId" liveboardId="libId" />
124
+ * }
125
+ * ```
84
126
  * @version SDK: 1.25.0 | Thoughtspot: 9.6.0.cl
85
127
  */
86
128
  preRenderId: string;
package/src/types.ts CHANGED
@@ -641,16 +641,19 @@ export interface ViewConfig {
641
641
  * visualization, or Liveboard.
642
642
  */
643
643
  runtimeFilters?: RuntimeFilter[];
644
- /**
645
- * The list of parameter override to apply to a search answer,
646
- * visualization, or Liveboard.
647
- */
644
+ /**
645
+ * The list of parameter override to apply to a search answer,
646
+ * visualization, or Liveboard.
647
+ *
648
+ * @version SDK : 1.25.0 | Thoughtspot: 9.2.0.cl, 9.5.0.sw
649
+ */
648
650
  runtimeParameters?: RuntimeParameter[];
651
+ /**
649
652
  /**
650
- * The locale/language to use for the embedded view.
651
- *
652
- * @version SDK: 1.9.4 | ThoughtSpot 8.1.0.cl, 8.4.1.sw
653
- */
653
+ * The locale/language to use for the embedded view.
654
+ *
655
+ * @version SDK: 1.9.4 | ThoughtSpot 8.1.0.cl, 8.4.1.sw
656
+ */
654
657
  locale?: string;
655
658
  /**
656
659
  * This is an object (key/val) of override flags which will be applied
@@ -712,27 +715,6 @@ export interface ViewConfig {
712
715
  * @hidden
713
716
  */
714
717
  excludeRuntimeFiltersfromURL?: boolean;
715
- /**
716
- * Boolean to hide liveboard header
717
- *
718
- * @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
719
- * @default false
720
- */
721
- hideLiveboardHeader?: boolean;
722
- /**
723
- * Boolean to show liveboard title
724
- *
725
- * @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
726
- * @default false
727
- */
728
- showLiveboardTitle?: boolean;
729
- /**
730
- * Boolean to show liveboard description
731
- *
732
- * @version SDK: 1.26.0 | Thoughtspot: 9.7.0.cl
733
- * @default false
734
- */
735
- showLiveboardDescription?: boolean;
736
718
  /**
737
719
  * The list of tab IDs to hide from the embedded.
738
720
  * This Tabs will be hidden from their respective LBs.
@@ -810,23 +792,23 @@ export interface ViewConfig {
810
792
  preRenderId?: string;
811
793
 
812
794
  /**
813
- * Determines whether the PreRender component should dynamically track the size
795
+ * Determines whether the PreRender component should not dynamically track the size
814
796
  * of its embedding element and adjust its own size accordingly.
815
797
  * Enabling this option allows the PreRender component to automatically adapt
816
798
  * its dimensions based on changes to the size of the embedding element.
817
799
  *
818
800
  * @type {boolean}
819
- * @default true
801
+ * @default false
820
802
  * @example
821
- * // Enable tracking PreRender size in the configuration
803
+ * // Disable tracking PreRender size in the configuration
822
804
  * const config = {
823
- * trackPreRenderSize: true,
805
+ * doNotTrackPreRenderSize: true,
824
806
  * };
825
807
  *
826
808
  * // Instantiate an object with the configuration
827
809
  * const myComponent = new MyComponent(config);
828
810
  */
829
- trackPreRenderSize?: boolean;
811
+ doNotTrackPreRenderSize?: boolean;
830
812
  }
831
813
 
832
814
  /**
@@ -1548,11 +1530,11 @@ export enum HostEvent {
1548
1530
  * @param - execute - executes the existing / updated query
1549
1531
  * @example
1550
1532
  * ```js
1551
- * searchEmbed.trigger(HostEvent.Search, {
1552
- * searchQuery: "[sales] by [item type],
1553
- * dataSources: ["cd252e5c-b552-49a8-821d-3eadaa049cca"]
1554
- * execute: true
1555
- * })
1533
+ * searchembed.trigger(HostEvent.Search, {
1534
+ searchQuery: "[sales] by [item type]",
1535
+ dataSources: ["cd252e5c-b552-49a8-821d-3eadaa049cca"],
1536
+ execute: true
1537
+ });
1556
1538
  * ```
1557
1539
  */
1558
1540
  Search = 'search',
@@ -2311,6 +2293,7 @@ export enum Param {
2311
2293
  DisableWorksheetChange = 'disableWorksheetChange',
2312
2294
  HideEurekaResults = 'hideEurekaResults',
2313
2295
  HideEurekaSuggestions = 'hideEurekaSuggestions',
2296
+ HideAutocompleteSuggestions = 'hideAutocompleteSuggestions',
2314
2297
  HideLiveboardHeader = 'hideLiveboardHeader',
2315
2298
  ShowLiveboardDescription = 'showLiveboardDescription',
2316
2299
  ShowLiveboardTitle = 'showLiveboardTitle',
@@ -2323,6 +2306,10 @@ export enum Param {
2323
2306
  HideHomepageLeftNav = 'hideHomepageLeftNav',
2324
2307
  ModularHomeExperienceEnabled = 'modularHomeExperience',
2325
2308
  PendoTrackingKey = 'additionalPendoKey',
2309
+ LiveboardHeaderSticky = 'isLiveboardHeaderSticky',
2310
+ IsProductTour = 'isProductTour',
2311
+ HideSearchBarTitle = 'hideSearchBarTitle',
2312
+ HideSageAnswerHeader = 'hideSageAnswerHeader',
2326
2313
  }
2327
2314
 
2328
2315
  /**
@@ -3162,6 +3149,16 @@ export enum Action {
3162
3149
  * @version SDK : 1.26.0 | Thoughtspot: 9.7.0.cl
3163
3150
  */
3164
3151
  PersonalisedViewsDropdown = 'personalisedViewsDropdown',
3152
+ /**
3153
+ * Action ID for Liveboard Users ( Recently Visited / social proof )
3154
+ *
3155
+ * @example
3156
+ * ```js
3157
+ * disabledActions: [Action.LiveboardUsers]
3158
+ * ```
3159
+ * @version SDK : 1.26.0 | Thoughtspot: 9.7.0.cl
3160
+ */
3161
+ LiveboardUsers = 'liveboardUsers',
3165
3162
  }
3166
3163
 
3167
3164
  export interface AnswerServiceType {
@@ -113,7 +113,7 @@ describe('Answer service tests', () => {
113
113
  const answerService = createAnswerService();
114
114
  answerService.fetchCSVBlob(undefined, true);
115
115
  expect(fetchMock).toHaveBeenCalledWith(
116
- `https://tshost/prism/download/answer/csv?sessionId=${defaultSession.sessionId}&genNo=${defaultSession.genNo}&userLocale=en-us&exportFileName=data&omitInfo=true`,
116
+ `https://tshost/prism/download/answer/csv?sessionId=${defaultSession.sessionId}&genNo=${defaultSession.genNo}&userLocale=en-us&exportFileName=data&hideCsvHeader=false`,
117
117
  expect.objectContaining({}),
118
118
  );
119
119
  });
@@ -98,13 +98,11 @@ export class AnswerService {
98
98
  *
99
99
  * @param userLocale
100
100
  * @param omitInfo Omit the download Info on top of the CSV
101
+ * @param includeInfo
101
102
  * @returns Response
102
103
  */
103
- public async fetchCSVBlob(userLocale = 'en-us', omitInfo = false): Promise<Response> {
104
- if (omitInfo) {
105
- console.warn('omitInfo not supported yet.');
106
- }
107
- const fetchUrl = `${this.thoughtSpotHost}/prism/download/answer/csv?sessionId=${this.session.sessionId}&genNo=${this.session.genNo}&userLocale=${userLocale}&exportFileName=data&omitInfo=${omitInfo}`;
104
+ public async fetchCSVBlob(userLocale = 'en-us', includeInfo = false): Promise<Response> {
105
+ const fetchUrl = `${this.thoughtSpotHost}/prism/download/answer/csv?sessionId=${this.session.sessionId}&genNo=${this.session.genNo}&userLocale=${userLocale}&exportFileName=data&hideCsvHeader=${!includeInfo}`;
108
106
  return fetch(fetchUrl, {
109
107
  credentials: 'include',
110
108
  });
@@ -66,6 +66,9 @@ export async function getSourceDetail(
66
66
  });
67
67
 
68
68
  const souceDetails = details[0];
69
- sourceDetailCache.set(sourceId, souceDetails);
69
+ if (details) {
70
+ sourceDetailCache.set(sourceId, souceDetails);
71
+ }
72
+
70
73
  return souceDetails;
71
74
  }
package/src/utils.spec.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  getRuntimeParameters,
10
10
  removeStyleProperties,
11
11
  setStyleProperties,
12
+ isUndefined,
12
13
  } from './utils';
13
14
  import { RuntimeFilterOp } from './types';
14
15
 
@@ -30,6 +31,19 @@ describe('unit test for utils', () => {
30
31
  ).toBe('bar=baz');
31
32
  });
32
33
 
34
+ test('getFilterQuery should encode URL params', () => {
35
+ expect(getFilterQuery([])).toBe(null);
36
+
37
+ expect(
38
+ getFilterQuery([
39
+ {
40
+ columnName: 'foo+foo',
41
+ operator: RuntimeFilterOp.NE,
42
+ values: ['bar+'],
43
+ },
44
+ ]),
45
+ ).toBe('col1=foo%2Bfoo&op1=NE&val1=bar%2B');
46
+ });
33
47
  test('getFilterQuery', () => {
34
48
  expect(getFilterQuery([])).toBe(null);
35
49
 
@@ -179,7 +193,6 @@ describe('unit test for utils', () => {
179
193
  it('should remove specified style properties from an HTML element', () => {
180
194
  const element = document.createElement('div');
181
195
 
182
- // Set initial styles for testing
183
196
  element.style.backgroundColor = 'blue';
184
197
  element.style.fontSize = '14px';
185
198
 
@@ -187,8 +200,8 @@ describe('unit test for utils', () => {
187
200
 
188
201
  removeStyleProperties(element, propertiesToRemove);
189
202
 
190
- expect(element.style.backgroundColor).toBe(''); // Check that the property is removed
191
- expect(element.style.fontSize).toBe(''); // Check that the property is removed
203
+ expect(element.style.backgroundColor).toBe('');
204
+ expect(element.style.fontSize).toBe('');
192
205
  });
193
206
 
194
207
  it('should handle undefined param', () => {
@@ -200,18 +213,15 @@ describe('unit test for utils', () => {
200
213
  it('should handle removing non-existent style properties', () => {
201
214
  const element = document.createElement('div');
202
215
 
203
- // Set initial styles for testing
204
216
  element.style.backgroundColor = 'blue';
205
217
  element.style.fontSize = '14px';
206
218
 
207
219
  const propertiesToRemove = ['color', 'border'];
208
220
 
209
- // Removing non-existent properties should not throw an error and
210
- // should not change existing styles
211
221
  removeStyleProperties(element, propertiesToRemove);
212
222
 
213
- expect(element.style.backgroundColor).toBe('blue'); // Style should remain unchanged
214
- expect(element.style.fontSize).toBe('14px'); // Style should remain unchanged
223
+ expect(element.style.backgroundColor).toBe('blue');
224
+ expect(element.style.fontSize).toBe('14px');
215
225
  });
216
226
  });
217
227
 
@@ -237,4 +247,9 @@ describe('unit test for utils', () => {
237
247
  }).not.toThrow();
238
248
  });
239
249
  });
250
+
251
+ test('isUndefined', () => {
252
+ expect(isUndefined(undefined)).toBe(true);
253
+ expect(isUndefined({})).toBe(false);
254
+ });
240
255
  });
package/src/utils.ts CHANGED
@@ -31,9 +31,9 @@ export const getFilterQuery = (runtimeFilters: RuntimeFilter[]): string => {
31
31
  const filters = runtimeFilters.map((filter, valueIndex) => {
32
32
  const index = valueIndex + 1;
33
33
  const filterExpr = [];
34
- filterExpr.push(`col${index}=${filter.columnName}`);
34
+ filterExpr.push(`col${index}=${encodeURIComponent(filter.columnName)}`);
35
35
  filterExpr.push(`op${index}=${filter.operator}`);
36
- filterExpr.push(filter.values.map((value) => `val${index}=${value}`).join('&'));
36
+ filterExpr.push(filter.values.map((value) => `val${index}=${encodeURIComponent(value)}`).join('&'));
37
37
 
38
38
  return filterExpr.join('&');
39
39
  });
@@ -315,3 +315,5 @@ export const removeStyleProperties = (element: HTMLElement, styleProperties: str
315
315
  element.style.removeProperty(styleProperty);
316
316
  });
317
317
  };
318
+
319
+ export const isUndefined = (value: any): boolean => value === undefined;