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