@thoughtspot/visual-embed-sdk 1.52.2-beta.1 → 1.53.0
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/css-variables.d.ts +373 -5
- package/cjs/src/css-variables.d.ts.map +1 -1
- package/cjs/src/embed/app.d.ts +14 -0
- package/cjs/src/embed/app.d.ts.map +1 -1
- package/cjs/src/embed/app.js +6 -3
- package/cjs/src/embed/app.js.map +1 -1
- package/cjs/src/embed/app.spec.js +28 -0
- package/cjs/src/embed/app.spec.js.map +1 -1
- package/cjs/src/embed/auto-frame-renderer.d.ts.map +1 -1
- package/cjs/src/embed/auto-frame-renderer.js +244 -4
- package/cjs/src/embed/auto-frame-renderer.js.map +1 -1
- package/cjs/src/embed/auto-frame-renderer.spec.js +389 -0
- package/cjs/src/embed/auto-frame-renderer.spec.js.map +1 -1
- package/cjs/src/embed/bodyless-conversation.js +1 -1
- package/cjs/src/embed/bodyless-conversation.js.map +1 -1
- package/cjs/src/embed/conversation.d.ts +15 -0
- package/cjs/src/embed/conversation.d.ts.map +1 -1
- package/cjs/src/embed/conversation.js +7 -3
- package/cjs/src/embed/conversation.js.map +1 -1
- package/cjs/src/embed/conversation.spec.js +66 -0
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/liveboard-override-utils.d.ts +59 -0
- package/cjs/src/embed/liveboard-override-utils.d.ts.map +1 -0
- package/cjs/src/embed/liveboard-override-utils.js +19 -0
- package/cjs/src/embed/liveboard-override-utils.js.map +1 -0
- package/cjs/src/embed/liveboard-override-utils.spec.d.ts +2 -0
- package/cjs/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
- package/cjs/src/embed/liveboard-override-utils.spec.js +34 -0
- package/cjs/src/embed/liveboard-override-utils.spec.js.map +1 -0
- package/cjs/src/embed/liveboard.d.ts +43 -1
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +11 -18
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +104 -54
- package/cjs/src/embed/liveboard.spec.js.map +1 -1
- package/cjs/src/embed/search-bar.js +1 -1
- package/cjs/src/embed/search-bar.js.map +1 -1
- package/cjs/src/embed/search.js +1 -1
- package/cjs/src/embed/search.js.map +1 -1
- package/cjs/src/embed/search.spec.js +20 -0
- package/cjs/src/embed/search.spec.js.map +1 -1
- package/cjs/src/embed/spotter-utils.d.ts +11 -0
- package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
- package/cjs/src/embed/spotter-utils.js +13 -1
- package/cjs/src/embed/spotter-utils.js.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.d.ts +15 -0
- package/cjs/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.js.map +1 -1
- package/cjs/src/embed/spotter-viz-utils.spec.js +11 -0
- package/cjs/src/embed/spotter-viz-utils.spec.js.map +1 -1
- package/cjs/src/embed/ts-embed.d.ts +27 -34
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +224 -102
- package/cjs/src/embed/ts-embed.js.map +1 -1
- package/cjs/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.spec.js +543 -171
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/index.d.ts +4 -2
- package/cjs/src/index.d.ts.map +1 -1
- package/cjs/src/index.js +4 -2
- package/cjs/src/index.js.map +1 -1
- package/cjs/src/mixpanel-service.d.ts +1 -0
- package/cjs/src/mixpanel-service.d.ts.map +1 -1
- package/cjs/src/mixpanel-service.js +1 -0
- package/cjs/src/mixpanel-service.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 +2 -1
- package/cjs/src/react/all-types-export.js.map +1 -1
- package/cjs/src/types.d.ts +182 -2
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +109 -0
- package/cjs/src/types.js.map +1 -1
- package/cjs/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
- package/cjs/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
- package/cjs/src/utils/graphql/answerService/answer-queries.js +8 -1
- package/cjs/src/utils/graphql/answerService/answer-queries.js.map +1 -1
- package/cjs/src/utils/graphql/answerService/answerService.d.ts +28 -4
- package/cjs/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
- package/cjs/src/utils/graphql/answerService/answerService.js +39 -4
- package/cjs/src/utils/graphql/answerService/answerService.js.map +1 -1
- package/cjs/src/utils/graphql/answerService/answerService.spec.js +124 -0
- package/cjs/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
- package/dist/{index-Bt56pC82.js → index-CyDR8j_0.js} +1 -1
- package/dist/src/css-variables.d.ts +373 -5
- package/dist/src/css-variables.d.ts.map +1 -1
- package/dist/src/embed/app.d.ts +14 -0
- package/dist/src/embed/app.d.ts.map +1 -1
- package/dist/src/embed/auto-frame-renderer.d.ts.map +1 -1
- package/dist/src/embed/conversation.d.ts +15 -0
- package/dist/src/embed/conversation.d.ts.map +1 -1
- package/dist/src/embed/liveboard-override-utils.d.ts +59 -0
- package/dist/src/embed/liveboard-override-utils.d.ts.map +1 -0
- package/dist/src/embed/liveboard-override-utils.spec.d.ts +2 -0
- package/dist/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
- package/dist/src/embed/liveboard.d.ts +43 -1
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/spotter-utils.d.ts +11 -0
- package/dist/src/embed/spotter-utils.d.ts.map +1 -1
- package/dist/src/embed/spotter-viz-utils.d.ts +15 -0
- package/dist/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.d.ts +27 -34
- package/dist/src/embed/ts-embed.d.ts.map +1 -1
- package/dist/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/mixpanel-service.d.ts +1 -0
- package/dist/src/mixpanel-service.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/types.d.ts +182 -2
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
- package/dist/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
- package/dist/src/utils/graphql/answerService/answerService.d.ts +28 -4
- package/dist/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
- package/dist/tsembed-react.es.js +437 -175
- package/dist/tsembed-react.js +436 -174
- package/dist/tsembed.es.js +680 -180
- package/dist/tsembed.js +678 -178
- package/dist/visual-embed-sdk-react-full.d.ts +702 -44
- package/dist/visual-embed-sdk-react.d.ts +697 -44
- package/dist/visual-embed-sdk.d.ts +729 -45
- package/lib/package.json +1 -1
- package/lib/src/css-variables.d.ts +373 -5
- package/lib/src/css-variables.d.ts.map +1 -1
- package/lib/src/embed/app.d.ts +14 -0
- package/lib/src/embed/app.d.ts.map +1 -1
- package/lib/src/embed/app.js +7 -4
- package/lib/src/embed/app.js.map +1 -1
- package/lib/src/embed/app.spec.js +28 -0
- package/lib/src/embed/app.spec.js.map +1 -1
- package/lib/src/embed/auto-frame-renderer.d.ts.map +1 -1
- package/lib/src/embed/auto-frame-renderer.js +244 -4
- package/lib/src/embed/auto-frame-renderer.js.map +1 -1
- package/lib/src/embed/auto-frame-renderer.spec.js +389 -0
- package/lib/src/embed/auto-frame-renderer.spec.js.map +1 -1
- package/lib/src/embed/bodyless-conversation.js +1 -1
- package/lib/src/embed/bodyless-conversation.js.map +1 -1
- package/lib/src/embed/conversation.d.ts +15 -0
- package/lib/src/embed/conversation.d.ts.map +1 -1
- package/lib/src/embed/conversation.js +8 -4
- package/lib/src/embed/conversation.js.map +1 -1
- package/lib/src/embed/conversation.spec.js +67 -1
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/liveboard-override-utils.d.ts +59 -0
- package/lib/src/embed/liveboard-override-utils.d.ts.map +1 -0
- package/lib/src/embed/liveboard-override-utils.js +15 -0
- package/lib/src/embed/liveboard-override-utils.js.map +1 -0
- package/lib/src/embed/liveboard-override-utils.spec.d.ts +2 -0
- package/lib/src/embed/liveboard-override-utils.spec.d.ts.map +1 -0
- package/lib/src/embed/liveboard-override-utils.spec.js +32 -0
- package/lib/src/embed/liveboard-override-utils.spec.js.map +1 -0
- package/lib/src/embed/liveboard.d.ts +43 -1
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +11 -17
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +104 -54
- package/lib/src/embed/liveboard.spec.js.map +1 -1
- package/lib/src/embed/search-bar.js +1 -1
- package/lib/src/embed/search-bar.js.map +1 -1
- package/lib/src/embed/search.js +1 -1
- package/lib/src/embed/search.js.map +1 -1
- package/lib/src/embed/search.spec.js +20 -0
- package/lib/src/embed/search.spec.js.map +1 -1
- package/lib/src/embed/spotter-utils.d.ts +11 -0
- package/lib/src/embed/spotter-utils.d.ts.map +1 -1
- package/lib/src/embed/spotter-utils.js +12 -0
- package/lib/src/embed/spotter-utils.js.map +1 -1
- package/lib/src/embed/spotter-viz-utils.d.ts +15 -0
- package/lib/src/embed/spotter-viz-utils.d.ts.map +1 -1
- package/lib/src/embed/spotter-viz-utils.js.map +1 -1
- package/lib/src/embed/spotter-viz-utils.spec.js +11 -0
- package/lib/src/embed/spotter-viz-utils.spec.js.map +1 -1
- package/lib/src/embed/ts-embed.d.ts +27 -34
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +224 -102
- package/lib/src/embed/ts-embed.js.map +1 -1
- package/lib/src/embed/ts-embed.spec.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.spec.js +544 -172
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/index.d.ts +4 -2
- package/lib/src/index.d.ts.map +1 -1
- package/lib/src/index.js +3 -2
- package/lib/src/index.js.map +1 -1
- package/lib/src/mixpanel-service.d.ts +1 -0
- package/lib/src/mixpanel-service.d.ts.map +1 -1
- package/lib/src/mixpanel-service.js +1 -0
- package/lib/src/mixpanel-service.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/types.d.ts +182 -2
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +109 -0
- package/lib/src/types.js.map +1 -1
- package/lib/src/utils/graphql/answerService/answer-queries.d.ts +1 -0
- package/lib/src/utils/graphql/answerService/answer-queries.d.ts.map +1 -1
- package/lib/src/utils/graphql/answerService/answer-queries.js +7 -0
- package/lib/src/utils/graphql/answerService/answer-queries.js.map +1 -1
- package/lib/src/utils/graphql/answerService/answerService.d.ts +28 -4
- package/lib/src/utils/graphql/answerService/answerService.d.ts.map +1 -1
- package/lib/src/utils/graphql/answerService/answerService.js +39 -4
- package/lib/src/utils/graphql/answerService/answerService.js.map +1 -1
- package/lib/src/utils/graphql/answerService/answerService.spec.js +125 -1
- package/lib/src/utils/graphql/answerService/answerService.spec.js.map +1 -1
- package/lib/src/visual-embed-sdk.d.ts +729 -45
- package/package.json +1 -1
- package/src/css-variables.ts +475 -26
- package/src/embed/app.spec.ts +32 -0
- package/src/embed/app.ts +28 -4
- package/src/embed/auto-frame-renderer.spec.ts +464 -0
- package/src/embed/auto-frame-renderer.ts +305 -6
- package/src/embed/bodyless-conversation.ts +1 -1
- package/src/embed/conversation.spec.ts +94 -1
- package/src/embed/conversation.ts +28 -3
- package/src/embed/liveboard-override-utils.spec.ts +38 -0
- package/src/embed/liveboard-override-utils.ts +71 -0
- package/src/embed/liveboard.spec.ts +119 -62
- package/src/embed/liveboard.ts +56 -21
- package/src/embed/search-bar.tsx +1 -1
- package/src/embed/search.spec.ts +23 -0
- package/src/embed/search.ts +1 -1
- package/src/embed/spotter-utils.ts +12 -0
- package/src/embed/spotter-viz-utils.spec.ts +11 -0
- package/src/embed/spotter-viz-utils.ts +15 -0
- package/src/embed/ts-embed.spec.ts +684 -213
- package/src/embed/ts-embed.ts +227 -97
- package/src/index.ts +16 -1
- package/src/mixpanel-service.ts +1 -0
- package/src/react/all-types-export.ts +6 -0
- package/src/types.ts +186 -5
- package/src/utils/graphql/answerService/answer-queries.ts +8 -0
- package/src/utils/graphql/answerService/answerService.spec.ts +145 -1
- package/src/utils/graphql/answerService/answerService.ts +65 -3
package/dist/tsembed.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* @thoughtspot/visual-embed-sdk version 1.
|
|
1
|
+
/* @thoughtspot/visual-embed-sdk version 1.53.0 */
|
|
2
2
|
'use client';
|
|
3
3
|
(function (global, factory) {
|
|
4
4
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
@@ -1214,6 +1214,36 @@
|
|
|
1214
1214
|
* ```
|
|
1215
1215
|
*/
|
|
1216
1216
|
EmbedEvent["Edit"] = "edit";
|
|
1217
|
+
/**
|
|
1218
|
+
* Emitted when a user clicks **Edit** on a Liveboard.
|
|
1219
|
+
*
|
|
1220
|
+
* Fired alongside {@link EmbedEvent.Edit} for backward compatibility;
|
|
1221
|
+
* listen to this instead of `Edit` to target the Liveboard surface only.
|
|
1222
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
1223
|
+
* @example
|
|
1224
|
+
* ```js
|
|
1225
|
+
* liveboardEmbed.on(EmbedEvent.EditLiveboard, payload => {
|
|
1226
|
+
* console.log('Liveboard edit', payload);
|
|
1227
|
+
* })
|
|
1228
|
+
* ```
|
|
1229
|
+
*/
|
|
1230
|
+
EmbedEvent["EditLiveboard"] = "editLiveboard";
|
|
1231
|
+
/**
|
|
1232
|
+
* Emitted when a user clicks **Edit** on a visualization inside a
|
|
1233
|
+
* Liveboard.
|
|
1234
|
+
*
|
|
1235
|
+
* Fired alongside {@link EmbedEvent.Edit} for backward compatibility;
|
|
1236
|
+
* listen to this instead of `Edit` to target the visualization surface
|
|
1237
|
+
* only.
|
|
1238
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
1239
|
+
* @example
|
|
1240
|
+
* ```js
|
|
1241
|
+
* liveboardEmbed.on(EmbedEvent.EditVisualization, payload => {
|
|
1242
|
+
* console.log('visualization edit', payload);
|
|
1243
|
+
* })
|
|
1244
|
+
* ```
|
|
1245
|
+
*/
|
|
1246
|
+
EmbedEvent["EditVisualization"] = "editVisualization";
|
|
1217
1247
|
/**
|
|
1218
1248
|
* Emitted when a user clicks *Make a copy* on a Liveboard
|
|
1219
1249
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
|
|
@@ -3185,6 +3215,35 @@
|
|
|
3185
3215
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
|
|
3186
3216
|
*/
|
|
3187
3217
|
HostEvent["Edit"] = "edit";
|
|
3218
|
+
/**
|
|
3219
|
+
* Trigger the **Edit** action on a Liveboard only — does not affect a
|
|
3220
|
+
* visualization's edit surface.
|
|
3221
|
+
*
|
|
3222
|
+
* Behaves like {@link HostEvent.Edit} restricted to the Liveboard
|
|
3223
|
+
* surface. Use {@link HostEvent.EditVisualization} to target a
|
|
3224
|
+
* visualization instead, or `HostEvent.Edit` to control whichever
|
|
3225
|
+
* surface applies contextually (unchanged, existing behavior).
|
|
3226
|
+
* @example
|
|
3227
|
+
* ```js
|
|
3228
|
+
* liveboardEmbed.trigger(HostEvent.EditLiveboard)
|
|
3229
|
+
* ```
|
|
3230
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
3231
|
+
*/
|
|
3232
|
+
HostEvent["EditLiveboard"] = "editLiveboard";
|
|
3233
|
+
/**
|
|
3234
|
+
* Trigger the **Edit** action on a specific visualization inside a
|
|
3235
|
+
* Liveboard only — does not affect the Liveboard-level edit surface.
|
|
3236
|
+
* @param - Object parameter. Includes the following keys:
|
|
3237
|
+
* - `vizId`: **Required.** The visualization to edit.
|
|
3238
|
+
*
|
|
3239
|
+
* @example
|
|
3240
|
+
* ```js
|
|
3241
|
+
* liveboardEmbed.trigger(HostEvent.EditVisualization, {vizId:
|
|
3242
|
+
* '730496d6-6903-4601-937e-2c691821af3c'})
|
|
3243
|
+
* ```
|
|
3244
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
3245
|
+
*/
|
|
3246
|
+
HostEvent["EditVisualization"] = "editVisualization";
|
|
3188
3247
|
/**
|
|
3189
3248
|
* Trigger the **Copy link** action on a Liveboard or visualization
|
|
3190
3249
|
* Payload: {@link VizScopedRequest}.
|
|
@@ -4747,6 +4806,22 @@
|
|
|
4747
4806
|
var Param;
|
|
4748
4807
|
(function (Param) {
|
|
4749
4808
|
Param["Tsmcp"] = "tsmcp";
|
|
4809
|
+
/**
|
|
4810
|
+
* Marker added by a host app replaying a stored conversation. Carries the
|
|
4811
|
+
* analytical session (conversation) identifier, from which the renderer
|
|
4812
|
+
* resolves the answer's current session parameters. Stripped before the
|
|
4813
|
+
* URL reaches the ThoughtSpot application.
|
|
4814
|
+
* @version SDK: 1.52.2 | ThoughtSpot Cloud: 26.9.0.cl
|
|
4815
|
+
*/
|
|
4816
|
+
Param["TsmcpConversationId"] = "tsmcpConversationId";
|
|
4817
|
+
/**
|
|
4818
|
+
* Zero-based position of the answer within the conversation, counting only
|
|
4819
|
+
* non-thinking answer items in message order. Accompanies
|
|
4820
|
+
* {@link TsmcpConversationId}; defaults to 0 when absent. Stripped before
|
|
4821
|
+
* the URL reaches the ThoughtSpot application.
|
|
4822
|
+
* @version SDK: 1.52.2 | ThoughtSpot Cloud: 26.9.0.cl
|
|
4823
|
+
*/
|
|
4824
|
+
Param["TsmcpAnswerIndex"] = "tsmcpAnswerIndex";
|
|
4750
4825
|
Param["EmbedApp"] = "embedApp";
|
|
4751
4826
|
Param["DataSources"] = "dataSources";
|
|
4752
4827
|
Param["DataSourceMode"] = "dataSourceMode";
|
|
@@ -4910,6 +4985,9 @@
|
|
|
4910
4985
|
Param["SpotterDataSources"] = "spotterDataSources";
|
|
4911
4986
|
Param["OpenSpotterOnLiveboardByDefault"] = "openSpotterOnLiveboardByDefault";
|
|
4912
4987
|
Param["ShowAnswerEditPanel"] = "showAnswerEditPanel";
|
|
4988
|
+
Param["IsDarkMode"] = "isDarkMode";
|
|
4989
|
+
Param["RadiantThemeEnabled"] = "radiantThemeEnabled";
|
|
4990
|
+
Param["SpotterExperienceVersion"] = "spotterExperienceVersion";
|
|
4913
4991
|
})(Param || (Param = {}));
|
|
4914
4992
|
/**
|
|
4915
4993
|
* ThoughtSpot application pages include actions and menu commands
|
|
@@ -5364,12 +5442,43 @@
|
|
|
5364
5442
|
* The *Edit* action on the Liveboard page and in the
|
|
5365
5443
|
* visualization menu.
|
|
5366
5444
|
* Opens a Liveboard or visualization in edit mode.
|
|
5445
|
+
*
|
|
5446
|
+
* Controls both surfaces together. To target one surface only, use
|
|
5447
|
+
* {@link Action.EditLiveboard} or {@link Action.EditVisualization}.
|
|
5367
5448
|
* @example
|
|
5368
5449
|
* ```js
|
|
5369
5450
|
* disabledActions: [Action.Edit]
|
|
5370
5451
|
* ```
|
|
5371
5452
|
*/
|
|
5372
5453
|
Action["Edit"] = "edit";
|
|
5454
|
+
/**
|
|
5455
|
+
* The *Edit* action on the Liveboard page only.
|
|
5456
|
+
* Opens a Liveboard in edit mode.
|
|
5457
|
+
*
|
|
5458
|
+
* Does not affect the *Edit* action in the visualization menu; use
|
|
5459
|
+
* {@link Action.EditVisualization} for that, or {@link Action.Edit} to
|
|
5460
|
+
* control both surfaces together.
|
|
5461
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
5462
|
+
* @example
|
|
5463
|
+
* ```js
|
|
5464
|
+
* disabledActions: [Action.EditLiveboard]
|
|
5465
|
+
* ```
|
|
5466
|
+
*/
|
|
5467
|
+
Action["EditLiveboard"] = "editLiveboard";
|
|
5468
|
+
/**
|
|
5469
|
+
* The *Edit* action in the visualization `...` menu only.
|
|
5470
|
+
* Opens a visualization in the editor.
|
|
5471
|
+
*
|
|
5472
|
+
* Does not affect the *Edit* action on the Liveboard page; use
|
|
5473
|
+
* {@link Action.EditLiveboard} for that, or {@link Action.Edit} to
|
|
5474
|
+
* control both surfaces together.
|
|
5475
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
5476
|
+
* @example
|
|
5477
|
+
* ```js
|
|
5478
|
+
* disabledActions: [Action.EditVisualization]
|
|
5479
|
+
* ```
|
|
5480
|
+
*/
|
|
5481
|
+
Action["EditVisualization"] = "editVisualization";
|
|
5373
5482
|
/**
|
|
5374
5483
|
* The text edit option for Liveboard and visualization titles.
|
|
5375
5484
|
* @example
|
|
@@ -7649,7 +7758,7 @@
|
|
|
7649
7758
|
TableContentDensity["Compact"] = "COMPACT";
|
|
7650
7759
|
})(exports.TableContentDensity || (exports.TableContentDensity = {}));
|
|
7651
7760
|
|
|
7652
|
-
var version$1="1.
|
|
7761
|
+
var version$1="1.53.0";var pkg = {version:version$1};
|
|
7653
7762
|
|
|
7654
7763
|
const { version } = pkg;
|
|
7655
7764
|
|
|
@@ -10316,6 +10425,13 @@ mutation RemoveColumns($session: BachSessionIdInput!, $logicalColumnIds: [GUID!]
|
|
|
10316
10425
|
${bachSessionId}
|
|
10317
10426
|
}
|
|
10318
10427
|
}
|
|
10428
|
+
`;
|
|
10429
|
+
const updateSort = `
|
|
10430
|
+
mutation UpdateSort($session: BachSessionIdInput!, $sortOrder: [AnswerColumnSortInput!]!) {
|
|
10431
|
+
Answer__updateSort(session: $session, sortOrder: $sortOrder) {
|
|
10432
|
+
${bachSessionId}
|
|
10433
|
+
}
|
|
10434
|
+
}
|
|
10319
10435
|
`;
|
|
10320
10436
|
const getAnswer = `
|
|
10321
10437
|
query GetAnswer($session: BachSessionIdInput!) {
|
|
@@ -10621,6 +10737,26 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
10621
10737
|
},
|
|
10622
10738
|
});
|
|
10623
10739
|
}
|
|
10740
|
+
/**
|
|
10741
|
+
* Adapt the sort options into the `updateSort` payload and send it.
|
|
10742
|
+
* @param sortOptions Columns to sort by, each with a direction.
|
|
10743
|
+
* @param sourceDetail
|
|
10744
|
+
*/
|
|
10745
|
+
async adaptSorting(sortOptions, sourceDetail) {
|
|
10746
|
+
const { answer } = await this.executeQuery(getAnswer, {});
|
|
10747
|
+
const guidToColumnId = getGuidToColumnIdMap(answer);
|
|
10748
|
+
const sortOrder = sortOptions.map((sort) => {
|
|
10749
|
+
const guid = getGuidsFromColumnNames(sourceDetail, [sort.columnName])
|
|
10750
|
+
.values().next().value;
|
|
10751
|
+
return {
|
|
10752
|
+
columnId: guidToColumnId.get(guid),
|
|
10753
|
+
sortType: sort.ascending ? 'ASCENDING' : 'DESCENDING',
|
|
10754
|
+
};
|
|
10755
|
+
});
|
|
10756
|
+
return this.executeQuery(updateSort, {
|
|
10757
|
+
sortOrder,
|
|
10758
|
+
});
|
|
10759
|
+
}
|
|
10624
10760
|
async updateDisplayMode(displayMode = "TABLE_MODE") {
|
|
10625
10761
|
return this.executeQuery(updateDisplayMode, {
|
|
10626
10762
|
displayMode,
|
|
@@ -10708,18 +10844,21 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
10708
10844
|
* automatically passed.
|
|
10709
10845
|
* @param outputColumnNames
|
|
10710
10846
|
* @param selectedPoints
|
|
10847
|
+
* @param sortOptions Optional columns to sort the underlying data by.
|
|
10711
10848
|
* @example
|
|
10712
10849
|
* ```js
|
|
10713
10850
|
* embed.on(EmbedEvent.CustomAction, e => {
|
|
10714
|
-
* const underlying = await e.answerService.getUnderlyingDataForPoint(
|
|
10715
|
-
* 'col name 1' // The column should exist in the data source.
|
|
10716
|
-
*
|
|
10851
|
+
* const underlying = await e.answerService.getUnderlyingDataForPoint(
|
|
10852
|
+
* ['col name 1'], // The column should exist in the data source.
|
|
10853
|
+
* undefined,
|
|
10854
|
+
* [{ columnName: 'col name 1', ascending: true }],
|
|
10855
|
+
* );
|
|
10717
10856
|
* const data = await underlying.fetchData(0, 100);
|
|
10718
10857
|
* })
|
|
10719
10858
|
* ```
|
|
10720
10859
|
* @version SDK: 1.25.0 | ThoughtSpot: 9.10.0.cl
|
|
10721
10860
|
*/
|
|
10722
|
-
async getUnderlyingDataForPoint(outputColumnNames, selectedPoints) {
|
|
10861
|
+
async getUnderlyingDataForPoint(outputColumnNames, selectedPoints, sortOptions) {
|
|
10723
10862
|
if (!selectedPoints && !this.selectedPoints) {
|
|
10724
10863
|
throw new Error('Needs to be triggered in context of a point');
|
|
10725
10864
|
}
|
|
@@ -10747,6 +10886,9 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
10747
10886
|
if (columnsToRemove.length) {
|
|
10748
10887
|
await unaggAnswerSession.removeColumns(columnsToRemove);
|
|
10749
10888
|
}
|
|
10889
|
+
if (sortOptions === null || sortOptions === void 0 ? void 0 : sortOptions.length) {
|
|
10890
|
+
await unaggAnswerSession.adaptSorting(sortOptions, sourceDetail);
|
|
10891
|
+
}
|
|
10750
10892
|
return unaggAnswerSession;
|
|
10751
10893
|
}
|
|
10752
10894
|
/**
|
|
@@ -10806,6 +10948,15 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
10806
10948
|
this.tmlOverride = override;
|
|
10807
10949
|
}
|
|
10808
10950
|
}
|
|
10951
|
+
/**
|
|
10952
|
+
* Build a map from a source column guid to the answer's viz column id, using
|
|
10953
|
+
* the `referencedColumns` link on each viz column.
|
|
10954
|
+
* @param answer
|
|
10955
|
+
*/
|
|
10956
|
+
function getGuidToColumnIdMap(answer) {
|
|
10957
|
+
const tableViz = answer.visualizations.find((viz) => viz.columns);
|
|
10958
|
+
return new Map(tableViz.columns.map((col) => [col.column.referencedColumns[0].guid, col.column.id]));
|
|
10959
|
+
}
|
|
10809
10960
|
/**
|
|
10810
10961
|
*
|
|
10811
10962
|
* @param sourceDetail
|
|
@@ -19820,6 +19971,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
19820
19971
|
const MIXPANEL_EVENT = {
|
|
19821
19972
|
VISUAL_SDK_RENDER_START: 'visual-sdk-render-start',
|
|
19822
19973
|
VISUAL_SDK_CALLED_INIT: 'visual-sdk-called-init',
|
|
19974
|
+
VISUAL_SDK_INIT_ACTIONS: 'visual-sdk-init-actions',
|
|
19823
19975
|
VISUAL_SDK_RENDER_COMPLETE: 'visual-sdk-render-complete',
|
|
19824
19976
|
VISUAL_SDK_RENDER_FAILED: 'visual-sdk-render-failed',
|
|
19825
19977
|
VISUAL_SDK_TRIGGER: 'visual-sdk-trigger',
|
|
@@ -22202,9 +22354,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
22202
22354
|
*/
|
|
22203
22355
|
const PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY = 'tsEmbedOriginalPosition';
|
|
22204
22356
|
const PRERENDER_WRAPPER_ID_PREFIX = 'tsEmbed-pre-render-wrapper-';
|
|
22205
|
-
const PRERENDER_PARKED_TRANSFORM = 'translateY(-100%)';
|
|
22206
|
-
/** The height createPreRenderWrapper() seeds before anything is measured. */
|
|
22207
|
-
const UNMEASURED_WRAPPER_HEIGHT = '100vh';
|
|
22208
22357
|
// The container applies UpdateEmbedParams through React state, so a delivered
|
|
22209
22358
|
// post is not the same as the params being in effect.
|
|
22210
22359
|
const UPDATE_EMBED_PARAMS_SETTLE_MS = 200;
|
|
@@ -22212,6 +22361,97 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
22212
22361
|
// truthy, so null or '' leaves the previous embed's values in place. '&' is
|
|
22213
22362
|
// truthy and parses to {}.
|
|
22214
22363
|
const NO_RUNTIME_PARAMS = '&';
|
|
22364
|
+
/**
|
|
22365
|
+
* Params kept on the iframe `src` when `excludeConfigFromURL` is set. The rest
|
|
22366
|
+
* are sent in the APP_INIT payload.
|
|
22367
|
+
* @internal
|
|
22368
|
+
*/
|
|
22369
|
+
const BOOTSTRAP_URL_PARAMS = new Set([
|
|
22370
|
+
// Marks the app as embedded.
|
|
22371
|
+
Param.EmbedApp,
|
|
22372
|
+
// The host page URL, used to validate the postMessage origin.
|
|
22373
|
+
Param.HostAppUrl,
|
|
22374
|
+
// The SDK version.
|
|
22375
|
+
Param.Version,
|
|
22376
|
+
// The authentication type set in init.
|
|
22377
|
+
Param.AuthType,
|
|
22378
|
+
// Whether the app signs the user in automatically.
|
|
22379
|
+
Param.AutoLogin,
|
|
22380
|
+
// Stops the app from redirecting to its login page.
|
|
22381
|
+
Param.DisableLoginRedirect,
|
|
22382
|
+
// Forces the SAML redirect for EmbeddedSSO.
|
|
22383
|
+
Param.ForceSAMLAutoRedirect,
|
|
22384
|
+
// Set for cookieless trusted authentication.
|
|
22385
|
+
Param.cookieless,
|
|
22386
|
+
// Lets the app use the pre-fetched auth info.
|
|
22387
|
+
Param.preAuthCache,
|
|
22388
|
+
// Blocks access to the full app outside the embed.
|
|
22389
|
+
Param.blockNonEmbedFullAppAccess,
|
|
22390
|
+
// The org to load, which the auth info depends on.
|
|
22391
|
+
Param.OverrideOrgId,
|
|
22392
|
+
// The host window height when the iframe loads.
|
|
22393
|
+
Param.ViewPortHeight,
|
|
22394
|
+
// The host window width when the iframe loads.
|
|
22395
|
+
Param.ViewPortWidth,
|
|
22396
|
+
// The app's client log level.
|
|
22397
|
+
Param.ClientLogLevel,
|
|
22398
|
+
// Lets the app override the native console.
|
|
22399
|
+
Param.OverrideNativeConsole,
|
|
22400
|
+
// An extra Pendo tracking key.
|
|
22401
|
+
Param.PendoTrackingKey,
|
|
22402
|
+
// The locale for number formatting.
|
|
22403
|
+
Param.NumberFormatLocale,
|
|
22404
|
+
// The locale for date formatting.
|
|
22405
|
+
Param.DateFormatLocale,
|
|
22406
|
+
// The currency format.
|
|
22407
|
+
Param.CurrencyFormat,
|
|
22408
|
+
// The UI language.
|
|
22409
|
+
Param.Locale,
|
|
22410
|
+
// Turns on dark mode.
|
|
22411
|
+
Param.IsDarkMode,
|
|
22412
|
+
// Turns on the radiant theme that dark mode needs.
|
|
22413
|
+
Param.RadiantThemeEnabled,
|
|
22414
|
+
// Marks a SearchEmbed or SearchBarEmbed.
|
|
22415
|
+
Param.searchEmbed,
|
|
22416
|
+
// Marks a LiveboardEmbed.
|
|
22417
|
+
Param.livedBoardEmbed,
|
|
22418
|
+
// Marks a SpotterAgentEmbed.
|
|
22419
|
+
Param.isSpotterAgentEmbed,
|
|
22420
|
+
// Marks a SpotterEmbed.
|
|
22421
|
+
Param.SpotterEnabled,
|
|
22422
|
+
// Marks an AppEmbed.
|
|
22423
|
+
Param.IsFullAppEmbed,
|
|
22424
|
+
// Legacy flag for the onBeforeGetVizData API intercept.
|
|
22425
|
+
Param.IsOnBeforeGetVizDataInterceptEnabled,
|
|
22426
|
+
// Lets the host override links in the app.
|
|
22427
|
+
Param.LinkOverride,
|
|
22428
|
+
// Turns on version 2 of the link overrides.
|
|
22429
|
+
Param.EnableLinkOverridesV2,
|
|
22430
|
+
// Stops links from opening in a new tab.
|
|
22431
|
+
Param.DisableRedirectionLinksInNewTab,
|
|
22432
|
+
// Uses replaceState instead of pushState for app navigation.
|
|
22433
|
+
Param.OverrideHistoryState,
|
|
22434
|
+
// Shows search results as a table.
|
|
22435
|
+
Param.ForceTable,
|
|
22436
|
+
// The URL of the custom string IDs file.
|
|
22437
|
+
Param.StringIDsUrl,
|
|
22438
|
+
// The data sources that search opens with.
|
|
22439
|
+
Param.DataSources,
|
|
22440
|
+
// Exposes translation IDs in the app.
|
|
22441
|
+
Param.ExposeTranslationIDs,
|
|
22442
|
+
// The URL of the custom icon sprite.
|
|
22443
|
+
Param.IconSpriteUrl,
|
|
22444
|
+
// The tag that filters the metadata lists in an AppEmbed.
|
|
22445
|
+
Param.Tag,
|
|
22446
|
+
// Set when a Liveboard embed shows a single visualization (vizId).
|
|
22447
|
+
Param.vizEmbed,
|
|
22448
|
+
// Whether search opens with the last-selected data sources.
|
|
22449
|
+
Param.UseLastSelectedDataSource,
|
|
22450
|
+
// The query mode Spotter opens in.
|
|
22451
|
+
Param.DefaultQueryMode,
|
|
22452
|
+
// The initial search query. Omitted with excludeSearchTokenStringFromURL.
|
|
22453
|
+
Param.searchTokenString,
|
|
22454
|
+
]);
|
|
22215
22455
|
/**
|
|
22216
22456
|
* The event id map from v2 event names to v1 event id
|
|
22217
22457
|
* v1 events are the classic embed events implemented in Blink v1
|
|
@@ -22240,6 +22480,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
22240
22480
|
this.embedNodeKey = '__tsEmbed';
|
|
22241
22481
|
this.embedContainerLoadedKey = '__tsEmbedContainerLoaded';
|
|
22242
22482
|
this.isAppInitialized = false;
|
|
22483
|
+
this.initDataParams = {};
|
|
22243
22484
|
/**
|
|
22244
22485
|
* Should we encode URL Query Params using base64 encoding which ThoughtSpot
|
|
22245
22486
|
* will generate for embedding. This provides additional security to
|
|
@@ -22249,6 +22490,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
22249
22490
|
this.shouldEncodeUrlQueryParams = false;
|
|
22250
22491
|
this.defaultHiddenActions = [exports.Action.ReportError];
|
|
22251
22492
|
this.preRenderContainerEl = document.body;
|
|
22493
|
+
this.containerScrollListener = null;
|
|
22252
22494
|
/**
|
|
22253
22495
|
* Handler for fullscreen change events
|
|
22254
22496
|
*/
|
|
@@ -22274,7 +22516,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
22274
22516
|
*/
|
|
22275
22517
|
this.appInitCb = async (_, responder) => {
|
|
22276
22518
|
try {
|
|
22277
|
-
const appInitData = await this.getAppInitData();
|
|
22519
|
+
const appInitData = this.withInitDataParams(await this.getAppInitData());
|
|
22278
22520
|
this.isAppInitialized = true;
|
|
22279
22521
|
responder({
|
|
22280
22522
|
type: exports.EmbedEvent.APP_INIT,
|
|
@@ -22702,6 +22944,18 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
22702
22944
|
async getAppInitData() {
|
|
22703
22945
|
return this.getDefaultAppInitData();
|
|
22704
22946
|
}
|
|
22947
|
+
withInitDataParams(appInitData) {
|
|
22948
|
+
if (isEmpty_1(this.initDataParams)) {
|
|
22949
|
+
return appInitData;
|
|
22950
|
+
}
|
|
22951
|
+
return {
|
|
22952
|
+
...appInitData,
|
|
22953
|
+
embedParams: {
|
|
22954
|
+
...this.initDataParams,
|
|
22955
|
+
...(appInitData.embedParams || {}),
|
|
22956
|
+
},
|
|
22957
|
+
};
|
|
22958
|
+
}
|
|
22705
22959
|
/**
|
|
22706
22960
|
* Helper method to refresh/update auth token for TrustedAuthTokenCookieless auth type
|
|
22707
22961
|
* @param responder - Function to send response back
|
|
@@ -22761,7 +23015,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
22761
23015
|
* @returns queryParams
|
|
22762
23016
|
*/
|
|
22763
23017
|
getBaseQueryParams(queryParams = {}) {
|
|
22764
|
-
var _a, _b, _c, _d;
|
|
23018
|
+
var _a, _b, _c, _d, _e;
|
|
22765
23019
|
let hostAppUrl = ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.host) || '';
|
|
22766
23020
|
// The below check is needed because TS Cloud firewall, blocks
|
|
22767
23021
|
// localhost/127.0.0.1 in any url param.
|
|
@@ -22798,6 +23052,15 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
22798
23052
|
if (this.embedConfig.currencyFormat) {
|
|
22799
23053
|
queryParams[Param.CurrencyFormat] = this.embedConfig.currencyFormat;
|
|
22800
23054
|
}
|
|
23055
|
+
// The view config wins over init, so an embed can opt out of a dark
|
|
23056
|
+
// mode set in `init`. `??` and not `||`, so that an explicit `false`
|
|
23057
|
+
// overrides an init-level `true`.
|
|
23058
|
+
const isDarkMode = (_c = this.viewConfig.isDarkMode) !== null && _c !== void 0 ? _c : this.embedConfig.isDarkMode;
|
|
23059
|
+
setParamIfDefined(queryParams, Param.IsDarkMode, isDarkMode, true);
|
|
23060
|
+
// The app's dark mode lives in its radiant theme, so turn that on too.
|
|
23061
|
+
if (isDarkMode) {
|
|
23062
|
+
queryParams[Param.RadiantThemeEnabled] = true;
|
|
23063
|
+
}
|
|
22801
23064
|
const { disabledActions, disabledActionReason, hiddenActions, visibleActions, hiddenTabs, visibleTabs, showAlerts, additionalFlags: additionalFlagsFromView, locale, customizations, contextMenuTrigger, linkOverride, enableLinkOverridesV2, insertInToSlide, disableRedirectionLinksInNewTab, overrideOrgId, overrideHistoryState, exposeTranslationIDs, primaryAction, } = this.viewConfig;
|
|
22802
23065
|
const { additionalFlags: additionalFlagsFromInit } = this.embedConfig;
|
|
22803
23066
|
const additionalFlags = {
|
|
@@ -22863,7 +23126,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
22863
23126
|
if (spriteUrl) {
|
|
22864
23127
|
queryParams[Param.IconSpriteUrl] = spriteUrl.replace('https://', '');
|
|
22865
23128
|
}
|
|
22866
|
-
const stringIDsUrl = ((
|
|
23129
|
+
const stringIDsUrl = ((_d = customizations === null || customizations === void 0 ? void 0 : customizations.content) === null || _d === void 0 ? void 0 : _d.stringIDsUrl) || ((_e = embedCustomizations === null || embedCustomizations === void 0 ? void 0 : embedCustomizations.content) === null || _e === void 0 ? void 0 : _e.stringIDsUrl);
|
|
22867
23130
|
if (stringIDsUrl) {
|
|
22868
23131
|
queryParams[Param.StringIDsUrl] = stringIDsUrl;
|
|
22869
23132
|
}
|
|
@@ -22917,13 +23180,32 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
22917
23180
|
return path;
|
|
22918
23181
|
}
|
|
22919
23182
|
getEmbedParams() {
|
|
22920
|
-
const queryParams = this.
|
|
23183
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
22921
23184
|
return getQueryParamString(queryParams);
|
|
22922
23185
|
}
|
|
22923
23186
|
getEmbedParamsObject() {
|
|
22924
23187
|
const params = this.getBaseQueryParams();
|
|
22925
23188
|
return params;
|
|
22926
23189
|
}
|
|
23190
|
+
getUrlQueryParamsObject() {
|
|
23191
|
+
const queryParams = this.getEmbedParamsObject();
|
|
23192
|
+
if (!this.isConfigExcludedFromUrl()) {
|
|
23193
|
+
this.initDataParams = {};
|
|
23194
|
+
return queryParams;
|
|
23195
|
+
}
|
|
23196
|
+
const urlParams = {};
|
|
23197
|
+
const excludedParams = {};
|
|
23198
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
23199
|
+
if (BOOTSTRAP_URL_PARAMS.has(key)) {
|
|
23200
|
+
urlParams[key] = value;
|
|
23201
|
+
}
|
|
23202
|
+
else {
|
|
23203
|
+
excludedParams[key] = deserializeParam(value);
|
|
23204
|
+
}
|
|
23205
|
+
});
|
|
23206
|
+
this.initDataParams = excludedParams;
|
|
23207
|
+
return urlParams;
|
|
23208
|
+
}
|
|
22927
23209
|
getRootIframeSrc() {
|
|
22928
23210
|
const query = this.getEmbedParams();
|
|
22929
23211
|
return this.getEmbedBasePath(query);
|
|
@@ -23094,7 +23376,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23094
23376
|
top: '0',
|
|
23095
23377
|
left: '0',
|
|
23096
23378
|
width: '100vw',
|
|
23097
|
-
height:
|
|
23379
|
+
height: '100vh',
|
|
23098
23380
|
};
|
|
23099
23381
|
setStyleProperties(preRenderWrapper, initialPreRenderWrapperStyle);
|
|
23100
23382
|
return preRenderWrapper;
|
|
@@ -23162,26 +23444,10 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23162
23444
|
return placeholder;
|
|
23163
23445
|
}
|
|
23164
23446
|
/**
|
|
23165
|
-
* Resolves the configured preRenderContainer to a live element
|
|
23166
|
-
* selector is re-queried on every call so
|
|
23167
|
-
* replacing the node) resolves to the
|
|
23168
|
-
* directly cannot be re-resolved.
|
|
23169
|
-
*
|
|
23170
|
-
* With nothing configured the frame goes into the host element's nearest
|
|
23171
|
-
* scrolling ancestor, falling back to `document.body`.
|
|
23172
|
-
*
|
|
23173
|
-
* The wrapper is absolutely positioned, so it follows the page for free —
|
|
23174
|
-
* but only while it sits inside whatever scrolls. `document.body` is right
|
|
23175
|
-
* only when the document itself is the scroller; an app that scrolls an
|
|
23176
|
-
* inner element instead left the frame pinned to the viewport while the page
|
|
23177
|
-
* moved under it (SCAL-338563). Being inside the scroller also lets wheel
|
|
23178
|
-
* events chain out of the frame into it, which they cannot do from
|
|
23179
|
-
* `document.body`.
|
|
23180
|
-
*
|
|
23181
|
-
* A scrolling ancestor is layout chrome rather than route content, so it
|
|
23182
|
-
* outlives the embed in practice; and if it does go, the host element goes
|
|
23183
|
-
* with it and this instance is remounting anyway.
|
|
23184
|
-
* `reconcilePreRenderContainer` re-runs this on a detached container.
|
|
23447
|
+
* Resolves the configured preRenderContainer to a live element, falling
|
|
23448
|
+
* back to `document.body`. A string selector is re-queried on every call so
|
|
23449
|
+
* a remounted container (E.g.: React replacing the node) resolves to the
|
|
23450
|
+
* fresh element; an element passed directly cannot be re-resolved.
|
|
23185
23451
|
*/
|
|
23186
23452
|
resolvePreRenderContainerTarget() {
|
|
23187
23453
|
var _a;
|
|
@@ -23201,13 +23467,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23201
23467
|
else if (containerConfig) {
|
|
23202
23468
|
container = containerConfig;
|
|
23203
23469
|
}
|
|
23204
|
-
|
|
23205
|
-
return container;
|
|
23206
|
-
}
|
|
23207
|
-
if (!this.hostElement) {
|
|
23208
|
-
return document.body;
|
|
23209
|
-
}
|
|
23210
|
-
return (_a = getScrollableAncestors(this.hostElement)[0]) !== null && _a !== void 0 ? _a : document.body;
|
|
23470
|
+
return (_a = container) !== null && _a !== void 0 ? _a : document.body;
|
|
23211
23471
|
}
|
|
23212
23472
|
inheritPreRenderContainer() {
|
|
23213
23473
|
var _a;
|
|
@@ -23252,9 +23512,8 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23252
23512
|
* Re-attaches the wrapper to a live container when the previously resolved
|
|
23253
23513
|
* one has been detached or no longer holds the wrapper — e.g. the host app
|
|
23254
23514
|
* remounted a custom preRenderContainer, which would otherwise leave a stale
|
|
23255
|
-
* reference and collapse the wrapper.
|
|
23256
|
-
*
|
|
23257
|
-
* is left untouched, as there is nothing to re-query.
|
|
23515
|
+
* reference and collapse the wrapper. Only string selectors can be
|
|
23516
|
+
* re-resolved; a container passed as an element is left untouched.
|
|
23258
23517
|
*/
|
|
23259
23518
|
reconcilePreRenderContainer() {
|
|
23260
23519
|
const wrapper = this.preRenderWrapper;
|
|
@@ -23273,6 +23532,14 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23273
23532
|
if (resolved === stored && stored.contains(wrapper)) {
|
|
23274
23533
|
return;
|
|
23275
23534
|
}
|
|
23535
|
+
if (this.containerScrollListener && stored !== resolved) {
|
|
23536
|
+
if (stored !== document.body) {
|
|
23537
|
+
stored.removeEventListener('scroll', this.containerScrollListener);
|
|
23538
|
+
}
|
|
23539
|
+
if (resolved !== document.body) {
|
|
23540
|
+
resolved.addEventListener('scroll', this.containerScrollListener);
|
|
23541
|
+
}
|
|
23542
|
+
}
|
|
23276
23543
|
this.preRenderContainerEl = resolved;
|
|
23277
23544
|
this.applyPreRenderContainerPositioning();
|
|
23278
23545
|
if (wrapper.parentNode !== resolved) {
|
|
@@ -23334,12 +23601,11 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23334
23601
|
*/
|
|
23335
23602
|
setIFrameHeight(height) {
|
|
23336
23603
|
if (this.isPreRendered) {
|
|
23337
|
-
const next = getCssDimension(height);
|
|
23338
23604
|
if (this.insertedDomEl) {
|
|
23339
|
-
this.insertedDomEl.style.height =
|
|
23605
|
+
this.insertedDomEl.style.height = getCssDimension(height);
|
|
23340
23606
|
}
|
|
23341
23607
|
else if (this.preRenderWrapper) {
|
|
23342
|
-
this.preRenderWrapper.style.height =
|
|
23608
|
+
this.preRenderWrapper.style.height = getCssDimension(height);
|
|
23343
23609
|
}
|
|
23344
23610
|
}
|
|
23345
23611
|
else {
|
|
@@ -23623,9 +23889,16 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23623
23889
|
* @param args
|
|
23624
23890
|
*/
|
|
23625
23891
|
async render() {
|
|
23892
|
+
var _a, _b, _c;
|
|
23626
23893
|
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_CALLED, {
|
|
23627
23894
|
embedComponentType: this.viewConfig.embedComponentType,
|
|
23628
23895
|
});
|
|
23896
|
+
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_INIT_ACTIONS, {
|
|
23897
|
+
embedComponentType: this.viewConfig.embedComponentType,
|
|
23898
|
+
hiddenActions: (_a = this.viewConfig.hiddenActions) !== null && _a !== void 0 ? _a : [],
|
|
23899
|
+
visibleActions: (_b = this.viewConfig.visibleActions) !== null && _b !== void 0 ? _b : [],
|
|
23900
|
+
disabledActions: (_c = this.viewConfig.disabledActions) !== null && _c !== void 0 ? _c : [],
|
|
23901
|
+
});
|
|
23629
23902
|
if (!getIsInitCalled()) {
|
|
23630
23903
|
logger$3.error(ERROR_MESSAGE.RENDER_CALLED_BEFORE_INIT);
|
|
23631
23904
|
}
|
|
@@ -23774,47 +24047,34 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23774
24047
|
delete container.dataset[PRERENDER_CONTAINER_ORIGINAL_POSITION_KEY];
|
|
23775
24048
|
}
|
|
23776
24049
|
/**
|
|
23777
|
-
*
|
|
23778
|
-
|
|
23779
|
-
|
|
23780
|
-
|
|
23781
|
-
* browser's job and costs nothing; repositioning it on scroll would mean a
|
|
23782
|
-
* layout read and a style write per frame to compensate for placing it in
|
|
23783
|
-
* the wrong box. Size is the one thing the browser will not do for us: the
|
|
23784
|
-
* placeholder grows when the embedded app reports a new height, and the
|
|
23785
|
-
* wrapper has to be told.
|
|
23786
|
-
*/
|
|
23787
|
-
observePreRenderSize() {
|
|
23788
|
-
var _a;
|
|
23789
|
-
if (this.getPreRenderConfig().doNotTrackSize || typeof ResizeObserver === 'undefined') {
|
|
23790
|
-
return;
|
|
23791
|
-
}
|
|
23792
|
-
const placeholder = this.getPreRenderPlaceHolderElement();
|
|
23793
|
-
if (!placeholder) {
|
|
24050
|
+
* Detaches and clears the container scroll listener, if one is attached.
|
|
24051
|
+
*/
|
|
24052
|
+
removeContainerScrollListener() {
|
|
24053
|
+
if (!this.containerScrollListener) {
|
|
23794
24054
|
return;
|
|
23795
24055
|
}
|
|
23796
|
-
|
|
23797
|
-
|
|
23798
|
-
this.
|
|
24056
|
+
const customContainer = this.getCustomPreRenderContainer();
|
|
24057
|
+
customContainer === null || customContainer === void 0 ? void 0 : customContainer.removeEventListener('scroll', this.containerScrollListener);
|
|
24058
|
+
this.containerScrollListener = null;
|
|
23799
24059
|
}
|
|
23800
24060
|
/**
|
|
23801
24061
|
* Destroys the ThoughtSpot embed, and remove any nodes from the DOM.
|
|
23802
24062
|
* @version SDK: 1.19.1 | ThoughtSpot: *
|
|
23803
24063
|
*/
|
|
23804
24064
|
destroy() {
|
|
23805
|
-
var _a, _b, _c
|
|
24065
|
+
var _a, _b, _c;
|
|
23806
24066
|
try {
|
|
23807
24067
|
this.removeFullscreenChangeHandler();
|
|
23808
|
-
|
|
24068
|
+
this.removeContainerScrollListener();
|
|
23809
24069
|
this.unsubscribeToEvents();
|
|
23810
|
-
(
|
|
24070
|
+
(_a = this.preRenderWrapper) === null || _a === void 0 ? void 0 : _a.remove();
|
|
23811
24071
|
this.restorePreRenderContainerPosition();
|
|
23812
24072
|
if (!this.isRendered) {
|
|
23813
24073
|
return;
|
|
23814
24074
|
}
|
|
23815
24075
|
if (!getEmbedConfig().waitForCleanupOnDestroy) {
|
|
23816
24076
|
this.trigger(exports.HostEvent.DestroyEmbed);
|
|
23817
|
-
(
|
|
24077
|
+
(_c = (_b = this.insertedDomEl) === null || _b === void 0 ? void 0 : _b.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(this.insertedDomEl);
|
|
23818
24078
|
}
|
|
23819
24079
|
else {
|
|
23820
24080
|
const cleanupTimeout = getEmbedConfig().cleanupTimeout;
|
|
@@ -23860,6 +24120,26 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23860
24120
|
this.isRendered = true;
|
|
23861
24121
|
return this.renderIFrame(prerenderFrameSrc);
|
|
23862
24122
|
}
|
|
24123
|
+
isConfigExcludedFromUrl() {
|
|
24124
|
+
var _a, _b, _c;
|
|
24125
|
+
const flag = (_b = (_a = this.viewConfig.additionalFlags) === null || _a === void 0 ? void 0 : _a.excludeConfigFromURL) !== null && _b !== void 0 ? _b : (_c = this.embedConfig.additionalFlags) === null || _c === void 0 ? void 0 : _c.excludeConfigFromURL;
|
|
24126
|
+
return flag === true || flag === 'true';
|
|
24127
|
+
}
|
|
24128
|
+
async triggerUpdateEmbedParams() {
|
|
24129
|
+
try {
|
|
24130
|
+
const params = await this.getUpdateEmbedParamsObject();
|
|
24131
|
+
this.trigger(exports.HostEvent.UpdateEmbedParams, params);
|
|
24132
|
+
}
|
|
24133
|
+
catch (error) {
|
|
24134
|
+
logger$3.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
|
|
24135
|
+
this.handleError({
|
|
24136
|
+
errorType: exports.ErrorDetailsTypes.API,
|
|
24137
|
+
message: (error === null || error === void 0 ? void 0 : error.message) || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
|
|
24138
|
+
code: exports.EmbedErrorCodes.UPDATE_PARAMS_FAILED,
|
|
24139
|
+
error: (error === null || error === void 0 ? void 0 : error.message) || error,
|
|
24140
|
+
});
|
|
24141
|
+
}
|
|
24142
|
+
}
|
|
23863
24143
|
beforePrerenderVisible() {
|
|
23864
24144
|
// We can ignore this as its a bit expensive and the newer customers
|
|
23865
24145
|
// have moved on to UpdateEmbedParams supported clusters
|
|
@@ -23870,17 +24150,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23870
24150
|
this.preRenderParamsApplied = new Promise((resolve) => {
|
|
23871
24151
|
this.executeAfterEmbedContainerLoaded(async () => {
|
|
23872
24152
|
try {
|
|
23873
|
-
|
|
23874
|
-
this.trigger(exports.HostEvent.UpdateEmbedParams, params);
|
|
23875
|
-
}
|
|
23876
|
-
catch (error) {
|
|
23877
|
-
logger$3.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
|
|
23878
|
-
this.handleError({
|
|
23879
|
-
errorType: exports.ErrorDetailsTypes.API,
|
|
23880
|
-
message: (error === null || error === void 0 ? void 0 : error.message) || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
|
|
23881
|
-
code: exports.EmbedErrorCodes.UPDATE_PARAMS_FAILED,
|
|
23882
|
-
error: (error === null || error === void 0 ? void 0 : error.message) || error,
|
|
23883
|
-
});
|
|
24153
|
+
await this.triggerUpdateEmbedParams();
|
|
23884
24154
|
}
|
|
23885
24155
|
finally {
|
|
23886
24156
|
setTimeout(resolve, UPDATE_EMBED_PARAMS_SETTLE_MS);
|
|
@@ -23895,7 +24165,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23895
24165
|
* wrapper to overlay it.
|
|
23896
24166
|
*/
|
|
23897
24167
|
async showPreRender() {
|
|
23898
|
-
var _a;
|
|
24168
|
+
var _a, _b;
|
|
23899
24169
|
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_SHOW_PRE_RENDER, {
|
|
23900
24170
|
preRenderId: this.getPreRenderConfig().id,
|
|
23901
24171
|
embedComponentType: this.viewConfig.embedComponentType,
|
|
@@ -23914,16 +24184,14 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23914
24184
|
this.beforePrerenderVisible();
|
|
23915
24185
|
if (this.hostElement) {
|
|
23916
24186
|
this.insertedDomEl = this.createPreRenderPlaceholder();
|
|
23917
|
-
|
|
23918
|
-
|
|
23919
|
-
|
|
23920
|
-
|
|
23921
|
-
|
|
23922
|
-
|
|
23923
|
-
|
|
23924
|
-
|
|
23925
|
-
&& wrapperHeight !== UNMEASURED_WRAPPER_HEIGHT) {
|
|
23926
|
-
this.insertedDomEl.style.height = wrapperHeight;
|
|
24187
|
+
if (this.viewConfig.fullHeight) {
|
|
24188
|
+
// If fullHeight has already sized the wrapper, seed the
|
|
24189
|
+
// placeholder with the same height so syncPreRenderStyle gets
|
|
24190
|
+
// an accurate rect.
|
|
24191
|
+
const existingHeight = this.preRenderWrapper.style.height;
|
|
24192
|
+
if (existingHeight) {
|
|
24193
|
+
this.insertedDomEl.style.height = existingHeight;
|
|
24194
|
+
}
|
|
23927
24195
|
}
|
|
23928
24196
|
const placeHolderId = this.getPreRenderIds().placeHolder;
|
|
23929
24197
|
// Remove any stale placeholder from a previous cycle. It is located
|
|
@@ -23937,19 +24205,29 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
23937
24205
|
(_a = this.hostElement.querySelector(`#${placeHolderId}`)) === null || _a === void 0 ? void 0 : _a.remove();
|
|
23938
24206
|
this.hostElement.appendChild(this.insertedDomEl);
|
|
23939
24207
|
this.syncPreRenderStyle();
|
|
23940
|
-
this.
|
|
24208
|
+
const customContainer = this.getCustomPreRenderContainer();
|
|
24209
|
+
if (customContainer && !this.containerScrollListener) {
|
|
24210
|
+
this.containerScrollListener = () => this.syncPreRenderStyle();
|
|
24211
|
+
customContainer.addEventListener('scroll', this.containerScrollListener);
|
|
24212
|
+
}
|
|
24213
|
+
if (!this.getPreRenderConfig().doNotTrackSize) {
|
|
24214
|
+
const observeTarget = (_b = this.insertedDomEl) !== null && _b !== void 0 ? _b : this.hostElement;
|
|
24215
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
24216
|
+
entries.forEach((entry) => {
|
|
24217
|
+
if (entry.target === observeTarget) {
|
|
24218
|
+
this.syncPreRenderStyle();
|
|
24219
|
+
}
|
|
24220
|
+
});
|
|
24221
|
+
});
|
|
24222
|
+
this.resizeObserver.observe(observeTarget);
|
|
24223
|
+
}
|
|
23941
24224
|
}
|
|
23942
24225
|
removeStyleProperties(this.preRenderWrapper, [
|
|
23943
24226
|
'z-index',
|
|
23944
24227
|
'opacity',
|
|
24228
|
+
'pointer-events',
|
|
23945
24229
|
'overflow',
|
|
23946
|
-
'transform',
|
|
23947
24230
|
]);
|
|
23948
|
-
// Set rather than removed: a container that carries `pointer-events:
|
|
23949
|
-
// none` — the usual styling for a parking root that must not swallow
|
|
23950
|
-
// clicks — passes it down, and dropping the property here would leave
|
|
23951
|
-
// the inherited `none` in force and the frame dead to input.
|
|
23952
|
-
setStyleProperties(this.preRenderWrapper, { pointerEvents: 'auto' });
|
|
23953
24231
|
this.subscribeToEvents();
|
|
23954
24232
|
// Setup fullscreen change handler for prerendered components
|
|
23955
24233
|
if (this.iFrame) {
|
|
@@ -24002,7 +24280,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
24002
24280
|
* If the component is not preRendered, it issues a warning.
|
|
24003
24281
|
*/
|
|
24004
24282
|
hidePreRender() {
|
|
24005
|
-
var _a;
|
|
24006
24283
|
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_HIDE_PRE_RENDER, {
|
|
24007
24284
|
preRenderId: this.getPreRenderConfig().id,
|
|
24008
24285
|
embedComponentType: this.viewConfig.embedComponentType,
|
|
@@ -24022,15 +24299,12 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
24022
24299
|
top: '0',
|
|
24023
24300
|
left: '0',
|
|
24024
24301
|
overflow: 'hidden',
|
|
24025
|
-
// Keeps the measured size — so the next show needs no resize, which
|
|
24026
|
-
// is the point of pre-rendering — while lifting the box out of
|
|
24027
|
-
// the container's scrollable area. Overflow only extends
|
|
24028
|
-
// downwards, so a hidden frame parked above the top edge adds
|
|
24029
|
-
// none, where one left at full height shows as blank scroll space.
|
|
24030
|
-
transform: PRERENDER_PARKED_TRANSFORM,
|
|
24031
24302
|
};
|
|
24032
24303
|
setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
|
|
24033
|
-
|
|
24304
|
+
this.removeContainerScrollListener();
|
|
24305
|
+
if (this.resizeObserver) {
|
|
24306
|
+
this.resizeObserver.disconnect();
|
|
24307
|
+
}
|
|
24034
24308
|
const placeHolderEle = this.getPreRenderPlaceHolderElement();
|
|
24035
24309
|
if (placeHolderEle) {
|
|
24036
24310
|
placeHolderEle.parentElement.removeChild(placeHolderEle);
|
|
@@ -24259,7 +24533,19 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
24259
24533
|
spotterAnalystConfig,
|
|
24260
24534
|
},
|
|
24261
24535
|
};
|
|
24262
|
-
}
|
|
24536
|
+
}
|
|
24537
|
+
/**
|
|
24538
|
+
* The Spotter experience version to load in the embedded view.
|
|
24539
|
+
* @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
24540
|
+
* @group Embed components
|
|
24541
|
+
*/
|
|
24542
|
+
exports.SpotterExperienceVersion = void 0;
|
|
24543
|
+
(function (SpotterExperienceVersion) {
|
|
24544
|
+
/**
|
|
24545
|
+
* The Spotter experience version introduced in ThoughtSpot 26.11.
|
|
24546
|
+
*/
|
|
24547
|
+
SpotterExperienceVersion["SPOTTER_2026_11"] = "spotter_2026_11";
|
|
24548
|
+
})(exports.SpotterExperienceVersion || (exports.SpotterExperienceVersion = {}));
|
|
24263
24549
|
|
|
24264
24550
|
function buildSpotterVizAppInitData(initData, viewConfig) {
|
|
24265
24551
|
const { spotterViz } = viewConfig;
|
|
@@ -24456,12 +24742,12 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
24456
24742
|
* embedded Liveboard or visualization.
|
|
24457
24743
|
*/
|
|
24458
24744
|
getEmbedParams() {
|
|
24459
|
-
const params = this.
|
|
24745
|
+
const params = this.getUrlQueryParamsObject();
|
|
24460
24746
|
return getQueryParamString(params, true);
|
|
24461
24747
|
}
|
|
24462
24748
|
getEmbedParamsObject() {
|
|
24463
24749
|
var _a;
|
|
24464
|
-
const { tag, hideTagFilterChips, hideObjects, liveboardV2, showPrimaryNavbar, disableProfileAndHelp, hideHamburger, hideObjectSearch, hideNotification, hideApplicationSwitcher, hideOrgSwitcher, enableSearchAssist, newConnectionsExperience, dataPanelV2 = true, updatedSpotterExperience, hideLiveboardHeader = false, showLiveboardTitle = true, showLiveboardDescription = true, showMaskedFilterChip = false, isLiveboardMasterpiecesEnabled, newChartsLibrary, hideHomepageLeftNav = false, modularHomeExperience, isLiveboardHeaderSticky = true, enableAskSage, collapseSearchBarInitially = false, enable2ColumnLayout, isLiveboardAlwaysOn12ColLayout, enableCustomColumnGroups = false, dataPanelCustomGroupsAccordionInitialState = exports.DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL, collapseSearchBar = true, isLiveboardCompactHeaderEnabled, showLiveboardVerifiedBadge = true, showLiveboardReverifyBanner = true, hideIrrelevantChipsInLiveboardTabs, isEnhancedFilterInteractivityEnabled, homePageSearchBarMode, isUnifiedSearchExperienceEnabled = true, enablePendoHelp = true, discoveryExperience, coverAndFilterOptionInPDF, isLiveboardStylingAndGroupingEnabled, liveboardGutter, isPNGInScheduledEmailsEnabled = false, isLiveboardXLSXCSVDownloadEnabled, isGranularXLSXCSVSchedulesEnabled, isCentralizedLiveboardFilterUXEnabled = false, isScopedLiveboardFilteringEnabled, isLinkParametersEnabled, updatedSpotterChatPrompt, showSpotterRadiance, defaultQueryMode, enableStopAnswerGenerationEmbed, spotterChatConfig, spotterDataSources, isThisPeriodInDateFiltersEnabled, enableHomepageAnnouncement = false, isContinuousLiveboardPDFEnabled, enableLiveboardDataCache, hideAnswerEditPanel, } = this.viewConfig;
|
|
24750
|
+
const { tag, hideTagFilterChips, hideObjects, liveboardV2, showPrimaryNavbar, disableProfileAndHelp, hideHamburger, hideObjectSearch, hideNotification, hideApplicationSwitcher, hideOrgSwitcher, enableSearchAssist, newConnectionsExperience, dataPanelV2 = true, updatedSpotterExperience, hideLiveboardHeader = false, showLiveboardTitle = true, showLiveboardDescription = true, showMaskedFilterChip = false, isLiveboardMasterpiecesEnabled, newChartsLibrary, hideHomepageLeftNav = false, modularHomeExperience, isLiveboardHeaderSticky = true, enableAskSage, collapseSearchBarInitially = false, enable2ColumnLayout, isLiveboardAlwaysOn12ColLayout, enableCustomColumnGroups = false, dataPanelCustomGroupsAccordionInitialState = exports.DataPanelCustomColumnGroupsAccordionState.EXPAND_ALL, collapseSearchBar = true, isLiveboardCompactHeaderEnabled, showLiveboardVerifiedBadge = true, showLiveboardReverifyBanner = true, hideIrrelevantChipsInLiveboardTabs, isEnhancedFilterInteractivityEnabled, homePageSearchBarMode, isUnifiedSearchExperienceEnabled = true, enablePendoHelp = true, discoveryExperience, coverAndFilterOptionInPDF, isLiveboardStylingAndGroupingEnabled, liveboardGutter, isPNGInScheduledEmailsEnabled = false, isLiveboardXLSXCSVDownloadEnabled, isGranularXLSXCSVSchedulesEnabled, isCentralizedLiveboardFilterUXEnabled = false, isScopedLiveboardFilteringEnabled, isLinkParametersEnabled, updatedSpotterChatPrompt, showSpotterRadiance, defaultQueryMode, enableStopAnswerGenerationEmbed, spotterChatConfig, spotterDataSources, isThisPeriodInDateFiltersEnabled, enableHomepageAnnouncement = false, isContinuousLiveboardPDFEnabled, enableLiveboardDataCache, hideAnswerEditPanel, spotterExperienceVersion, } = this.viewConfig;
|
|
24465
24751
|
let params = {};
|
|
24466
24752
|
params[Param.PrimaryNavHidden] = !showPrimaryNavbar;
|
|
24467
24753
|
params[Param.HideProfleAndHelp] = !!disableProfileAndHelp;
|
|
@@ -24516,6 +24802,9 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
24516
24802
|
if (spotterDataSources && spotterDataSources.length) {
|
|
24517
24803
|
params[Param.SpotterDataSources] = JSON.stringify(spotterDataSources);
|
|
24518
24804
|
}
|
|
24805
|
+
if (spotterExperienceVersion !== undefined) {
|
|
24806
|
+
params[Param.SpotterExperienceVersion] = spotterExperienceVersion;
|
|
24807
|
+
}
|
|
24519
24808
|
// Handle spotterChatConfig params
|
|
24520
24809
|
if (spotterChatConfig) {
|
|
24521
24810
|
const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, enableStarterPrompts, openSpotterOnLiveboardByDefault, } = spotterChatConfig;
|
|
@@ -24634,7 +24923,7 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
24634
24923
|
}
|
|
24635
24924
|
// Navigation V1/V2 and home page V1/V2 are deprecated. V3 is now the
|
|
24636
24925
|
// default experience, Need to send navigationVersion=v3 and
|
|
24637
|
-
// homepageVersion=v3 even when the no discoveryExperience /
|
|
24926
|
+
// homepageVersion=v3 even when the no discoveryExperience /
|
|
24638
24927
|
// modularHomeExperience config is set. Without these
|
|
24639
24928
|
// params, older TSA versions (< 26.7) fall back to V2 for nav and
|
|
24640
24929
|
// home page, so the defaults must be sent explicitly from the SDK.
|
|
@@ -24773,46 +25062,6 @@ mutation GetUnsavedAnswerTML($session: BachSessionIdInput!, $exportDependencies:
|
|
|
24773
25062
|
}
|
|
24774
25063
|
}
|
|
24775
25064
|
|
|
24776
|
-
/**
|
|
24777
|
-
* This method is like `_.isEqual` except that it accepts `customizer` which
|
|
24778
|
-
* is invoked to compare values. If `customizer` returns `undefined`, comparisons
|
|
24779
|
-
* are handled by the method instead. The `customizer` is invoked with up to
|
|
24780
|
-
* six arguments: (objValue, othValue [, index|key, object, other, stack]).
|
|
24781
|
-
*
|
|
24782
|
-
* @static
|
|
24783
|
-
* @memberOf _
|
|
24784
|
-
* @since 4.0.0
|
|
24785
|
-
* @category Lang
|
|
24786
|
-
* @param {*} value The value to compare.
|
|
24787
|
-
* @param {*} other The other value to compare.
|
|
24788
|
-
* @param {Function} [customizer] The function to customize comparisons.
|
|
24789
|
-
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
24790
|
-
* @example
|
|
24791
|
-
*
|
|
24792
|
-
* function isGreeting(value) {
|
|
24793
|
-
* return /^h(?:i|ello)$/.test(value);
|
|
24794
|
-
* }
|
|
24795
|
-
*
|
|
24796
|
-
* function customizer(objValue, othValue) {
|
|
24797
|
-
* if (isGreeting(objValue) && isGreeting(othValue)) {
|
|
24798
|
-
* return true;
|
|
24799
|
-
* }
|
|
24800
|
-
* }
|
|
24801
|
-
*
|
|
24802
|
-
* var array = ['hello', 'goodbye'];
|
|
24803
|
-
* var other = ['hi', 'goodbye'];
|
|
24804
|
-
*
|
|
24805
|
-
* _.isEqualWith(array, other, customizer);
|
|
24806
|
-
* // => true
|
|
24807
|
-
*/
|
|
24808
|
-
function isEqualWith(value, other, customizer) {
|
|
24809
|
-
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
24810
|
-
var result = customizer ? customizer(value, other) : undefined;
|
|
24811
|
-
return result === undefined ? _baseIsEqual(value, other, undefined, customizer) : !!result;
|
|
24812
|
-
}
|
|
24813
|
-
|
|
24814
|
-
var isEqualWith_1 = isEqualWith;
|
|
24815
|
-
|
|
24816
25065
|
const getPreviewQuery = `
|
|
24817
25066
|
query GetEurekaVizSnapshots(
|
|
24818
25067
|
$vizId: String!, $liveboardId: String!) {
|
|
@@ -24883,6 +25132,21 @@ query GetEurekaVizSnapshots(
|
|
|
24883
25132
|
document.head.insertAdjacentHTML('beforeend', previewStyles);
|
|
24884
25133
|
};
|
|
24885
25134
|
|
|
25135
|
+
function buildLiveboardOverrideAppInitData(initData, viewConfig) {
|
|
25136
|
+
var _a;
|
|
25137
|
+
const { liveboardOverride } = viewConfig;
|
|
25138
|
+
// ThoughtSpot ignores an override with no data source entries; skip it.
|
|
25139
|
+
if (!((_a = liveboardOverride === null || liveboardOverride === void 0 ? void 0 : liveboardOverride.dataSourceOverride) === null || _a === void 0 ? void 0 : _a.length))
|
|
25140
|
+
return initData;
|
|
25141
|
+
return {
|
|
25142
|
+
...initData,
|
|
25143
|
+
embedParams: {
|
|
25144
|
+
...(initData.embedParams || {}),
|
|
25145
|
+
liveboardOverride,
|
|
25146
|
+
},
|
|
25147
|
+
};
|
|
25148
|
+
}
|
|
25149
|
+
|
|
24886
25150
|
/**
|
|
24887
25151
|
* Copyright (c) 2022
|
|
24888
25152
|
*
|
|
@@ -24947,14 +25211,15 @@ query GetEurekaVizSnapshots(
|
|
|
24947
25211
|
async getAppInitData() {
|
|
24948
25212
|
const defaultAppInitData = await super.getAppInitData();
|
|
24949
25213
|
const vizInitData = buildSpotterVizAppInitData(defaultAppInitData, this.viewConfig);
|
|
24950
|
-
|
|
25214
|
+
const starterPromptsInitData = buildStarterPromptsAppInitData(vizInitData, this.viewConfig);
|
|
25215
|
+
return buildLiveboardOverrideAppInitData(starterPromptsInitData, this.viewConfig);
|
|
24951
25216
|
}
|
|
24952
25217
|
/**
|
|
24953
25218
|
* Construct a map of params to be passed on to the
|
|
24954
25219
|
* embedded Liveboard or visualization.
|
|
24955
25220
|
*/
|
|
24956
25221
|
getEmbedParams() {
|
|
24957
|
-
const params = this.
|
|
25222
|
+
const params = this.getUrlQueryParamsObject();
|
|
24958
25223
|
const queryParams = getQueryParamString(params, true);
|
|
24959
25224
|
return queryParams;
|
|
24960
25225
|
}
|
|
@@ -24962,7 +25227,7 @@ query GetEurekaVizSnapshots(
|
|
|
24962
25227
|
var _a;
|
|
24963
25228
|
let params = {};
|
|
24964
25229
|
params = this.getBaseQueryParams(params);
|
|
24965
|
-
const { enableVizTransformations, visibleVizs, liveboardV2, vizId, hideTabPanel, activeTabId, hideLiveboardHeader, showLiveboardDescription, showLiveboardTitle, isLiveboardHeaderSticky = true, isLiveboardCompactHeaderEnabled, showLiveboardVerifiedBadge = true, showLiveboardReverifyBanner = true, hideIrrelevantChipsInLiveboardTabs, showMaskedFilterChip = false, isLiveboardMasterpiecesEnabled, newChartsLibrary, isEnhancedFilterInteractivityEnabled, enableAskSage, enable2ColumnLayout, isLiveboardAlwaysOn12ColLayout, dataPanelV2 = true, updatedSpotterExperience, enableCustomColumnGroups = false, oAuthPollingInterval, isForceRedirect, dataSourceId, coverAndFilterOptionInPDF, isLiveboardStylingAndGroupingEnabled, liveboardGutter, isPNGInScheduledEmailsEnabled = false, isLiveboardXLSXCSVDownloadEnabled, isGranularXLSXCSVSchedulesEnabled, showSpotterLimitations, isCentralizedLiveboardFilterUXEnabled = false, isScopedLiveboardFilteringEnabled, isLinkParametersEnabled, updatedSpotterChatPrompt, showSpotterRadiance, enableStopAnswerGenerationEmbed, spotterChatConfig, isThisPeriodInDateFiltersEnabled, isContinuousLiveboardPDFEnabled, enableLiveboardDataCache, } = this.viewConfig;
|
|
25230
|
+
const { enableVizTransformations, visibleVizs, liveboardV2, vizId, hideTabPanel, activeTabId, hideLiveboardHeader, showLiveboardDescription, showLiveboardTitle, isLiveboardHeaderSticky = true, isLiveboardCompactHeaderEnabled, showLiveboardVerifiedBadge = true, showLiveboardReverifyBanner = true, hideIrrelevantChipsInLiveboardTabs, showMaskedFilterChip = false, isLiveboardMasterpiecesEnabled, newChartsLibrary, isEnhancedFilterInteractivityEnabled, enableAskSage, enable2ColumnLayout, isLiveboardAlwaysOn12ColLayout, dataPanelV2 = true, updatedSpotterExperience, enableCustomColumnGroups = false, oAuthPollingInterval, isForceRedirect, dataSourceId, coverAndFilterOptionInPDF, isLiveboardStylingAndGroupingEnabled, liveboardGutter, isPNGInScheduledEmailsEnabled = false, isLiveboardXLSXCSVDownloadEnabled, isGranularXLSXCSVSchedulesEnabled, showSpotterLimitations, isCentralizedLiveboardFilterUXEnabled = false, isScopedLiveboardFilteringEnabled, isLinkParametersEnabled, updatedSpotterChatPrompt, showSpotterRadiance, enableStopAnswerGenerationEmbed, spotterChatConfig, isThisPeriodInDateFiltersEnabled, isContinuousLiveboardPDFEnabled, enableLiveboardDataCache, spotterExperienceVersion, } = this.viewConfig;
|
|
24966
25231
|
const preventLiveboardFilterRemoval = this.viewConfig.preventLiveboardFilterRemoval
|
|
24967
25232
|
|| this.viewConfig.preventPinboardFilterRemoval;
|
|
24968
25233
|
(_a = this.fullHeightController) === null || _a === void 0 ? void 0 : _a.addQueryParams(params);
|
|
@@ -25024,6 +25289,9 @@ query GetEurekaVizSnapshots(
|
|
|
25024
25289
|
if (isLiveboardStylingAndGroupingEnabled !== undefined) {
|
|
25025
25290
|
params[Param.IsLiveboardStylingAndGroupingEnabled] = isLiveboardStylingAndGroupingEnabled;
|
|
25026
25291
|
}
|
|
25292
|
+
if (spotterExperienceVersion !== undefined) {
|
|
25293
|
+
params[Param.SpotterExperienceVersion] = spotterExperienceVersion;
|
|
25294
|
+
}
|
|
25027
25295
|
if (liveboardGutter !== undefined) {
|
|
25028
25296
|
params[Param.LiveboardGutter] = liveboardGutter;
|
|
25029
25297
|
}
|
|
@@ -25193,12 +25461,10 @@ query GetEurekaVizSnapshots(
|
|
|
25193
25461
|
beforePrerenderVisible() {
|
|
25194
25462
|
super.beforePrerenderVisible();
|
|
25195
25463
|
// Captured before showPreRender() hands the wrapper over to this
|
|
25196
|
-
// instance.
|
|
25197
|
-
//
|
|
25464
|
+
// instance. Itself means a hide/show, not a hand-over, so there is
|
|
25465
|
+
// nothing stale to clear.
|
|
25198
25466
|
const previous = this.getPreRenderObj();
|
|
25199
|
-
const showing = this.
|
|
25200
|
-
? undefined
|
|
25201
|
-
: previous === null || previous === void 0 ? void 0 : previous.currentLiveboardState;
|
|
25467
|
+
const showing = previous === this ? undefined : previous === null || previous === void 0 ? void 0 : previous.currentLiveboardState;
|
|
25202
25468
|
this.executeAfterEmbedContainerLoaded(async () => {
|
|
25203
25469
|
// Without this the params callback suspends on its await and
|
|
25204
25470
|
// Navigate goes out first, so the container loads with the previous
|
|
@@ -25225,14 +25491,6 @@ query GetEurekaVizSnapshots(
|
|
|
25225
25491
|
};
|
|
25226
25492
|
});
|
|
25227
25493
|
}
|
|
25228
|
-
// Callbacks are compared as equal: React passes a fresh closure per render.
|
|
25229
|
-
isSameEmbedConfig(previous) {
|
|
25230
|
-
if (!previous)
|
|
25231
|
-
return false;
|
|
25232
|
-
if (previous === this)
|
|
25233
|
-
return true;
|
|
25234
|
-
return isEqualWith_1(previous.viewConfig, this.viewConfig, (a, b) => (typeof a === 'function' && typeof b === 'function' ? true : undefined));
|
|
25235
|
-
}
|
|
25236
25494
|
// The whole route, not just the liveboard id: the path is built from the
|
|
25237
25495
|
// viz, tab and view too, so a same-liveboard show onto another tab is a
|
|
25238
25496
|
// real navigation.
|
|
@@ -25495,7 +25753,7 @@ query GetEurekaVizSnapshots(
|
|
|
25495
25753
|
}
|
|
25496
25754
|
getEmbedParams() {
|
|
25497
25755
|
const { runtimeParameters, runtimeFilters, excludeRuntimeParametersfromURL, excludeRuntimeFiltersfromURL, } = this.viewConfig;
|
|
25498
|
-
const queryParams = this.
|
|
25756
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
25499
25757
|
let query = '';
|
|
25500
25758
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
25501
25759
|
if (queryParamsString) {
|
|
@@ -25583,7 +25841,7 @@ query GetEurekaVizSnapshots(
|
|
|
25583
25841
|
* @param dataSources A list of data source GUIDs
|
|
25584
25842
|
*/
|
|
25585
25843
|
getIFrameSrc() {
|
|
25586
|
-
const queryParams = this.
|
|
25844
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
25587
25845
|
const path = 'search-bar-embed';
|
|
25588
25846
|
let query = '';
|
|
25589
25847
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
@@ -26017,7 +26275,7 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
|
|
|
26017
26275
|
getIframeSrc() {
|
|
26018
26276
|
const { sessionId, genNo, acSessionId, acGenNo, convId, messageId, } = this.viewConfig;
|
|
26019
26277
|
const path = 'conv-assist-answer';
|
|
26020
|
-
const queryParams = this.
|
|
26278
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
26021
26279
|
let query = '';
|
|
26022
26280
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
26023
26281
|
if (queryParamsString) {
|
|
@@ -26214,18 +26472,22 @@ query SendMessage($params: Input_convassist_SendMessageRequest) {
|
|
|
26214
26472
|
}
|
|
26215
26473
|
}
|
|
26216
26474
|
setParamIfDefined(queryParams, Param.UpdatedSpotterExperience, updatedSpotterExperience, true);
|
|
26475
|
+
setParamIfDefined(queryParams, Param.SpotterExperienceVersion, this.viewConfig.spotterExperienceVersion);
|
|
26217
26476
|
return queryParams;
|
|
26218
26477
|
}
|
|
26219
26478
|
getIframeSrc() {
|
|
26220
|
-
const { worksheetId, searchOptions, runtimeFilters, excludeRuntimeFiltersfromURL, runtimeParameters, excludeRuntimeParametersfromURL, sharedConversationId, dataSources, } = this.viewConfig;
|
|
26479
|
+
const { worksheetId, searchOptions, runtimeFilters, excludeRuntimeFiltersfromURL, runtimeParameters, excludeRuntimeParametersfromURL, sharedConversationId, dataSources, spotterExperienceVersion, } = this.viewConfig;
|
|
26221
26480
|
// Deep-link into the read-only shared-conversation reader view when a
|
|
26222
26481
|
// shared conversation id is supplied (e.g. a recipient landing from a
|
|
26223
26482
|
// host-configured CONVERSATION_URL share link); otherwise the normal
|
|
26224
26483
|
// Spotter conversation surface.
|
|
26225
|
-
|
|
26484
|
+
let path = sharedConversationId
|
|
26226
26485
|
? `insights/conv-assist/s/${encodeURIComponent(sharedConversationId)}`
|
|
26227
26486
|
: 'insights/conv-assist';
|
|
26228
|
-
|
|
26487
|
+
if (spotterExperienceVersion === exports.SpotterExperienceVersion.SPOTTER_2026_11) {
|
|
26488
|
+
path = path.replace('insights/conv-assist', 'insights/spotter');
|
|
26489
|
+
}
|
|
26490
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
26229
26491
|
let query = '';
|
|
26230
26492
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
26231
26493
|
if (queryParamsString) {
|
|
@@ -27015,6 +27277,20 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
|
|
|
27015
27277
|
return { filters: [...liveboardFilterParams, ...runtimeFilterParams] };
|
|
27016
27278
|
}
|
|
27017
27279
|
|
|
27280
|
+
/**
|
|
27281
|
+
* Route the ThoughtSpot application uses to render a single conversational
|
|
27282
|
+
* answer. Used when a replayed frame carries no route of its own.
|
|
27283
|
+
*/
|
|
27284
|
+
const CONV_ASSIST_ANSWER_ROUTE = '/embed/conv-assist-answer';
|
|
27285
|
+
/**
|
|
27286
|
+
* Base path of the conversation service, proxied by the cluster's nginx as
|
|
27287
|
+
* the `convex` upstream. These are the same handlers the public
|
|
27288
|
+
* `/api/rest/2.0/ai/agent/conversations/...` endpoints proxy to, so the
|
|
27289
|
+
* response shapes are identical, but calling them directly skips the prism
|
|
27290
|
+
* hop and its error re-wrapping.
|
|
27291
|
+
*/
|
|
27292
|
+
const CONVERSATION_SERVICE_PATH = '/conversation/v2';
|
|
27293
|
+
const DEFAULT_STALE_ANSWER_NOTICE = 'This data may have changed since the last time you had a chat.';
|
|
27018
27294
|
/**
|
|
27019
27295
|
* Starts an automatic renderer that watches the DOM for iframes containing
|
|
27020
27296
|
* the `tsmcp=true` query parameter and replaces them with fully configured
|
|
@@ -27077,6 +27353,111 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
|
|
|
27077
27353
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
27078
27354
|
return observer;
|
|
27079
27355
|
}
|
|
27356
|
+
/**
|
|
27357
|
+
* Writes resolved session parameters into the route's hash query string,
|
|
27358
|
+
* preserving the route and any other hash params the source URL carried.
|
|
27359
|
+
*
|
|
27360
|
+
* @param sourceHash - The source URL's hash, with or without a leading `#`.
|
|
27361
|
+
* Falls back to the conversational-answer route when empty, so a host app
|
|
27362
|
+
* replaying a chat need only supply the conversation identifier.
|
|
27363
|
+
*/
|
|
27364
|
+
function buildAnswerHash(sourceHash, resolved) {
|
|
27365
|
+
const withoutHash = (sourceHash || '').replace('#', '');
|
|
27366
|
+
const [route, existingQuery] = withoutHash.split('?');
|
|
27367
|
+
const params = new URLSearchParams(existingQuery || '');
|
|
27368
|
+
Object.entries(resolved).forEach(([key, value]) => params.set(key, value));
|
|
27369
|
+
return `${route || CONV_ASSIST_ANSWER_ROUTE}?${params.toString()}`;
|
|
27370
|
+
}
|
|
27371
|
+
/**
|
|
27372
|
+
* Reads {@link Param.TsmcpAnswerIndex} as a whole, non-negative array index.
|
|
27373
|
+
*
|
|
27374
|
+
* Anything else - absent, malformed, fractional, negative - falls back to the
|
|
27375
|
+
* first answer rather than indexing with a value that can never match.
|
|
27376
|
+
*/
|
|
27377
|
+
function answerIndexFromParam(raw) {
|
|
27378
|
+
const parsed = Number(raw);
|
|
27379
|
+
return Number.isInteger(parsed) && parsed >= 0 ? parsed : 0;
|
|
27380
|
+
}
|
|
27381
|
+
/**
|
|
27382
|
+
* In-flight answer-id list requests, keyed by conversation-service URL.
|
|
27383
|
+
*
|
|
27384
|
+
* Replaying a stored chat mounts every one of its frames at once, and each
|
|
27385
|
+
* frame resolves on its own. Without this, N frames from one conversation make
|
|
27386
|
+
* N identical list calls. Sharing the in-flight request collapses them to one.
|
|
27387
|
+
*
|
|
27388
|
+
* Only the id list is shared, and only while its request is in flight: the
|
|
27389
|
+
* entry is dropped once the request settles, whether it succeeded or not. A
|
|
27390
|
+
* failed response is therefore never reused, and a frame mounted later always
|
|
27391
|
+
* reads a fresh list. The per-answer load call is never shared - it returns
|
|
27392
|
+
* live session state with its own expiry.
|
|
27393
|
+
*/
|
|
27394
|
+
const answerIdListRequests = new Map();
|
|
27395
|
+
/**
|
|
27396
|
+
* Lists a conversation's answer ids: its non-thinking `answer` items, in
|
|
27397
|
+
* message order. The host app counts answers the same way, so the Nth id here
|
|
27398
|
+
* is the Nth stored answer.
|
|
27399
|
+
*
|
|
27400
|
+
* @param conversationUrl - The conversation's base URL on the conversation
|
|
27401
|
+
* service, `{host}/conversation/v2/{encoded id}`.
|
|
27402
|
+
* @param conversationId - The conversation identifier, used in log messages.
|
|
27403
|
+
* @returns The ids, or `null` when the conversation cannot be read. Never
|
|
27404
|
+
* rejects, so callers sharing the request need no error handling of their own.
|
|
27405
|
+
*/
|
|
27406
|
+
async function fetchAnswerIds(conversationUrl, conversationId) {
|
|
27407
|
+
try {
|
|
27408
|
+
const messagesResponse = await tokenizedFetch(`${conversationUrl}/public`, {
|
|
27409
|
+
credentials: 'include',
|
|
27410
|
+
headers: { Accept: 'application/json' },
|
|
27411
|
+
});
|
|
27412
|
+
if (!messagesResponse.ok) {
|
|
27413
|
+
logger$3.warn(`[AutoFrameRenderer] Conversation fetch failed for ${conversationId}: ${messagesResponse.status}`);
|
|
27414
|
+
return null;
|
|
27415
|
+
}
|
|
27416
|
+
const messagesBody = await messagesResponse.json();
|
|
27417
|
+
const messages = messagesBody === null || messagesBody === void 0 ? void 0 : messagesBody.messages;
|
|
27418
|
+
const answerIds = [];
|
|
27419
|
+
for (const message of Array.isArray(messages) ? messages : []) {
|
|
27420
|
+
for (const item of (message === null || message === void 0 ? void 0 : message.response_items) || []) {
|
|
27421
|
+
if ((item === null || item === void 0 ? void 0 : item.type) === 'answer' && (item === null || item === void 0 ? void 0 : item.is_thinking) === false && (item === null || item === void 0 ? void 0 : item.answer_id)) {
|
|
27422
|
+
answerIds.push(item.answer_id);
|
|
27423
|
+
}
|
|
27424
|
+
}
|
|
27425
|
+
}
|
|
27426
|
+
return answerIds;
|
|
27427
|
+
}
|
|
27428
|
+
catch (e) {
|
|
27429
|
+
logger$3.warn(`[AutoFrameRenderer] Failed to list answers for ${conversationId}: ${e}`);
|
|
27430
|
+
return null;
|
|
27431
|
+
}
|
|
27432
|
+
}
|
|
27433
|
+
/**
|
|
27434
|
+
* The answer-id list for a conversation, joining a request already in flight
|
|
27435
|
+
* for it.
|
|
27436
|
+
*
|
|
27437
|
+
* @param conversationUrl - The conversation's base URL on the conversation
|
|
27438
|
+
* service. Also the key requests are shared under.
|
|
27439
|
+
* @param conversationId - The conversation identifier, used in log messages.
|
|
27440
|
+
* @param stale - A request the caller already read and found too short. It is
|
|
27441
|
+
* not reused; the first caller to pass it starts a new request, and the
|
|
27442
|
+
* others join that one.
|
|
27443
|
+
* @returns The shared request: the ids, or `null` when the conversation cannot
|
|
27444
|
+
* be read. Never rejects.
|
|
27445
|
+
*/
|
|
27446
|
+
function getAnswerIds(conversationUrl, conversationId, stale) {
|
|
27447
|
+
const inFlight = answerIdListRequests.get(conversationUrl);
|
|
27448
|
+
if (inFlight && inFlight !== stale) {
|
|
27449
|
+
return inFlight;
|
|
27450
|
+
}
|
|
27451
|
+
const request = fetchAnswerIds(conversationUrl, conversationId);
|
|
27452
|
+
answerIdListRequests.set(conversationUrl, request);
|
|
27453
|
+
const release = () => {
|
|
27454
|
+
if (answerIdListRequests.get(conversationUrl) === request) {
|
|
27455
|
+
answerIdListRequests.delete(conversationUrl);
|
|
27456
|
+
}
|
|
27457
|
+
};
|
|
27458
|
+
request.then(release, release);
|
|
27459
|
+
return request;
|
|
27460
|
+
}
|
|
27080
27461
|
function isTSMCPIframe(iframe) {
|
|
27081
27462
|
try {
|
|
27082
27463
|
const url = new URL(iframe.src);
|
|
@@ -27110,20 +27491,112 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
|
|
|
27110
27491
|
* ThoughtSpot application.
|
|
27111
27492
|
*
|
|
27112
27493
|
* @param sourceSrc - The original iframe's `src` URL string.
|
|
27494
|
+
* @param preserveSourceUrl - When true, return the source URL unchanged.
|
|
27113
27495
|
* @returns The constructed URL to use for the ThoughtSpot embed iframe.
|
|
27114
27496
|
*/
|
|
27115
|
-
getMCPIframeSrc(sourceSrc) {
|
|
27116
|
-
|
|
27497
|
+
getMCPIframeSrc(sourceSrc, resolved, preserveSourceUrl = false) {
|
|
27498
|
+
if (preserveSourceUrl) {
|
|
27499
|
+
return sourceSrc;
|
|
27500
|
+
}
|
|
27501
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
27117
27502
|
const sourceURL = new URL(sourceSrc);
|
|
27118
27503
|
const existingQueryParams = sourceURL.searchParams;
|
|
27119
27504
|
const existingQueryParamsObject = Object.fromEntries(existingQueryParams);
|
|
27120
27505
|
delete existingQueryParamsObject[Param.Tsmcp];
|
|
27506
|
+
// Replay markers address the SDK, not the ThoughtSpot application.
|
|
27507
|
+
delete existingQueryParamsObject[Param.TsmcpConversationId];
|
|
27508
|
+
delete existingQueryParamsObject[Param.TsmcpAnswerIndex];
|
|
27121
27509
|
const mergedQueryParams = { ...queryParams, ...existingQueryParamsObject };
|
|
27122
27510
|
const mergedQueryParamsString = getQueryParamString(mergedQueryParams, true);
|
|
27123
27511
|
const queryString = mergedQueryParamsString ? `?${mergedQueryParamsString}` : '';
|
|
27124
|
-
const
|
|
27512
|
+
const hash = resolved
|
|
27513
|
+
? buildAnswerHash(sourceURL.hash, resolved)
|
|
27514
|
+
: sourceURL.hash.replace('#', '');
|
|
27515
|
+
const frameSrc = `${this.getEmbedBasePath(queryString)}${hash}`;
|
|
27125
27516
|
return frameSrc;
|
|
27126
27517
|
}
|
|
27518
|
+
/**
|
|
27519
|
+
* Resolves the current session parameters for an answer stored only as a
|
|
27520
|
+
* conversation identifier plus an ordinal position.
|
|
27521
|
+
*
|
|
27522
|
+
* The answer object behind `sessionId`/`genNo` expires (roughly 8 hours),
|
|
27523
|
+
* so a host app replaying a stored chat cannot persist those values. It
|
|
27524
|
+
* persists the conversation identifier instead, and this walks the two
|
|
27525
|
+
* conversation-service APIs to rebuild them:
|
|
27526
|
+
*
|
|
27527
|
+
* 1. `GET {conv}/public` lists the conversation's messages; the
|
|
27528
|
+
* non-thinking `answer` items, in message order, give the answer ids.
|
|
27529
|
+
* Frames from the same conversation share one in-flight call - see
|
|
27530
|
+
* {@link getAnswerIds}.
|
|
27531
|
+
* 2. `POST {conv}/message/{id}/load/public` turns the answer id at
|
|
27532
|
+
* `answerIndex` into a live session identifier, generation number and
|
|
27533
|
+
* agent-context state.
|
|
27534
|
+
*
|
|
27535
|
+
* @returns The resolved parameters, or `null` when resolution fails - the
|
|
27536
|
+
* caller then falls back to whatever the source URL already carried.
|
|
27537
|
+
*/
|
|
27538
|
+
async resolveAnswerSessionParams(conversationId, answerIndex) {
|
|
27539
|
+
const base = `${this.thoughtSpotHost}${CONVERSATION_SERVICE_PATH}/${encodeURIComponent(conversationId)}`;
|
|
27540
|
+
try {
|
|
27541
|
+
const listRequest = getAnswerIds(base, conversationId);
|
|
27542
|
+
let answerIds = await listRequest;
|
|
27543
|
+
if (answerIds && !answerIds[answerIndex]) {
|
|
27544
|
+
// The list only grows, so a short one may predate this answer:
|
|
27545
|
+
// a frame that joined a request started before it was added.
|
|
27546
|
+
// Read the list once more before giving up.
|
|
27547
|
+
answerIds = await getAnswerIds(base, conversationId, listRequest);
|
|
27548
|
+
}
|
|
27549
|
+
if (!answerIds) {
|
|
27550
|
+
return null;
|
|
27551
|
+
}
|
|
27552
|
+
const answerId = answerIds[answerIndex];
|
|
27553
|
+
if (!answerId) {
|
|
27554
|
+
logger$3.warn(`[AutoFrameRenderer] No answer at index ${answerIndex} in conversation ${conversationId} (found ${answerIds.length}).`);
|
|
27555
|
+
return null;
|
|
27556
|
+
}
|
|
27557
|
+
// The load handler is a POST upstream; the public REST endpoint
|
|
27558
|
+
// exposed it as a GET and supplied this body on the caller's
|
|
27559
|
+
// behalf.
|
|
27560
|
+
const detailsResponse = await tokenizedFetch(`${base}/message/${encodeURIComponent(answerId)}/load/public`, {
|
|
27561
|
+
credentials: 'include',
|
|
27562
|
+
method: 'POST',
|
|
27563
|
+
headers: {
|
|
27564
|
+
Accept: 'application/json',
|
|
27565
|
+
'Content-Type': 'application/json',
|
|
27566
|
+
'x-requested-by': 'ThoughtSpot',
|
|
27567
|
+
},
|
|
27568
|
+
body: JSON.stringify({ type: 'TS_ANSWER' }),
|
|
27569
|
+
});
|
|
27570
|
+
if (!detailsResponse.ok) {
|
|
27571
|
+
logger$3.warn(`[AutoFrameRenderer] Answer load failed for ${answerId}: ${detailsResponse.status}`);
|
|
27572
|
+
return null;
|
|
27573
|
+
}
|
|
27574
|
+
const detailsBody = await detailsResponse.json();
|
|
27575
|
+
const answer = detailsBody === null || detailsBody === void 0 ? void 0 : detailsBody.answer;
|
|
27576
|
+
const acState = answer === null || answer === void 0 ? void 0 : answer.ac_state;
|
|
27577
|
+
// All four are nullable in the load-answer response. A missing
|
|
27578
|
+
// generation number is as unusable as a missing session id:
|
|
27579
|
+
// stringifying it would put a literal "null" in the hash. Fail
|
|
27580
|
+
// the resolve instead and let the caller fall back.
|
|
27581
|
+
if (!(answer === null || answer === void 0 ? void 0 : answer.session_identifier)
|
|
27582
|
+
|| !(acState === null || acState === void 0 ? void 0 : acState.transaction_identifier)
|
|
27583
|
+
|| !(Number.isInteger(answer.generation_number) && answer.generation_number > 0)
|
|
27584
|
+
|| !(Number.isInteger(acState.generation_number) && acState.generation_number > 0)) {
|
|
27585
|
+
logger$3.warn(`[AutoFrameRenderer] Answer load returned incomplete session state for ${answerId}.`);
|
|
27586
|
+
return null;
|
|
27587
|
+
}
|
|
27588
|
+
return {
|
|
27589
|
+
sessionId: answer.session_identifier,
|
|
27590
|
+
genNo: String(answer.generation_number),
|
|
27591
|
+
acSessionId: acState.transaction_identifier,
|
|
27592
|
+
acGenNo: String(acState.generation_number),
|
|
27593
|
+
};
|
|
27594
|
+
}
|
|
27595
|
+
catch (e) {
|
|
27596
|
+
logger$3.warn(`[AutoFrameRenderer] Failed to resolve stored answer: ${e}`);
|
|
27597
|
+
return null;
|
|
27598
|
+
}
|
|
27599
|
+
}
|
|
27127
27600
|
/**
|
|
27128
27601
|
* Overrides the base insertion behavior so the new embed iframe
|
|
27129
27602
|
* replaces the original iframe in-place rather than being appended
|
|
@@ -27152,10 +27625,37 @@ query GetEurekaResults($params: Input_eureka_SearchRequest) {
|
|
|
27152
27625
|
if (this.shouldWaitForRenderPromise) {
|
|
27153
27626
|
await this.isReadyForRenderPromise;
|
|
27154
27627
|
}
|
|
27155
|
-
|
|
27628
|
+
// Only frames that ask for it take the replay path. A frame straight
|
|
27629
|
+
// from the MCP server carries its own session params and no
|
|
27630
|
+
// conversation id, so it renders exactly as it always has.
|
|
27631
|
+
const sourceParams = new URL(iframe.src).searchParams;
|
|
27632
|
+
const conversationId = sourceParams.get(Param.TsmcpConversationId);
|
|
27633
|
+
let resolved = null;
|
|
27634
|
+
if (conversationId) {
|
|
27635
|
+
resolved = await this.resolveAnswerSessionParams(conversationId, answerIndexFromParam(sourceParams.get(Param.TsmcpAnswerIndex)));
|
|
27636
|
+
}
|
|
27637
|
+
const src = this.getMCPIframeSrc(iframe.src, resolved !== null && resolved !== void 0 ? resolved : undefined, Boolean(conversationId) && !resolved);
|
|
27156
27638
|
await this.renderIFrame(src);
|
|
27639
|
+
// Mark only answers actually re-resolved: their numbers were computed
|
|
27640
|
+
// now, not when the conversation happened.
|
|
27641
|
+
if (resolved && !this.viewConfig.suppressStaleAnswerNotice) {
|
|
27642
|
+
this.markAsStaleAnswer();
|
|
27643
|
+
}
|
|
27157
27644
|
this.isRendered = true;
|
|
27158
27645
|
}
|
|
27646
|
+
/**
|
|
27647
|
+
* Adds the "data may have changed" notice to the rendered frame as a
|
|
27648
|
+
* native tooltip, so it needs no stylesheet and cannot disturb the host
|
|
27649
|
+
* app's layout.
|
|
27650
|
+
*/
|
|
27651
|
+
markAsStaleAnswer() {
|
|
27652
|
+
if (!this.iFrame) {
|
|
27653
|
+
return;
|
|
27654
|
+
}
|
|
27655
|
+
this.iFrame.title = this.viewConfig.staleAnswerNoticeText || DEFAULT_STALE_ANSWER_NOTICE;
|
|
27656
|
+
// Exposed so a host app can style or replace the native tooltip.
|
|
27657
|
+
this.iFrame.dataset.tsStaleAnswer = 'true';
|
|
27658
|
+
}
|
|
27159
27659
|
}
|
|
27160
27660
|
|
|
27161
27661
|
const ALIAS = Symbol.for('yaml.alias');
|