@thoughtspot/visual-embed-sdk 1.39.2-alpha.1 → 1.39.2-alpha.3

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 (171) hide show
  1. package/cjs/package.json +1 -1
  2. package/cjs/src/config.spec.js +9 -0
  3. package/cjs/src/config.spec.js.map +1 -1
  4. package/cjs/src/embed/app.d.ts +75 -15
  5. package/cjs/src/embed/app.d.ts.map +1 -1
  6. package/cjs/src/embed/app.js +68 -9
  7. package/cjs/src/embed/app.js.map +1 -1
  8. package/cjs/src/embed/app.spec.js +360 -7
  9. package/cjs/src/embed/app.spec.js.map +1 -1
  10. package/cjs/src/embed/bodyless-conversation.d.ts +19 -7
  11. package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
  12. package/cjs/src/embed/bodyless-conversation.js +24 -4
  13. package/cjs/src/embed/bodyless-conversation.js.map +1 -1
  14. package/cjs/src/embed/bodyless-conversation.spec.js +8 -190
  15. package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
  16. package/cjs/src/embed/conversation.d.ts +2 -60
  17. package/cjs/src/embed/conversation.d.ts.map +1 -1
  18. package/cjs/src/embed/conversation.js +1 -9
  19. package/cjs/src/embed/conversation.js.map +1 -1
  20. package/cjs/src/embed/conversation.spec.js +0 -102
  21. package/cjs/src/embed/conversation.spec.js.map +1 -1
  22. package/cjs/src/embed/liveboard.d.ts +56 -0
  23. package/cjs/src/embed/liveboard.d.ts.map +1 -1
  24. package/cjs/src/embed/liveboard.js +46 -0
  25. package/cjs/src/embed/liveboard.js.map +1 -1
  26. package/cjs/src/embed/liveboard.spec.js +206 -0
  27. package/cjs/src/embed/liveboard.spec.js.map +1 -1
  28. package/cjs/src/errors.d.ts +1 -0
  29. package/cjs/src/errors.d.ts.map +1 -1
  30. package/cjs/src/errors.js +1 -0
  31. package/cjs/src/errors.js.map +1 -1
  32. package/cjs/src/index.d.ts +2 -2
  33. package/cjs/src/index.d.ts.map +1 -1
  34. package/cjs/src/index.js +2 -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 +3 -2
  39. package/cjs/src/react/all-types-export.js.map +1 -1
  40. package/cjs/src/react/index.d.ts +71 -20
  41. package/cjs/src/react/index.d.ts.map +1 -1
  42. package/cjs/src/react/index.js +79 -42
  43. package/cjs/src/react/index.js.map +1 -1
  44. package/cjs/src/react/index.spec.js +436 -100
  45. package/cjs/src/react/index.spec.js.map +1 -1
  46. package/cjs/src/types.d.ts +46 -4
  47. package/cjs/src/types.d.ts.map +1 -1
  48. package/cjs/src/types.js +28 -0
  49. package/cjs/src/types.js.map +1 -1
  50. package/cjs/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
  51. package/cjs/src/utils/graphql/nlsService/conversation-service.js +2 -0
  52. package/cjs/src/utils/graphql/nlsService/conversation-service.js.map +1 -1
  53. package/cjs/src/utils/processTrigger.js +2 -1
  54. package/cjs/src/utils/processTrigger.js.map +1 -1
  55. package/cjs/src/utils.d.ts +6 -0
  56. package/cjs/src/utils.d.ts.map +1 -1
  57. package/cjs/src/utils.js +23 -3
  58. package/cjs/src/utils.js.map +1 -1
  59. package/cjs/src/utils.spec.js +237 -1
  60. package/cjs/src/utils.spec.js.map +1 -1
  61. package/dist/index-D1pyb7RG.js +7371 -0
  62. package/dist/index-e3Uw3YFO.js +7371 -0
  63. package/dist/src/embed/app.d.ts +75 -15
  64. package/dist/src/embed/app.d.ts.map +1 -1
  65. package/dist/src/embed/bodyless-conversation.d.ts +19 -7
  66. package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
  67. package/dist/src/embed/conversation.d.ts +2 -60
  68. package/dist/src/embed/conversation.d.ts.map +1 -1
  69. package/dist/src/embed/liveboard.d.ts +56 -0
  70. package/dist/src/embed/liveboard.d.ts.map +1 -1
  71. package/dist/src/errors.d.ts +1 -0
  72. package/dist/src/errors.d.ts.map +1 -1
  73. package/dist/src/index.d.ts +2 -2
  74. package/dist/src/index.d.ts.map +1 -1
  75. package/dist/src/react/all-types-export.d.ts +1 -1
  76. package/dist/src/react/all-types-export.d.ts.map +1 -1
  77. package/dist/src/react/index.d.ts +71 -20
  78. package/dist/src/react/index.d.ts.map +1 -1
  79. package/dist/src/types.d.ts +46 -4
  80. package/dist/src/types.d.ts.map +1 -1
  81. package/dist/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
  82. package/dist/src/utils.d.ts +6 -0
  83. package/dist/src/utils.d.ts.map +1 -1
  84. package/dist/tsembed-react.es.js +276 -74
  85. package/dist/tsembed-react.js +276 -72
  86. package/dist/tsembed.es.js +194 -27
  87. package/dist/tsembed.js +192 -25
  88. package/dist/visual-embed-sdk-react-full.d.ts +246 -105
  89. package/dist/visual-embed-sdk-react.d.ts +246 -105
  90. package/dist/visual-embed-sdk.d.ts +176 -86
  91. package/lib/package.json +1 -1
  92. package/lib/src/config.spec.js +9 -0
  93. package/lib/src/config.spec.js.map +1 -1
  94. package/lib/src/embed/app.d.ts +75 -15
  95. package/lib/src/embed/app.d.ts.map +1 -1
  96. package/lib/src/embed/app.js +68 -9
  97. package/lib/src/embed/app.js.map +1 -1
  98. package/lib/src/embed/app.spec.js +361 -8
  99. package/lib/src/embed/app.spec.js.map +1 -1
  100. package/lib/src/embed/bodyless-conversation.d.ts +19 -7
  101. package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
  102. package/lib/src/embed/bodyless-conversation.js +23 -4
  103. package/lib/src/embed/bodyless-conversation.js.map +1 -1
  104. package/lib/src/embed/bodyless-conversation.spec.js +9 -191
  105. package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
  106. package/lib/src/embed/conversation.d.ts +2 -60
  107. package/lib/src/embed/conversation.d.ts.map +1 -1
  108. package/lib/src/embed/conversation.js +2 -10
  109. package/lib/src/embed/conversation.js.map +1 -1
  110. package/lib/src/embed/conversation.spec.js +2 -104
  111. package/lib/src/embed/conversation.spec.js.map +1 -1
  112. package/lib/src/embed/liveboard.d.ts +56 -0
  113. package/lib/src/embed/liveboard.d.ts.map +1 -1
  114. package/lib/src/embed/liveboard.js +47 -1
  115. package/lib/src/embed/liveboard.js.map +1 -1
  116. package/lib/src/embed/liveboard.spec.js +206 -0
  117. package/lib/src/embed/liveboard.spec.js.map +1 -1
  118. package/lib/src/errors.d.ts +1 -0
  119. package/lib/src/errors.d.ts.map +1 -1
  120. package/lib/src/errors.js +1 -0
  121. package/lib/src/errors.js.map +1 -1
  122. package/lib/src/index.d.ts +2 -2
  123. package/lib/src/index.d.ts.map +1 -1
  124. package/lib/src/index.js +2 -2
  125. package/lib/src/index.js.map +1 -1
  126. package/lib/src/react/all-types-export.d.ts +1 -1
  127. package/lib/src/react/all-types-export.d.ts.map +1 -1
  128. package/lib/src/react/all-types-export.js +1 -1
  129. package/lib/src/react/all-types-export.js.map +1 -1
  130. package/lib/src/react/index.d.ts +71 -20
  131. package/lib/src/react/index.d.ts.map +1 -1
  132. package/lib/src/react/index.js +79 -43
  133. package/lib/src/react/index.js.map +1 -1
  134. package/lib/src/react/index.spec.js +439 -103
  135. package/lib/src/react/index.spec.js.map +1 -1
  136. package/lib/src/types.d.ts +46 -4
  137. package/lib/src/types.d.ts.map +1 -1
  138. package/lib/src/types.js +28 -0
  139. package/lib/src/types.js.map +1 -1
  140. package/lib/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
  141. package/lib/src/utils/graphql/nlsService/conversation-service.js +2 -0
  142. package/lib/src/utils/graphql/nlsService/conversation-service.js.map +1 -1
  143. package/lib/src/utils/processTrigger.js +2 -1
  144. package/lib/src/utils/processTrigger.js.map +1 -1
  145. package/lib/src/utils.d.ts +6 -0
  146. package/lib/src/utils.d.ts.map +1 -1
  147. package/lib/src/utils.js +21 -2
  148. package/lib/src/utils.js.map +1 -1
  149. package/lib/src/utils.spec.js +238 -2
  150. package/lib/src/utils.spec.js.map +1 -1
  151. package/lib/src/visual-embed-sdk.d.ts +178 -88
  152. package/package.json +1 -1
  153. package/src/config.spec.ts +11 -0
  154. package/src/embed/app.spec.ts +451 -8
  155. package/src/embed/app.ts +131 -27
  156. package/src/embed/bodyless-conversation.spec.ts +9 -203
  157. package/src/embed/bodyless-conversation.ts +24 -10
  158. package/src/embed/conversation.spec.ts +5 -131
  159. package/src/embed/conversation.ts +10 -82
  160. package/src/embed/liveboard.spec.ts +254 -1
  161. package/src/embed/liveboard.ts +96 -5
  162. package/src/errors.ts +1 -0
  163. package/src/index.ts +2 -0
  164. package/src/react/all-types-export.ts +2 -1
  165. package/src/react/index.spec.tsx +556 -157
  166. package/src/react/index.tsx +117 -51
  167. package/src/types.ts +42 -0
  168. package/src/utils/graphql/nlsService/conversation-service.ts +2 -0
  169. package/src/utils/processTrigger.ts +1 -1
  170. package/src/utils.spec.ts +279 -2
  171. package/src/utils.ts +28 -2
@@ -1,8 +1,10 @@
1
- import { SpotterEmbed, SpotterEmbedViewConfig, ConversationEmbed } from './conversation';
2
- import { TsEmbed } from './ts-embed';
1
+ import {
2
+ SpotterEmbed,
3
+ SpotterEmbedViewConfig,
4
+ } from './conversation';
3
5
  import * as authInstance from '../auth';
4
6
  import { Action, init } from '../index';
5
- import { AuthType, Param, RuntimeFilterOp } from '../types';
7
+ import { AuthType, Param } from '../types';
6
8
  import {
7
9
  getDocumentBody,
8
10
  getIFrameSrc,
@@ -178,132 +180,4 @@ describe('ConversationEmbed', () => {
178
180
  `http://${thoughtSpotHost}/v2/?${defaultParams}&${Param.DisableActions}=[%22${Action.InConversationTraining}%22]&${Param.DisableActionReason}=${disabledReason}&isSpotterExperienceEnabled=true&enableDataPanelV2=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
179
181
  );
180
182
  });
181
-
182
- it('should render the conversation embed with runtime filters', async () => {
183
- const viewConfig: SpotterEmbedViewConfig = {
184
- worksheetId: 'worksheetId',
185
- searchOptions: {
186
- searchQuery: 'searchQuery',
187
- },
188
- runtimeFilters: [
189
- {
190
- columnName: 'revenue',
191
- operator: RuntimeFilterOp.EQ,
192
- values: [1000],
193
- },
194
- ],
195
- };
196
-
197
- const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
198
- await conversationEmbed.render();
199
- expectUrlMatchesWithParams(
200
- getIFrameSrc(),
201
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&col1=revenue&op1=EQ&val1=1000#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
202
- );
203
- });
204
-
205
- it('should render the conversation embed with runtime parameters', async () => {
206
- const viewConfig: SpotterEmbedViewConfig = {
207
- worksheetId: 'worksheetId',
208
- searchOptions: {
209
- searchQuery: 'searchQuery',
210
- },
211
- runtimeParameters: [
212
- {
213
- name: 'Date Range',
214
- value: '30',
215
- },
216
- ],
217
- };
218
-
219
- const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
220
- await conversationEmbed.render();
221
- expectUrlMatchesWithParams(
222
- getIFrameSrc(),
223
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&param1=Date%20Range&paramVal1=30#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
224
- );
225
- });
226
-
227
- it('should render the conversation embed with runtime parameters excluded from URL', async () => {
228
- const viewConfig: SpotterEmbedViewConfig = {
229
- worksheetId: 'worksheetId',
230
- searchOptions: {
231
- searchQuery: 'searchQuery',
232
- },
233
- runtimeParameters: [
234
- {
235
- name: 'Date Range',
236
- value: '30',
237
- },
238
- {
239
- name: 'Region',
240
- value: 'North America',
241
- },
242
- ],
243
- excludeRuntimeParametersfromURL: true,
244
- };
245
-
246
- const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
247
- await conversationEmbed.render();
248
- expectUrlMatchesWithParams(
249
- getIFrameSrc(),
250
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
251
- );
252
- });
253
-
254
- it('should render the conversation embed with both runtime filters and parameters', async () => {
255
- const viewConfig: SpotterEmbedViewConfig = {
256
- worksheetId: 'worksheetId',
257
- searchOptions: {
258
- searchQuery: 'searchQuery',
259
- },
260
- runtimeParameters: [
261
- {
262
- name: 'Date Range',
263
- value: '30',
264
- },
265
- ],
266
- runtimeFilters: [
267
- {
268
- columnName: 'revenue',
269
- operator: RuntimeFilterOp.EQ,
270
- values: [1000],
271
- },
272
- ],
273
- excludeRuntimeParametersfromURL: false,
274
- excludeRuntimeFiltersfromURL: false,
275
- };
276
-
277
- const conversationEmbed = new SpotterEmbed(getRootEl(), viewConfig);
278
- await conversationEmbed.render();
279
- expectUrlMatchesWithParams(
280
- getIFrameSrc(),
281
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&col1=revenue&op1=EQ&val1=1000&param1=Date%20Range&paramVal1=30#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
282
- );
283
- });
284
-
285
- it('should ensure deprecated ConversationEmbed class maintains same functionality as SpotterEmbed', async () => {
286
- const viewConfig: SpotterEmbedViewConfig = {
287
- worksheetId: 'worksheetId',
288
- searchOptions: {
289
- searchQuery: 'searchQuery',
290
- },
291
- runtimeParameters: [
292
- {
293
- name: 'Date Range',
294
- value: '30',
295
- },
296
- ],
297
- };
298
-
299
- // Test with deprecated class
300
- const conversationEmbed = new ConversationEmbed(getRootEl(), viewConfig);
301
- await conversationEmbed.render();
302
-
303
- // Verify it generates the same URL structure as SpotterEmbed
304
- expectUrlMatchesWithParams(
305
- getIFrameSrc(),
306
- `http://${thoughtSpotHost}/v2/?${defaultParams}&isSpotterExperienceEnabled=true&param1=Date%20Range&paramVal1=30#/embed/insights/conv-assist?worksheet=worksheetId&query=searchQuery`,
307
- );
308
- });
309
183
  });
@@ -1,10 +1,10 @@
1
1
  import isUndefined from 'lodash/isUndefined';
2
2
  import { ERROR_MESSAGE } from '../errors';
3
- import { Param, BaseViewConfig, RuntimeFilter, RuntimeParameter } from '../types';
3
+ import { Param, BaseViewConfig } from '../types';
4
4
  import { TsEmbed } from './ts-embed';
5
- import { getQueryParamString, getFilterQuery, getRuntimeParameters } from '../utils';
5
+ import { getQueryParamString } from '../utils';
6
6
 
7
- /**
7
+ /**
8
8
  * Configuration for search options
9
9
  */
10
10
  export interface SearchOptions {
@@ -20,8 +20,7 @@ export interface SearchOptions {
20
20
  */
21
21
  export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAction'> {
22
22
  /**
23
- * The ID of the data source object. For example, Model, View, or Table. Spotter uses
24
- * this object to query data and generate Answers.
23
+ * The ID of the data source object. For example, Model, View, or Table. Spotter uses this object to query data and generate Answers.
25
24
  */
26
25
  worksheetId: string;
27
26
  /**
@@ -31,7 +30,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
31
30
  /**
32
31
  * disableSourceSelection : Disables data source selection
33
32
  * but still display the selected data source.
34
- *
33
+ *
35
34
  * Supported embed types: `SpotterEmbed`
36
35
  * @example
37
36
  * ```js
@@ -45,7 +44,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
45
44
  disableSourceSelection?: boolean;
46
45
  /**
47
46
  * hideSourceSelection : Hide data source selection
48
- *
47
+ *
49
48
  * Supported embed types: `SpotterEmbed`
50
49
  * @example
51
50
  * ```js
@@ -59,7 +58,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
59
58
  hideSourceSelection?: boolean;
60
59
  /**
61
60
  * Flag to control Data panel experience
62
- *
61
+ *
63
62
  * Supported embed types: `SageEmbed`, `AppEmbed`, `SearchBarEmbed`, `LiveboardEmbed`, `SearchEmbed`
64
63
  * @default false
65
64
  * @version SDK: 1.36.0 | ThoughtSpot Cloud: 10.4.0.cl
@@ -77,7 +76,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
77
76
  * showSpotterLimitations : show limitation text
78
77
  * of the spotter underneath the chat input.
79
78
  * default is false.
80
- *
79
+ *
81
80
  * Supported embed types: `SpotterEmbed`
82
81
  * @example
83
82
  * ```js
@@ -92,7 +91,7 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
92
91
  /**
93
92
  * hideSampleQuestions : Hide sample questions on
94
93
  * the initial screen of the conversation.
95
- *
94
+ *
96
95
  * Supported embed types: `SpotterEmbed`
97
96
  * @example
98
97
  * ```js
@@ -104,63 +103,6 @@ export interface SpotterEmbedViewConfig extends Omit<BaseViewConfig, 'primaryAct
104
103
  * @version SDK: 1.36.0 | ThoughtSpot: 10.6.0.cl
105
104
  */
106
105
  hideSampleQuestions?: boolean;
107
- /**
108
- * The list of runtime filters to apply to a search Answer,
109
- * visualization, or Liveboard.
110
- *
111
- * Supported embed types: `SpotterEmbed`
112
- * @example
113
- * ```js
114
- * const embed = new SpotterEmbed('#tsEmbed', {
115
- * ... // other embed view config
116
- * runtimeFilters: [
117
- * {
118
- * columnName: 'value',
119
- * operator: RuntimeFilterOp.EQ,
120
- * values: ['string' | 123 | true],
121
- * },
122
- * ],
123
- * })
124
- * ```
125
- */
126
- runtimeFilters?: RuntimeFilter[];
127
- /**
128
- * Flag to control whether runtime filters should be included in the URL.
129
- * If true, filters will be passed via app initialization payload instead.
130
- * If false/undefined, filters will be added to URL (default behavior).
131
- *
132
- * Supported embed types: `SpotterEmbed`
133
- * @default false
134
- */
135
- excludeRuntimeFiltersfromURL?: boolean;
136
- /**
137
- * The list of runtime parameters to apply to the conversation.
138
- *
139
- * Supported embed types: `SpotterEmbed`
140
- * @example
141
- * ```js
142
- * const embed = new SpotterEmbed('#tsEmbed', {
143
- * ... // other embed view config
144
- * runtimeParameters: [
145
- * {
146
- * name: 'Parameter Name',
147
- * value: 'Parameter Value',
148
- * },
149
- * ],
150
- * })
151
- * ```
152
- */
153
- runtimeParameters?: RuntimeParameter[];
154
- /**
155
- * Flag to control whether runtime parameters should be included in the URL.
156
- * If true, parameters will be passed via app initialization payload instead.
157
- * If false/undefined, parameters will be added to URL (default behavior).
158
- *
159
- * Supported embed types: `SpotterEmbed`
160
- * @default false
161
- *
162
- */
163
- excludeRuntimeParametersfromURL?: boolean;
164
106
  }
165
107
 
166
108
  /**
@@ -202,10 +144,6 @@ export class SpotterEmbed extends TsEmbed {
202
144
  dataPanelV2,
203
145
  showSpotterLimitations,
204
146
  hideSampleQuestions,
205
- runtimeFilters,
206
- excludeRuntimeFiltersfromURL,
207
- runtimeParameters,
208
- excludeRuntimeParametersfromURL,
209
147
  } = this.viewConfig;
210
148
  const path = 'insights/conv-assist';
211
149
  if (!worksheetId) {
@@ -237,21 +175,11 @@ export class SpotterEmbed extends TsEmbed {
237
175
  if (queryParamsString) {
238
176
  query = `?${queryParamsString}`;
239
177
  }
240
-
241
- const filterQuery = getFilterQuery(runtimeFilters || []);
242
- if (filterQuery && !excludeRuntimeFiltersfromURL) {
243
- query += `&${filterQuery}`;
244
- }
245
-
246
- const parameterQuery = getRuntimeParameters(runtimeParameters || []);
247
- if (parameterQuery && !excludeRuntimeParametersfromURL) {
248
- query += `&${parameterQuery}`;
249
- }
250
-
251
178
  const tsPostHashParams = this.getThoughtSpotPostUrlParams({
252
179
  worksheet: worksheetId,
253
180
  query: searchOptions?.searchQuery || '',
254
181
  });
182
+
255
183
  return `${this.getEmbedBasePath(query)}/embed/${path}${tsPostHashParams}`;
256
184
  }
257
185
 
@@ -786,7 +786,7 @@ describe('Liveboard/viz embed tests', () => {
786
786
  await waitFor(() => !!getIFrameEl());
787
787
 
788
788
  const ts = '__tsEmbed';
789
- expect(document.getElementById(libEmbed.getPreRenderIds().wrapper)[ts]).toEqual(
789
+ expect((document.getElementById(libEmbed.getPreRenderIds().wrapper) as any)[ts]).toEqual(
790
790
  libEmbed,
791
791
  );
792
792
 
@@ -814,6 +814,259 @@ describe('Liveboard/viz embed tests', () => {
814
814
  });
815
815
  });
816
816
 
817
+ describe('LazyLoadingForFullHeight functionality', () => {
818
+ let mockIFrame: HTMLIFrameElement;
819
+
820
+ beforeEach(() => {
821
+ mockIFrame = document.createElement('iframe');
822
+ mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
823
+ top: 100,
824
+ left: 150,
825
+ bottom: 600,
826
+ right: 800,
827
+ width: 650,
828
+ height: 500,
829
+ });
830
+ jest.spyOn(document, 'createElement').mockImplementation((tagName) => {
831
+ if (tagName === 'iframe') {
832
+ return mockIFrame;
833
+ }
834
+ return document.createElement(tagName);
835
+ });
836
+ });
837
+
838
+ afterEach(() => {
839
+ jest.restoreAllMocks();
840
+ });
841
+
842
+ test('should set lazyLoadingMargin parameter when provided', async () => {
843
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
844
+ ...defaultViewConfig,
845
+ liveboardId,
846
+ fullHeight: true,
847
+ lazyLoadingForFullHeight: true,
848
+ lazyLoadingMargin: '100px 0px',
849
+ } as LiveboardViewConfig);
850
+
851
+ await liveboardEmbed.render();
852
+
853
+ await executeAfterWait(() => {
854
+ const iframeSrc = getIFrameSrc();
855
+ expect(iframeSrc).toContain('isLazyLoadingForEmbedEnabled=true');
856
+ expect(iframeSrc).toContain('isFullHeightPinboard=true');
857
+ expect(iframeSrc).toContain('rootMarginForLazyLoad=100px%200px');
858
+ }, 100);
859
+ });
860
+
861
+ test('should set isLazyLoadingForEmbedEnabled=true when both fullHeight and lazyLoadingForFullHeight are enabled', async () => {
862
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
863
+ ...defaultViewConfig,
864
+ liveboardId,
865
+ fullHeight: true,
866
+ lazyLoadingForFullHeight: true,
867
+ } as LiveboardViewConfig);
868
+
869
+ await liveboardEmbed.render();
870
+
871
+ await executeAfterWait(() => {
872
+ const iframeSrc = getIFrameSrc();
873
+ expect(iframeSrc).toContain('isLazyLoadingForEmbedEnabled=true');
874
+ expect(iframeSrc).toContain('isFullHeightPinboard=true');
875
+ }, 100);
876
+ });
877
+
878
+ test('should not set lazyLoadingForEmbed when lazyLoadingForFullHeight is enabled but fullHeight is false', async () => {
879
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
880
+ ...defaultViewConfig,
881
+ liveboardId,
882
+ fullHeight: false,
883
+ lazyLoadingForFullHeight: true,
884
+ } as LiveboardViewConfig);
885
+
886
+ await liveboardEmbed.render();
887
+
888
+ await executeAfterWait(() => {
889
+ const iframeSrc = getIFrameSrc();
890
+ expect(iframeSrc).not.toContain('isLazyLoadingForEmbedEnabled=true');
891
+ expect(iframeSrc).not.toContain('isFullHeightPinboard=true');
892
+ }, 100);
893
+ });
894
+
895
+ test('should not set isLazyLoadingForEmbedEnabled when fullHeight is true but lazyLoadingForFullHeight is false', async () => {
896
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
897
+ ...defaultViewConfig,
898
+ liveboardId,
899
+ fullHeight: true,
900
+ lazyLoadingForFullHeight: false,
901
+ } as LiveboardViewConfig);
902
+
903
+ await liveboardEmbed.render();
904
+
905
+ await executeAfterWait(() => {
906
+ const iframeSrc = getIFrameSrc();
907
+ expect(iframeSrc).not.toContain('isLazyLoadingForEmbedEnabled=true');
908
+ expect(iframeSrc).toContain('isFullHeightPinboard=true');
909
+ }, 100);
910
+ });
911
+
912
+ test('should register event handlers to adjust iframe height', async () => {
913
+ const onSpy = jest.spyOn(LiveboardEmbed.prototype, 'on');
914
+
915
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
916
+ ...defaultViewConfig,
917
+ liveboardId,
918
+ fullHeight: true,
919
+ lazyLoadingForFullHeight: true,
920
+ } as LiveboardViewConfig);
921
+
922
+ await liveboardEmbed.render();
923
+
924
+ await executeAfterWait(() => {
925
+ expect(onSpy).toHaveBeenCalledWith(EmbedEvent.EmbedHeight, expect.anything());
926
+ expect(onSpy).toHaveBeenCalledWith(EmbedEvent.RouteChange, expect.anything());
927
+ expect(onSpy).toHaveBeenCalledWith(EmbedEvent.EmbedIframeCenter, expect.anything());
928
+ expect(onSpy).toHaveBeenCalledWith(EmbedEvent.RequestVisibleEmbedCoordinates, expect.anything());
929
+ }, 100);
930
+ });
931
+
932
+ test('should send correct visible data when RequestVisibleEmbedCoordinates is triggered', async () => {
933
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
934
+ ...defaultViewConfig,
935
+ liveboardId,
936
+ fullHeight: true,
937
+ lazyLoadingForFullHeight: true,
938
+ } as LiveboardViewConfig);
939
+
940
+ const mockTrigger = jest.spyOn(liveboardEmbed, 'trigger');
941
+
942
+ await liveboardEmbed.render();
943
+
944
+ // Trigger the lazy load data calculation
945
+ (liveboardEmbed as any).sendFullHeightLazyLoadData();
946
+
947
+ expect(mockTrigger).toHaveBeenCalledWith(HostEvent.VisibleEmbedCoordinates, {
948
+ top: 0,
949
+ height: 500,
950
+ left: 0,
951
+ width: 650,
952
+ });
953
+ });
954
+
955
+ test('should calculate correct visible data for partially visible full height element', async () => {
956
+ mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
957
+ top: -50,
958
+ left: -30,
959
+ bottom: 700,
960
+ right: 1024,
961
+ width: 1054,
962
+ height: 750,
963
+ });
964
+
965
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
966
+ ...defaultViewConfig,
967
+ liveboardId,
968
+ fullHeight: true,
969
+ lazyLoadingForFullHeight: true,
970
+ } as LiveboardViewConfig);
971
+
972
+ const mockTrigger = jest.spyOn(liveboardEmbed, 'trigger');
973
+
974
+ await liveboardEmbed.render();
975
+
976
+ // Trigger the lazy load data calculation
977
+ (liveboardEmbed as any).sendFullHeightLazyLoadData();
978
+
979
+ expect(mockTrigger).toHaveBeenCalledWith(HostEvent.VisibleEmbedCoordinates, {
980
+ top: 50,
981
+ height: 700,
982
+ left: 30,
983
+ width: 1024,
984
+ });
985
+ });
986
+
987
+ test('should add window event listeners for resize and scroll when fullHeight and lazyLoadingForFullHeight are enabled', async () => {
988
+ const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
989
+
990
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
991
+ ...defaultViewConfig,
992
+ liveboardId,
993
+ fullHeight: true,
994
+ lazyLoadingForFullHeight: true,
995
+ } as LiveboardViewConfig);
996
+
997
+ await liveboardEmbed.render();
998
+
999
+ // Wait for the post-render events to be registered
1000
+ await executeAfterWait(() => {
1001
+ expect(addEventListenerSpy).toHaveBeenCalledWith('resize', expect.anything());
1002
+ expect(addEventListenerSpy).toHaveBeenCalledWith('scroll', expect.anything(), true);
1003
+ }, 100);
1004
+
1005
+ addEventListenerSpy.mockRestore();
1006
+ });
1007
+
1008
+ test('should remove window event listeners on destroy when fullHeight and lazyLoadingForFullHeight are enabled', async () => {
1009
+ const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
1010
+
1011
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1012
+ ...defaultViewConfig,
1013
+ liveboardId,
1014
+ fullHeight: true,
1015
+ lazyLoadingForFullHeight: true,
1016
+ } as LiveboardViewConfig);
1017
+
1018
+ await liveboardEmbed.render();
1019
+ liveboardEmbed.destroy();
1020
+
1021
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.anything());
1022
+ expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.anything());
1023
+
1024
+ removeEventListenerSpy.mockRestore();
1025
+ });
1026
+
1027
+ test('should handle RequestVisibleEmbedCoordinates event and respond with correct data', async () => {
1028
+ // Mock the iframe element
1029
+ mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
1030
+ top: 100,
1031
+ left: 150,
1032
+ bottom: 600,
1033
+ right: 800,
1034
+ width: 650,
1035
+ height: 500,
1036
+ });
1037
+ Object.defineProperty(mockIFrame, 'scrollHeight', { value: 500 });
1038
+
1039
+ const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
1040
+ ...defaultViewConfig,
1041
+ liveboardId,
1042
+ fullHeight: true,
1043
+ lazyLoadingForFullHeight: true,
1044
+ } as LiveboardViewConfig);
1045
+
1046
+ // Set the iframe before render
1047
+ (liveboardEmbed as any).iFrame = mockIFrame;
1048
+
1049
+ await liveboardEmbed.render();
1050
+
1051
+ // Create a mock responder function
1052
+ const mockResponder = jest.fn();
1053
+
1054
+ // Trigger the handler directly
1055
+ (liveboardEmbed as any).requestVisibleEmbedCoordinatesHandler({}, mockResponder);
1056
+
1057
+ // Verify the responder was called with the correct data
1058
+ expect(mockResponder).toHaveBeenCalledWith({
1059
+ type: EmbedEvent.RequestVisibleEmbedCoordinates,
1060
+ data: {
1061
+ top: 0,
1062
+ height: 500,
1063
+ left: 0,
1064
+ width: 650,
1065
+ },
1066
+ });
1067
+ });
1068
+ });
1069
+
817
1070
  describe('Host events for liveborad', () => {
818
1071
  test('Host event with empty param', async () => {
819
1072
  const mockProcessTrigger = jest.spyOn(tsEmbed.TsEmbed.prototype, 'trigger');