@thoughtspot/visual-embed-sdk 1.52.2-beta.2 → 1.53.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 +1 -1
- package/cjs/src/contracts/contracts.spec.js +4 -0
- package/cjs/src/contracts/contracts.spec.js.map +1 -1
- package/cjs/src/contracts/host-event-contracts.d.ts +10 -0
- package/cjs/src/contracts/host-event-contracts.d.ts.map +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 +15 -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 +29 -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 +88 -0
- package/cjs/src/embed/conversation.spec.js.map +1 -1
- package/cjs/src/embed/host-events.spec.js +32 -0
- package/cjs/src/embed/host-events.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 +44 -13
- package/cjs/src/embed/liveboard.d.ts.map +1 -1
- package/cjs/src/embed/liveboard.js +19 -23
- package/cjs/src/embed/liveboard.js.map +1 -1
- package/cjs/src/embed/liveboard.spec.js +122 -0
- 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 +12 -0
- package/cjs/src/embed/spotter-utils.d.ts.map +1 -1
- package/cjs/src/embed/spotter-utils.js +20 -2
- package/cjs/src/embed/spotter-utils.js.map +1 -1
- package/cjs/src/embed/spotter-utils.spec.js +19 -0
- package/cjs/src/embed/spotter-utils.spec.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 +18 -20
- package/cjs/src/embed/ts-embed.d.ts.map +1 -1
- package/cjs/src/embed/ts-embed.js +181 -45
- 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 +610 -0
- package/cjs/src/embed/ts-embed.spec.js.map +1 -1
- package/cjs/src/index.d.ts +5 -3
- 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 +251 -4
- package/cjs/src/types.d.ts.map +1 -1
- package/cjs/src/types.js +176 -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/cjs/src/utils/runtimeTelemetry.d.ts +11 -0
- package/cjs/src/utils/runtimeTelemetry.d.ts.map +1 -0
- package/cjs/src/utils/runtimeTelemetry.js +34 -0
- package/cjs/src/utils/runtimeTelemetry.js.map +1 -0
- package/cjs/src/utils/runtimeTelemetry.spec.d.ts +2 -0
- package/cjs/src/utils/runtimeTelemetry.spec.d.ts.map +1 -0
- package/cjs/src/utils/runtimeTelemetry.spec.js +124 -0
- package/cjs/src/utils/runtimeTelemetry.spec.js.map +1 -0
- package/dist/{index-CnHREfvN.js → index-CrBnZBZv.js} +1 -1
- package/dist/src/contracts/host-event-contracts.d.ts +10 -0
- package/dist/src/contracts/host-event-contracts.d.ts.map +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 +15 -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 +29 -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 +44 -13
- package/dist/src/embed/liveboard.d.ts.map +1 -1
- package/dist/src/embed/spotter-utils.d.ts +12 -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 +18 -20
- 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 +5 -3
- 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 +251 -4
- 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/src/utils/runtimeTelemetry.d.ts +11 -0
- package/dist/src/utils/runtimeTelemetry.d.ts.map +1 -0
- package/dist/src/utils/runtimeTelemetry.spec.d.ts +2 -0
- package/dist/src/utils/runtimeTelemetry.spec.d.ts.map +1 -0
- package/dist/tsembed-react.es.js +500 -85
- package/dist/tsembed-react.js +499 -84
- package/dist/tsembed.es.js +743 -90
- package/dist/tsembed.js +741 -88
- package/dist/visual-embed-sdk-react-full.d.ts +788 -44
- package/dist/visual-embed-sdk-react.d.ts +783 -44
- package/dist/visual-embed-sdk.d.ts +815 -45
- package/lib/package.json +1 -1
- package/lib/src/contracts/contracts.spec.js +4 -0
- package/lib/src/contracts/contracts.spec.js.map +1 -1
- package/lib/src/contracts/host-event-contracts.d.ts +10 -0
- package/lib/src/contracts/host-event-contracts.d.ts.map +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 +15 -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 +29 -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 +89 -1
- package/lib/src/embed/conversation.spec.js.map +1 -1
- package/lib/src/embed/host-events.spec.js +32 -0
- package/lib/src/embed/host-events.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 +44 -13
- package/lib/src/embed/liveboard.d.ts.map +1 -1
- package/lib/src/embed/liveboard.js +19 -23
- package/lib/src/embed/liveboard.js.map +1 -1
- package/lib/src/embed/liveboard.spec.js +122 -0
- 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 +12 -0
- package/lib/src/embed/spotter-utils.d.ts.map +1 -1
- package/lib/src/embed/spotter-utils.js +19 -1
- package/lib/src/embed/spotter-utils.js.map +1 -1
- package/lib/src/embed/spotter-utils.spec.js +19 -0
- package/lib/src/embed/spotter-utils.spec.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 +18 -20
- package/lib/src/embed/ts-embed.d.ts.map +1 -1
- package/lib/src/embed/ts-embed.js +181 -45
- 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 +611 -1
- package/lib/src/embed/ts-embed.spec.js.map +1 -1
- package/lib/src/index.d.ts +5 -3
- 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 +251 -4
- package/lib/src/types.d.ts.map +1 -1
- package/lib/src/types.js +176 -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/utils/runtimeTelemetry.d.ts +11 -0
- package/lib/src/utils/runtimeTelemetry.d.ts.map +1 -0
- package/lib/src/utils/runtimeTelemetry.js +28 -0
- package/lib/src/utils/runtimeTelemetry.js.map +1 -0
- package/lib/src/utils/runtimeTelemetry.spec.d.ts +2 -0
- package/lib/src/utils/runtimeTelemetry.spec.d.ts.map +1 -0
- package/lib/src/utils/runtimeTelemetry.spec.js +122 -0
- package/lib/src/utils/runtimeTelemetry.spec.js.map +1 -0
- package/lib/src/visual-embed-sdk.d.ts +815 -45
- package/package.json +1 -1
- package/src/contracts/contracts.spec.ts +4 -0
- package/src/contracts/host-event-contracts.ts +13 -0
- package/src/css-variables.ts +475 -26
- package/src/embed/app.spec.ts +32 -0
- package/src/embed/app.ts +29 -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 +118 -1
- package/src/embed/conversation.ts +42 -3
- package/src/embed/host-events.spec.ts +44 -0
- 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 +138 -0
- package/src/embed/liveboard.ts +64 -24
- 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.spec.ts +20 -0
- package/src/embed/spotter-utils.ts +24 -1
- 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 +767 -0
- package/src/embed/ts-embed.ts +186 -41
- package/src/index.ts +18 -1
- package/src/mixpanel-service.ts +1 -0
- package/src/react/all-types-export.ts +7 -0
- package/src/types.ts +254 -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/src/utils/runtimeTelemetry.spec.ts +148 -0
- package/src/utils/runtimeTelemetry.ts +50 -0
package/dist/tsembed.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* @thoughtspot/visual-embed-sdk version 1.
|
|
1
|
+
/* @thoughtspot/visual-embed-sdk version 1.53.1 */
|
|
2
2
|
'use client';
|
|
3
3
|
function _mergeNamespaces(n, m) {
|
|
4
4
|
m.forEach(function (e) {
|
|
@@ -1208,6 +1208,36 @@ var EmbedEvent;
|
|
|
1208
1208
|
* ```
|
|
1209
1209
|
*/
|
|
1210
1210
|
EmbedEvent["Edit"] = "edit";
|
|
1211
|
+
/**
|
|
1212
|
+
* Emitted when a user clicks **Edit** on a Liveboard.
|
|
1213
|
+
*
|
|
1214
|
+
* Fired alongside {@link EmbedEvent.Edit} for backward compatibility;
|
|
1215
|
+
* listen to this instead of `Edit` to target the Liveboard surface only.
|
|
1216
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
1217
|
+
* @example
|
|
1218
|
+
* ```js
|
|
1219
|
+
* liveboardEmbed.on(EmbedEvent.EditLiveboard, payload => {
|
|
1220
|
+
* console.log('Liveboard edit', payload);
|
|
1221
|
+
* })
|
|
1222
|
+
* ```
|
|
1223
|
+
*/
|
|
1224
|
+
EmbedEvent["EditLiveboard"] = "editLiveboard";
|
|
1225
|
+
/**
|
|
1226
|
+
* Emitted when a user clicks **Edit** on a visualization inside a
|
|
1227
|
+
* Liveboard.
|
|
1228
|
+
*
|
|
1229
|
+
* Fired alongside {@link EmbedEvent.Edit} for backward compatibility;
|
|
1230
|
+
* listen to this instead of `Edit` to target the visualization surface
|
|
1231
|
+
* only.
|
|
1232
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
1233
|
+
* @example
|
|
1234
|
+
* ```js
|
|
1235
|
+
* liveboardEmbed.on(EmbedEvent.EditVisualization, payload => {
|
|
1236
|
+
* console.log('visualization edit', payload);
|
|
1237
|
+
* })
|
|
1238
|
+
* ```
|
|
1239
|
+
*/
|
|
1240
|
+
EmbedEvent["EditVisualization"] = "editVisualization";
|
|
1211
1241
|
/**
|
|
1212
1242
|
* Emitted when a user clicks *Make a copy* on a Liveboard
|
|
1213
1243
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
|
|
@@ -3179,6 +3209,46 @@ var HostEvent;
|
|
|
3179
3209
|
* @version SDK: 1.15.0 | ThoughtSpot: 8.7.0.cl, 8.8.1.sw
|
|
3180
3210
|
*/
|
|
3181
3211
|
HostEvent["Edit"] = "edit";
|
|
3212
|
+
/**
|
|
3213
|
+
* Trigger the **Edit** action on a Liveboard only — does not affect a
|
|
3214
|
+
* visualization's edit surface.
|
|
3215
|
+
*
|
|
3216
|
+
* Behaves like {@link HostEvent.Edit} restricted to the Liveboard
|
|
3217
|
+
* surface. Use {@link HostEvent.EditVisualization} to target a
|
|
3218
|
+
* visualization instead, or `HostEvent.Edit` to control whichever
|
|
3219
|
+
* surface applies contextually (unchanged, existing behavior).
|
|
3220
|
+
* @example
|
|
3221
|
+
* ```js
|
|
3222
|
+
* liveboardEmbed.trigger(HostEvent.EditLiveboard)
|
|
3223
|
+
* ```
|
|
3224
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
3225
|
+
*/
|
|
3226
|
+
HostEvent["EditLiveboard"] = "editLiveboard";
|
|
3227
|
+
/**
|
|
3228
|
+
* Trigger the **Edit** action on a specific visualization inside a
|
|
3229
|
+
* Liveboard only — does not affect the Liveboard-level edit surface.
|
|
3230
|
+
* @param - Object parameter. Includes the following keys:
|
|
3231
|
+
* - `vizId`: **Required.** The visualization to edit.
|
|
3232
|
+
*
|
|
3233
|
+
* @example
|
|
3234
|
+
* ```js
|
|
3235
|
+
* liveboardEmbed.trigger(HostEvent.EditVisualization, {vizId:
|
|
3236
|
+
* '730496d6-6903-4601-937e-2c691821af3c'})
|
|
3237
|
+
* ```
|
|
3238
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
3239
|
+
*/
|
|
3240
|
+
HostEvent["EditVisualization"] = "editVisualization";
|
|
3241
|
+
/**
|
|
3242
|
+
* Exits Liveboard edit mode , equivalent to clicking the
|
|
3243
|
+
* *Cancel* button in the Liveboard edit header. The Liveboard returns to
|
|
3244
|
+
* view mode and the embedded app emits the {@link EmbedEvent.Cancel} event.
|
|
3245
|
+
* @version SDK: 1.55.0 | ThoughtSpot Cloud: 26.12.0.cl
|
|
3246
|
+
* @example
|
|
3247
|
+
* ```js
|
|
3248
|
+
* liveboardEmbed.trigger(HostEvent.ExitEditMode);
|
|
3249
|
+
* ```
|
|
3250
|
+
*/
|
|
3251
|
+
HostEvent["ExitEditMode"] = "exitEditMode";
|
|
3182
3252
|
/**
|
|
3183
3253
|
* Trigger the **Copy link** action on a Liveboard or visualization
|
|
3184
3254
|
* Payload: {@link VizScopedRequest}.
|
|
@@ -4714,6 +4784,39 @@ var HostEvent;
|
|
|
4714
4784
|
* @version SDK: 1.49.0 | ThoughtSpot Cloud: 26.6.0.cl
|
|
4715
4785
|
*/
|
|
4716
4786
|
HostEvent["RefreshLiveboardBrowserCache"] = "refreshLiveboardBrowserCache";
|
|
4787
|
+
/**
|
|
4788
|
+
* Switch the embed between dark appearance and its default appearance
|
|
4789
|
+
* while it is open, without reloading it.
|
|
4790
|
+
* Payload: {@link UpdateThemeRequest}.
|
|
4791
|
+
*
|
|
4792
|
+
* Use it to keep the embed in step with a theme switch in your
|
|
4793
|
+
* application; the appearance the embed loads with is set by `isDarkMode`.
|
|
4794
|
+
* The event resolves with the applied value, such as `{ isDarkMode: true }`.
|
|
4795
|
+
* When dark appearance is not available in the embed, the embed does not
|
|
4796
|
+
* change and the event rejects with an error message instead.
|
|
4797
|
+
* @version SDK: 1.55.0 | ThoughtSpot Cloud: 26.12.0.cl
|
|
4798
|
+
* @param - `isDarkMode` - `true` for dark appearance, `false` for the
|
|
4799
|
+
* default appearance.
|
|
4800
|
+
* @example
|
|
4801
|
+
* ```js
|
|
4802
|
+
* appEmbed.trigger(HostEvent.UpdateTheme, { isDarkMode: true });
|
|
4803
|
+
* ```
|
|
4804
|
+
* @example
|
|
4805
|
+
* ```js
|
|
4806
|
+
* // Follow a theme switch in your application
|
|
4807
|
+
* const themeSwitch = document.querySelector('#theme-switch');
|
|
4808
|
+
* themeSwitch.addEventListener('change', async (event) => {
|
|
4809
|
+
* try {
|
|
4810
|
+
* await appEmbed.trigger(HostEvent.UpdateTheme, {
|
|
4811
|
+
* isDarkMode: event.target.checked,
|
|
4812
|
+
* });
|
|
4813
|
+
* } catch (error) {
|
|
4814
|
+
* console.warn(error);
|
|
4815
|
+
* }
|
|
4816
|
+
* });
|
|
4817
|
+
* ```
|
|
4818
|
+
*/
|
|
4819
|
+
HostEvent["UpdateTheme"] = "UpdateTheme";
|
|
4717
4820
|
})(HostEvent || (HostEvent = {}));
|
|
4718
4821
|
/**
|
|
4719
4822
|
* The different visual modes that the data sources panel within
|
|
@@ -4741,6 +4844,22 @@ var DataSourceVisualMode;
|
|
|
4741
4844
|
var Param;
|
|
4742
4845
|
(function (Param) {
|
|
4743
4846
|
Param["Tsmcp"] = "tsmcp";
|
|
4847
|
+
/**
|
|
4848
|
+
* Marker added by a host app replaying a stored conversation. Carries the
|
|
4849
|
+
* analytical session (conversation) identifier, from which the renderer
|
|
4850
|
+
* resolves the answer's current session parameters. Stripped before the
|
|
4851
|
+
* URL reaches the ThoughtSpot application.
|
|
4852
|
+
* @version SDK: 1.52.2 | ThoughtSpot Cloud: 26.9.0.cl
|
|
4853
|
+
*/
|
|
4854
|
+
Param["TsmcpConversationId"] = "tsmcpConversationId";
|
|
4855
|
+
/**
|
|
4856
|
+
* Zero-based position of the answer within the conversation, counting only
|
|
4857
|
+
* non-thinking answer items in message order. Accompanies
|
|
4858
|
+
* {@link TsmcpConversationId}; defaults to 0 when absent. Stripped before
|
|
4859
|
+
* the URL reaches the ThoughtSpot application.
|
|
4860
|
+
* @version SDK: 1.52.2 | ThoughtSpot Cloud: 26.9.0.cl
|
|
4861
|
+
*/
|
|
4862
|
+
Param["TsmcpAnswerIndex"] = "tsmcpAnswerIndex";
|
|
4744
4863
|
Param["EmbedApp"] = "embedApp";
|
|
4745
4864
|
Param["DataSources"] = "dataSources";
|
|
4746
4865
|
Param["DataSourceMode"] = "dataSourceMode";
|
|
@@ -4904,6 +5023,9 @@ var Param;
|
|
|
4904
5023
|
Param["SpotterDataSources"] = "spotterDataSources";
|
|
4905
5024
|
Param["OpenSpotterOnLiveboardByDefault"] = "openSpotterOnLiveboardByDefault";
|
|
4906
5025
|
Param["ShowAnswerEditPanel"] = "showAnswerEditPanel";
|
|
5026
|
+
Param["IsDarkMode"] = "isDarkMode";
|
|
5027
|
+
Param["RadiantThemeEnabled"] = "radiantThemeEnabled";
|
|
5028
|
+
Param["SpotterExperienceVersion"] = "spotterExperienceVersion";
|
|
4907
5029
|
})(Param || (Param = {}));
|
|
4908
5030
|
/**
|
|
4909
5031
|
* ThoughtSpot application pages include actions and menu commands
|
|
@@ -5358,12 +5480,43 @@ var Action;
|
|
|
5358
5480
|
* The *Edit* action on the Liveboard page and in the
|
|
5359
5481
|
* visualization menu.
|
|
5360
5482
|
* Opens a Liveboard or visualization in edit mode.
|
|
5483
|
+
*
|
|
5484
|
+
* Controls both surfaces together. To target one surface only, use
|
|
5485
|
+
* {@link Action.EditLiveboard} or {@link Action.EditVisualization}.
|
|
5361
5486
|
* @example
|
|
5362
5487
|
* ```js
|
|
5363
5488
|
* disabledActions: [Action.Edit]
|
|
5364
5489
|
* ```
|
|
5365
5490
|
*/
|
|
5366
5491
|
Action["Edit"] = "edit";
|
|
5492
|
+
/**
|
|
5493
|
+
* The *Edit* action on the Liveboard page only.
|
|
5494
|
+
* Opens a Liveboard in edit mode.
|
|
5495
|
+
*
|
|
5496
|
+
* Does not affect the *Edit* action in the visualization menu; use
|
|
5497
|
+
* {@link Action.EditVisualization} for that, or {@link Action.Edit} to
|
|
5498
|
+
* control both surfaces together.
|
|
5499
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
5500
|
+
* @example
|
|
5501
|
+
* ```js
|
|
5502
|
+
* disabledActions: [Action.EditLiveboard]
|
|
5503
|
+
* ```
|
|
5504
|
+
*/
|
|
5505
|
+
Action["EditLiveboard"] = "editLiveboard";
|
|
5506
|
+
/**
|
|
5507
|
+
* The *Edit* action in the visualization `...` menu only.
|
|
5508
|
+
* Opens a visualization in the editor.
|
|
5509
|
+
*
|
|
5510
|
+
* Does not affect the *Edit* action on the Liveboard page; use
|
|
5511
|
+
* {@link Action.EditLiveboard} for that, or {@link Action.Edit} to
|
|
5512
|
+
* control both surfaces together.
|
|
5513
|
+
* @version SDK: 1.54.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
5514
|
+
* @example
|
|
5515
|
+
* ```js
|
|
5516
|
+
* disabledActions: [Action.EditVisualization]
|
|
5517
|
+
* ```
|
|
5518
|
+
*/
|
|
5519
|
+
Action["EditVisualization"] = "editVisualization";
|
|
5367
5520
|
/**
|
|
5368
5521
|
* The text edit option for Liveboard and visualization titles.
|
|
5369
5522
|
* @example
|
|
@@ -7139,6 +7292,29 @@ var Action;
|
|
|
7139
7292
|
* ```
|
|
7140
7293
|
*/
|
|
7141
7294
|
Action["CustomizeHomepage"] = "customizeHomepage";
|
|
7295
|
+
/**
|
|
7296
|
+
* Controls the visibility and disabled state of the *Cancel* button in the
|
|
7297
|
+
* Liveboard edit header, the button that discards the changes made in edit
|
|
7298
|
+
* mode and returns the Liveboard to view mode. The button is shown only
|
|
7299
|
+
* while the Liveboard is in edit mode.
|
|
7300
|
+
* @version SDK: 1.55.0 | ThoughtSpot Cloud: 26.12.0.cl
|
|
7301
|
+
* @example
|
|
7302
|
+
* ```js
|
|
7303
|
+
* const liveboardEmbed = new LiveboardEmbed('#tsEmbed', {
|
|
7304
|
+
* ... // other embed view config
|
|
7305
|
+
* hiddenActions: [Action.Cancel],
|
|
7306
|
+
* });
|
|
7307
|
+
* ```
|
|
7308
|
+
* @example
|
|
7309
|
+
* ```js
|
|
7310
|
+
* const liveboardEmbed = new LiveboardEmbed('#tsEmbed', {
|
|
7311
|
+
* ... // other embed view config
|
|
7312
|
+
* disabledActions: [Action.Cancel],
|
|
7313
|
+
* disabledActionReason: 'Save your changes to leave edit mode',
|
|
7314
|
+
* });
|
|
7315
|
+
* ```
|
|
7316
|
+
*/
|
|
7317
|
+
Action["Cancel"] = "cancel";
|
|
7142
7318
|
})(Action || (Action = {}));
|
|
7143
7319
|
var PrefetchFeatures;
|
|
7144
7320
|
(function (PrefetchFeatures) {
|
|
@@ -7643,7 +7819,7 @@ var TableContentDensity;
|
|
|
7643
7819
|
TableContentDensity["Compact"] = "COMPACT";
|
|
7644
7820
|
})(TableContentDensity || (TableContentDensity = {}));
|
|
7645
7821
|
|
|
7646
|
-
var version$1="1.
|
|
7822
|
+
var version$1="1.53.1";var pkg = {version:version$1};
|
|
7647
7823
|
|
|
7648
7824
|
const { version } = pkg;
|
|
7649
7825
|
|
|
@@ -10311,6 +10487,13 @@ const addFilter = `
|
|
|
10311
10487
|
}
|
|
10312
10488
|
}
|
|
10313
10489
|
`;
|
|
10490
|
+
const updateSort = `
|
|
10491
|
+
mutation UpdateSort($session: BachSessionIdInput!, $sortOrder: [AnswerColumnSortInput!]!) {
|
|
10492
|
+
Answer__updateSort(session: $session, sortOrder: $sortOrder) {
|
|
10493
|
+
${bachSessionId}
|
|
10494
|
+
}
|
|
10495
|
+
}
|
|
10496
|
+
`;
|
|
10314
10497
|
const getAnswer = `
|
|
10315
10498
|
query GetAnswer($session: BachSessionIdInput!) {
|
|
10316
10499
|
getAnswer(session: $session) {
|
|
@@ -10615,6 +10798,26 @@ class AnswerService {
|
|
|
10615
10798
|
},
|
|
10616
10799
|
});
|
|
10617
10800
|
}
|
|
10801
|
+
/**
|
|
10802
|
+
* Adapt the sort options into the `updateSort` payload and send it.
|
|
10803
|
+
* @param sortOptions Columns to sort by, each with a direction.
|
|
10804
|
+
* @param sourceDetail
|
|
10805
|
+
*/
|
|
10806
|
+
async adaptSorting(sortOptions, sourceDetail) {
|
|
10807
|
+
const { answer } = await this.executeQuery(getAnswer, {});
|
|
10808
|
+
const guidToColumnId = getGuidToColumnIdMap(answer);
|
|
10809
|
+
const sortOrder = sortOptions.map((sort) => {
|
|
10810
|
+
const guid = getGuidsFromColumnNames(sourceDetail, [sort.columnName])
|
|
10811
|
+
.values().next().value;
|
|
10812
|
+
return {
|
|
10813
|
+
columnId: guidToColumnId.get(guid),
|
|
10814
|
+
sortType: sort.ascending ? 'ASCENDING' : 'DESCENDING',
|
|
10815
|
+
};
|
|
10816
|
+
});
|
|
10817
|
+
return this.executeQuery(updateSort, {
|
|
10818
|
+
sortOrder,
|
|
10819
|
+
});
|
|
10820
|
+
}
|
|
10618
10821
|
async updateDisplayMode(displayMode = "TABLE_MODE") {
|
|
10619
10822
|
return this.executeQuery(updateDisplayMode, {
|
|
10620
10823
|
displayMode,
|
|
@@ -10702,18 +10905,21 @@ class AnswerService {
|
|
|
10702
10905
|
* automatically passed.
|
|
10703
10906
|
* @param outputColumnNames
|
|
10704
10907
|
* @param selectedPoints
|
|
10908
|
+
* @param sortOptions Optional columns to sort the underlying data by.
|
|
10705
10909
|
* @example
|
|
10706
10910
|
* ```js
|
|
10707
10911
|
* embed.on(EmbedEvent.CustomAction, e => {
|
|
10708
|
-
* const underlying = await e.answerService.getUnderlyingDataForPoint(
|
|
10709
|
-
* 'col name 1' // The column should exist in the data source.
|
|
10710
|
-
*
|
|
10912
|
+
* const underlying = await e.answerService.getUnderlyingDataForPoint(
|
|
10913
|
+
* ['col name 1'], // The column should exist in the data source.
|
|
10914
|
+
* undefined,
|
|
10915
|
+
* [{ columnName: 'col name 1', ascending: true }],
|
|
10916
|
+
* );
|
|
10711
10917
|
* const data = await underlying.fetchData(0, 100);
|
|
10712
10918
|
* })
|
|
10713
10919
|
* ```
|
|
10714
10920
|
* @version SDK: 1.25.0 | ThoughtSpot: 9.10.0.cl
|
|
10715
10921
|
*/
|
|
10716
|
-
async getUnderlyingDataForPoint(outputColumnNames, selectedPoints) {
|
|
10922
|
+
async getUnderlyingDataForPoint(outputColumnNames, selectedPoints, sortOptions) {
|
|
10717
10923
|
if (!selectedPoints && !this.selectedPoints) {
|
|
10718
10924
|
throw new Error('Needs to be triggered in context of a point');
|
|
10719
10925
|
}
|
|
@@ -10741,6 +10947,9 @@ class AnswerService {
|
|
|
10741
10947
|
if (columnsToRemove.length) {
|
|
10742
10948
|
await unaggAnswerSession.removeColumns(columnsToRemove);
|
|
10743
10949
|
}
|
|
10950
|
+
if (sortOptions === null || sortOptions === void 0 ? void 0 : sortOptions.length) {
|
|
10951
|
+
await unaggAnswerSession.adaptSorting(sortOptions, sourceDetail);
|
|
10952
|
+
}
|
|
10744
10953
|
return unaggAnswerSession;
|
|
10745
10954
|
}
|
|
10746
10955
|
/**
|
|
@@ -10779,7 +10988,7 @@ class AnswerService {
|
|
|
10779
10988
|
async getTML() {
|
|
10780
10989
|
const { object } = await this.executeQuery(getAnswerTML, {});
|
|
10781
10990
|
const edoc = object[0].edoc;
|
|
10782
|
-
const YAML = await import('./index-
|
|
10991
|
+
const YAML = await import('./index-CrBnZBZv.js');
|
|
10783
10992
|
const parsedDoc = YAML.parse(edoc);
|
|
10784
10993
|
return {
|
|
10785
10994
|
answer: {
|
|
@@ -10800,6 +11009,15 @@ class AnswerService {
|
|
|
10800
11009
|
this.tmlOverride = override;
|
|
10801
11010
|
}
|
|
10802
11011
|
}
|
|
11012
|
+
/**
|
|
11013
|
+
* Build a map from a source column guid to the answer's viz column id, using
|
|
11014
|
+
* the `referencedColumns` link on each viz column.
|
|
11015
|
+
* @param answer
|
|
11016
|
+
*/
|
|
11017
|
+
function getGuidToColumnIdMap(answer) {
|
|
11018
|
+
const tableViz = answer.visualizations.find((viz) => viz.columns);
|
|
11019
|
+
return new Map(tableViz.columns.map((col) => [col.column.referencedColumns[0].guid, col.column.id]));
|
|
11020
|
+
}
|
|
10803
11021
|
/**
|
|
10804
11022
|
*
|
|
10805
11023
|
* @param sourceDetail
|
|
@@ -19814,6 +20032,7 @@ let mixpanelInstance;
|
|
|
19814
20032
|
const MIXPANEL_EVENT = {
|
|
19815
20033
|
VISUAL_SDK_RENDER_START: 'visual-sdk-render-start',
|
|
19816
20034
|
VISUAL_SDK_CALLED_INIT: 'visual-sdk-called-init',
|
|
20035
|
+
VISUAL_SDK_INIT_ACTIONS: 'visual-sdk-init-actions',
|
|
19817
20036
|
VISUAL_SDK_RENDER_COMPLETE: 'visual-sdk-render-complete',
|
|
19818
20037
|
VISUAL_SDK_RENDER_FAILED: 'visual-sdk-render-failed',
|
|
19819
20038
|
VISUAL_SDK_TRIGGER: 'visual-sdk-trigger',
|
|
@@ -19888,6 +20107,32 @@ function initMixpanel(sessionInfo) {
|
|
|
19888
20107
|
}
|
|
19889
20108
|
}
|
|
19890
20109
|
|
|
20110
|
+
// Membership is checked, not just the key: a bare key allowlist would upload an
|
|
20111
|
+
// arbitrary customer string sitting under `operator` verbatim.
|
|
20112
|
+
const isEnumMember = (enumObject, value) => typeof value === 'string' && Object.values(enumObject).includes(value);
|
|
20113
|
+
const uniqueEnumMembers = (enumObject, values) => Array.from(new Set(values.filter((v) => isEnumMember(enumObject, v))));
|
|
20114
|
+
const describeRuntimeFilters = (runtimeFilters) => ({
|
|
20115
|
+
count: runtimeFilters.length,
|
|
20116
|
+
operators: uniqueEnumMembers(RuntimeFilterOp, runtimeFilters.map((filter) => filter === null || filter === void 0 ? void 0 : filter.operator)),
|
|
20117
|
+
});
|
|
20118
|
+
const describeRuntimeParameters = (runtimeParameters) => ({
|
|
20119
|
+
count: runtimeParameters.length,
|
|
20120
|
+
applicabilityLevels: uniqueEnumMembers(ApplicabilityLevel, runtimeParameters.map((parameter) => { var _a; return (_a = parameter === null || parameter === void 0 ? void 0 : parameter.applicability) === null || _a === void 0 ? void 0 : _a.level; })),
|
|
20121
|
+
});
|
|
20122
|
+
// Column names, parameter names and operands are customer data and must never
|
|
20123
|
+
// reach Mixpanel; an unrecognized shape is dropped rather than forwarded.
|
|
20124
|
+
const summarizeRuntimeDataForTelemetry = (viewConfig) => {
|
|
20125
|
+
const { runtimeFilters, runtimeParameters, ...rest } = viewConfig !== null && viewConfig !== void 0 ? viewConfig : {};
|
|
20126
|
+
const telemetryProps = { ...rest };
|
|
20127
|
+
if (Array.isArray(runtimeFilters)) {
|
|
20128
|
+
telemetryProps.runtimeFilters = describeRuntimeFilters(runtimeFilters);
|
|
20129
|
+
}
|
|
20130
|
+
if (Array.isArray(runtimeParameters)) {
|
|
20131
|
+
telemetryProps.runtimeParameters = describeRuntimeParameters(runtimeParameters);
|
|
20132
|
+
}
|
|
20133
|
+
return telemetryProps;
|
|
20134
|
+
};
|
|
20135
|
+
|
|
19891
20136
|
var eventemitter3 = createCommonjsModule(function (module) {
|
|
19892
20137
|
|
|
19893
20138
|
var has = Object.prototype.hasOwnProperty
|
|
@@ -22206,6 +22451,97 @@ const UPDATE_EMBED_PARAMS_SETTLE_MS = 200;
|
|
|
22206
22451
|
// truthy, so null or '' leaves the previous embed's values in place. '&' is
|
|
22207
22452
|
// truthy and parses to {}.
|
|
22208
22453
|
const NO_RUNTIME_PARAMS = '&';
|
|
22454
|
+
/**
|
|
22455
|
+
* Params kept on the iframe `src` when `excludeConfigFromURL` is set. The rest
|
|
22456
|
+
* are sent in the APP_INIT payload.
|
|
22457
|
+
* @internal
|
|
22458
|
+
*/
|
|
22459
|
+
const BOOTSTRAP_URL_PARAMS = new Set([
|
|
22460
|
+
// Marks the app as embedded.
|
|
22461
|
+
Param.EmbedApp,
|
|
22462
|
+
// The host page URL, used to validate the postMessage origin.
|
|
22463
|
+
Param.HostAppUrl,
|
|
22464
|
+
// The SDK version.
|
|
22465
|
+
Param.Version,
|
|
22466
|
+
// The authentication type set in init.
|
|
22467
|
+
Param.AuthType,
|
|
22468
|
+
// Whether the app signs the user in automatically.
|
|
22469
|
+
Param.AutoLogin,
|
|
22470
|
+
// Stops the app from redirecting to its login page.
|
|
22471
|
+
Param.DisableLoginRedirect,
|
|
22472
|
+
// Forces the SAML redirect for EmbeddedSSO.
|
|
22473
|
+
Param.ForceSAMLAutoRedirect,
|
|
22474
|
+
// Set for cookieless trusted authentication.
|
|
22475
|
+
Param.cookieless,
|
|
22476
|
+
// Lets the app use the pre-fetched auth info.
|
|
22477
|
+
Param.preAuthCache,
|
|
22478
|
+
// Blocks access to the full app outside the embed.
|
|
22479
|
+
Param.blockNonEmbedFullAppAccess,
|
|
22480
|
+
// The org to load, which the auth info depends on.
|
|
22481
|
+
Param.OverrideOrgId,
|
|
22482
|
+
// The host window height when the iframe loads.
|
|
22483
|
+
Param.ViewPortHeight,
|
|
22484
|
+
// The host window width when the iframe loads.
|
|
22485
|
+
Param.ViewPortWidth,
|
|
22486
|
+
// The app's client log level.
|
|
22487
|
+
Param.ClientLogLevel,
|
|
22488
|
+
// Lets the app override the native console.
|
|
22489
|
+
Param.OverrideNativeConsole,
|
|
22490
|
+
// An extra Pendo tracking key.
|
|
22491
|
+
Param.PendoTrackingKey,
|
|
22492
|
+
// The locale for number formatting.
|
|
22493
|
+
Param.NumberFormatLocale,
|
|
22494
|
+
// The locale for date formatting.
|
|
22495
|
+
Param.DateFormatLocale,
|
|
22496
|
+
// The currency format.
|
|
22497
|
+
Param.CurrencyFormat,
|
|
22498
|
+
// The UI language.
|
|
22499
|
+
Param.Locale,
|
|
22500
|
+
// Turns on dark mode.
|
|
22501
|
+
Param.IsDarkMode,
|
|
22502
|
+
// Turns on the radiant theme that dark mode needs.
|
|
22503
|
+
Param.RadiantThemeEnabled,
|
|
22504
|
+
// Marks a SearchEmbed or SearchBarEmbed.
|
|
22505
|
+
Param.searchEmbed,
|
|
22506
|
+
// Marks a LiveboardEmbed.
|
|
22507
|
+
Param.livedBoardEmbed,
|
|
22508
|
+
// Marks a SpotterAgentEmbed.
|
|
22509
|
+
Param.isSpotterAgentEmbed,
|
|
22510
|
+
// Marks a SpotterEmbed.
|
|
22511
|
+
Param.SpotterEnabled,
|
|
22512
|
+
// Marks an AppEmbed.
|
|
22513
|
+
Param.IsFullAppEmbed,
|
|
22514
|
+
// Legacy flag for the onBeforeGetVizData API intercept.
|
|
22515
|
+
Param.IsOnBeforeGetVizDataInterceptEnabled,
|
|
22516
|
+
// Lets the host override links in the app.
|
|
22517
|
+
Param.LinkOverride,
|
|
22518
|
+
// Turns on version 2 of the link overrides.
|
|
22519
|
+
Param.EnableLinkOverridesV2,
|
|
22520
|
+
// Stops links from opening in a new tab.
|
|
22521
|
+
Param.DisableRedirectionLinksInNewTab,
|
|
22522
|
+
// Uses replaceState instead of pushState for app navigation.
|
|
22523
|
+
Param.OverrideHistoryState,
|
|
22524
|
+
// Shows search results as a table.
|
|
22525
|
+
Param.ForceTable,
|
|
22526
|
+
// The URL of the custom string IDs file.
|
|
22527
|
+
Param.StringIDsUrl,
|
|
22528
|
+
// The data sources that search opens with.
|
|
22529
|
+
Param.DataSources,
|
|
22530
|
+
// Exposes translation IDs in the app.
|
|
22531
|
+
Param.ExposeTranslationIDs,
|
|
22532
|
+
// The URL of the custom icon sprite.
|
|
22533
|
+
Param.IconSpriteUrl,
|
|
22534
|
+
// The tag that filters the metadata lists in an AppEmbed.
|
|
22535
|
+
Param.Tag,
|
|
22536
|
+
// Set when a Liveboard embed shows a single visualization (vizId).
|
|
22537
|
+
Param.vizEmbed,
|
|
22538
|
+
// Whether search opens with the last-selected data sources.
|
|
22539
|
+
Param.UseLastSelectedDataSource,
|
|
22540
|
+
// The query mode Spotter opens in.
|
|
22541
|
+
Param.DefaultQueryMode,
|
|
22542
|
+
// The initial search query. Omitted with excludeSearchTokenStringFromURL.
|
|
22543
|
+
Param.searchTokenString,
|
|
22544
|
+
]);
|
|
22209
22545
|
/**
|
|
22210
22546
|
* The event id map from v2 event names to v1 event id
|
|
22211
22547
|
* v1 events are the classic embed events implemented in Blink v1
|
|
@@ -22234,6 +22570,7 @@ class TsEmbed {
|
|
|
22234
22570
|
this.embedNodeKey = '__tsEmbed';
|
|
22235
22571
|
this.embedContainerLoadedKey = '__tsEmbedContainerLoaded';
|
|
22236
22572
|
this.isAppInitialized = false;
|
|
22573
|
+
this.initDataParams = {};
|
|
22237
22574
|
/**
|
|
22238
22575
|
* Should we encode URL Query Params using base64 encoding which ThoughtSpot
|
|
22239
22576
|
* will generate for embedding. This provides additional security to
|
|
@@ -22268,7 +22605,7 @@ class TsEmbed {
|
|
|
22268
22605
|
*/
|
|
22269
22606
|
this.appInitCb = async (_, responder) => {
|
|
22270
22607
|
try {
|
|
22271
|
-
const appInitData = await this.getAppInitData();
|
|
22608
|
+
const appInitData = this.withInitDataParams(await this.getAppInitData());
|
|
22272
22609
|
this.isAppInitialized = true;
|
|
22273
22610
|
responder({
|
|
22274
22611
|
type: EmbedEvent.APP_INIT,
|
|
@@ -22422,9 +22759,7 @@ class TsEmbed {
|
|
|
22422
22759
|
...viewConfig,
|
|
22423
22760
|
};
|
|
22424
22761
|
this.registerAppInit();
|
|
22425
|
-
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_EMBED_CREATE,
|
|
22426
|
-
...viewConfig,
|
|
22427
|
-
});
|
|
22762
|
+
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_EMBED_CREATE, summarizeRuntimeDataForTelemetry(viewConfig));
|
|
22428
22763
|
const embedConfig = getEmbedConfig();
|
|
22429
22764
|
if (embedConfig) {
|
|
22430
22765
|
this.embedConfig = embedConfig;
|
|
@@ -22696,6 +23031,18 @@ class TsEmbed {
|
|
|
22696
23031
|
async getAppInitData() {
|
|
22697
23032
|
return this.getDefaultAppInitData();
|
|
22698
23033
|
}
|
|
23034
|
+
withInitDataParams(appInitData) {
|
|
23035
|
+
if (isEmpty_1(this.initDataParams)) {
|
|
23036
|
+
return appInitData;
|
|
23037
|
+
}
|
|
23038
|
+
return {
|
|
23039
|
+
...appInitData,
|
|
23040
|
+
embedParams: {
|
|
23041
|
+
...this.initDataParams,
|
|
23042
|
+
...(appInitData.embedParams || {}),
|
|
23043
|
+
},
|
|
23044
|
+
};
|
|
23045
|
+
}
|
|
22699
23046
|
/**
|
|
22700
23047
|
* Helper method to refresh/update auth token for TrustedAuthTokenCookieless auth type
|
|
22701
23048
|
* @param responder - Function to send response back
|
|
@@ -22755,7 +23102,7 @@ class TsEmbed {
|
|
|
22755
23102
|
* @returns queryParams
|
|
22756
23103
|
*/
|
|
22757
23104
|
getBaseQueryParams(queryParams = {}) {
|
|
22758
|
-
var _a, _b, _c, _d;
|
|
23105
|
+
var _a, _b, _c, _d, _e;
|
|
22759
23106
|
let hostAppUrl = ((_a = window === null || window === void 0 ? void 0 : window.location) === null || _a === void 0 ? void 0 : _a.host) || '';
|
|
22760
23107
|
// The below check is needed because TS Cloud firewall, blocks
|
|
22761
23108
|
// localhost/127.0.0.1 in any url param.
|
|
@@ -22792,6 +23139,15 @@ class TsEmbed {
|
|
|
22792
23139
|
if (this.embedConfig.currencyFormat) {
|
|
22793
23140
|
queryParams[Param.CurrencyFormat] = this.embedConfig.currencyFormat;
|
|
22794
23141
|
}
|
|
23142
|
+
// The view config wins over init, so an embed can opt out of a dark
|
|
23143
|
+
// mode set in `init`. `??` and not `||`, so that an explicit `false`
|
|
23144
|
+
// overrides an init-level `true`.
|
|
23145
|
+
const isDarkMode = (_c = this.viewConfig.isDarkMode) !== null && _c !== void 0 ? _c : this.embedConfig.isDarkMode;
|
|
23146
|
+
setParamIfDefined(queryParams, Param.IsDarkMode, isDarkMode, true);
|
|
23147
|
+
// The app's dark mode lives in its radiant theme, so turn that on too.
|
|
23148
|
+
if (isDarkMode) {
|
|
23149
|
+
queryParams[Param.RadiantThemeEnabled] = true;
|
|
23150
|
+
}
|
|
22795
23151
|
const { disabledActions, disabledActionReason, hiddenActions, visibleActions, hiddenTabs, visibleTabs, showAlerts, additionalFlags: additionalFlagsFromView, locale, customizations, contextMenuTrigger, linkOverride, enableLinkOverridesV2, insertInToSlide, disableRedirectionLinksInNewTab, overrideOrgId, overrideHistoryState, exposeTranslationIDs, primaryAction, } = this.viewConfig;
|
|
22796
23152
|
const { additionalFlags: additionalFlagsFromInit } = this.embedConfig;
|
|
22797
23153
|
const additionalFlags = {
|
|
@@ -22857,7 +23213,7 @@ class TsEmbed {
|
|
|
22857
23213
|
if (spriteUrl) {
|
|
22858
23214
|
queryParams[Param.IconSpriteUrl] = spriteUrl.replace('https://', '');
|
|
22859
23215
|
}
|
|
22860
|
-
const stringIDsUrl = ((
|
|
23216
|
+
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);
|
|
22861
23217
|
if (stringIDsUrl) {
|
|
22862
23218
|
queryParams[Param.StringIDsUrl] = stringIDsUrl;
|
|
22863
23219
|
}
|
|
@@ -22911,13 +23267,32 @@ class TsEmbed {
|
|
|
22911
23267
|
return path;
|
|
22912
23268
|
}
|
|
22913
23269
|
getEmbedParams() {
|
|
22914
|
-
const queryParams = this.
|
|
23270
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
22915
23271
|
return getQueryParamString(queryParams);
|
|
22916
23272
|
}
|
|
22917
23273
|
getEmbedParamsObject() {
|
|
22918
23274
|
const params = this.getBaseQueryParams();
|
|
22919
23275
|
return params;
|
|
22920
23276
|
}
|
|
23277
|
+
getUrlQueryParamsObject() {
|
|
23278
|
+
const queryParams = this.getEmbedParamsObject();
|
|
23279
|
+
if (!this.isConfigExcludedFromUrl()) {
|
|
23280
|
+
this.initDataParams = {};
|
|
23281
|
+
return queryParams;
|
|
23282
|
+
}
|
|
23283
|
+
const urlParams = {};
|
|
23284
|
+
const excludedParams = {};
|
|
23285
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
23286
|
+
if (BOOTSTRAP_URL_PARAMS.has(key)) {
|
|
23287
|
+
urlParams[key] = value;
|
|
23288
|
+
}
|
|
23289
|
+
else {
|
|
23290
|
+
excludedParams[key] = deserializeParam(value);
|
|
23291
|
+
}
|
|
23292
|
+
});
|
|
23293
|
+
this.initDataParams = excludedParams;
|
|
23294
|
+
return urlParams;
|
|
23295
|
+
}
|
|
22921
23296
|
getRootIframeSrc() {
|
|
22922
23297
|
const query = this.getEmbedParams();
|
|
22923
23298
|
return this.getEmbedBasePath(query);
|
|
@@ -23156,26 +23531,12 @@ class TsEmbed {
|
|
|
23156
23531
|
return placeholder;
|
|
23157
23532
|
}
|
|
23158
23533
|
/**
|
|
23159
|
-
* Resolves the configured preRenderContainer
|
|
23160
|
-
*
|
|
23161
|
-
*
|
|
23162
|
-
*
|
|
23163
|
-
*
|
|
23164
|
-
*
|
|
23165
|
-
* scrolling ancestor, falling back to `document.body`.
|
|
23166
|
-
*
|
|
23167
|
-
* The wrapper is absolutely positioned, so it follows the page for free —
|
|
23168
|
-
* but only while it sits inside whatever scrolls. `document.body` is right
|
|
23169
|
-
* only when the document itself is the scroller; an app that scrolls an
|
|
23170
|
-
* inner element instead left the frame pinned to the viewport while the page
|
|
23171
|
-
* moved under it (SCAL-338563). Being inside the scroller also lets wheel
|
|
23172
|
-
* events chain out of the frame into it, which they cannot do from
|
|
23173
|
-
* `document.body`.
|
|
23174
|
-
*
|
|
23175
|
-
* A scrolling ancestor is layout chrome rather than route content, so it
|
|
23176
|
-
* outlives the embed in practice; and if it does go, the host element goes
|
|
23177
|
-
* with it and this instance is remounting anyway.
|
|
23178
|
-
* `reconcilePreRenderContainer` re-runs this on a detached container.
|
|
23534
|
+
* Resolves the configured preRenderContainer, or defaults to the host's
|
|
23535
|
+
* nearest scrolling ancestor (document.body if none). The absolutely
|
|
23536
|
+
* positioned wrapper only follows the page while it sits inside what
|
|
23537
|
+
* scrolls, so body is right only when the document itself scrolls — an inner
|
|
23538
|
+
* scroller left the frame pinned to the viewport (SCAL-338563). A string
|
|
23539
|
+
* selector is re-queried each call so a remounted container resolves fresh.
|
|
23179
23540
|
*/
|
|
23180
23541
|
resolvePreRenderContainerTarget() {
|
|
23181
23542
|
var _a;
|
|
@@ -23617,9 +23978,16 @@ class TsEmbed {
|
|
|
23617
23978
|
* @param args
|
|
23618
23979
|
*/
|
|
23619
23980
|
async render() {
|
|
23981
|
+
var _a, _b, _c;
|
|
23620
23982
|
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_RENDER_CALLED, {
|
|
23621
23983
|
embedComponentType: this.viewConfig.embedComponentType,
|
|
23622
23984
|
});
|
|
23985
|
+
uploadMixpanelEvent(MIXPANEL_EVENT.VISUAL_SDK_INIT_ACTIONS, {
|
|
23986
|
+
embedComponentType: this.viewConfig.embedComponentType,
|
|
23987
|
+
hiddenActions: (_a = this.viewConfig.hiddenActions) !== null && _a !== void 0 ? _a : [],
|
|
23988
|
+
visibleActions: (_b = this.viewConfig.visibleActions) !== null && _b !== void 0 ? _b : [],
|
|
23989
|
+
disabledActions: (_c = this.viewConfig.disabledActions) !== null && _c !== void 0 ? _c : [],
|
|
23990
|
+
});
|
|
23623
23991
|
if (!getIsInitCalled()) {
|
|
23624
23992
|
logger$3.error(ERROR_MESSAGE.RENDER_CALLED_BEFORE_INIT);
|
|
23625
23993
|
}
|
|
@@ -23854,6 +24222,26 @@ class TsEmbed {
|
|
|
23854
24222
|
this.isRendered = true;
|
|
23855
24223
|
return this.renderIFrame(prerenderFrameSrc);
|
|
23856
24224
|
}
|
|
24225
|
+
isConfigExcludedFromUrl() {
|
|
24226
|
+
var _a, _b, _c;
|
|
24227
|
+
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;
|
|
24228
|
+
return flag === true || flag === 'true';
|
|
24229
|
+
}
|
|
24230
|
+
async triggerUpdateEmbedParams() {
|
|
24231
|
+
try {
|
|
24232
|
+
const params = await this.getUpdateEmbedParamsObject();
|
|
24233
|
+
this.trigger(HostEvent.UpdateEmbedParams, params);
|
|
24234
|
+
}
|
|
24235
|
+
catch (error) {
|
|
24236
|
+
logger$3.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
|
|
24237
|
+
this.handleError({
|
|
24238
|
+
errorType: ErrorDetailsTypes.API,
|
|
24239
|
+
message: (error === null || error === void 0 ? void 0 : error.message) || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
|
|
24240
|
+
code: EmbedErrorCodes.UPDATE_PARAMS_FAILED,
|
|
24241
|
+
error: (error === null || error === void 0 ? void 0 : error.message) || error,
|
|
24242
|
+
});
|
|
24243
|
+
}
|
|
24244
|
+
}
|
|
23857
24245
|
beforePrerenderVisible() {
|
|
23858
24246
|
// We can ignore this as its a bit expensive and the newer customers
|
|
23859
24247
|
// have moved on to UpdateEmbedParams supported clusters
|
|
@@ -23864,17 +24252,7 @@ class TsEmbed {
|
|
|
23864
24252
|
this.preRenderParamsApplied = new Promise((resolve) => {
|
|
23865
24253
|
this.executeAfterEmbedContainerLoaded(async () => {
|
|
23866
24254
|
try {
|
|
23867
|
-
|
|
23868
|
-
this.trigger(HostEvent.UpdateEmbedParams, params);
|
|
23869
|
-
}
|
|
23870
|
-
catch (error) {
|
|
23871
|
-
logger$3.error(ERROR_MESSAGE.UPDATE_PARAMS_FAILED, error);
|
|
23872
|
-
this.handleError({
|
|
23873
|
-
errorType: ErrorDetailsTypes.API,
|
|
23874
|
-
message: (error === null || error === void 0 ? void 0 : error.message) || ERROR_MESSAGE.UPDATE_PARAMS_FAILED,
|
|
23875
|
-
code: EmbedErrorCodes.UPDATE_PARAMS_FAILED,
|
|
23876
|
-
error: (error === null || error === void 0 ? void 0 : error.message) || error,
|
|
23877
|
-
});
|
|
24255
|
+
await this.triggerUpdateEmbedParams();
|
|
23878
24256
|
}
|
|
23879
24257
|
finally {
|
|
23880
24258
|
setTimeout(resolve, UPDATE_EMBED_PARAMS_SETTLE_MS);
|
|
@@ -24008,19 +24386,21 @@ class TsEmbed {
|
|
|
24008
24386
|
return;
|
|
24009
24387
|
}
|
|
24010
24388
|
const { zIndex } = this.getPreRenderConfig();
|
|
24389
|
+
// A hidden pre-render frame must add no scroll space to the host page.
|
|
24011
24390
|
const preRenderHideStyles = {
|
|
24012
24391
|
opacity: '0',
|
|
24013
24392
|
pointerEvents: 'none',
|
|
24014
24393
|
zIndex: zIndex !== undefined ? String(zIndex) : '-1000',
|
|
24015
|
-
|
|
24394
|
+
// Resolves to the viewport, so the hidden frame belongs to no
|
|
24395
|
+
// scroll container's overflow; syncPreRenderStyle restores absolute
|
|
24396
|
+
// on show.
|
|
24397
|
+
position: 'fixed',
|
|
24016
24398
|
top: '0',
|
|
24017
24399
|
left: '0',
|
|
24018
24400
|
overflow: 'hidden',
|
|
24019
|
-
//
|
|
24020
|
-
//
|
|
24021
|
-
//
|
|
24022
|
-
// downwards, so a hidden frame parked above the top edge adds
|
|
24023
|
-
// none, where one left at full height shows as blank scroll space.
|
|
24401
|
+
// The one exception: a transformed or contained ancestor captures
|
|
24402
|
+
// `fixed`; parking above the top edge keeps it out of that
|
|
24403
|
+
// overflow.
|
|
24024
24404
|
transform: PRERENDER_PARKED_TRANSFORM,
|
|
24025
24405
|
};
|
|
24026
24406
|
setStyleProperties(this.preRenderWrapper, preRenderHideStyles);
|
|
@@ -24190,8 +24570,11 @@ function buildSpotterSidebarAppInitData(defaultAppInitData, viewConfig, handleEr
|
|
|
24190
24570
|
embedParams: { visualOverridesParams: visualOverrides },
|
|
24191
24571
|
};
|
|
24192
24572
|
}
|
|
24573
|
+
// The app reads enableSpotterInstructionAndMoreSettings from the top level
|
|
24574
|
+
// of embedParams, so lift it out of the sidebar config.
|
|
24575
|
+
const { enableSpotterInstructionAndMoreSettings, ...sidebarConfigRest } = spotterSidebarConfig || {};
|
|
24193
24576
|
const resolvedSidebarConfig = {
|
|
24194
|
-
...
|
|
24577
|
+
...sidebarConfigRest,
|
|
24195
24578
|
...(resolvedEnablePastConversations !== undefined && {
|
|
24196
24579
|
enablePastConversationsSidebar: resolvedEnablePastConversations,
|
|
24197
24580
|
}),
|
|
@@ -24213,6 +24596,9 @@ function buildSpotterSidebarAppInitData(defaultAppInitData, viewConfig, handleEr
|
|
|
24213
24596
|
embedParams: {
|
|
24214
24597
|
...(defaultAppInitData.embedParams || {}),
|
|
24215
24598
|
spotterSidebarConfig: resolvedSidebarConfig,
|
|
24599
|
+
...(enableSpotterInstructionAndMoreSettings !== undefined
|
|
24600
|
+
? { enableSpotterInstructionAndMoreSettings }
|
|
24601
|
+
: {}),
|
|
24216
24602
|
...(visualOverrides !== undefined ? { visualOverridesParams: visualOverrides } : {}),
|
|
24217
24603
|
},
|
|
24218
24604
|
};
|
|
@@ -24253,7 +24639,19 @@ function buildSpotterAnalystAppInitData(initData, viewConfig) {
|
|
|
24253
24639
|
spotterAnalystConfig,
|
|
24254
24640
|
},
|
|
24255
24641
|
};
|
|
24256
|
-
}
|
|
24642
|
+
}
|
|
24643
|
+
/**
|
|
24644
|
+
* The Spotter experience version to load in the embedded view.
|
|
24645
|
+
* @version SDK: 1.53.0 | ThoughtSpot Cloud: 26.11.0.cl
|
|
24646
|
+
* @group Embed components
|
|
24647
|
+
*/
|
|
24648
|
+
var SpotterExperienceVersion;
|
|
24649
|
+
(function (SpotterExperienceVersion) {
|
|
24650
|
+
/**
|
|
24651
|
+
* The Spotter experience version introduced in ThoughtSpot 26.11.
|
|
24652
|
+
*/
|
|
24653
|
+
SpotterExperienceVersion["SPOTTER_2026_11"] = "spotter_2026_11";
|
|
24654
|
+
})(SpotterExperienceVersion || (SpotterExperienceVersion = {}));
|
|
24257
24655
|
|
|
24258
24656
|
function buildSpotterVizAppInitData(initData, viewConfig) {
|
|
24259
24657
|
const { spotterViz } = viewConfig;
|
|
@@ -24450,12 +24848,12 @@ class AppEmbed extends V1Embed {
|
|
|
24450
24848
|
* embedded Liveboard or visualization.
|
|
24451
24849
|
*/
|
|
24452
24850
|
getEmbedParams() {
|
|
24453
|
-
const params = this.
|
|
24851
|
+
const params = this.getUrlQueryParamsObject();
|
|
24454
24852
|
return getQueryParamString(params, true);
|
|
24455
24853
|
}
|
|
24456
24854
|
getEmbedParamsObject() {
|
|
24457
24855
|
var _a;
|
|
24458
|
-
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 = DataPanelCustomColumnGroupsAccordionState$1.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;
|
|
24856
|
+
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 = DataPanelCustomColumnGroupsAccordionState$1.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;
|
|
24459
24857
|
let params = {};
|
|
24460
24858
|
params[Param.PrimaryNavHidden] = !showPrimaryNavbar;
|
|
24461
24859
|
params[Param.HideProfleAndHelp] = !!disableProfileAndHelp;
|
|
@@ -24510,6 +24908,9 @@ class AppEmbed extends V1Embed {
|
|
|
24510
24908
|
if (spotterDataSources && spotterDataSources.length) {
|
|
24511
24909
|
params[Param.SpotterDataSources] = JSON.stringify(spotterDataSources);
|
|
24512
24910
|
}
|
|
24911
|
+
if (spotterExperienceVersion !== undefined) {
|
|
24912
|
+
params[Param.SpotterExperienceVersion] = spotterExperienceVersion;
|
|
24913
|
+
}
|
|
24513
24914
|
// Handle spotterChatConfig params
|
|
24514
24915
|
if (spotterChatConfig) {
|
|
24515
24916
|
const { hideToolResponseCardBranding, toolResponseCardBrandingLabel, spotterFileUploadEnabled, spotterFileUploadFileTypes, enableStarterPrompts, openSpotterOnLiveboardByDefault, } = spotterChatConfig;
|
|
@@ -24628,7 +25029,7 @@ class AppEmbed extends V1Embed {
|
|
|
24628
25029
|
}
|
|
24629
25030
|
// Navigation V1/V2 and home page V1/V2 are deprecated. V3 is now the
|
|
24630
25031
|
// default experience, Need to send navigationVersion=v3 and
|
|
24631
|
-
// homepageVersion=v3 even when the no discoveryExperience /
|
|
25032
|
+
// homepageVersion=v3 even when the no discoveryExperience /
|
|
24632
25033
|
// modularHomeExperience config is set. Without these
|
|
24633
25034
|
// params, older TSA versions (< 26.7) fall back to V2 for nav and
|
|
24634
25035
|
// home page, so the defaults must be sent explicitly from the SDK.
|
|
@@ -24877,6 +25278,21 @@ const addPreviewStylesIfNotPresent = () => {
|
|
|
24877
25278
|
document.head.insertAdjacentHTML('beforeend', previewStyles);
|
|
24878
25279
|
};
|
|
24879
25280
|
|
|
25281
|
+
function buildLiveboardOverrideAppInitData(initData, viewConfig) {
|
|
25282
|
+
var _a;
|
|
25283
|
+
const { liveboardOverride } = viewConfig;
|
|
25284
|
+
// ThoughtSpot ignores an override with no data source entries; skip it.
|
|
25285
|
+
if (!((_a = liveboardOverride === null || liveboardOverride === void 0 ? void 0 : liveboardOverride.dataSourceOverride) === null || _a === void 0 ? void 0 : _a.length))
|
|
25286
|
+
return initData;
|
|
25287
|
+
return {
|
|
25288
|
+
...initData,
|
|
25289
|
+
embedParams: {
|
|
25290
|
+
...(initData.embedParams || {}),
|
|
25291
|
+
liveboardOverride,
|
|
25292
|
+
},
|
|
25293
|
+
};
|
|
25294
|
+
}
|
|
25295
|
+
|
|
24880
25296
|
/**
|
|
24881
25297
|
* Copyright (c) 2022
|
|
24882
25298
|
*
|
|
@@ -24946,14 +25362,15 @@ class LiveboardEmbed extends V1Embed {
|
|
|
24946
25362
|
async getAppInitData() {
|
|
24947
25363
|
const defaultAppInitData = await super.getAppInitData();
|
|
24948
25364
|
const vizInitData = buildSpotterVizAppInitData(defaultAppInitData, this.viewConfig);
|
|
24949
|
-
|
|
25365
|
+
const starterPromptsInitData = buildStarterPromptsAppInitData(vizInitData, this.viewConfig);
|
|
25366
|
+
return buildLiveboardOverrideAppInitData(starterPromptsInitData, this.viewConfig);
|
|
24950
25367
|
}
|
|
24951
25368
|
/**
|
|
24952
25369
|
* Construct a map of params to be passed on to the
|
|
24953
25370
|
* embedded Liveboard or visualization.
|
|
24954
25371
|
*/
|
|
24955
25372
|
getEmbedParams() {
|
|
24956
|
-
const params = this.
|
|
25373
|
+
const params = this.getUrlQueryParamsObject();
|
|
24957
25374
|
const queryParams = getQueryParamString(params, true);
|
|
24958
25375
|
return queryParams;
|
|
24959
25376
|
}
|
|
@@ -24961,7 +25378,7 @@ class LiveboardEmbed extends V1Embed {
|
|
|
24961
25378
|
var _a;
|
|
24962
25379
|
let params = {};
|
|
24963
25380
|
params = this.getBaseQueryParams(params);
|
|
24964
|
-
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;
|
|
25381
|
+
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;
|
|
24965
25382
|
const preventLiveboardFilterRemoval = this.viewConfig.preventLiveboardFilterRemoval
|
|
24966
25383
|
|| this.viewConfig.preventPinboardFilterRemoval;
|
|
24967
25384
|
(_a = this.fullHeightController) === null || _a === void 0 ? void 0 : _a.addQueryParams(params);
|
|
@@ -25023,6 +25440,9 @@ class LiveboardEmbed extends V1Embed {
|
|
|
25023
25440
|
if (isLiveboardStylingAndGroupingEnabled !== undefined) {
|
|
25024
25441
|
params[Param.IsLiveboardStylingAndGroupingEnabled] = isLiveboardStylingAndGroupingEnabled;
|
|
25025
25442
|
}
|
|
25443
|
+
if (spotterExperienceVersion !== undefined) {
|
|
25444
|
+
params[Param.SpotterExperienceVersion] = spotterExperienceVersion;
|
|
25445
|
+
}
|
|
25026
25446
|
if (liveboardGutter !== undefined) {
|
|
25027
25447
|
params[Param.LiveboardGutter] = liveboardGutter;
|
|
25028
25448
|
}
|
|
@@ -25195,7 +25615,7 @@ class LiveboardEmbed extends V1Embed {
|
|
|
25195
25615
|
// instance. React builds a new instance per mount, so an equal config
|
|
25196
25616
|
// is a hide/show, not a hand-over: there is nothing stale to clear.
|
|
25197
25617
|
const previous = this.getPreRenderObj();
|
|
25198
|
-
const
|
|
25618
|
+
const previousRoute = this.isSameEmbedConfig(previous)
|
|
25199
25619
|
? undefined
|
|
25200
25620
|
: previous === null || previous === void 0 ? void 0 : previous.currentLiveboardState;
|
|
25201
25621
|
this.executeAfterEmbedContainerLoaded(async () => {
|
|
@@ -25203,7 +25623,7 @@ class LiveboardEmbed extends V1Embed {
|
|
|
25203
25623
|
// Navigate goes out first, so the container loads with the previous
|
|
25204
25624
|
// config's filters.
|
|
25205
25625
|
await this.preRenderParamsApplied;
|
|
25206
|
-
if (this.
|
|
25626
|
+
if (this.isAlreadyOnSameRoute(previousRoute)) {
|
|
25207
25627
|
// Navigate to the route we are already on is a no-op, so the
|
|
25208
25628
|
// liveboard keeps its state. Home unmounts the container, which
|
|
25209
25629
|
// clears it.
|
|
@@ -25224,18 +25644,9 @@ class LiveboardEmbed extends V1Embed {
|
|
|
25224
25644
|
};
|
|
25225
25645
|
});
|
|
25226
25646
|
}
|
|
25227
|
-
|
|
25228
|
-
|
|
25229
|
-
|
|
25230
|
-
* Undefined-valued keys are dropped before comparing. `navigateToLiveboard`
|
|
25231
|
-
* assigns `vizId`, `activeTabId` and `personalizedViewId` unconditionally,
|
|
25232
|
-
* so an instance that has been shown once carries those keys as `undefined`
|
|
25233
|
-
* while a freshly constructed one does not have them at all. `isEqual`
|
|
25234
|
-
* counts own keys, so without this the comparison can never be true after
|
|
25235
|
-
* the first show — which is the whole case this exists for.
|
|
25236
|
-
*
|
|
25237
|
-
* Callbacks compare as equal: React passes a fresh closure per render.
|
|
25238
|
-
*/
|
|
25647
|
+
// definedEntries drops undefined-valued keys: a shown instance carries
|
|
25648
|
+
// vizId/activeTabId/etc as undefined, so a raw isEqual never matches again.
|
|
25649
|
+
// Functions compare equal, since React passes a fresh closure per render.
|
|
25239
25650
|
isSameEmbedConfig(previous) {
|
|
25240
25651
|
if (!previous)
|
|
25241
25652
|
return false;
|
|
@@ -25246,14 +25657,14 @@ class LiveboardEmbed extends V1Embed {
|
|
|
25246
25657
|
// The whole route, not just the liveboard id: the path is built from the
|
|
25247
25658
|
// viz, tab and view too, so a same-liveboard show onto another tab is a
|
|
25248
25659
|
// real navigation.
|
|
25249
|
-
|
|
25250
|
-
if (!(
|
|
25660
|
+
isAlreadyOnSameRoute(previousRoute) {
|
|
25661
|
+
if (!(previousRoute === null || previousRoute === void 0 ? void 0 : previousRoute.liveboardId))
|
|
25251
25662
|
return false;
|
|
25252
25663
|
const { liveboardId, vizId, activeTabId, personalizedViewId, } = this.viewConfig;
|
|
25253
|
-
return
|
|
25254
|
-
&&
|
|
25255
|
-
&&
|
|
25256
|
-
&&
|
|
25664
|
+
return previousRoute.liveboardId === liveboardId
|
|
25665
|
+
&& previousRoute.vizId === vizId
|
|
25666
|
+
&& previousRoute.activeTabId === activeTabId
|
|
25667
|
+
&& previousRoute.personalizedViewId === personalizedViewId;
|
|
25257
25668
|
}
|
|
25258
25669
|
async handleRenderForPrerender() {
|
|
25259
25670
|
if (isUndefined$1(this.viewConfig.liveboardId)) {
|
|
@@ -25505,7 +25916,7 @@ class SearchEmbed extends TsEmbed {
|
|
|
25505
25916
|
}
|
|
25506
25917
|
getEmbedParams() {
|
|
25507
25918
|
const { runtimeParameters, runtimeFilters, excludeRuntimeParametersfromURL, excludeRuntimeFiltersfromURL, } = this.viewConfig;
|
|
25508
|
-
const queryParams = this.
|
|
25919
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
25509
25920
|
let query = '';
|
|
25510
25921
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
25511
25922
|
if (queryParamsString) {
|
|
@@ -25593,7 +26004,7 @@ class SearchBarEmbed extends TsEmbed {
|
|
|
25593
26004
|
* @param dataSources A list of data source GUIDs
|
|
25594
26005
|
*/
|
|
25595
26006
|
getIFrameSrc() {
|
|
25596
|
-
const queryParams = this.
|
|
26007
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
25597
26008
|
const path = 'search-bar-embed';
|
|
25598
26009
|
let query = '';
|
|
25599
26010
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
@@ -26027,7 +26438,7 @@ class ConversationMessage extends TsEmbed {
|
|
|
26027
26438
|
getIframeSrc() {
|
|
26028
26439
|
const { sessionId, genNo, acSessionId, acGenNo, convId, messageId, } = this.viewConfig;
|
|
26029
26440
|
const path = 'conv-assist-answer';
|
|
26030
|
-
const queryParams = this.
|
|
26441
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
26031
26442
|
let query = '';
|
|
26032
26443
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
26033
26444
|
if (queryParamsString) {
|
|
@@ -26224,18 +26635,22 @@ class SpotterEmbed extends TsEmbed {
|
|
|
26224
26635
|
}
|
|
26225
26636
|
}
|
|
26226
26637
|
setParamIfDefined(queryParams, Param.UpdatedSpotterExperience, updatedSpotterExperience, true);
|
|
26638
|
+
setParamIfDefined(queryParams, Param.SpotterExperienceVersion, this.viewConfig.spotterExperienceVersion);
|
|
26227
26639
|
return queryParams;
|
|
26228
26640
|
}
|
|
26229
26641
|
getIframeSrc() {
|
|
26230
|
-
const { worksheetId, searchOptions, runtimeFilters, excludeRuntimeFiltersfromURL, runtimeParameters, excludeRuntimeParametersfromURL, sharedConversationId, dataSources, } = this.viewConfig;
|
|
26642
|
+
const { worksheetId, searchOptions, runtimeFilters, excludeRuntimeFiltersfromURL, runtimeParameters, excludeRuntimeParametersfromURL, sharedConversationId, dataSources, spotterExperienceVersion, } = this.viewConfig;
|
|
26231
26643
|
// Deep-link into the read-only shared-conversation reader view when a
|
|
26232
26644
|
// shared conversation id is supplied (e.g. a recipient landing from a
|
|
26233
26645
|
// host-configured CONVERSATION_URL share link); otherwise the normal
|
|
26234
26646
|
// Spotter conversation surface.
|
|
26235
|
-
|
|
26647
|
+
let path = sharedConversationId
|
|
26236
26648
|
? `insights/conv-assist/s/${encodeURIComponent(sharedConversationId)}`
|
|
26237
26649
|
: 'insights/conv-assist';
|
|
26238
|
-
|
|
26650
|
+
if (spotterExperienceVersion === SpotterExperienceVersion.SPOTTER_2026_11) {
|
|
26651
|
+
path = path.replace('insights/conv-assist', 'insights/spotter');
|
|
26652
|
+
}
|
|
26653
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
26239
26654
|
let query = '';
|
|
26240
26655
|
const queryParamsString = getQueryParamString(queryParams, true);
|
|
26241
26656
|
if (queryParamsString) {
|
|
@@ -27025,6 +27440,20 @@ function convertFilterChangedToUpdateFiltersPayload(filterChangedPayload) {
|
|
|
27025
27440
|
return { filters: [...liveboardFilterParams, ...runtimeFilterParams] };
|
|
27026
27441
|
}
|
|
27027
27442
|
|
|
27443
|
+
/**
|
|
27444
|
+
* Route the ThoughtSpot application uses to render a single conversational
|
|
27445
|
+
* answer. Used when a replayed frame carries no route of its own.
|
|
27446
|
+
*/
|
|
27447
|
+
const CONV_ASSIST_ANSWER_ROUTE = '/embed/conv-assist-answer';
|
|
27448
|
+
/**
|
|
27449
|
+
* Base path of the conversation service, proxied by the cluster's nginx as
|
|
27450
|
+
* the `convex` upstream. These are the same handlers the public
|
|
27451
|
+
* `/api/rest/2.0/ai/agent/conversations/...` endpoints proxy to, so the
|
|
27452
|
+
* response shapes are identical, but calling them directly skips the prism
|
|
27453
|
+
* hop and its error re-wrapping.
|
|
27454
|
+
*/
|
|
27455
|
+
const CONVERSATION_SERVICE_PATH = '/conversation/v2';
|
|
27456
|
+
const DEFAULT_STALE_ANSWER_NOTICE = 'This data may have changed since the last time you had a chat.';
|
|
27028
27457
|
/**
|
|
27029
27458
|
* Starts an automatic renderer that watches the DOM for iframes containing
|
|
27030
27459
|
* the `tsmcp=true` query parameter and replaces them with fully configured
|
|
@@ -27087,6 +27516,111 @@ function startAutoMCPFrameRenderer(viewConfig = {}) {
|
|
|
27087
27516
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
27088
27517
|
return observer;
|
|
27089
27518
|
}
|
|
27519
|
+
/**
|
|
27520
|
+
* Writes resolved session parameters into the route's hash query string,
|
|
27521
|
+
* preserving the route and any other hash params the source URL carried.
|
|
27522
|
+
*
|
|
27523
|
+
* @param sourceHash - The source URL's hash, with or without a leading `#`.
|
|
27524
|
+
* Falls back to the conversational-answer route when empty, so a host app
|
|
27525
|
+
* replaying a chat need only supply the conversation identifier.
|
|
27526
|
+
*/
|
|
27527
|
+
function buildAnswerHash(sourceHash, resolved) {
|
|
27528
|
+
const withoutHash = (sourceHash || '').replace('#', '');
|
|
27529
|
+
const [route, existingQuery] = withoutHash.split('?');
|
|
27530
|
+
const params = new URLSearchParams(existingQuery || '');
|
|
27531
|
+
Object.entries(resolved).forEach(([key, value]) => params.set(key, value));
|
|
27532
|
+
return `${route || CONV_ASSIST_ANSWER_ROUTE}?${params.toString()}`;
|
|
27533
|
+
}
|
|
27534
|
+
/**
|
|
27535
|
+
* Reads {@link Param.TsmcpAnswerIndex} as a whole, non-negative array index.
|
|
27536
|
+
*
|
|
27537
|
+
* Anything else - absent, malformed, fractional, negative - falls back to the
|
|
27538
|
+
* first answer rather than indexing with a value that can never match.
|
|
27539
|
+
*/
|
|
27540
|
+
function answerIndexFromParam(raw) {
|
|
27541
|
+
const parsed = Number(raw);
|
|
27542
|
+
return Number.isInteger(parsed) && parsed >= 0 ? parsed : 0;
|
|
27543
|
+
}
|
|
27544
|
+
/**
|
|
27545
|
+
* In-flight answer-id list requests, keyed by conversation-service URL.
|
|
27546
|
+
*
|
|
27547
|
+
* Replaying a stored chat mounts every one of its frames at once, and each
|
|
27548
|
+
* frame resolves on its own. Without this, N frames from one conversation make
|
|
27549
|
+
* N identical list calls. Sharing the in-flight request collapses them to one.
|
|
27550
|
+
*
|
|
27551
|
+
* Only the id list is shared, and only while its request is in flight: the
|
|
27552
|
+
* entry is dropped once the request settles, whether it succeeded or not. A
|
|
27553
|
+
* failed response is therefore never reused, and a frame mounted later always
|
|
27554
|
+
* reads a fresh list. The per-answer load call is never shared - it returns
|
|
27555
|
+
* live session state with its own expiry.
|
|
27556
|
+
*/
|
|
27557
|
+
const answerIdListRequests = new Map();
|
|
27558
|
+
/**
|
|
27559
|
+
* Lists a conversation's answer ids: its non-thinking `answer` items, in
|
|
27560
|
+
* message order. The host app counts answers the same way, so the Nth id here
|
|
27561
|
+
* is the Nth stored answer.
|
|
27562
|
+
*
|
|
27563
|
+
* @param conversationUrl - The conversation's base URL on the conversation
|
|
27564
|
+
* service, `{host}/conversation/v2/{encoded id}`.
|
|
27565
|
+
* @param conversationId - The conversation identifier, used in log messages.
|
|
27566
|
+
* @returns The ids, or `null` when the conversation cannot be read. Never
|
|
27567
|
+
* rejects, so callers sharing the request need no error handling of their own.
|
|
27568
|
+
*/
|
|
27569
|
+
async function fetchAnswerIds(conversationUrl, conversationId) {
|
|
27570
|
+
try {
|
|
27571
|
+
const messagesResponse = await tokenizedFetch(`${conversationUrl}/public`, {
|
|
27572
|
+
credentials: 'include',
|
|
27573
|
+
headers: { Accept: 'application/json' },
|
|
27574
|
+
});
|
|
27575
|
+
if (!messagesResponse.ok) {
|
|
27576
|
+
logger$3.warn(`[AutoFrameRenderer] Conversation fetch failed for ${conversationId}: ${messagesResponse.status}`);
|
|
27577
|
+
return null;
|
|
27578
|
+
}
|
|
27579
|
+
const messagesBody = await messagesResponse.json();
|
|
27580
|
+
const messages = messagesBody === null || messagesBody === void 0 ? void 0 : messagesBody.messages;
|
|
27581
|
+
const answerIds = [];
|
|
27582
|
+
for (const message of Array.isArray(messages) ? messages : []) {
|
|
27583
|
+
for (const item of (message === null || message === void 0 ? void 0 : message.response_items) || []) {
|
|
27584
|
+
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)) {
|
|
27585
|
+
answerIds.push(item.answer_id);
|
|
27586
|
+
}
|
|
27587
|
+
}
|
|
27588
|
+
}
|
|
27589
|
+
return answerIds;
|
|
27590
|
+
}
|
|
27591
|
+
catch (e) {
|
|
27592
|
+
logger$3.warn(`[AutoFrameRenderer] Failed to list answers for ${conversationId}: ${e}`);
|
|
27593
|
+
return null;
|
|
27594
|
+
}
|
|
27595
|
+
}
|
|
27596
|
+
/**
|
|
27597
|
+
* The answer-id list for a conversation, joining a request already in flight
|
|
27598
|
+
* for it.
|
|
27599
|
+
*
|
|
27600
|
+
* @param conversationUrl - The conversation's base URL on the conversation
|
|
27601
|
+
* service. Also the key requests are shared under.
|
|
27602
|
+
* @param conversationId - The conversation identifier, used in log messages.
|
|
27603
|
+
* @param stale - A request the caller already read and found too short. It is
|
|
27604
|
+
* not reused; the first caller to pass it starts a new request, and the
|
|
27605
|
+
* others join that one.
|
|
27606
|
+
* @returns The shared request: the ids, or `null` when the conversation cannot
|
|
27607
|
+
* be read. Never rejects.
|
|
27608
|
+
*/
|
|
27609
|
+
function getAnswerIds(conversationUrl, conversationId, stale) {
|
|
27610
|
+
const inFlight = answerIdListRequests.get(conversationUrl);
|
|
27611
|
+
if (inFlight && inFlight !== stale) {
|
|
27612
|
+
return inFlight;
|
|
27613
|
+
}
|
|
27614
|
+
const request = fetchAnswerIds(conversationUrl, conversationId);
|
|
27615
|
+
answerIdListRequests.set(conversationUrl, request);
|
|
27616
|
+
const release = () => {
|
|
27617
|
+
if (answerIdListRequests.get(conversationUrl) === request) {
|
|
27618
|
+
answerIdListRequests.delete(conversationUrl);
|
|
27619
|
+
}
|
|
27620
|
+
};
|
|
27621
|
+
request.then(release, release);
|
|
27622
|
+
return request;
|
|
27623
|
+
}
|
|
27090
27624
|
function isTSMCPIframe(iframe) {
|
|
27091
27625
|
try {
|
|
27092
27626
|
const url = new URL(iframe.src);
|
|
@@ -27120,20 +27654,112 @@ class AutoFrameRenderer extends TsEmbed {
|
|
|
27120
27654
|
* ThoughtSpot application.
|
|
27121
27655
|
*
|
|
27122
27656
|
* @param sourceSrc - The original iframe's `src` URL string.
|
|
27657
|
+
* @param preserveSourceUrl - When true, return the source URL unchanged.
|
|
27123
27658
|
* @returns The constructed URL to use for the ThoughtSpot embed iframe.
|
|
27124
27659
|
*/
|
|
27125
|
-
getMCPIframeSrc(sourceSrc) {
|
|
27126
|
-
|
|
27660
|
+
getMCPIframeSrc(sourceSrc, resolved, preserveSourceUrl = false) {
|
|
27661
|
+
if (preserveSourceUrl) {
|
|
27662
|
+
return sourceSrc;
|
|
27663
|
+
}
|
|
27664
|
+
const queryParams = this.getUrlQueryParamsObject();
|
|
27127
27665
|
const sourceURL = new URL(sourceSrc);
|
|
27128
27666
|
const existingQueryParams = sourceURL.searchParams;
|
|
27129
27667
|
const existingQueryParamsObject = Object.fromEntries(existingQueryParams);
|
|
27130
27668
|
delete existingQueryParamsObject[Param.Tsmcp];
|
|
27669
|
+
// Replay markers address the SDK, not the ThoughtSpot application.
|
|
27670
|
+
delete existingQueryParamsObject[Param.TsmcpConversationId];
|
|
27671
|
+
delete existingQueryParamsObject[Param.TsmcpAnswerIndex];
|
|
27131
27672
|
const mergedQueryParams = { ...queryParams, ...existingQueryParamsObject };
|
|
27132
27673
|
const mergedQueryParamsString = getQueryParamString(mergedQueryParams, true);
|
|
27133
27674
|
const queryString = mergedQueryParamsString ? `?${mergedQueryParamsString}` : '';
|
|
27134
|
-
const
|
|
27675
|
+
const hash = resolved
|
|
27676
|
+
? buildAnswerHash(sourceURL.hash, resolved)
|
|
27677
|
+
: sourceURL.hash.replace('#', '');
|
|
27678
|
+
const frameSrc = `${this.getEmbedBasePath(queryString)}${hash}`;
|
|
27135
27679
|
return frameSrc;
|
|
27136
27680
|
}
|
|
27681
|
+
/**
|
|
27682
|
+
* Resolves the current session parameters for an answer stored only as a
|
|
27683
|
+
* conversation identifier plus an ordinal position.
|
|
27684
|
+
*
|
|
27685
|
+
* The answer object behind `sessionId`/`genNo` expires (roughly 8 hours),
|
|
27686
|
+
* so a host app replaying a stored chat cannot persist those values. It
|
|
27687
|
+
* persists the conversation identifier instead, and this walks the two
|
|
27688
|
+
* conversation-service APIs to rebuild them:
|
|
27689
|
+
*
|
|
27690
|
+
* 1. `GET {conv}/public` lists the conversation's messages; the
|
|
27691
|
+
* non-thinking `answer` items, in message order, give the answer ids.
|
|
27692
|
+
* Frames from the same conversation share one in-flight call - see
|
|
27693
|
+
* {@link getAnswerIds}.
|
|
27694
|
+
* 2. `POST {conv}/message/{id}/load/public` turns the answer id at
|
|
27695
|
+
* `answerIndex` into a live session identifier, generation number and
|
|
27696
|
+
* agent-context state.
|
|
27697
|
+
*
|
|
27698
|
+
* @returns The resolved parameters, or `null` when resolution fails - the
|
|
27699
|
+
* caller then falls back to whatever the source URL already carried.
|
|
27700
|
+
*/
|
|
27701
|
+
async resolveAnswerSessionParams(conversationId, answerIndex) {
|
|
27702
|
+
const base = `${this.thoughtSpotHost}${CONVERSATION_SERVICE_PATH}/${encodeURIComponent(conversationId)}`;
|
|
27703
|
+
try {
|
|
27704
|
+
const listRequest = getAnswerIds(base, conversationId);
|
|
27705
|
+
let answerIds = await listRequest;
|
|
27706
|
+
if (answerIds && !answerIds[answerIndex]) {
|
|
27707
|
+
// The list only grows, so a short one may predate this answer:
|
|
27708
|
+
// a frame that joined a request started before it was added.
|
|
27709
|
+
// Read the list once more before giving up.
|
|
27710
|
+
answerIds = await getAnswerIds(base, conversationId, listRequest);
|
|
27711
|
+
}
|
|
27712
|
+
if (!answerIds) {
|
|
27713
|
+
return null;
|
|
27714
|
+
}
|
|
27715
|
+
const answerId = answerIds[answerIndex];
|
|
27716
|
+
if (!answerId) {
|
|
27717
|
+
logger$3.warn(`[AutoFrameRenderer] No answer at index ${answerIndex} in conversation ${conversationId} (found ${answerIds.length}).`);
|
|
27718
|
+
return null;
|
|
27719
|
+
}
|
|
27720
|
+
// The load handler is a POST upstream; the public REST endpoint
|
|
27721
|
+
// exposed it as a GET and supplied this body on the caller's
|
|
27722
|
+
// behalf.
|
|
27723
|
+
const detailsResponse = await tokenizedFetch(`${base}/message/${encodeURIComponent(answerId)}/load/public`, {
|
|
27724
|
+
credentials: 'include',
|
|
27725
|
+
method: 'POST',
|
|
27726
|
+
headers: {
|
|
27727
|
+
Accept: 'application/json',
|
|
27728
|
+
'Content-Type': 'application/json',
|
|
27729
|
+
'x-requested-by': 'ThoughtSpot',
|
|
27730
|
+
},
|
|
27731
|
+
body: JSON.stringify({ type: 'TS_ANSWER' }),
|
|
27732
|
+
});
|
|
27733
|
+
if (!detailsResponse.ok) {
|
|
27734
|
+
logger$3.warn(`[AutoFrameRenderer] Answer load failed for ${answerId}: ${detailsResponse.status}`);
|
|
27735
|
+
return null;
|
|
27736
|
+
}
|
|
27737
|
+
const detailsBody = await detailsResponse.json();
|
|
27738
|
+
const answer = detailsBody === null || detailsBody === void 0 ? void 0 : detailsBody.answer;
|
|
27739
|
+
const acState = answer === null || answer === void 0 ? void 0 : answer.ac_state;
|
|
27740
|
+
// All four are nullable in the load-answer response. A missing
|
|
27741
|
+
// generation number is as unusable as a missing session id:
|
|
27742
|
+
// stringifying it would put a literal "null" in the hash. Fail
|
|
27743
|
+
// the resolve instead and let the caller fall back.
|
|
27744
|
+
if (!(answer === null || answer === void 0 ? void 0 : answer.session_identifier)
|
|
27745
|
+
|| !(acState === null || acState === void 0 ? void 0 : acState.transaction_identifier)
|
|
27746
|
+
|| !(Number.isInteger(answer.generation_number) && answer.generation_number > 0)
|
|
27747
|
+
|| !(Number.isInteger(acState.generation_number) && acState.generation_number > 0)) {
|
|
27748
|
+
logger$3.warn(`[AutoFrameRenderer] Answer load returned incomplete session state for ${answerId}.`);
|
|
27749
|
+
return null;
|
|
27750
|
+
}
|
|
27751
|
+
return {
|
|
27752
|
+
sessionId: answer.session_identifier,
|
|
27753
|
+
genNo: String(answer.generation_number),
|
|
27754
|
+
acSessionId: acState.transaction_identifier,
|
|
27755
|
+
acGenNo: String(acState.generation_number),
|
|
27756
|
+
};
|
|
27757
|
+
}
|
|
27758
|
+
catch (e) {
|
|
27759
|
+
logger$3.warn(`[AutoFrameRenderer] Failed to resolve stored answer: ${e}`);
|
|
27760
|
+
return null;
|
|
27761
|
+
}
|
|
27762
|
+
}
|
|
27137
27763
|
/**
|
|
27138
27764
|
* Overrides the base insertion behavior so the new embed iframe
|
|
27139
27765
|
* replaces the original iframe in-place rather than being appended
|
|
@@ -27162,10 +27788,37 @@ class AutoFrameRenderer extends TsEmbed {
|
|
|
27162
27788
|
if (this.shouldWaitForRenderPromise) {
|
|
27163
27789
|
await this.isReadyForRenderPromise;
|
|
27164
27790
|
}
|
|
27165
|
-
|
|
27791
|
+
// Only frames that ask for it take the replay path. A frame straight
|
|
27792
|
+
// from the MCP server carries its own session params and no
|
|
27793
|
+
// conversation id, so it renders exactly as it always has.
|
|
27794
|
+
const sourceParams = new URL(iframe.src).searchParams;
|
|
27795
|
+
const conversationId = sourceParams.get(Param.TsmcpConversationId);
|
|
27796
|
+
let resolved = null;
|
|
27797
|
+
if (conversationId) {
|
|
27798
|
+
resolved = await this.resolveAnswerSessionParams(conversationId, answerIndexFromParam(sourceParams.get(Param.TsmcpAnswerIndex)));
|
|
27799
|
+
}
|
|
27800
|
+
const src = this.getMCPIframeSrc(iframe.src, resolved !== null && resolved !== void 0 ? resolved : undefined, Boolean(conversationId) && !resolved);
|
|
27166
27801
|
await this.renderIFrame(src);
|
|
27802
|
+
// Mark only answers actually re-resolved: their numbers were computed
|
|
27803
|
+
// now, not when the conversation happened.
|
|
27804
|
+
if (resolved && !this.viewConfig.suppressStaleAnswerNotice) {
|
|
27805
|
+
this.markAsStaleAnswer();
|
|
27806
|
+
}
|
|
27167
27807
|
this.isRendered = true;
|
|
27168
27808
|
}
|
|
27809
|
+
/**
|
|
27810
|
+
* Adds the "data may have changed" notice to the rendered frame as a
|
|
27811
|
+
* native tooltip, so it needs no stylesheet and cannot disturb the host
|
|
27812
|
+
* app's layout.
|
|
27813
|
+
*/
|
|
27814
|
+
markAsStaleAnswer() {
|
|
27815
|
+
if (!this.iFrame) {
|
|
27816
|
+
return;
|
|
27817
|
+
}
|
|
27818
|
+
this.iFrame.title = this.viewConfig.staleAnswerNoticeText || DEFAULT_STALE_ANSWER_NOTICE;
|
|
27819
|
+
// Exposed so a host app can style or replace the native tooltip.
|
|
27820
|
+
this.iFrame.dataset.tsStaleAnswer = 'true';
|
|
27821
|
+
}
|
|
27169
27822
|
}
|
|
27170
27823
|
|
|
27171
|
-
export { Action, AnswerService, AppEmbed, ApplicabilityLevel, AuthEvent, AuthFailureType, AuthStatus, AuthType, BackgroundFormatType, BodylessConversation, ConditionalFormattingComparisonType, ConditionalFormattingOperator, ContextMenuTriggerOptions, ContextType, ConversationEmbed, CustomActionTarget, CustomActionsPosition, DataLabelFilterOperator, DataPanelCustomColumnGroupsAccordionState$1 as DataPanelCustomColumnGroupsAccordionState, DataSourceVisualMode, EmbedErrorCodes, EmbedErrorSeverity, EmbedEvent, ErrorDetailsTypes, HomeLeftNavItem, HomePage, HomePageSearchBarMode, HomepageModule, HostEvent, InterceptedApiType, LegendPosition, ListPage, ListPageColumns, LiveboardEmbed, LogLevel, MIXPANEL_EVENT, Page, PinboardEmbed, PrefetchFeatures, PrimaryNavbarVersion, RuntimeFilterOp, SearchBarEmbed, SearchEmbed, SpotterAgentEmbed, SpotterEmbed, SpotterQueryMode, TableContentDensity, TableTheme, UIPassthroughEvent, convertFilterChangedToUpdateFiltersPayload, createLiveboardWithAnswers, executeTML, exportTML, getAnswerFromQuery, getEmbedConfig as getInitConfig, getSessionInfo, init, logout, prefetch, reloadIframe, resetCachedAuthToken, startAutoMCPFrameRenderer, tokenizedFetch, uploadMixpanelEvent };
|
|
27824
|
+
export { Action, AnswerService, AppEmbed, ApplicabilityLevel, AuthEvent, AuthFailureType, AuthStatus, AuthType, BackgroundFormatType, BodylessConversation, ConditionalFormattingComparisonType, ConditionalFormattingOperator, ContextMenuTriggerOptions, ContextType, ConversationEmbed, CustomActionTarget, CustomActionsPosition, DataLabelFilterOperator, DataPanelCustomColumnGroupsAccordionState$1 as DataPanelCustomColumnGroupsAccordionState, DataSourceVisualMode, EmbedErrorCodes, EmbedErrorSeverity, EmbedEvent, ErrorDetailsTypes, HomeLeftNavItem, HomePage, HomePageSearchBarMode, HomepageModule, HostEvent, InterceptedApiType, LegendPosition, ListPage, ListPageColumns, LiveboardEmbed, LogLevel, MIXPANEL_EVENT, Page, PinboardEmbed, PrefetchFeatures, PrimaryNavbarVersion, RuntimeFilterOp, SearchBarEmbed, SearchEmbed, SpotterAgentEmbed, SpotterEmbed, SpotterExperienceVersion, SpotterQueryMode, TableContentDensity, TableTheme, UIPassthroughEvent, convertFilterChangedToUpdateFiltersPayload, createLiveboardWithAnswers, executeTML, exportTML, getAnswerFromQuery, getEmbedConfig as getInitConfig, getSessionInfo, init, logout, prefetch, reloadIframe, resetCachedAuthToken, startAutoMCPFrameRenderer, tokenizedFetch, uploadMixpanelEvent };
|