@thoughtspot/visual-embed-sdk 1.39.1 → 1.39.2-alpha.2
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/config.spec.js +9 -0
- package/cjs/src/config.spec.js.map +1 -1
- package/cjs/src/embed/app.d.ts +75 -15
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +69 -9
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +374 -12
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.d.ts +19 -7
- package/cjs/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/cjs/src/embed/bodyless-conversation.js +24 -4
- package/cjs/src/embed/bodyless-conversation.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.spec.js +8 -190
- package/cjs/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +28 -0
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/embedConfig.d.ts +9 -7
- package/cjs/src/embed/embedConfig.d.ts.map +1 -1
- package/cjs/src/embed/embedConfig.js +9 -7
- package/cjs/src/embed/embedConfig.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +56 -17
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +48 -4
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +215 -11
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +5 -0
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +16 -1
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +164 -0
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/errors.d.ts +1 -0
- package/cjs/src/errors.d.ts.map +1 -1
- package/cjs/src/errors.js +1 -0
- package/cjs/src/errors.js.map +1 -1
- package/cjs/src/index.d.ts +2 -2
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +2 -1
- package/cjs/src/index.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 +3 -2
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/react/index.d.ts +71 -20
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +79 -42
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/react/index.spec.js +436 -100
- package/cjs/src/react/index.spec.js.map +1 -1
- package/cjs/src/types.d.ts +80 -6
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +45 -1
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
- package/cjs/src/utils/graphql/nlsService/conversation-service.js +2 -0
- package/cjs/src/utils/graphql/nlsService/conversation-service.js.map +1 -1
- package/cjs/src/utils/processTrigger.js +2 -1
- package/cjs/src/utils/processTrigger.js.map +1 -1
- package/cjs/src/utils.d.ts +6 -0
- package/cjs/src/utils.d.ts.map +1 -1
- package/cjs/src/utils.js +23 -3
- package/cjs/src/utils.js.map +1 -1
- package/cjs/src/utils.spec.js +237 -1
- package/cjs/src/utils.spec.js.map +1 -1
- package/dist/{index-JaFaxrvQ.js → index-CmEQfuE3.js} +1 -1
- package/dist/index-DeFzsyFF.js +7371 -0
- package/dist/index-Dpf0rd6w.js +7371 -0
- package/dist/index-UuEbsISo.js +7447 -0
- package/dist/index-e3Uw3YFO.js +7371 -0
- package/dist/src/embed/app.d.ts +75 -15
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/bodyless-conversation.d.ts +19 -7
- package/dist/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/dist/src/embed/embedConfig.d.ts +9 -7
- package/dist/src/embed/embedConfig.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +56 -17
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +5 -0
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/errors.d.ts +1 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.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 +71 -20
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +80 -6
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
- package/dist/src/utils.d.ts +6 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +320 -78
- package/dist/tsembed-react.js +320 -76
- package/dist/tsembed.es.js +238 -31
- package/dist/tsembed.js +236 -29
- package/dist/visual-embed-sdk-react-full.d.ts +288 -72
- package/dist/visual-embed-sdk-react.d.ts +288 -72
- package/dist/visual-embed-sdk.d.ts +218 -53
- package/lib/package.json +1 -1
- package/lib/src/config.spec.js +9 -0
- package/lib/src/config.spec.js.map +1 -1
- package/lib/src/embed/app.d.ts +75 -15
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +69 -9
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +376 -14
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.d.ts +19 -7
- package/lib/src/embed/bodyless-conversation.d.ts.map +1 -1
- package/lib/src/embed/bodyless-conversation.js +23 -4
- package/lib/src/embed/bodyless-conversation.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.spec.js +9 -191
- package/lib/src/embed/bodyless-conversation.spec.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +30 -2
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/embedConfig.d.ts +9 -7
- package/lib/src/embed/embedConfig.d.ts.map +1 -1
- package/lib/src/embed/embedConfig.js +9 -7
- package/lib/src/embed/embedConfig.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +56 -17
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +49 -5
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +215 -11
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +5 -0
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +16 -1
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +164 -0
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/errors.d.ts +1 -0
- package/lib/src/errors.d.ts.map +1 -1
- package/lib/src/errors.js +1 -0
- package/lib/src/errors.js.map +1 -1
- package/lib/src/index.d.ts +2 -2
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -2
- package/lib/src/index.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 +71 -20
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +79 -43
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/react/index.spec.js +439 -103
- package/lib/src/react/index.spec.js.map +1 -1
- package/lib/src/types.d.ts +80 -6
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +45 -1
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/graphql/nlsService/conversation-service.d.ts.map +1 -1
- package/lib/src/utils/graphql/nlsService/conversation-service.js +2 -0
- package/lib/src/utils/graphql/nlsService/conversation-service.js.map +1 -1
- package/lib/src/utils/processTrigger.js +2 -1
- package/lib/src/utils/processTrigger.js.map +1 -1
- package/lib/src/utils.d.ts +6 -0
- package/lib/src/utils.d.ts.map +1 -1
- package/lib/src/utils.js +21 -2
- package/lib/src/utils.js.map +1 -1
- package/lib/src/utils.spec.js +238 -2
- package/lib/src/utils.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +219 -54
- package/package.json +1 -1
- package/src/config.spec.ts +11 -0
- package/src/embed/app.spec.ts +479 -26
- package/src/embed/app.ts +133 -27
- package/src/embed/bodyless-conversation.spec.ts +9 -203
- package/src/embed/bodyless-conversation.ts +24 -10
- package/src/embed/conversation.spec.ts +40 -2
- package/src/embed/embedConfig.ts +10 -8
- package/src/embed/liveboard.spec.ts +256 -5
- package/src/embed/liveboard.ts +99 -27
- package/src/embed/ts-embed.spec.ts +225 -0
- package/src/embed/ts-embed.ts +19 -0
- package/src/errors.ts +1 -0
- package/src/index.ts +2 -0
- package/src/react/all-types-export.ts +2 -1
- package/src/react/index.spec.tsx +556 -157
- package/src/react/index.tsx +117 -51
- package/src/types.ts +117 -43
- package/src/utils/graphql/nlsService/conversation-service.ts +2 -0
- package/src/utils/processTrigger.ts +1 -1
- package/src/utils.spec.ts +279 -2
- package/src/utils.ts +28 -2
package/src/embed/embedConfig.ts
CHANGED
|
@@ -10,13 +10,14 @@ const configKey = 'embedConfig';
|
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
12
|
* ```js
|
|
13
|
+
* import { getInitConfig } from '@thoughtspot/visual-embed-sdk';
|
|
14
|
+
* // Call the getInitConfig method to retrieve the embed configuration
|
|
13
15
|
* const config = getInitConfig();
|
|
16
|
+
* // Log the configuration settings
|
|
14
17
|
* console.log(config);
|
|
15
18
|
* ```
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* Returns the `EmbedConfig` object, which
|
|
19
|
-
* contains the configuration settings used to
|
|
19
|
+
* Returns the link:https://developers.thoughtspot.com/docs/Interface_EmbedConfig[EmbedConfig]
|
|
20
|
+
* object, which contains the configuration settings used to
|
|
20
21
|
* initialize the SDK, including the following:
|
|
21
22
|
*
|
|
22
23
|
* - `thoughtSpotHost` - ThoughtSpot host URL
|
|
@@ -24,10 +25,11 @@ const configKey = 'embedConfig';
|
|
|
24
25
|
* `AuthServerCookieless` for `AuthType.TrustedAuthTokenCookieless`
|
|
25
26
|
* - `customizations` - Style, text, and icon customization settings
|
|
26
27
|
* that were applied during the SDK initialization.
|
|
27
|
-
*
|
|
28
|
-
* For a comprehensive list of embed configuration settings,
|
|
29
|
-
* see link:https://developers.thoughtspot.com/docs/Interface_EmbedConfig[Developer Documentation].
|
|
30
28
|
*
|
|
29
|
+
* The following JSON output shows the embed configuration
|
|
30
|
+
* settings returned from the code in the previous example:
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
31
33
|
* ```json
|
|
32
34
|
* {
|
|
33
35
|
* "thoughtSpotHost": "https://{ThoughtSpot-Host}",
|
|
@@ -49,7 +51,7 @@ const configKey = 'embedConfig';
|
|
|
49
51
|
* "authTriggerContainer": "#your-own-div"
|
|
50
52
|
* }
|
|
51
53
|
* ```
|
|
52
|
-
* @version SDK: 1.19.0 | ThoughtSpot: 9.0.0.cl, 9.0.1.
|
|
54
|
+
* @version SDK: 1.19.0 | ThoughtSpot: 9.0.0.cl, 9.0.1.sw, and later
|
|
53
55
|
* @group Global methods
|
|
54
56
|
*/
|
|
55
57
|
export const getEmbedConfig = (): EmbedConfig => getValueFromWindow(configKey) || ({} as any);
|
|
@@ -347,7 +347,7 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
347
347
|
await executeAfterWait(() => {
|
|
348
348
|
expectUrlMatchesWithParams(
|
|
349
349
|
getIFrameSrc(),
|
|
350
|
-
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&
|
|
350
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&arePdfCoverFilterPageCheckboxesEnabled=true${prefixParams}#/embed/viz/${liveboardId}`,
|
|
351
351
|
);
|
|
352
352
|
});
|
|
353
353
|
});
|
|
@@ -362,7 +362,7 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
362
362
|
await executeAfterWait(() => {
|
|
363
363
|
expectUrlMatchesWithParams(
|
|
364
364
|
getIFrameSrc(),
|
|
365
|
-
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&
|
|
365
|
+
`http://${thoughtSpotHost}/?embedApp=true${defaultParams}&arePdfCoverFilterPageCheckboxesEnabled=false&${prefixParams}#/embed/viz/${liveboardId}`,
|
|
366
366
|
);
|
|
367
367
|
});
|
|
368
368
|
});
|
|
@@ -770,8 +770,9 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
770
770
|
});
|
|
771
771
|
|
|
772
772
|
let resizeObserverCb: any;
|
|
773
|
-
(window as any).ResizeObserver =
|
|
774
|
-
|
|
773
|
+
(window as any).ResizeObserver =
|
|
774
|
+
window.ResizeObserver ||
|
|
775
|
+
jest.fn().mockImplementation((resizeObserverCbParam: any) => {
|
|
775
776
|
resizeObserverCb = resizeObserverCbParam;
|
|
776
777
|
return {
|
|
777
778
|
disconnect: jest.fn(),
|
|
@@ -785,7 +786,7 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
785
786
|
await waitFor(() => !!getIFrameEl());
|
|
786
787
|
|
|
787
788
|
const ts = '__tsEmbed';
|
|
788
|
-
expect(document.getElementById(libEmbed.getPreRenderIds().wrapper)[ts]).toEqual(
|
|
789
|
+
expect((document.getElementById(libEmbed.getPreRenderIds().wrapper) as any)[ts]).toEqual(
|
|
789
790
|
libEmbed,
|
|
790
791
|
);
|
|
791
792
|
|
|
@@ -813,6 +814,256 @@ describe('Liveboard/viz embed tests', () => {
|
|
|
813
814
|
});
|
|
814
815
|
});
|
|
815
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
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('resize', expect.anything());
|
|
1000
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('scroll', expect.anything());
|
|
1001
|
+
|
|
1002
|
+
addEventListenerSpy.mockRestore();
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
test('should remove window event listeners on destroy when fullHeight and lazyLoadingForFullHeight are enabled', async () => {
|
|
1006
|
+
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
|
|
1007
|
+
|
|
1008
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1009
|
+
...defaultViewConfig,
|
|
1010
|
+
liveboardId,
|
|
1011
|
+
fullHeight: true,
|
|
1012
|
+
lazyLoadingForFullHeight: true,
|
|
1013
|
+
} as LiveboardViewConfig);
|
|
1014
|
+
|
|
1015
|
+
await liveboardEmbed.render();
|
|
1016
|
+
liveboardEmbed.destroy();
|
|
1017
|
+
|
|
1018
|
+
expect(removeEventListenerSpy).toHaveBeenCalledWith('resize', expect.anything());
|
|
1019
|
+
expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', expect.anything());
|
|
1020
|
+
|
|
1021
|
+
removeEventListenerSpy.mockRestore();
|
|
1022
|
+
});
|
|
1023
|
+
|
|
1024
|
+
test('should handle RequestVisibleEmbedCoordinates event and respond with correct data', async () => {
|
|
1025
|
+
// Mock the iframe element
|
|
1026
|
+
mockIFrame.getBoundingClientRect = jest.fn().mockReturnValue({
|
|
1027
|
+
top: 100,
|
|
1028
|
+
left: 150,
|
|
1029
|
+
bottom: 600,
|
|
1030
|
+
right: 800,
|
|
1031
|
+
width: 650,
|
|
1032
|
+
height: 500,
|
|
1033
|
+
});
|
|
1034
|
+
Object.defineProperty(mockIFrame, 'scrollHeight', { value: 500 });
|
|
1035
|
+
|
|
1036
|
+
const liveboardEmbed = new LiveboardEmbed(getRootEl(), {
|
|
1037
|
+
...defaultViewConfig,
|
|
1038
|
+
liveboardId,
|
|
1039
|
+
fullHeight: true,
|
|
1040
|
+
lazyLoadingForFullHeight: true,
|
|
1041
|
+
} as LiveboardViewConfig);
|
|
1042
|
+
|
|
1043
|
+
// Set the iframe before render
|
|
1044
|
+
(liveboardEmbed as any).iFrame = mockIFrame;
|
|
1045
|
+
|
|
1046
|
+
await liveboardEmbed.render();
|
|
1047
|
+
|
|
1048
|
+
// Create a mock responder function
|
|
1049
|
+
const mockResponder = jest.fn();
|
|
1050
|
+
|
|
1051
|
+
// Trigger the handler directly
|
|
1052
|
+
(liveboardEmbed as any).requestVisibleEmbedCoordinatesHandler({}, mockResponder);
|
|
1053
|
+
|
|
1054
|
+
// Verify the responder was called with the correct data
|
|
1055
|
+
expect(mockResponder).toHaveBeenCalledWith({
|
|
1056
|
+
type: EmbedEvent.RequestVisibleEmbedCoordinates,
|
|
1057
|
+
data: {
|
|
1058
|
+
top: 0,
|
|
1059
|
+
height: 500,
|
|
1060
|
+
left: 0,
|
|
1061
|
+
width: 650,
|
|
1062
|
+
},
|
|
1063
|
+
});
|
|
1064
|
+
});
|
|
1065
|
+
});
|
|
1066
|
+
|
|
816
1067
|
describe('Host events for liveborad', () => {
|
|
817
1068
|
test('Host event with empty param', async () => {
|
|
818
1069
|
const mockProcessTrigger = jest.spyOn(tsEmbed.TsEmbed.prototype, 'trigger');
|
package/src/embed/liveboard.ts
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
BaseViewConfig,
|
|
22
22
|
LiveboardAppEmbedViewConfig,
|
|
23
23
|
} from '../types';
|
|
24
|
-
import { getQueryParamString, isUndefined } from '../utils';
|
|
24
|
+
import { calculateVisibleElementData, getQueryParamString, isUndefined } from '../utils';
|
|
25
25
|
import { getAuthPromise } from './base';
|
|
26
26
|
import { TsEmbed, V1Embed } from './ts-embed';
|
|
27
27
|
import { addPreviewStylesIfNotPresent } from '../utils/global-styles';
|
|
@@ -269,24 +269,6 @@ export interface LiveboardViewConfig extends BaseViewConfig, LiveboardOtherViewC
|
|
|
269
269
|
* })
|
|
270
270
|
*/
|
|
271
271
|
dataSourceId?: string;
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* This flag is for show/hide checkboxes for include or exclude
|
|
275
|
-
* cover page and filters in the Liveboard PDF.
|
|
276
|
-
*
|
|
277
|
-
* Supported embed types: `LiveboardEmbed`
|
|
278
|
-
* @version SDK: 1.37.0 | ThoughtSpot:10.8.0.cl
|
|
279
|
-
* @default true
|
|
280
|
-
* Supported embed types: `LiveboardEmbed`
|
|
281
|
-
* @example
|
|
282
|
-
* ```js
|
|
283
|
-
* const embed = new LiveboardEmbed('#tsEmbed', {
|
|
284
|
-
* ... //other embed view config
|
|
285
|
-
* coverAndFilterOptionInPDF: false,
|
|
286
|
-
* })
|
|
287
|
-
* ```
|
|
288
|
-
*/
|
|
289
|
-
coverAndFilterOptionInPDF?: boolean;
|
|
290
272
|
/**
|
|
291
273
|
* The list of tab IDs to hide from the embedded.
|
|
292
274
|
* This Tabs will be hidden from their respective LBs.
|
|
@@ -342,6 +324,47 @@ export interface LiveboardViewConfig extends BaseViewConfig, LiveboardOtherViewC
|
|
|
342
324
|
* ```
|
|
343
325
|
*/
|
|
344
326
|
isLiveboardStylingAndGroupingEnabled?: boolean;
|
|
327
|
+
/**
|
|
328
|
+
* This flag is used to enable the full height lazy load data.
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```js
|
|
332
|
+
* const embed = new LiveboardEmbed('#embed-container', {
|
|
333
|
+
* // ...other options
|
|
334
|
+
* fullHeight: true,
|
|
335
|
+
* lazyLoadingForFullHeight: true,
|
|
336
|
+
* })
|
|
337
|
+
* ```
|
|
338
|
+
*
|
|
339
|
+
* @type {boolean}
|
|
340
|
+
* @default false
|
|
341
|
+
* @version SDK: 1.39.0 | ThoughtSpot:10.10.0.cl
|
|
342
|
+
*/
|
|
343
|
+
lazyLoadingForFullHeight?: boolean;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* The margin to be used for lazy loading.
|
|
347
|
+
*
|
|
348
|
+
* For example, if the margin is set to '10px',
|
|
349
|
+
* the visualization will be loaded 10px before the its top edge is visible in the
|
|
350
|
+
* viewport.
|
|
351
|
+
*
|
|
352
|
+
* The format is similar to CSS margin.
|
|
353
|
+
*
|
|
354
|
+
* @example
|
|
355
|
+
* ```js
|
|
356
|
+
* const embed = new LiveboardEmbed('#embed-container', {
|
|
357
|
+
* // ...other options
|
|
358
|
+
* fullHeight: true,
|
|
359
|
+
* lazyLoadingForFullHeight: true,
|
|
360
|
+
* // Using 0px, the visualization will be only loaded when its visible in the viewport.
|
|
361
|
+
* lazyLoadingMargin: '0px',
|
|
362
|
+
* })
|
|
363
|
+
* ```
|
|
364
|
+
* @type {string}
|
|
365
|
+
* @version SDK: 1.39.0 | ThoughtSpot:10.10.0.cl
|
|
366
|
+
*/
|
|
367
|
+
lazyLoadingMargin?: string;
|
|
345
368
|
}
|
|
346
369
|
|
|
347
370
|
/**
|
|
@@ -364,19 +387,20 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
364
387
|
|
|
365
388
|
private defaultHeight = 500;
|
|
366
389
|
|
|
367
|
-
|
|
390
|
+
|
|
368
391
|
constructor(domSelector: DOMSelector, viewConfig: LiveboardViewConfig) {
|
|
369
392
|
viewConfig.embedComponentType = 'LiveboardEmbed';
|
|
370
393
|
super(domSelector, viewConfig);
|
|
371
394
|
if (this.viewConfig.fullHeight === true) {
|
|
372
395
|
if (this.viewConfig.vizId) {
|
|
373
396
|
logger.warn('Full height is currently only supported for Liveboard embeds.' +
|
|
374
|
-
|
|
397
|
+
'Using full height with vizId might lead to unexpected behavior.');
|
|
375
398
|
}
|
|
376
399
|
|
|
377
400
|
this.on(EmbedEvent.RouteChange, this.setIframeHeightForNonEmbedLiveboard);
|
|
378
401
|
this.on(EmbedEvent.EmbedHeight, this.updateIFrameHeight);
|
|
379
402
|
this.on(EmbedEvent.EmbedIframeCenter, this.embedIframeCenter);
|
|
403
|
+
this.on(EmbedEvent.RequestVisibleEmbedCoordinates, this.requestVisibleEmbedCoordinatesHandler);
|
|
380
404
|
}
|
|
381
405
|
}
|
|
382
406
|
|
|
@@ -385,7 +409,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
385
409
|
* embedded Liveboard or visualization.
|
|
386
410
|
*/
|
|
387
411
|
protected getEmbedParams() {
|
|
388
|
-
let params = {};
|
|
412
|
+
let params: any = {};
|
|
389
413
|
params = this.getBaseQueryParams(params);
|
|
390
414
|
const {
|
|
391
415
|
enableVizTransformations,
|
|
@@ -411,7 +435,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
411
435
|
oAuthPollingInterval,
|
|
412
436
|
isForceRedirect,
|
|
413
437
|
dataSourceId,
|
|
414
|
-
coverAndFilterOptionInPDF,
|
|
438
|
+
coverAndFilterOptionInPDF = false,
|
|
415
439
|
isLiveboardStylingAndGroupingEnabled,
|
|
416
440
|
} = this.viewConfig;
|
|
417
441
|
|
|
@@ -420,6 +444,10 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
420
444
|
|
|
421
445
|
if (fullHeight === true) {
|
|
422
446
|
params[Param.fullHeight] = true;
|
|
447
|
+
if (this.viewConfig.lazyLoadingForFullHeight) {
|
|
448
|
+
params[Param.IsLazyLoadingForEmbedEnabled] = true;
|
|
449
|
+
params[Param.RootMarginForLazyLoad] = this.viewConfig.lazyLoadingMargin;
|
|
450
|
+
}
|
|
423
451
|
}
|
|
424
452
|
if (defaultHeight) {
|
|
425
453
|
this.defaultHeight = defaultHeight;
|
|
@@ -471,9 +499,6 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
471
499
|
params[Param.DataSourceId] = dataSourceId;
|
|
472
500
|
}
|
|
473
501
|
|
|
474
|
-
if (coverAndFilterOptionInPDF !== undefined) {
|
|
475
|
-
params[Param.CoverAndFilterOptionInPDF] = coverAndFilterOptionInPDF;
|
|
476
|
-
}
|
|
477
502
|
|
|
478
503
|
if (isLiveboardStylingAndGroupingEnabled !== undefined) {
|
|
479
504
|
params[Param.IsLiveboardStylingAndGroupingEnabled] = isLiveboardStylingAndGroupingEnabled;
|
|
@@ -486,6 +511,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
486
511
|
params[Param.HideIrrelevantFiltersInTab] = hideIrrelevantChipsInLiveboardTabs;
|
|
487
512
|
params[Param.DataPanelV2Enabled] = dataPanelV2;
|
|
488
513
|
params[Param.EnableCustomColumnGroups] = enableCustomColumnGroups;
|
|
514
|
+
params[Param.CoverAndFilterOptionInPDF] = coverAndFilterOptionInPDF;
|
|
489
515
|
const queryParams = getQueryParamString(params, true);
|
|
490
516
|
|
|
491
517
|
return queryParams;
|
|
@@ -504,6 +530,23 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
504
530
|
return suffix;
|
|
505
531
|
}
|
|
506
532
|
|
|
533
|
+
private sendFullHeightLazyLoadData = () => {
|
|
534
|
+
const data = calculateVisibleElementData(this.iFrame);
|
|
535
|
+
this.trigger(HostEvent.VisibleEmbedCoordinates, data);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* This is a handler for the RequestVisibleEmbedCoordinates event.
|
|
540
|
+
* It is used to send the visible coordinates data to the host application.
|
|
541
|
+
* @param data The event payload
|
|
542
|
+
* @param responder The responder function
|
|
543
|
+
*/
|
|
544
|
+
private requestVisibleEmbedCoordinatesHandler = (data: MessagePayload, responder: any) => {
|
|
545
|
+
logger.info('Sending RequestVisibleEmbedCoordinates', data);
|
|
546
|
+
const visibleCoordinatesData = calculateVisibleElementData(this.iFrame);
|
|
547
|
+
responder({ type: EmbedEvent.RequestVisibleEmbedCoordinates, data: visibleCoordinatesData });
|
|
548
|
+
}
|
|
549
|
+
|
|
507
550
|
/**
|
|
508
551
|
* Construct the URL of the embedded ThoughtSpot Liveboard or visualization
|
|
509
552
|
* to be loaded within the iFrame.
|
|
@@ -529,6 +572,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
529
572
|
*/
|
|
530
573
|
private updateIFrameHeight = (data: MessagePayload) => {
|
|
531
574
|
this.setIFrameHeight(Math.max(data.data, this.defaultHeight));
|
|
575
|
+
this.sendFullHeightLazyLoadData();
|
|
532
576
|
};
|
|
533
577
|
|
|
534
578
|
private embedIframeCenter = (data: MessagePayload, responder: any) => {
|
|
@@ -602,7 +646,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
602
646
|
}
|
|
603
647
|
|
|
604
648
|
protected beforePrerenderVisible(): void {
|
|
605
|
-
const embedObj = this.insertedDomEl?.[this.embedNodeKey] as LiveboardEmbed;
|
|
649
|
+
const embedObj = (this.insertedDomEl as any)?.[this.embedNodeKey] as LiveboardEmbed;
|
|
606
650
|
|
|
607
651
|
if (isUndefined(embedObj)) return;
|
|
608
652
|
|
|
@@ -642,6 +686,33 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
642
686
|
}
|
|
643
687
|
return super.trigger(messageType, dataWithVizId);
|
|
644
688
|
}
|
|
689
|
+
/**
|
|
690
|
+
* Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
|
|
691
|
+
* @version SDK: 1.39.0 | ThoughtSpot: 10.10.0.cl
|
|
692
|
+
*/
|
|
693
|
+
public destroy() {
|
|
694
|
+
super.destroy();
|
|
695
|
+
this.unregisterLazyLoadEvents();
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
private postRender() {
|
|
699
|
+
this.registerLazyLoadEvents();
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
private registerLazyLoadEvents() {
|
|
703
|
+
if (this.viewConfig.fullHeight && this.viewConfig.lazyLoadingForFullHeight) {
|
|
704
|
+
// TODO: Use passive: true, install modernizr to check for passive
|
|
705
|
+
window.addEventListener('resize', this.sendFullHeightLazyLoadData);
|
|
706
|
+
window.addEventListener('scroll', this.sendFullHeightLazyLoadData);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
private unregisterLazyLoadEvents() {
|
|
711
|
+
if (this.viewConfig.fullHeight && this.viewConfig.lazyLoadingForFullHeight) {
|
|
712
|
+
window.removeEventListener('resize', this.sendFullHeightLazyLoadData);
|
|
713
|
+
window.removeEventListener('scroll', this.sendFullHeightLazyLoadData);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
645
716
|
|
|
646
717
|
/**
|
|
647
718
|
* Render an embedded ThoughtSpot Liveboard or visualization
|
|
@@ -655,6 +726,7 @@ export class LiveboardEmbed extends V1Embed {
|
|
|
655
726
|
await this.renderV1Embed(src);
|
|
656
727
|
this.showPreviewLoader();
|
|
657
728
|
|
|
729
|
+
this.postRender();
|
|
658
730
|
return this;
|
|
659
731
|
}
|
|
660
732
|
|