@thoughtspot/visual-embed-sdk 1.24.0-preRender.2 → 1.24.0-preRender.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.
- package/cjs/package.json +1 -1
- package/cjs/src/embed/app.d.ts +1 -3
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +2 -8
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +1 -3
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +2 -8
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/sage.d.ts +1 -3
- package/cjs/src/embed/sage.d.ts.map +1 -1
- package/cjs/src/embed/sage.js +2 -8
- package/cjs/src/embed/sage.js.map +1 -1
- package/cjs/src/embed/search.d.ts +1 -4
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js +2 -9
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +45 -15
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +112 -92
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +102 -0
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/react/all-types-export.d.ts +1 -1
- package/cjs/src/react/all-types-export.d.ts.map +1 -1
- package/cjs/src/react/all-types-export.js +6 -2
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/react/index.d.ts +103 -5
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +81 -1
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/react/index.spec.js +22 -0
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/types.d.ts +18 -0
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils.d.ts +27 -0
- package/cjs/src/utils.d.ts.map +1 -1
- package/cjs/src/utils.js +31 -0
- package/cjs/src/utils.js.map +1 -1
- package/cjs/src/utils.spec.d.ts +0 -3
- package/cjs/src/utils.spec.d.ts.map +1 -1
- package/cjs/src/utils.spec.js +59 -6
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/src/embed/app.d.ts +1 -3
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +1 -3
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/sage.d.ts +1 -3
- package/dist/src/embed/sage.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +1 -4
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +45 -15
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/react/all-types-export.d.ts +1 -1
- package/dist/src/react/all-types-export.d.ts.map +1 -1
- package/dist/src/react/index.d.ts +103 -5
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +18 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils.d.ts +27 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.spec.d.ts +0 -3
- package/dist/src/utils.spec.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +233 -127
- package/dist/tsembed-react.js +233 -126
- package/dist/tsembed.es.js +152 -126
- package/dist/tsembed.js +152 -126
- package/dist/visual-embed-sdk-react-full.d.ts +164 -32
- package/dist/visual-embed-sdk-react.d.ts +164 -32
- package/dist/visual-embed-sdk.d.ts +61 -27
- package/lib/package.json +1 -1
- package/lib/src/embed/app.d.ts +1 -3
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +2 -8
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +1 -3
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +2 -8
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/sage.d.ts +1 -3
- package/lib/src/embed/sage.d.ts.map +1 -1
- package/lib/src/embed/sage.js +2 -8
- package/lib/src/embed/sage.js.map +1 -1
- package/lib/src/embed/search.d.ts +1 -4
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +2 -9
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +45 -15
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +112 -92
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +102 -0
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/react/all-types-export.d.ts +1 -1
- package/lib/src/react/all-types-export.d.ts.map +1 -1
- package/lib/src/react/all-types-export.js +1 -1
- package/lib/src/react/all-types-export.js.map +1 -1
- package/lib/src/react/index.d.ts +103 -5
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +80 -0
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +23 -1
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/types.d.ts +18 -0
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils.d.ts +27 -0
- package/lib/src/utils.d.ts.map +1 -1
- package/lib/src/utils.js +31 -0
- package/lib/src/utils.js.map +1 -1
- package/lib/src/utils.spec.d.ts +0 -3
- package/lib/src/utils.spec.d.ts.map +1 -1
- package/lib/src/utils.spec.js +60 -7
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +61 -27
- package/package.json +1 -1
- package/src/embed/app.ts +6 -11
- package/src/embed/liveboard.ts +2 -11
- package/src/embed/sage.ts +2 -11
- package/src/embed/search.ts +2 -12
- package/src/embed/ts-embed.spec.ts +127 -0
- package/src/embed/ts-embed.ts +139 -120
- package/src/react/all-types-export.ts +5 -1
- package/src/react/index.spec.tsx +42 -1
- package/src/react/index.tsx +120 -17
- package/src/types.ts +19 -0
- package/src/utils.spec.ts +78 -7
- package/src/utils.ts +29 -1
package/src/embed/sage.ts
CHANGED
|
@@ -168,22 +168,13 @@ export class SageEmbed extends V1Embed {
|
|
|
168
168
|
/**
|
|
169
169
|
* Render the embedded ThoughtSpot Sage
|
|
170
170
|
*
|
|
171
|
-
* @param showPreRenderByDefault
|
|
172
171
|
* @returns {SageEmbed} Eureka/Sage embed
|
|
173
172
|
*/
|
|
174
|
-
public render(
|
|
173
|
+
public render(): SageEmbed {
|
|
175
174
|
super.render();
|
|
176
175
|
|
|
177
176
|
const src = this.getIFrameSrc();
|
|
178
|
-
this.renderV1Embed(src
|
|
179
|
-
|
|
180
|
-
return this;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
public preRender(showPreRenderByDefault = false): SageEmbed {
|
|
184
|
-
super.preRender(showPreRenderByDefault);
|
|
185
|
-
|
|
186
|
-
this.render(showPreRenderByDefault);
|
|
177
|
+
this.renderV1Embed(src);
|
|
187
178
|
|
|
188
179
|
return this;
|
|
189
180
|
}
|
package/src/embed/search.ts
CHANGED
|
@@ -259,15 +259,13 @@ export class SearchEmbed extends TsEmbed {
|
|
|
259
259
|
|
|
260
260
|
/**
|
|
261
261
|
* Render the embedded ThoughtSpot search
|
|
262
|
-
*
|
|
263
|
-
* @param showPreRenderByDefault
|
|
264
262
|
*/
|
|
265
|
-
public render(
|
|
263
|
+
public render(): SearchEmbed {
|
|
266
264
|
super.render();
|
|
267
265
|
const { answerId } = this.viewConfig;
|
|
268
266
|
|
|
269
267
|
const src = this.getIFrameSrc(answerId);
|
|
270
|
-
this.renderIFrame(src
|
|
268
|
+
this.renderIFrame(src);
|
|
271
269
|
getAuthPromise().then(() => {
|
|
272
270
|
if (
|
|
273
271
|
checkReleaseVersionInBeta(
|
|
@@ -280,12 +278,4 @@ export class SearchEmbed extends TsEmbed {
|
|
|
280
278
|
});
|
|
281
279
|
return this;
|
|
282
280
|
}
|
|
283
|
-
|
|
284
|
-
public preRender(showPreRenderByDefault = false): SearchEmbed {
|
|
285
|
-
super.preRender();
|
|
286
|
-
|
|
287
|
-
this.render(showPreRenderByDefault);
|
|
288
|
-
|
|
289
|
-
return this;
|
|
290
|
-
}
|
|
291
281
|
}
|
|
@@ -1258,4 +1258,131 @@ describe('Unit test case for ts embed', () => {
|
|
|
1258
1258
|
});
|
|
1259
1259
|
});
|
|
1260
1260
|
});
|
|
1261
|
+
|
|
1262
|
+
describe('validate preRender flow', () => {
|
|
1263
|
+
beforeAll(() => {
|
|
1264
|
+
init({
|
|
1265
|
+
thoughtSpotHost: 'tshost',
|
|
1266
|
+
authType: AuthType.None,
|
|
1267
|
+
});
|
|
1268
|
+
});
|
|
1269
|
+
|
|
1270
|
+
afterAll(() => {
|
|
1271
|
+
const rootEle = document.getElementById('myRoot');
|
|
1272
|
+
rootEle.remove();
|
|
1273
|
+
});
|
|
1274
|
+
|
|
1275
|
+
const createRootEleForEmbed = () => {
|
|
1276
|
+
const rootEle = document.createElement('div');
|
|
1277
|
+
rootEle.id = 'myRoot';
|
|
1278
|
+
const tsEmbedDiv = document.createElement('div');
|
|
1279
|
+
tsEmbedDiv.id = 'tsEmbedDiv';
|
|
1280
|
+
rootEle.appendChild(tsEmbedDiv);
|
|
1281
|
+
document.body.appendChild(rootEle);
|
|
1282
|
+
};
|
|
1283
|
+
|
|
1284
|
+
it('should preRender and hide the iframe', async () => {
|
|
1285
|
+
createRootEleForEmbed();
|
|
1286
|
+
|
|
1287
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
1288
|
+
preRenderId: 'i-am-preRendered',
|
|
1289
|
+
liveboardId: 'myLiveboardId',
|
|
1290
|
+
});
|
|
1291
|
+
|
|
1292
|
+
libEmbed.preRender();
|
|
1293
|
+
|
|
1294
|
+
await waitFor(() => !!getIFrameEl());
|
|
1295
|
+
|
|
1296
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
1297
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
1298
|
+
expect(preRenderWrapper.style.opacity).toBe('0');
|
|
1299
|
+
expect(preRenderWrapper.style.pointerEvents).toBe('none');
|
|
1300
|
+
expect(preRenderWrapper.style.zIndex).toBe('-1000');
|
|
1301
|
+
|
|
1302
|
+
const preRenderChild = (document
|
|
1303
|
+
.getElementById(preRenderIds.child) as HTMLIFrameElement);
|
|
1304
|
+
expect(preRenderWrapper.children[0]).toEqual(preRenderChild);
|
|
1305
|
+
expect(preRenderChild).toBeInstanceOf(HTMLIFrameElement);
|
|
1306
|
+
expect(preRenderChild.src).toMatch(/^http:\/\/tshost.*\/myLiveboardId/);
|
|
1307
|
+
|
|
1308
|
+
const tsEmbedDiv = document.getElementById('tsEmbedDiv');
|
|
1309
|
+
tsEmbedDiv.style.width = '100px';
|
|
1310
|
+
tsEmbedDiv.style.height = '100px';
|
|
1311
|
+
|
|
1312
|
+
let resizeObserverCb: any;
|
|
1313
|
+
(window as any).ResizeObserver = window.ResizeObserver
|
|
1314
|
+
|| jest.fn().mockImplementation((resizeObserverCbParam) => {
|
|
1315
|
+
resizeObserverCb = resizeObserverCbParam;
|
|
1316
|
+
return ({
|
|
1317
|
+
disconnect: jest.fn(),
|
|
1318
|
+
observe: jest.fn(),
|
|
1319
|
+
unobserve: jest.fn(),
|
|
1320
|
+
});
|
|
1321
|
+
});
|
|
1322
|
+
|
|
1323
|
+
// show preRender
|
|
1324
|
+
libEmbed.showPreRender();
|
|
1325
|
+
|
|
1326
|
+
resizeObserverCb([{
|
|
1327
|
+
target: tsEmbedDiv,
|
|
1328
|
+
contentRect: { height: 297, width: 987 },
|
|
1329
|
+
}]);
|
|
1330
|
+
|
|
1331
|
+
expect(preRenderWrapper.style.height).toEqual(`${297}px`);
|
|
1332
|
+
expect(preRenderWrapper.style.width).toEqual(`${987}px`);
|
|
1333
|
+
|
|
1334
|
+
expect(preRenderWrapper.style.opacity).toBe('');
|
|
1335
|
+
expect(preRenderWrapper.style.pointerEvents).toBe('');
|
|
1336
|
+
expect(preRenderWrapper.style.zIndex).toBe('');
|
|
1337
|
+
|
|
1338
|
+
libEmbed.hidePreRender();
|
|
1339
|
+
expect(preRenderWrapper.style.opacity).toBe('0');
|
|
1340
|
+
expect(preRenderWrapper.style.pointerEvents).toBe('none');
|
|
1341
|
+
expect(preRenderWrapper.style.zIndex).toBe('-1000');
|
|
1342
|
+
|
|
1343
|
+
libEmbed.destroy();
|
|
1344
|
+
expect(document.getElementById(preRenderIds.wrapper)).toBe(null);
|
|
1345
|
+
});
|
|
1346
|
+
|
|
1347
|
+
it('preRender called without preRenderId should log error ', () => {
|
|
1348
|
+
createRootEleForEmbed();
|
|
1349
|
+
|
|
1350
|
+
spyOn(console, 'error');
|
|
1351
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
1352
|
+
liveboardId: 'myLiveboardId',
|
|
1353
|
+
});
|
|
1354
|
+
libEmbed.preRender();
|
|
1355
|
+
|
|
1356
|
+
expect(console.error).toHaveBeenCalledWith('PreRender id is required for preRender');
|
|
1357
|
+
});
|
|
1358
|
+
|
|
1359
|
+
it('showPreRender should preRender if not available', async () => {
|
|
1360
|
+
createRootEleForEmbed();
|
|
1361
|
+
|
|
1362
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
1363
|
+
preRenderId: 'i-am-preRendered',
|
|
1364
|
+
liveboardId: 'myLiveboardId',
|
|
1365
|
+
});
|
|
1366
|
+
const preRenderIds = libEmbed.getPreRenderIds();
|
|
1367
|
+
libEmbed.showPreRender();
|
|
1368
|
+
await waitFor(() => !!getIFrameEl());
|
|
1369
|
+
const preRenderWrapper = document.getElementById(preRenderIds.wrapper);
|
|
1370
|
+
|
|
1371
|
+
expect(preRenderWrapper.style.opacity).toBe('');
|
|
1372
|
+
expect(preRenderWrapper.style.pointerEvents).toBe('');
|
|
1373
|
+
expect(preRenderWrapper.style.zIndex).toBe('');
|
|
1374
|
+
});
|
|
1375
|
+
|
|
1376
|
+
it('hidePreRender should not preRender if not available', async () => {
|
|
1377
|
+
createRootEleForEmbed();
|
|
1378
|
+
|
|
1379
|
+
const libEmbed = new LiveboardEmbed('#tsEmbedDiv', {
|
|
1380
|
+
preRenderId: 'i-am-preRendered',
|
|
1381
|
+
liveboardId: 'myLiveboardId',
|
|
1382
|
+
});
|
|
1383
|
+
spyOn(libEmbed, 'preRender');
|
|
1384
|
+
libEmbed.hidePreRender();
|
|
1385
|
+
expect(libEmbed.preRender).toHaveBeenCalledTimes(0);
|
|
1386
|
+
});
|
|
1387
|
+
});
|
|
1261
1388
|
});
|
package/src/embed/ts-embed.ts
CHANGED
|
@@ -136,6 +136,11 @@ export class TsEmbed {
|
|
|
136
136
|
*/
|
|
137
137
|
private isError: boolean;
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* A flag that is set to true post preRender.
|
|
141
|
+
*/
|
|
142
|
+
private isPreRendered: boolean;
|
|
143
|
+
|
|
139
144
|
/**
|
|
140
145
|
* Should we encode URL Query Params using base64 encoding which thoughtspot
|
|
141
146
|
* will generate for embedding. This provides additional security to
|
|
@@ -147,6 +152,8 @@ export class TsEmbed {
|
|
|
147
152
|
|
|
148
153
|
private defaultHiddenActions = [Action.ReportError];
|
|
149
154
|
|
|
155
|
+
private resizeObserver: ResizeObserver;
|
|
156
|
+
|
|
150
157
|
constructor(domSelector: DOMSelector, viewConfig?: ViewConfig) {
|
|
151
158
|
this.el = getDOMNode(domSelector);
|
|
152
159
|
// TODO: handle error
|
|
@@ -377,7 +384,8 @@ export class TsEmbed {
|
|
|
377
384
|
queryParams[Param.ViewPortWidth] = window.innerWidth;
|
|
378
385
|
queryParams[Param.Version] = version;
|
|
379
386
|
queryParams[Param.AuthType] = this.embedConfig.authType;
|
|
380
|
-
queryParams[Param.blockNonEmbedFullAppAccess] = this.embedConfig.blockNonEmbedFullAppAccess
|
|
387
|
+
queryParams[Param.blockNonEmbedFullAppAccess] = this.embedConfig.blockNonEmbedFullAppAccess
|
|
388
|
+
?? true;
|
|
381
389
|
if (this.embedConfig.disableLoginRedirect === true || this.embedConfig.autoLogin === true) {
|
|
382
390
|
queryParams[Param.DisableLoginRedirect] = true;
|
|
383
391
|
}
|
|
@@ -454,7 +462,8 @@ export class TsEmbed {
|
|
|
454
462
|
queryParams[Param.ContextMenuTrigger] = false;
|
|
455
463
|
}
|
|
456
464
|
|
|
457
|
-
const spriteUrl = customizations?.iconSpriteUrl
|
|
465
|
+
const spriteUrl = customizations?.iconSpriteUrl
|
|
466
|
+
|| this.embedConfig.customizations?.iconSpriteUrl;
|
|
458
467
|
if (spriteUrl) {
|
|
459
468
|
queryParams[Param.IconSpriteUrl] = spriteUrl.replace('https://', '');
|
|
460
469
|
}
|
|
@@ -533,7 +542,9 @@ export class TsEmbed {
|
|
|
533
542
|
// @ts-ignore
|
|
534
543
|
iFrame.allow = 'clipboard-read; clipboard-write';
|
|
535
544
|
|
|
536
|
-
const {
|
|
545
|
+
const {
|
|
546
|
+
height: frameHeight, width: frameWidth, ...restParams
|
|
547
|
+
} = this.viewConfig.frameParams || {};
|
|
537
548
|
const width = getCssDimension(frameWidth || DEFAULT_EMBED_WIDTH);
|
|
538
549
|
const height = getCssDimension(frameHeight || DEFAULT_EMBED_HEIGHT);
|
|
539
550
|
setAttributes(iFrame, restParams);
|
|
@@ -545,12 +556,9 @@ export class TsEmbed {
|
|
|
545
556
|
return iFrame;
|
|
546
557
|
}
|
|
547
558
|
|
|
548
|
-
protected handleInsertionIntoDOM(child: string | Node
|
|
559
|
+
protected handleInsertionIntoDOM(child: string | Node): void {
|
|
549
560
|
if (this.isPreRendered) {
|
|
550
|
-
|
|
551
|
-
throw Error('PreRender id is required for preRender');
|
|
552
|
-
}
|
|
553
|
-
this.insertIntoDOMForPreRender(child, showPreRenderByDefault);
|
|
561
|
+
this.insertIntoDOMForPreRender(child);
|
|
554
562
|
} else {
|
|
555
563
|
this.insertIntoDOM(child);
|
|
556
564
|
}
|
|
@@ -561,9 +569,8 @@ export class TsEmbed {
|
|
|
561
569
|
* event listeners.
|
|
562
570
|
*
|
|
563
571
|
* @param url - The URL of the embedded ThoughtSpot app.
|
|
564
|
-
* @param showPreRenderByDefault - The flag to show the preRender by default.
|
|
565
572
|
*/
|
|
566
|
-
protected async renderIFrame(url: string
|
|
573
|
+
protected async renderIFrame(url: string): Promise<any> {
|
|
567
574
|
if (this.isError) {
|
|
568
575
|
return null;
|
|
569
576
|
}
|
|
@@ -588,10 +595,7 @@ export class TsEmbed {
|
|
|
588
595
|
return getAuthPromise()
|
|
589
596
|
?.then((isLoggedIn: boolean) => {
|
|
590
597
|
if (!isLoggedIn) {
|
|
591
|
-
this.handleInsertionIntoDOM(
|
|
592
|
-
this.embedConfig.loginFailedMessage,
|
|
593
|
-
showPreRenderByDefault,
|
|
594
|
-
);
|
|
598
|
+
this.handleInsertionIntoDOM(this.embedConfig.loginFailedMessage);
|
|
595
599
|
return;
|
|
596
600
|
}
|
|
597
601
|
|
|
@@ -614,7 +618,7 @@ export class TsEmbed {
|
|
|
614
618
|
this.iFrame.addEventListener('error', () => {
|
|
615
619
|
nextInQueue();
|
|
616
620
|
});
|
|
617
|
-
this.handleInsertionIntoDOM(this.iFrame
|
|
621
|
+
this.handleInsertionIntoDOM(this.iFrame);
|
|
618
622
|
const prefetchIframe = document.querySelectorAll('.prefetchIframe');
|
|
619
623
|
if (prefetchIframe.length) {
|
|
620
624
|
prefetchIframe.forEach((el) => {
|
|
@@ -634,15 +638,6 @@ export class TsEmbed {
|
|
|
634
638
|
});
|
|
635
639
|
}
|
|
636
640
|
|
|
637
|
-
public getPreRenderIds() {
|
|
638
|
-
return {
|
|
639
|
-
wrapper: `tsEmbed-pre-render-wrapper-${this.viewConfig.preRenderId}`,
|
|
640
|
-
// shield:
|
|
641
|
-
// `tsEmbed-pre-render-shield-${this.viewConfig.preRenderId}`,
|
|
642
|
-
child: `tsEmbed-pre-render-child-${this.viewConfig.preRenderId}`,
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
|
|
646
641
|
protected createPreRenderWrapper(): HTMLDivElement {
|
|
647
642
|
if (!this.viewConfig.preRenderId) {
|
|
648
643
|
throw new Error('PreRender id is required to create PreRender wrapper');
|
|
@@ -661,32 +656,18 @@ export class TsEmbed {
|
|
|
661
656
|
};
|
|
662
657
|
setStyleProperties(preRenderWrapper, initialPreRenderWrapperStyle);
|
|
663
658
|
|
|
664
|
-
// const preRenderShield = document.createElement('div');
|
|
665
|
-
// preRenderShield.id = preRenderIds.shield;
|
|
666
|
-
// setStyleProperties(preRenderShield, { position: 'absolute',
|
|
667
|
-
// width: '100%', height: '100%' });
|
|
668
|
-
|
|
669
|
-
// preRenderWrapper.appendChild(preRenderShield);
|
|
670
|
-
|
|
671
|
-
// this.preRenderWrapper = preRenderWrapper;
|
|
672
|
-
// this.preRenderShield = preRenderShield;
|
|
673
|
-
// this.preRenderChild = child;
|
|
674
|
-
|
|
675
659
|
return preRenderWrapper;
|
|
676
660
|
}
|
|
677
661
|
|
|
678
662
|
protected preRenderWrapper: HTMLElement;
|
|
679
663
|
|
|
680
|
-
// protected preRenderShield: HTMLElement;
|
|
681
|
-
|
|
682
664
|
protected preRenderChild: HTMLElement;
|
|
683
665
|
|
|
684
666
|
protected connectPreRendered(): boolean {
|
|
685
667
|
const preRenderIds = this.getPreRenderIds();
|
|
686
668
|
this.preRenderWrapper = this.preRenderWrapper
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
// || document.getElementById(preRenderIds.shield);
|
|
669
|
+
|| document.getElementById(preRenderIds.wrapper);
|
|
670
|
+
|
|
690
671
|
this.preRenderChild = this.preRenderChild || document.getElementById(preRenderIds.child);
|
|
691
672
|
|
|
692
673
|
if (this.preRenderWrapper && this.preRenderChild) {
|
|
@@ -698,7 +679,7 @@ export class TsEmbed {
|
|
|
698
679
|
}
|
|
699
680
|
|
|
700
681
|
protected isPreRenderAvailable(): boolean {
|
|
701
|
-
return this.isPreRendered;
|
|
682
|
+
return this.isPreRendered && Boolean(this.preRenderWrapper && this.preRenderChild);
|
|
702
683
|
}
|
|
703
684
|
|
|
704
685
|
protected createPreRenderChild(child: string | Node): HTMLElement {
|
|
@@ -724,10 +705,7 @@ export class TsEmbed {
|
|
|
724
705
|
return divChildNode;
|
|
725
706
|
}
|
|
726
707
|
|
|
727
|
-
protected insertIntoDOMForPreRender(
|
|
728
|
-
child: string | Node,
|
|
729
|
-
showPreRenderByDefault = false,
|
|
730
|
-
): void {
|
|
708
|
+
protected insertIntoDOMForPreRender(child: string | Node): void {
|
|
731
709
|
const preRenderChild = this.createPreRenderChild(child);
|
|
732
710
|
const preRenderWrapper = this.createPreRenderWrapper();
|
|
733
711
|
preRenderWrapper.appendChild(preRenderChild);
|
|
@@ -739,83 +717,17 @@ export class TsEmbed {
|
|
|
739
717
|
this.iFrame = preRenderChild;
|
|
740
718
|
}
|
|
741
719
|
|
|
742
|
-
if (showPreRenderByDefault) {
|
|
720
|
+
if (this.showPreRenderByDefault) {
|
|
743
721
|
this.showPreRender();
|
|
744
722
|
} else {
|
|
745
723
|
this.hidePreRender();
|
|
746
724
|
}
|
|
747
725
|
|
|
726
|
+
this.insertedDomEl = preRenderWrapper;
|
|
748
727
|
document.body.appendChild(preRenderWrapper);
|
|
749
728
|
}
|
|
750
729
|
|
|
751
|
-
|
|
752
|
-
if (!this.isPreRenderAvailable()) {
|
|
753
|
-
// if the embed component is not preRendered , nothing to hide
|
|
754
|
-
console.warn(
|
|
755
|
-
'Warning: You should call PreRender before hiding it using hidePreRender.',
|
|
756
|
-
);
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
const preRenderHideStyles = {
|
|
760
|
-
opacity: '0',
|
|
761
|
-
pointerEvents: 'none',
|
|
762
|
-
zIndex: '-1000',
|
|
763
|
-
position: 'absolute ',
|
|
764
|
-
top: '0',
|
|
765
|
-
left: '0',
|
|
766
|
-
};
|
|
767
|
-
setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
|
|
768
|
-
|
|
769
|
-
// const childBoundingRect = this.preRenderChild.getBoundingClientRect();
|
|
770
|
-
//
|
|
771
|
-
// setStyleProperties(this.preRenderShield, {
|
|
772
|
-
// opacity: '0',
|
|
773
|
-
// pointerEvents: 'none',
|
|
774
|
-
// zIndex: '1',
|
|
775
|
-
// width: `${childBoundingRect.width}px`,
|
|
776
|
-
// height: `${childBoundingRect.height}px`,
|
|
777
|
-
// position: 'absolute',
|
|
778
|
-
// top: '0',
|
|
779
|
-
// left: '0',
|
|
780
|
-
// });
|
|
781
|
-
|
|
782
|
-
this.unsubscribeToEvents();
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
public showPreRender(): void {
|
|
786
|
-
if (!this.isPreRenderAvailable()) {
|
|
787
|
-
const isAvailable = this.connectPreRendered();
|
|
788
|
-
if (!isAvailable) {
|
|
789
|
-
// if the Embed component is not preRendered , Render it now and
|
|
790
|
-
this.preRender(true);
|
|
791
|
-
// show it (hide is defalt behaviour)
|
|
792
|
-
// console.log('No preRender found, creating new ');
|
|
793
|
-
return;
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
this.syncPreRenderStyle();
|
|
798
|
-
|
|
799
|
-
removeStyleProperties(this.preRenderWrapper, ['z-index', 'opacity', 'pointer-events']);
|
|
800
|
-
|
|
801
|
-
// setStyleProperties(this.preRenderShield, { zIndex: '-1' });
|
|
802
|
-
|
|
803
|
-
this.subscribeToEvents();
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
public syncPreRenderStyle(): void {
|
|
807
|
-
if (!this.el) {
|
|
808
|
-
throw new Error('Embed element is not defined');
|
|
809
|
-
}
|
|
810
|
-
const elBoundingClient = this.el.getBoundingClientRect();
|
|
811
|
-
|
|
812
|
-
setStyleProperties(this.preRenderWrapper, {
|
|
813
|
-
top: `${elBoundingClient.y}px`,
|
|
814
|
-
left: `${elBoundingClient.x}px`,
|
|
815
|
-
width: `${elBoundingClient.width}px`,
|
|
816
|
-
height: `${elBoundingClient.height}px`,
|
|
817
|
-
});
|
|
818
|
-
}
|
|
730
|
+
private showPreRenderByDefault = false;
|
|
819
731
|
|
|
820
732
|
protected insertIntoDOM(child: string | Node): void {
|
|
821
733
|
if (this.viewConfig.insertAsSibling) {
|
|
@@ -1048,15 +960,19 @@ export class TsEmbed {
|
|
|
1048
960
|
return this;
|
|
1049
961
|
}
|
|
1050
962
|
|
|
1051
|
-
private isPreRendered: boolean;
|
|
1052
|
-
|
|
1053
963
|
/**
|
|
1054
964
|
* Creates the preRender shell
|
|
1055
965
|
*
|
|
1056
|
-
* @param showPreRenderByDefault
|
|
966
|
+
* @param showPreRenderByDefault - Show the preRender after render, hidden by default
|
|
1057
967
|
*/
|
|
1058
968
|
public preRender(showPreRenderByDefault = false): TsEmbed {
|
|
969
|
+
if (!this.viewConfig.preRenderId) {
|
|
970
|
+
console.error('PreRender id is required for preRender');
|
|
971
|
+
return this;
|
|
972
|
+
}
|
|
1059
973
|
this.isPreRendered = true;
|
|
974
|
+
this.showPreRenderByDefault = showPreRenderByDefault;
|
|
975
|
+
this.render();
|
|
1060
976
|
return this;
|
|
1061
977
|
}
|
|
1062
978
|
|
|
@@ -1120,6 +1036,110 @@ export class TsEmbed {
|
|
|
1120
1036
|
const prerenderFrameSrc = this.getRootIframeSrc();
|
|
1121
1037
|
return this.renderIFrame(prerenderFrameSrc);
|
|
1122
1038
|
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Displays the PreRender component.
|
|
1042
|
+
* If the component is not preRendered, it attempts to create and render it.
|
|
1043
|
+
* Also, synchronizes the style of the PreRender component with the embedding
|
|
1044
|
+
* element.
|
|
1045
|
+
*/
|
|
1046
|
+
public showPreRender(): void {
|
|
1047
|
+
if (!this.isPreRenderAvailable()) {
|
|
1048
|
+
const isAvailable = this.connectPreRendered();
|
|
1049
|
+
if (!isAvailable) {
|
|
1050
|
+
// if the Embed component is not preRendered , Render it now and
|
|
1051
|
+
this.preRender(true);
|
|
1052
|
+
return;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
if (this.el) {
|
|
1057
|
+
this.syncPreRenderStyle();
|
|
1058
|
+
|
|
1059
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
1060
|
+
entries.forEach((entry) => {
|
|
1061
|
+
if (entry.contentRect && entry.target === this.el) {
|
|
1062
|
+
setStyleProperties(this.preRenderWrapper, {
|
|
1063
|
+
width: `${entry.contentRect.width}px`,
|
|
1064
|
+
height: `${entry.contentRect.height}px`,
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
});
|
|
1068
|
+
});
|
|
1069
|
+
this.resizeObserver.observe(this.el);
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
removeStyleProperties(this.preRenderWrapper, ['z-index', 'opacity', 'pointer-events']);
|
|
1073
|
+
|
|
1074
|
+
this.subscribeToEvents();
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
/**
|
|
1078
|
+
* Synchronizes the style properties of the PreRender component with the embedding
|
|
1079
|
+
* element. This function adjusts the position, width, and height of the PreRender
|
|
1080
|
+
* component
|
|
1081
|
+
* to match the dimensions and position of the embedding element.
|
|
1082
|
+
*
|
|
1083
|
+
* @throws {Error} Throws an error if the embedding element (passed as domSelector)
|
|
1084
|
+
* is not defined or not found.
|
|
1085
|
+
*/
|
|
1086
|
+
public syncPreRenderStyle(): void {
|
|
1087
|
+
if (!this.el) {
|
|
1088
|
+
throw new Error('Embed element is not defined');
|
|
1089
|
+
}
|
|
1090
|
+
const elBoundingClient = this.el.getBoundingClientRect();
|
|
1091
|
+
|
|
1092
|
+
setStyleProperties(this.preRenderWrapper, {
|
|
1093
|
+
top: `${elBoundingClient.y}px`,
|
|
1094
|
+
left: `${elBoundingClient.x}px`,
|
|
1095
|
+
width: `${elBoundingClient.width}px`,
|
|
1096
|
+
height: `${elBoundingClient.height}px`,
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/**
|
|
1101
|
+
* Hides the PreRender component if it is available.
|
|
1102
|
+
* If the component is not preRendered, it issues a warning.
|
|
1103
|
+
*/
|
|
1104
|
+
public hidePreRender(): void {
|
|
1105
|
+
if (!this.isPreRenderAvailable()) {
|
|
1106
|
+
// if the embed component is not preRendered , nothing to hide
|
|
1107
|
+
console.warn(
|
|
1108
|
+
'Warning: You should call PreRender before hiding it using hidePreRender.',
|
|
1109
|
+
);
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
1112
|
+
const preRenderHideStyles = {
|
|
1113
|
+
opacity: '0',
|
|
1114
|
+
pointerEvents: 'none',
|
|
1115
|
+
zIndex: '-1000',
|
|
1116
|
+
position: 'absolute ',
|
|
1117
|
+
top: '0',
|
|
1118
|
+
left: '0',
|
|
1119
|
+
};
|
|
1120
|
+
setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
|
|
1121
|
+
|
|
1122
|
+
if (this.resizeObserver) {
|
|
1123
|
+
this.resizeObserver.disconnect();
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
this.unsubscribeToEvents();
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/**
|
|
1130
|
+
* Retrieves unique HTML element IDs for PreRender-related elements.
|
|
1131
|
+
* These IDs are constructed based on the provided 'preRenderId' from 'viewConfig'.
|
|
1132
|
+
*
|
|
1133
|
+
* @returns {object} An object containing the IDs for the PreRender elements.
|
|
1134
|
+
* @property {string} wrapper - The HTML element ID for the PreRender wrapper.
|
|
1135
|
+
* @property {string} child - The HTML element ID for the PreRender child.
|
|
1136
|
+
*/
|
|
1137
|
+
public getPreRenderIds() {
|
|
1138
|
+
return {
|
|
1139
|
+
wrapper: `tsEmbed-pre-render-wrapper-${this.viewConfig.preRenderId}`,
|
|
1140
|
+
child: `tsEmbed-pre-render-child-${this.viewConfig.preRenderId}`,
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1123
1143
|
}
|
|
1124
1144
|
|
|
1125
1145
|
/**
|
|
@@ -1141,10 +1161,9 @@ export class V1Embed extends TsEmbed {
|
|
|
1141
1161
|
* Render the app in an iframe and set up event handlers
|
|
1142
1162
|
*
|
|
1143
1163
|
* @param iframeSrc
|
|
1144
|
-
* @param showPreRenderByDefault - if true the preRender will be shown by default
|
|
1145
1164
|
*/
|
|
1146
|
-
protected renderV1Embed(iframeSrc: string
|
|
1147
|
-
return this.renderIFrame(iframeSrc
|
|
1165
|
+
protected renderV1Embed(iframeSrc: string): Promise<any> {
|
|
1166
|
+
return this.renderIFrame(iframeSrc);
|
|
1148
1167
|
}
|
|
1149
1168
|
|
|
1150
1169
|
protected getRootIframeSrc(): string {
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
export {
|
|
2
2
|
SearchEmbed,
|
|
3
|
+
PreRenderedSearchEmbed,
|
|
3
4
|
LiveboardEmbed,
|
|
5
|
+
PreRenderedLiveboardEmbed,
|
|
4
6
|
SearchBarEmbed,
|
|
7
|
+
PreRenderedSearchBarEmbed,
|
|
5
8
|
AppEmbed,
|
|
9
|
+
PreRenderedAppEmbed,
|
|
6
10
|
SageEmbed,
|
|
11
|
+
PreRenderedSageEmbed,
|
|
7
12
|
useEmbedRef,
|
|
8
|
-
PreRenderedLiveboardEmbed,
|
|
9
13
|
} from './index';
|
|
10
14
|
|
|
11
15
|
export {
|
package/src/react/index.spec.tsx
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
mockMessageChannel,
|
|
16
16
|
} from '../test/test-utils';
|
|
17
17
|
import {
|
|
18
|
-
SearchEmbed, AppEmbed, LiveboardEmbed, useEmbedRef, SearchBarEmbed,
|
|
18
|
+
SearchEmbed, AppEmbed, LiveboardEmbed, useEmbedRef, SearchBarEmbed, PreRenderedLiveboardEmbed,
|
|
19
19
|
} from './index';
|
|
20
20
|
import * as allExports from './index';
|
|
21
21
|
import {
|
|
@@ -226,6 +226,47 @@ describe('React Components', () => {
|
|
|
226
226
|
);
|
|
227
227
|
});
|
|
228
228
|
});
|
|
229
|
+
|
|
230
|
+
describe('PreRenderedLiveboardEmbed', () => {
|
|
231
|
+
it('should preRender the liveboard ', async () => {
|
|
232
|
+
const preRenderId = 'tsEmbed-pre-render-wrapper-test';
|
|
233
|
+
|
|
234
|
+
const { container } = render(
|
|
235
|
+
<PreRenderedLiveboardEmbed
|
|
236
|
+
className="embedClass"
|
|
237
|
+
preRenderId="test"
|
|
238
|
+
liveboardId="libId"
|
|
239
|
+
/>,
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
await waitFor(() => getIFrameEl());
|
|
243
|
+
const preRenderWrapper = document.body.querySelector(`#${preRenderId}`) as HTMLDivElement;
|
|
244
|
+
|
|
245
|
+
expect(preRenderWrapper).toBeInstanceOf(HTMLDivElement);
|
|
246
|
+
expect((preRenderWrapper as HTMLDivElement).childElementCount).toBe(1);
|
|
247
|
+
|
|
248
|
+
const preRenderChildId = 'tsEmbed-pre-render-child-test';
|
|
249
|
+
const preRenderChild = document.body.querySelector(`#${preRenderChildId}`);
|
|
250
|
+
expect(preRenderWrapper.children[0]).toBe(preRenderChild);
|
|
251
|
+
|
|
252
|
+
(window as any).ResizeObserver = jest.fn().mockImplementation(() => ({
|
|
253
|
+
disconnect: jest.fn(),
|
|
254
|
+
observe: jest.fn(),
|
|
255
|
+
unobserve: jest.fn(),
|
|
256
|
+
}));
|
|
257
|
+
const { container: libContainer } = render(
|
|
258
|
+
<LiveboardEmbed
|
|
259
|
+
className="embedClass"
|
|
260
|
+
preRenderId="test"
|
|
261
|
+
liveboardId="libId"
|
|
262
|
+
/>,
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
expect(preRenderWrapper.style.opacity).toBe('');
|
|
266
|
+
expect(preRenderWrapper.style.pointerEvents).toBe('');
|
|
267
|
+
expect(preRenderWrapper.style.zIndex).toBe('');
|
|
268
|
+
});
|
|
269
|
+
});
|
|
229
270
|
});
|
|
230
271
|
|
|
231
272
|
describe('allExports', () => {
|