@thoughtspot/visual-embed-sdk 1.24.0-dev → 1.24.0-preRender.1
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 +2 -3
- package/cjs/src/embed/TsEmbed.d.ts +302 -0
- package/cjs/src/embed/TsEmbed.d.ts.map +1 -0
- package/cjs/src/embed/TsEmbed.js +851 -0
- package/cjs/src/embed/TsEmbed.js.map +1 -0
- package/cjs/src/embed/app.d.ts +4 -1
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +9 -2
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/base.d.ts +2 -0
- package/cjs/src/embed/base.d.ts.map +1 -1
- package/cjs/src/embed/base.js +2 -0
- package/cjs/src/embed/base.js.map +1 -1
- package/cjs/src/embed/liveboard.d.ts +3 -2
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +6 -5
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/sage.d.ts +4 -1
- package/cjs/src/embed/sage.d.ts.map +1 -1
- package/cjs/src/embed/sage.js +9 -2
- package/cjs/src/embed/sage.js.map +1 -1
- package/cjs/src/embed/search-bar.d.ts +1 -0
- package/cjs/src/embed/search-bar.d.ts.map +1 -1
- package/cjs/src/embed/search-bar.js +1 -0
- package/cjs/src/embed/search-bar.js.map +1 -1
- package/cjs/src/embed/search.d.ts +5 -1
- package/cjs/src/embed/search.d.ts.map +1 -1
- package/cjs/src/embed/search.js +10 -2
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +14 -7
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +94 -63
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +47 -0
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/index.d.ts +3 -2
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +3 -1
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/mixpanel-service.d.ts.map +1 -1
- package/cjs/src/mixpanel-service.js +2 -0
- package/cjs/src/mixpanel-service.js.map +1 -1
- package/cjs/src/mixpanel-service.spec.js +1 -0
- package/cjs/src/mixpanel-service.spec.js.map +1 -1
- package/cjs/src/react/index.d.ts +5 -1
- package/cjs/src/react/index.d.ts.map +1 -1
- package/cjs/src/react/index.js +8 -8
- package/cjs/src/react/index.js.map +1 -1
- package/cjs/src/types.d.ts +60 -19
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +7 -13
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/graphql/answerService/answer-queries.d.ts +5 -0
- package/cjs/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -0
- package/cjs/src/utils/graphql/answerService/answer-queries.js +80 -0
- package/cjs/src/utils/graphql/answerService/answer-queries.js.map +1 -0
- package/cjs/src/utils/graphql/answerService/answerService.d.ts +61 -0
- package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -0
- package/cjs/src/utils/graphql/answerService/answerService.js +182 -0
- package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -0
- package/cjs/src/utils/graphql/answerService/answerService.spec.d.ts +2 -0
- package/cjs/src/utils/graphql/answerService/answerService.spec.d.ts.map +1 -0
- package/cjs/src/utils/graphql/answerService/answerService.spec.js +201 -0
- package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -0
- package/cjs/src/utils/graphql/graphql-request.d.ts +15 -0
- package/cjs/src/utils/graphql/graphql-request.d.ts.map +1 -0
- package/cjs/src/utils/graphql/graphql-request.js +40 -0
- package/cjs/src/utils/graphql/graphql-request.js.map +1 -0
- package/cjs/src/utils/graphql/sourceService.d.ts +8 -0
- package/cjs/src/utils/graphql/sourceService.d.ts.map +1 -0
- package/cjs/src/utils/graphql/sourceService.js +69 -0
- package/cjs/src/utils/graphql/sourceService.js.map +1 -0
- package/cjs/src/utils/graphql/sourceService.spec.d.ts +2 -0
- package/cjs/src/utils/graphql/sourceService.spec.d.ts.map +1 -0
- package/cjs/src/utils/graphql/sourceService.spec.js +12 -0
- package/cjs/src/utils/graphql/sourceService.spec.js.map +1 -0
- package/cjs/src/utils/processData.d.ts.map +1 -1
- package/cjs/src/utils/processData.js +7 -11
- package/cjs/src/utils/processData.js.map +1 -1
- package/cjs/src/utils/processData.spec.js +13 -17
- package/cjs/src/utils/processData.spec.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 +26 -1
- package/cjs/src/utils.js.map +1 -1
- package/dist/src/embed/app.d.ts +4 -1
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/base.d.ts +2 -0
- package/dist/src/embed/base.d.ts.map +1 -1
- package/dist/src/embed/liveboard.d.ts +3 -2
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/sage.d.ts +4 -1
- package/dist/src/embed/sage.d.ts.map +1 -1
- package/dist/src/embed/search-bar.d.ts +1 -0
- package/dist/src/embed/search-bar.d.ts.map +1 -1
- package/dist/src/embed/search.d.ts +5 -1
- package/dist/src/embed/search.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +14 -7
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/mixpanel-service.d.ts.map +1 -1
- package/dist/src/react/index.d.ts +5 -1
- package/dist/src/react/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +60 -19
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/graphql/answerService/answer-queries.d.ts +5 -0
- package/dist/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -0
- package/dist/src/utils/graphql/answerService/answerService.d.ts +61 -0
- package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -0
- package/dist/src/utils/graphql/answerService/answerService.spec.d.ts +2 -0
- package/dist/src/utils/graphql/answerService/answerService.spec.d.ts.map +1 -0
- package/dist/src/utils/graphql/graphql-request.d.ts +15 -0
- package/dist/src/utils/graphql/graphql-request.d.ts.map +1 -0
- package/dist/src/utils/graphql/sourceService.d.ts +8 -0
- package/dist/src/utils/graphql/sourceService.d.ts.map +1 -0
- package/dist/src/utils/graphql/sourceService.spec.d.ts +2 -0
- package/dist/src/utils/graphql/sourceService.spec.d.ts.map +1 -0
- package/dist/src/utils/processData.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 +513 -150
- package/dist/tsembed-react.js +516 -149
- package/dist/tsembed.es.js +556 -146
- package/dist/tsembed.js +556 -145
- package/dist/visual-embed-sdk-react-full.d.ts +152 -33
- package/dist/visual-embed-sdk-react.d.ts +152 -33
- package/dist/visual-embed-sdk.d.ts +147 -32
- package/lib/package.json +2 -3
- package/lib/src/embed/TsEmbed.d.ts +302 -0
- package/lib/src/embed/TsEmbed.d.ts.map +1 -0
- package/lib/src/embed/TsEmbed.js +847 -0
- package/lib/src/embed/TsEmbed.js.map +1 -0
- package/lib/src/embed/app.d.ts +4 -1
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +9 -2
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/base.d.ts +2 -0
- package/lib/src/embed/base.d.ts.map +1 -1
- package/lib/src/embed/base.js +2 -0
- package/lib/src/embed/base.js.map +1 -1
- package/lib/src/embed/liveboard.d.ts +3 -2
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +6 -5
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/sage.d.ts +4 -1
- package/lib/src/embed/sage.d.ts.map +1 -1
- package/lib/src/embed/sage.js +9 -2
- package/lib/src/embed/sage.js.map +1 -1
- package/lib/src/embed/search-bar.d.ts +1 -0
- package/lib/src/embed/search-bar.d.ts.map +1 -1
- package/lib/src/embed/search-bar.js +1 -0
- package/lib/src/embed/search-bar.js.map +1 -1
- package/lib/src/embed/search.d.ts +5 -1
- package/lib/src/embed/search.d.ts.map +1 -1
- package/lib/src/embed/search.js +10 -2
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +14 -7
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +94 -63
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +47 -0
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/index.d.ts +3 -2
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +2 -1
- package/lib/src/index.js.map +1 -1
- package/lib/src/mixpanel-service.d.ts.map +1 -1
- package/lib/src/mixpanel-service.js +2 -0
- package/lib/src/mixpanel-service.js.map +1 -1
- package/lib/src/mixpanel-service.spec.js +1 -0
- package/lib/src/mixpanel-service.spec.js.map +1 -1
- package/lib/src/react/index.d.ts +5 -1
- package/lib/src/react/index.d.ts.map +1 -1
- package/lib/src/react/index.js +7 -7
- package/lib/src/react/index.js.map +1 -1
- package/lib/src/types.d.ts +60 -19
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +6 -12
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/graphql/answerService/answer-queries.d.ts +5 -0
- package/lib/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -0
- package/lib/src/utils/graphql/answerService/answer-queries.js +77 -0
- package/lib/src/utils/graphql/answerService/answer-queries.js.map +1 -0
- package/lib/src/utils/graphql/answerService/answerService.d.ts +61 -0
- package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -0
- package/lib/src/utils/graphql/answerService/answerService.js +177 -0
- package/lib/src/utils/graphql/answerService/answerService.js.map +1 -0
- package/lib/src/utils/graphql/answerService/answerService.spec.d.ts +2 -0
- package/lib/src/utils/graphql/answerService/answerService.spec.d.ts.map +1 -0
- package/lib/src/utils/graphql/answerService/answerService.spec.js +199 -0
- package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -0
- package/lib/src/utils/graphql/graphql-request.d.ts +15 -0
- package/lib/src/utils/graphql/graphql-request.d.ts.map +1 -0
- package/lib/src/utils/graphql/graphql-request.js +36 -0
- package/lib/src/utils/graphql/graphql-request.js.map +1 -0
- package/lib/src/utils/graphql/sourceService.d.ts +8 -0
- package/lib/src/utils/graphql/sourceService.d.ts.map +1 -0
- package/lib/src/utils/graphql/sourceService.js +65 -0
- package/lib/src/utils/graphql/sourceService.js.map +1 -0
- package/lib/src/utils/graphql/sourceService.spec.d.ts +2 -0
- package/lib/src/utils/graphql/sourceService.spec.d.ts.map +1 -0
- package/lib/src/utils/graphql/sourceService.spec.js +10 -0
- package/lib/src/utils/graphql/sourceService.spec.js.map +1 -0
- package/lib/src/utils/processData.d.ts.map +1 -1
- package/lib/src/utils/processData.js +8 -12
- package/lib/src/utils/processData.js.map +1 -1
- package/lib/src/utils/processData.spec.js +14 -18
- package/lib/src/utils/processData.spec.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 +23 -0
- package/lib/src/utils.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +153 -33
- package/package.json +2 -3
- package/src/embed/app.ts +13 -6
- package/src/embed/base.ts +2 -0
- package/src/embed/liveboard.ts +7 -5
- package/src/embed/sage.ts +13 -2
- package/src/embed/search-bar.tsx +2 -0
- package/src/embed/search.ts +14 -2
- package/src/embed/ts-embed.spec.ts +49 -0
- package/src/embed/ts-embed.ts +116 -64
- package/src/index.ts +5 -0
- package/src/mixpanel-service.spec.ts +1 -0
- package/src/mixpanel-service.ts +1 -0
- package/src/react/index.tsx +50 -45
- package/src/types.ts +64 -21
- package/src/utils/graphql/answerService/answer-queries.ts +80 -0
- package/src/utils/graphql/answerService/answerService.spec.ts +231 -0
- package/src/utils/graphql/answerService/answerService.ts +234 -0
- package/src/utils/graphql/graphql-request.ts +45 -0
- package/src/utils/graphql/sourceService.spec.ts +10 -0
- package/src/utils/graphql/sourceService.ts +71 -0
- package/src/utils/processData.spec.ts +15 -25
- package/src/utils/processData.ts +13 -15
- package/src/utils.ts +24 -0
- package/src/utils/answerService.spec.ts +0 -41
- package/src/utils/answerService.ts +0 -63
package/src/types.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { CustomCssVariables } from './css-variables';
|
|
11
|
+
import type { SessionInterface } from './utils/graphql/answerService/answerService';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* The authentication mechanism for allowing access to the
|
|
@@ -532,7 +533,7 @@ export interface EmbedConfig {
|
|
|
532
533
|
}
|
|
533
534
|
|
|
534
535
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
535
|
-
export interface LayoutConfig {}
|
|
536
|
+
export interface LayoutConfig { }
|
|
536
537
|
|
|
537
538
|
/**
|
|
538
539
|
* Embedded iFrame configuration
|
|
@@ -756,6 +757,13 @@ export interface ViewConfig {
|
|
|
756
757
|
* @version SDK: 1.27.0 | Thoughtspot: 9.8.0.cl
|
|
757
758
|
*/
|
|
758
759
|
hiddenHomepageModules?: HomepageModule[];
|
|
760
|
+
/**
|
|
761
|
+
* reordering the home page modules
|
|
762
|
+
* eg: reorderedHomepageModules = [HomepageModule.MyLibrary, HomepageModule.Watchlist]
|
|
763
|
+
*
|
|
764
|
+
* @version SDK: 1.28.0 | Thoughtspot: 9.9.0.cl
|
|
765
|
+
*/
|
|
766
|
+
reorderedHomepageModules?: HomepageModule[];
|
|
759
767
|
/**
|
|
760
768
|
* The list of tab IDs to show in the embedded.
|
|
761
769
|
* Only this Tabs will be shown in their respective LBs.
|
|
@@ -785,9 +793,20 @@ export interface ViewConfig {
|
|
|
785
793
|
*/
|
|
786
794
|
hiddenHomeLeftNavItems?: HomeLeftNavItem[];
|
|
787
795
|
/**
|
|
788
|
-
*
|
|
796
|
+
* PreRender id to be used for PreRendering the embed.
|
|
797
|
+
* Use PreRender to render the embed in the background and then
|
|
798
|
+
* show or hide the rendered embed using showPreRender or hidePreRender respectively.
|
|
799
|
+
*
|
|
800
|
+
* @example
|
|
801
|
+
* ```js
|
|
802
|
+
* const embed = new LiveboardEmbed('#embed', {
|
|
803
|
+
* ... // other liveboard view config
|
|
804
|
+
* preRenderId: "preRenderId-123"
|
|
805
|
+
* });
|
|
806
|
+
* embed.showPreRender();
|
|
807
|
+
* ```
|
|
808
|
+
* @version SDK: 1.25.0 | Thoughtspot: 9.6.0.cl
|
|
789
809
|
*/
|
|
790
|
-
|
|
791
810
|
preRenderId?: string;
|
|
792
811
|
}
|
|
793
812
|
|
|
@@ -921,27 +940,27 @@ export enum HomepageModule {
|
|
|
921
940
|
/**
|
|
922
941
|
* Search bar
|
|
923
942
|
*/
|
|
924
|
-
Search = '
|
|
943
|
+
Search = 'SEARCH',
|
|
925
944
|
/**
|
|
926
945
|
* kPI watchlist module
|
|
927
946
|
*/
|
|
928
|
-
Watchlist = '
|
|
947
|
+
Watchlist = 'WATCHLIST',
|
|
929
948
|
/**
|
|
930
949
|
* favorite objects
|
|
931
950
|
*/
|
|
932
|
-
Favorite = '
|
|
951
|
+
Favorite = 'FAVORITE',
|
|
933
952
|
/**
|
|
934
953
|
* List of answers and liveboards
|
|
935
954
|
*/
|
|
936
|
-
MyLibrary = '
|
|
955
|
+
MyLibrary = 'MY_LIBRARY',
|
|
937
956
|
/**
|
|
938
957
|
* Trending list
|
|
939
958
|
*/
|
|
940
|
-
Trending = '
|
|
959
|
+
Trending = 'TRENDING',
|
|
941
960
|
/**
|
|
942
961
|
* Learning videos
|
|
943
962
|
*/
|
|
944
|
-
Learning = '
|
|
963
|
+
Learning = 'LEARNING',
|
|
945
964
|
}
|
|
946
965
|
|
|
947
966
|
/**
|
|
@@ -3126,18 +3145,6 @@ export enum Action {
|
|
|
3126
3145
|
PersonalisedViewsDropdown = 'personalisedViewsDropdown',
|
|
3127
3146
|
}
|
|
3128
3147
|
|
|
3129
|
-
export interface SessionInterface {
|
|
3130
|
-
sessionId: string;
|
|
3131
|
-
genNo: number;
|
|
3132
|
-
acSession: { sessionId: string; genNo: number };
|
|
3133
|
-
}
|
|
3134
|
-
|
|
3135
|
-
// eslint-disable-next-line no-shadow
|
|
3136
|
-
export enum OperationType {
|
|
3137
|
-
GetChartWithData = 'GetChartWithData',
|
|
3138
|
-
GetTableWithHeadlineData = 'GetTableWithHeadlineData',
|
|
3139
|
-
}
|
|
3140
|
-
|
|
3141
3148
|
export interface AnswerServiceType {
|
|
3142
3149
|
getAnswer?: (offset: number, batchSize: number) => any;
|
|
3143
3150
|
}
|
|
@@ -3156,3 +3163,39 @@ export enum ContextMenuTriggerOptions {
|
|
|
3156
3163
|
LEFT_CLICK = 'left-click',
|
|
3157
3164
|
RIGHT_CLICK = 'right-click',
|
|
3158
3165
|
}
|
|
3166
|
+
|
|
3167
|
+
export interface ColumnValue {
|
|
3168
|
+
column: {
|
|
3169
|
+
id: string,
|
|
3170
|
+
name: string,
|
|
3171
|
+
dataType: string,
|
|
3172
|
+
[key: string]: any
|
|
3173
|
+
},
|
|
3174
|
+
value: string | number | boolean;
|
|
3175
|
+
}
|
|
3176
|
+
|
|
3177
|
+
export interface VizPoint {
|
|
3178
|
+
selectedAttributes: ColumnValue[],
|
|
3179
|
+
selectedMeasures: ColumnValue[]
|
|
3180
|
+
}
|
|
3181
|
+
|
|
3182
|
+
export interface CustomActionPayload {
|
|
3183
|
+
contextMenuPoints?: {
|
|
3184
|
+
clickedPoint: VizPoint
|
|
3185
|
+
selectedPoints: VizPoint[]
|
|
3186
|
+
};
|
|
3187
|
+
embedAnswerData: {
|
|
3188
|
+
name: string,
|
|
3189
|
+
id: string,
|
|
3190
|
+
sources: {
|
|
3191
|
+
header: {
|
|
3192
|
+
guid: string
|
|
3193
|
+
}
|
|
3194
|
+
},
|
|
3195
|
+
columns: any[],
|
|
3196
|
+
data: any[],
|
|
3197
|
+
[key: string]: any
|
|
3198
|
+
};
|
|
3199
|
+
session: SessionInterface;
|
|
3200
|
+
vizId?: string;
|
|
3201
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const bachSessionId = `
|
|
2
|
+
id {
|
|
3
|
+
sessionId
|
|
4
|
+
genNo
|
|
5
|
+
acSession {
|
|
6
|
+
sessionId
|
|
7
|
+
genNo
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
export const getUnaggregatedAnswerSession = `
|
|
13
|
+
mutation GetUnAggregatedAnswerSession($session: BachSessionIdInput!, $columns: [UserPointSelectionInput!]!) {
|
|
14
|
+
Answer__getUnaggregatedAnswer(session: $session, columns: $columns) {
|
|
15
|
+
${bachSessionId}
|
|
16
|
+
answer {
|
|
17
|
+
visualizations {
|
|
18
|
+
... on TableViz {
|
|
19
|
+
columns {
|
|
20
|
+
column {
|
|
21
|
+
id
|
|
22
|
+
name
|
|
23
|
+
referencedColumns {
|
|
24
|
+
guid
|
|
25
|
+
displayName
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
export const removeColumns = `
|
|
37
|
+
mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!], $columnIds: [GUID!]) {
|
|
38
|
+
Answer__removeColumns(
|
|
39
|
+
session: $session
|
|
40
|
+
logicalColumnIds: $logicalColumnIds
|
|
41
|
+
columnIds: $columnIds
|
|
42
|
+
) {
|
|
43
|
+
${bachSessionId}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
export const addColumns = `
|
|
49
|
+
mutation AddColumns($session: BachSessionIdInput!, $columns: [AnswerColumnInfo!]!) {
|
|
50
|
+
Answer__addColumn(session: $session, columns: $columns) {
|
|
51
|
+
${bachSessionId}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
export const getAnswerData = `
|
|
57
|
+
query GetTableWithHeadlineData($session: BachSessionIdInput!, $deadline: Int!, $dataPaginationParams: DataPaginationParamsInput!) {
|
|
58
|
+
getAnswer(session: $session) {
|
|
59
|
+
${bachSessionId}
|
|
60
|
+
answer {
|
|
61
|
+
id
|
|
62
|
+
visualizations {
|
|
63
|
+
id
|
|
64
|
+
... on TableViz {
|
|
65
|
+
columns {
|
|
66
|
+
column {
|
|
67
|
+
id
|
|
68
|
+
name
|
|
69
|
+
type
|
|
70
|
+
aggregationType
|
|
71
|
+
dataType
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
data(deadline: $deadline, pagination: $dataPaginationParams)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
`;
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import 'jest-fetch-mock';
|
|
2
|
+
import { VizPoint } from 'src/types';
|
|
3
|
+
import { AnswerService } from './answerService';
|
|
4
|
+
import { getAnswerData, removeColumns } from './answer-queries';
|
|
5
|
+
|
|
6
|
+
const defaultSession = {
|
|
7
|
+
sessionId: 'id',
|
|
8
|
+
genNo: 1,
|
|
9
|
+
acSession: {
|
|
10
|
+
sessionId: 'ac',
|
|
11
|
+
genNo: 0,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param answer
|
|
17
|
+
* @param point
|
|
18
|
+
*/
|
|
19
|
+
function createAnswerService(answer = {}, point?: VizPoint[]) {
|
|
20
|
+
return new AnswerService(
|
|
21
|
+
defaultSession,
|
|
22
|
+
answer,
|
|
23
|
+
'https://tshost',
|
|
24
|
+
point,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('Answer service tests', () => {
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
fetchMock.resetMocks();
|
|
31
|
+
});
|
|
32
|
+
test('Execute query should execute the supplied graphql on the session', async () => {
|
|
33
|
+
fetchMock.mockResponseOnce(JSON.stringify({
|
|
34
|
+
data: {
|
|
35
|
+
Bla: {
|
|
36
|
+
id: {},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
}));
|
|
40
|
+
const answerService = createAnswerService();
|
|
41
|
+
answerService.executeQuery(
|
|
42
|
+
'query Bla {}',
|
|
43
|
+
{ a: 1 },
|
|
44
|
+
);
|
|
45
|
+
expect(fetchMock).toBeCalledWith('https://tshost/prism/?op=Bla', expect.objectContaining({
|
|
46
|
+
body: JSON.stringify({
|
|
47
|
+
operationName: 'Bla',
|
|
48
|
+
query: 'query Bla {}',
|
|
49
|
+
variables: {
|
|
50
|
+
session: defaultSession,
|
|
51
|
+
a: 1,
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
54
|
+
}));
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('Should return error when failure', async () => {
|
|
58
|
+
fetchMock.mockRejectOnce(new Error('testError'));
|
|
59
|
+
const answerService = createAnswerService();
|
|
60
|
+
const data = await answerService.executeQuery(
|
|
61
|
+
'query Bla {}',
|
|
62
|
+
{ a: 1 },
|
|
63
|
+
);
|
|
64
|
+
expect(data.message).toBe('testError');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('fetchData should call the right graphql, and return data', async () => {
|
|
68
|
+
fetchMock.mockResponseOnce(JSON.stringify({
|
|
69
|
+
data: {
|
|
70
|
+
getAnswer: {
|
|
71
|
+
id: {},
|
|
72
|
+
answer: {
|
|
73
|
+
visualizations: [{
|
|
74
|
+
columns: [{
|
|
75
|
+
column: {
|
|
76
|
+
id: 'id1',
|
|
77
|
+
},
|
|
78
|
+
}],
|
|
79
|
+
data: {
|
|
80
|
+
foo: 1,
|
|
81
|
+
},
|
|
82
|
+
}],
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
}));
|
|
87
|
+
const answerService = createAnswerService();
|
|
88
|
+
const data = await answerService.fetchData(20, 10);
|
|
89
|
+
expect(fetchMock).toHaveBeenCalledWith(
|
|
90
|
+
'https://tshost/prism/?op=GetTableWithHeadlineData',
|
|
91
|
+
expect.objectContaining({
|
|
92
|
+
body: JSON.stringify({
|
|
93
|
+
operationName: 'GetTableWithHeadlineData',
|
|
94
|
+
query: getAnswerData,
|
|
95
|
+
variables: {
|
|
96
|
+
session: defaultSession,
|
|
97
|
+
deadline: 0,
|
|
98
|
+
dataPaginationParams: {
|
|
99
|
+
isClientPaginated: true,
|
|
100
|
+
offset: 20,
|
|
101
|
+
size: 10,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
}),
|
|
105
|
+
}),
|
|
106
|
+
);
|
|
107
|
+
expect(data.columns[0].column.id).toBe('id1');
|
|
108
|
+
expect(data.data.foo).toBe(1);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('fetchCSVBlob should call the right API', async () => {
|
|
112
|
+
fetchMock.once('Bla');
|
|
113
|
+
const answerService = createAnswerService();
|
|
114
|
+
answerService.fetchCSVBlob(undefined, true);
|
|
115
|
+
expect(fetchMock).toHaveBeenCalledWith(
|
|
116
|
+
`https://tshost/prism/download/answer/csv?sessionId=${defaultSession.sessionId}&genNo=${defaultSession.genNo}&userLocale=en-us&exportFileName=data&omitInfo=true`,
|
|
117
|
+
expect.objectContaining({}),
|
|
118
|
+
);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('getUnderlyingDataForPoint should call the right APIs', async () => {
|
|
122
|
+
fetchMock.mockResponses(
|
|
123
|
+
JSON.stringify({
|
|
124
|
+
data: {
|
|
125
|
+
getSourceDetailById: [{
|
|
126
|
+
columns: [{
|
|
127
|
+
id: 'id1',
|
|
128
|
+
name: 'col1',
|
|
129
|
+
}, {
|
|
130
|
+
id: 'id2',
|
|
131
|
+
name: 'col2',
|
|
132
|
+
}, {
|
|
133
|
+
id: 'id3',
|
|
134
|
+
name: 'col3',
|
|
135
|
+
}],
|
|
136
|
+
}],
|
|
137
|
+
},
|
|
138
|
+
}),
|
|
139
|
+
JSON.stringify({
|
|
140
|
+
data: {
|
|
141
|
+
Answer__getUnaggregatedAnswer: {
|
|
142
|
+
id: {
|
|
143
|
+
...defaultSession,
|
|
144
|
+
},
|
|
145
|
+
answer: {
|
|
146
|
+
visualizations: [{
|
|
147
|
+
columns: [{
|
|
148
|
+
column: {
|
|
149
|
+
id: 'oid1',
|
|
150
|
+
name: 'col1',
|
|
151
|
+
referencedColumns: [{
|
|
152
|
+
guid: 'id1',
|
|
153
|
+
}],
|
|
154
|
+
},
|
|
155
|
+
}],
|
|
156
|
+
}],
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
}),
|
|
161
|
+
JSON.stringify({
|
|
162
|
+
data: {
|
|
163
|
+
Answer__addColumn: {
|
|
164
|
+
id: {
|
|
165
|
+
genNo: 2,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
}),
|
|
170
|
+
JSON.stringify({
|
|
171
|
+
data: {
|
|
172
|
+
Answer__removeColumns: {
|
|
173
|
+
id: {
|
|
174
|
+
genNo: 3,
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
}),
|
|
179
|
+
);
|
|
180
|
+
const answerService = createAnswerService({
|
|
181
|
+
sources: [{
|
|
182
|
+
header: {
|
|
183
|
+
guid: 'source1',
|
|
184
|
+
},
|
|
185
|
+
}],
|
|
186
|
+
}, [{
|
|
187
|
+
selectedAttributes: [{
|
|
188
|
+
column: {
|
|
189
|
+
id: 'oid1', // output column id
|
|
190
|
+
name: 'col1',
|
|
191
|
+
dataType: 'CHAR',
|
|
192
|
+
},
|
|
193
|
+
value: '1',
|
|
194
|
+
}, {
|
|
195
|
+
column: {
|
|
196
|
+
id: 'oid3',
|
|
197
|
+
name: 'col3',
|
|
198
|
+
dataType: 'DATE',
|
|
199
|
+
},
|
|
200
|
+
value: 12345,
|
|
201
|
+
}],
|
|
202
|
+
selectedMeasures: [],
|
|
203
|
+
}]);
|
|
204
|
+
const underlying = await answerService.getUnderlyingDataForPoint(['col2']);
|
|
205
|
+
expect(fetchMock).toHaveBeenCalledTimes(4);
|
|
206
|
+
expect(underlying.getSession().genNo).toBe(3);
|
|
207
|
+
expect(fetchMock).toHaveBeenCalledWith(
|
|
208
|
+
'https://tshost/prism/?op=RemoveColumns',
|
|
209
|
+
expect.objectContaining({
|
|
210
|
+
body: JSON.stringify({
|
|
211
|
+
operationName: 'RemoveColumns',
|
|
212
|
+
query: removeColumns,
|
|
213
|
+
variables: {
|
|
214
|
+
session: {
|
|
215
|
+
...defaultSession,
|
|
216
|
+
genNo: 2,
|
|
217
|
+
},
|
|
218
|
+
logicalColumnIds: [
|
|
219
|
+
'id1',
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
}),
|
|
223
|
+
}),
|
|
224
|
+
);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test('getUnderlyingDataForPoint should throw when no point is selected', async () => {
|
|
228
|
+
const answerService = createAnswerService({}, null);
|
|
229
|
+
await expect(answerService.getUnderlyingDataForPoint(['col2'])).rejects.toThrow();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import type { ColumnValue, VizPoint } from '../../../types';
|
|
2
|
+
import { deepMerge, removeTypename } from '../../../utils';
|
|
3
|
+
import { graphqlQuery } from '../graphql-request';
|
|
4
|
+
import { getSourceDetail } from '../sourceService';
|
|
5
|
+
import * as queries from './answer-queries';
|
|
6
|
+
|
|
7
|
+
export interface SessionInterface {
|
|
8
|
+
sessionId: string;
|
|
9
|
+
genNo: number;
|
|
10
|
+
acSession: { sessionId: string; genNo: number };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// eslint-disable-next-line no-shadow
|
|
14
|
+
export enum OperationType {
|
|
15
|
+
GetChartWithData = 'GetChartWithData',
|
|
16
|
+
GetTableWithHeadlineData = 'GetTableWithHeadlineData',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface UnderlyingDataPoint {
|
|
20
|
+
columnId: string;
|
|
21
|
+
dataValue: any;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Class representing the answer service provided with the
|
|
26
|
+
* custom action payload. This service could be used to run
|
|
27
|
+
* graphql queries in the context of the answer on which the
|
|
28
|
+
* custom action was triggered.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```js
|
|
32
|
+
* embed.on(EmbedEvent.CustomAction, e => {
|
|
33
|
+
* const underlying = await e.answerService.getUnderlyingDataForPoint([
|
|
34
|
+
* 'col name 1'
|
|
35
|
+
* ]);
|
|
36
|
+
* const data = await underlying.fetchData(0, 100);
|
|
37
|
+
* })
|
|
38
|
+
* ```
|
|
39
|
+
* @version
|
|
40
|
+
* ThoughtSpot: 9.9.0.cl / SDK: 1.25.0
|
|
41
|
+
*/
|
|
42
|
+
export class AnswerService {
|
|
43
|
+
constructor(
|
|
44
|
+
private session: SessionInterface,
|
|
45
|
+
private answer: any,
|
|
46
|
+
private thoughtSpotHost: string,
|
|
47
|
+
private selectedPoints?: VizPoint[],
|
|
48
|
+
) {
|
|
49
|
+
this.session = removeTypename(session);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public async getSourceDetail() {
|
|
53
|
+
const sourceId = this.answer.sources[0].header.guid;
|
|
54
|
+
return getSourceDetail(
|
|
55
|
+
this.thoughtSpotHost,
|
|
56
|
+
sourceId,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public async removeColumns(columnIds: string[]) {
|
|
61
|
+
return this.executeQuery(
|
|
62
|
+
queries.removeColumns,
|
|
63
|
+
{
|
|
64
|
+
logicalColumnIds: columnIds,
|
|
65
|
+
},
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public async addColumns(columnIds: string[]) {
|
|
70
|
+
return this.executeQuery(
|
|
71
|
+
queries.addColumns,
|
|
72
|
+
{
|
|
73
|
+
columns: columnIds.map((colId) => ({ logicalColumnId: colId })),
|
|
74
|
+
},
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public async fetchData(offset = 0, size = 1000) {
|
|
79
|
+
const { answer } = await this.executeQuery(
|
|
80
|
+
queries.getAnswerData,
|
|
81
|
+
{
|
|
82
|
+
deadline: 0,
|
|
83
|
+
dataPaginationParams: {
|
|
84
|
+
isClientPaginated: true,
|
|
85
|
+
offset,
|
|
86
|
+
size,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
const { columns, data } = answer.visualizations[0];
|
|
91
|
+
return {
|
|
92
|
+
columns,
|
|
93
|
+
data,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
*
|
|
99
|
+
* @param userLocale
|
|
100
|
+
* @param omitInfo Omit the download Info on top of the CSV
|
|
101
|
+
* @returns Response
|
|
102
|
+
*/
|
|
103
|
+
public async fetchCSVBlob(userLocale = 'en-us', omitInfo = false): Promise<Response> {
|
|
104
|
+
if (omitInfo) {
|
|
105
|
+
console.warn('omitInfo not supported yet.');
|
|
106
|
+
}
|
|
107
|
+
const fetchUrl = `${this.thoughtSpotHost}/prism/download/answer/csv?sessionId=${this.session.sessionId}&genNo=${this.session.genNo}&userLocale=${userLocale}&exportFileName=data&omitInfo=${omitInfo}`;
|
|
108
|
+
return fetch(fetchUrl, {
|
|
109
|
+
credentials: 'include',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public async getUnderlyingDataForPoint(
|
|
114
|
+
outputColumnNames: string[],
|
|
115
|
+
selectedPoints?: UnderlyingDataPoint[],
|
|
116
|
+
): Promise<AnswerService> {
|
|
117
|
+
if (!selectedPoints && !this.selectedPoints) {
|
|
118
|
+
throw new Error('Needs to be triggered in context of a point');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!selectedPoints) {
|
|
122
|
+
selectedPoints = getSelectedPointsForUnderlyingDataQuery(
|
|
123
|
+
this.selectedPoints,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const sourceDetail = await this.getSourceDetail();
|
|
128
|
+
const ouputColumnGuids = getGuidsFromColumnNames(sourceDetail, outputColumnNames);
|
|
129
|
+
const unAggAnswer = await graphqlQuery({
|
|
130
|
+
query: queries.getUnaggregatedAnswerSession,
|
|
131
|
+
variables: {
|
|
132
|
+
session: this.session,
|
|
133
|
+
columns: selectedPoints,
|
|
134
|
+
},
|
|
135
|
+
thoughtSpotHost: this.thoughtSpotHost,
|
|
136
|
+
});
|
|
137
|
+
const unaggAnswerSession = new AnswerService(
|
|
138
|
+
unAggAnswer.id,
|
|
139
|
+
unAggAnswer.answer,
|
|
140
|
+
this.thoughtSpotHost,
|
|
141
|
+
);
|
|
142
|
+
const currentColumns: Set<string> = new Set(
|
|
143
|
+
unAggAnswer.answer.visualizations[0].columns
|
|
144
|
+
.map(
|
|
145
|
+
(c: any) => c.column.referencedColumns[0].guid,
|
|
146
|
+
),
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const columnsToAdd = [...ouputColumnGuids].filter((col) => !currentColumns.has(col));
|
|
150
|
+
if (columnsToAdd.length) {
|
|
151
|
+
await unaggAnswerSession.addColumns(columnsToAdd);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const columnsToRemove = [...currentColumns].filter((col) => !ouputColumnGuids.has(col));
|
|
155
|
+
if (columnsToRemove.length) {
|
|
156
|
+
await unaggAnswerSession.removeColumns(columnsToRemove);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return unaggAnswerSession;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public async executeQuery(query: string, variables: any): Promise<any> {
|
|
163
|
+
const data = await graphqlQuery({
|
|
164
|
+
query,
|
|
165
|
+
variables: {
|
|
166
|
+
session: this.session,
|
|
167
|
+
...variables,
|
|
168
|
+
},
|
|
169
|
+
thoughtSpotHost: this.thoughtSpotHost,
|
|
170
|
+
isCompositeQuery: false,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
this.session = deepMerge(this.session, data?.id || {}) as unknown as SessionInterface;
|
|
174
|
+
return data;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public getSession() {
|
|
178
|
+
return this.session;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
*
|
|
184
|
+
* @param sourceDetail
|
|
185
|
+
* @param colNames
|
|
186
|
+
*/
|
|
187
|
+
function getGuidsFromColumnNames(sourceDetail: any, colNames: string[]) {
|
|
188
|
+
const cols = sourceDetail.columns.reduce((colSet: any, col: any) => {
|
|
189
|
+
colSet[col.name] = col;
|
|
190
|
+
return colSet;
|
|
191
|
+
}, {});
|
|
192
|
+
|
|
193
|
+
return new Set(colNames.map((colName) => {
|
|
194
|
+
const col = cols[colName];
|
|
195
|
+
return col.id;
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
*
|
|
201
|
+
* @param selectedPoints
|
|
202
|
+
*/
|
|
203
|
+
function getSelectedPointsForUnderlyingDataQuery(
|
|
204
|
+
selectedPoints: VizPoint[],
|
|
205
|
+
): UnderlyingDataPoint[] {
|
|
206
|
+
const underlyingDataPoint: UnderlyingDataPoint[] = [];
|
|
207
|
+
/**
|
|
208
|
+
*
|
|
209
|
+
* @param colVal
|
|
210
|
+
*/
|
|
211
|
+
function addPointFromColVal(colVal: ColumnValue) {
|
|
212
|
+
const dataType = colVal.column.dataType;
|
|
213
|
+
const id = colVal.column.id;
|
|
214
|
+
let dataValue;
|
|
215
|
+
if (dataType === 'DATE') {
|
|
216
|
+
dataValue = [{
|
|
217
|
+
epochRange: {
|
|
218
|
+
startEpoch: colVal.value,
|
|
219
|
+
},
|
|
220
|
+
}];
|
|
221
|
+
} else {
|
|
222
|
+
dataValue = [{ value: colVal.value }];
|
|
223
|
+
}
|
|
224
|
+
underlyingDataPoint.push({
|
|
225
|
+
columnId: colVal.column.id,
|
|
226
|
+
dataValue,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
selectedPoints.forEach((p) => {
|
|
231
|
+
p.selectedAttributes.forEach(addPointFromColVal);
|
|
232
|
+
});
|
|
233
|
+
return underlyingDataPoint;
|
|
234
|
+
}
|