diff --git a/modules/ROOT/pages/abac-migration-from-jwt-beta.adoc b/modules/ROOT/pages/abac-migration-from-jwt-beta.adoc index ff4618475..9febe109f 100644 --- a/modules/ROOT/pages/abac-migration-from-jwt-beta.adoc +++ b/modules/ROOT/pages/abac-migration-from-jwt-beta.adoc @@ -175,7 +175,7 @@ Verify that variable values are correctly assigned to users using one of the fol * Send a `POST` request to the `/api/rest/2.0/users/search` with user details, and explore the `variable_values` section of the response payload. * Send a `POST` request to the `/api/rest/2.0/template/variables/search` API endpoint with variable details. In the request body, specify the `response_content` as `METADATA_AND_VALUES`, and explore the variable values for each user in the response payload. -If you want to update the values of variables, use either `/api/rest/2.0/template/variables/update-values` or `/api/rest/2.0/auth/token/custom` API endpoint. +If you want to update the values of variables, use either `/api/rest/2.0/template/variables/{identifier}/update-values` or `/api/rest/2.0/auth/token/custom` API endpoint. == Review the configuration Before you begin testing, your setup should have the following JWT ABAC configuration: diff --git a/modules/ROOT/pages/abac-migration-from-jwt-ga.adoc b/modules/ROOT/pages/abac-migration-from-jwt-ga.adoc index 90c33514d..09c381ec3 100644 --- a/modules/ROOT/pages/abac-migration-from-jwt-ga.adoc +++ b/modules/ROOT/pages/abac-migration-from-jwt-ga.adoc @@ -148,7 +148,7 @@ Users with administration and *Can Administer and Bypass RLS* privileges are exe + [NOTE] ==== -To update variable values for a user, use the `/api/rest/2.0/auth/token/custom` or `/api/rest/2.0/template/variables/update-values` API endpoint. +To update variable values for a user, use the `/api/rest/2.0/auth/token/custom` or `/api/rest/2.0/template/variables/{identifier}/update-values` API endpoint. ==== == Expected setup before the testing phase diff --git a/modules/ROOT/pages/abac_rls-variables.adoc b/modules/ROOT/pages/abac_rls-variables.adoc index f5f3245a5..96cd340e7 100644 --- a/modules/ROOT/pages/abac_rls-variables.adoc +++ b/modules/ROOT/pages/abac_rls-variables.adoc @@ -162,7 +162,7 @@ The following rule restricts access to rows where the `date_column` is within th To set or update variable values for a user, use the `POST /api/rest/2.0/auth/token/custom` endpoint when logging in the user. -You can also use the `/api/rest/2.0/template/variables/update-values` endpoint for bulk operations or targeted resets. +You can also use the `/api/rest/2.0/template/variables/{identifier}/update-values` endpoint for bulk operations or targeted resets. The variable attributes defined in the token request take effect only if they are referenced in an RLS rule. If the variables are not used in any formula or RLS rule, they have no impact on data access. Before generating the request with variable attributes, ensure that the xref:abac_rls-variables.adoc#_add_or_update_rls_rules_with_variable_references[variables are added to the RLS rules] for the table. @@ -263,7 +263,7 @@ If you don't want to append or replace any attribute values, do not pass any det === Resetting a user or a variable Passing an empty array along with a formula variable name in the token request *does not reset the attribute values* for that formula variable for that user. -To change formula variable attributes of a user, especially to set entitlements to an empty set, use the `/api/rest/2.0/template/variables/update-values` API endpoint. +To change formula variable attributes of a user, especially to set entitlements to an empty set, use the `/api/rest/2.0/template/variables/{identifier}/update-values` API endpoint. [WARNING] ==== diff --git a/modules/ROOT/pages/api-changelog.adoc b/modules/ROOT/pages/api-changelog.adoc index 8cbd88b85..22cb4c719 100644 --- a/modules/ROOT/pages/api-changelog.adoc +++ b/modules/ROOT/pages/api-changelog.adoc @@ -97,6 +97,7 @@ If the current period inclusion in rolling date filters feature is enabled on yo To disable this feature, use the `isThisPeriodInDateFiltersEnabled` setting. To hide, show, or disable this option in the embed view, use the action ID, `Action.IncludeCurrentPeriod`. |==== + == Version 1.46.x, March 2026 [width="100%" cols="1,4"] @@ -265,7 +266,7 @@ The `HostEvent.UpdateParameters` event now supports configuring the `isVisibleTo [width="100%" cols="1,4"] |==== -|[tag greenBackground]#NEW FEATURE# a|*Runtime overrides in Spotter embed* +|[tag greenBackground]#NEW FEATURE# a|*Runtime overrides in Spotter embed* The Visual Embed SDK now supports runtime overrides in Spotter embed. diff --git a/modules/ROOT/pages/collections.adoc b/modules/ROOT/pages/collections.adoc new file mode 100644 index 000000000..d1638447d --- /dev/null +++ b/modules/ROOT/pages/collections.adoc @@ -0,0 +1,317 @@ += Collections [beta betaBackground]^Beta^ +:toc: true +:toclevels: 1 +:page-title: Collections +:page-pageid: collections +:page-description: group different ThoughtSpot objects into Collections to manage them more easily. + + +ThoughtSpot now provides REST APIs that enable developers to organize different ThoughtSpot objects into an organizational container called *Collections*. These objects can be Liveboards, Answers, data models, tables, and even other Collections. +Collections provide a powerful way to manage your data assets, making discovery and collaboration easier, while ensuring the integrity of embedded workflows. + +[NOTE] +==== +The Collections APIs are in Beta and disabled by default on ThoughtSpot instances. To enable these APIs on your instance, contact ThoughtSpot Support. +==== + +== Before you begin + +* For REST API v2 operations, the Org context is determined based on the authentication token used in your API requests. Ensure you log in to the appropriate Org context from which you want to send API requests. +* When enabled on a ThoughtSpot instance, Collections can be created by any user, and need no special user privileges. + + +== Create a Collection +To create a new Collection, send a `POST` request to the `POST /api/rest/2.0/collections/create` API endpoint, with the following parameters in the request body. + +=== Request parameters +In your `POST` request body, include the following parameters: + +[width="100%" cols="1,4"] +[options='header'] +|===== +|Parameter|Description + +|`name` a|__String__. Required. Specify a name for the Collection. +|`description` a|__String__. Optional. A short description for the Collection. +|`metadata` a|__Array__. Optional. The details for the metadata objects to be added to the Collection. + +* `type` + +Metadata type. Select one of the following values: +** `LIVEBOARD` +** `ANSWER` +** `LOGICAL_TABLE` +** `COLLECTION` ++ +To create nested collections, assign the `COLLECTION` metadata to a Collection. + +* `identifiers` + +List of unique IDs or names of metadata objects. +|===== + +==== Example request +[source,CURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/collections/create' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "name": "Demo Collection", + "metadata": [ + { + "type": "LIVEBOARD", + "identifiers": [ + "Retail sales (Sample)", + "fe307a35-5242-445f-b3cb-b84cd1fc339c" + ] + }, + { + "type": "COLLECTION", + "identifiers": [ + "Collection A" + ] + } + ], + "description": "For testing" +}' + +---- + +==== API response + +If the API request is successful, a Collection with the given metadata objects will be created. + +== Search for a Collection +To get a list of Collections, send a `POST` request to the `POST /api/rest/2.0/collections/search` API endpoint. + +If no parameters are specified, the API returns the first 10 collections (or fewer, depending on the total number available). + +=== Request parameters +In your `POST` request body, include the following parameters: + +[width="100%" cols="1,4"] +[options='header'] +|===== +|Parameter|Description + +|`name_pattern` a|__String__. Optional. Specify any case agnostic pattern to match the name of a Collection. Use `%` to perform a wildcard search by name. +|`record_offset` a|__Number__. Optional. The index of the first record to be included. Default value is 0. +|`record_size` a|__Number__. Optional. The total number of records to be searched. Default value is 10. Set to -1 to search across all available collections. +|`collection_identifiers` a|__Array__. Optional. GUID of the Collection(s) to be searched. `name_pattern` takes precedence over the `collection_identifiers`. +|`created_by_user_identifiers` a|__Array__. Optional. Searches for Collections by the name of the author. +|`include_metadata` a|__Boolean__. Optional. When set to `true`, includes the metadata objects within each Collection in the response. +|`sort_options` a|__Array__. Optional. To sort the search results, specify the field to apply the sort on `field_name`, and the sort order `order`. +|===== + +==== Example request +[source,CURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/collections/search' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "record_offset": 2, + "record_size": 15, + "include_metadata": false, + "name_pattern": "%", + "sort_options": { + "field_name": "NAME", + "order": "ASC" + } +}' +---- + +==== API response + +If the API request is successful, it will return a list of Collection(s) matching the search criteria. + +== Update a Collection +To update an existing Collection, send a `POST` request to the `POST /api/rest/2.0/collections/{collection_identifier}/update` API endpoint. + +=== Request parameters +In your `POST` request body, include the following parameters: + +[width="100%" cols="1,4"] +[options='header'] +|===== +|Parameter|Description + +|`collection_identifier` a| Required. GUID of the Collection to be updated. `collection_identifier` is passed as a parameter in the API request. +|`name` a|__String__. Optional. New name for the Collection. +|`description` a|__String__. Optional. Updated or a newly added description for the Collection. +|`metadata` a|__Array__. Required. The details for the metadata objects to be added, removed, or replaced in the Collection. + +* `type` +* `identifiers` +|`operation` a|__Enum__. Required. Specify the nature of the update. Select one of the following values: + +* ADD: Adds the specified metadata objects to the existing Collection without removing the current objects. +* REMOVE: Removes only the specified metadata objects from the Collection. +* REPLACE. __Default__: This replaces all existing objects in the Collection with the objects specified in this replace request. +|===== + +==== Example request +[source,CURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/collections/0e5fd958-cb2b-43f0-b67f-13ac5c805bad/update' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "operation": "ADD", + "metadata": [ + { + "type": "LIVEBOARD", + "identifiers": [ + "6fee1adb-1c50-4c15-8d49-4fe0503d0b34" + ] + } + ] +}' +---- +==== API response + +If the API request is successful, the object specified in the API request is added to the Collection. + +==== Example request +[source,CURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/collections/0e5fd958-cb2b-43f0-b67f-13ac5c805bad/update' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "operation": "REMOVE", + "metadata": [ + { + "type": "LIVEBOARD", + "identifiers": [ + "6fee1adb-1c50-4c15-8d49-4fe0503d0b34" + ] + } + ] +}' +---- + +==== API response + +If the API request is successful, the object specified in the API request is removed from the Collection. + +==== Example request +[source,CURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/collections/0e5fd958-cb2b-43f0-b67f-13ac5c805bad/update' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "operation": "REPLACE", + "metadata": [ + { + "type": "LIVEBOARD", + "identifiers": [ + "6fee1adb-1c50-4c15-8d49-4fe0503d0b34", + "87328d32-2bf0-4fc4-ac51-a738712d7e79" + ] + }, + { + "type": "COLLECTION", + "identifiers": [ + "6d85c77c-4822-42ba-8074-6306a90ba8e1" + ] + } + ] +}' +---- + + +==== API response + +If the API request is successful, the objects in the Collection are replaced with the objects in this API request. + +== Delete a Collection +To remove an existing Collection, send a `POST` request to the `POST /api/rest/2.0/collections/delete` API endpoint. + +=== Request parameters +In your `POST` request body, include the following parameters: + +[width="100%" cols="1,4"] +[options='header'] +|===== +|Parameter|Description + +|`collection_identifiers` a|__String__. Required. GUID of the Collection to be deleted. +|`delete_children` a|__String__. Optional. Set to `true` to delete child objects in the Collection where the user has permission. Any objects without delete access will be ignored. +|`dry_run` a|__String__. Optional. Set to true to preview the deletion process without removing any objects. The response lists the items that would be deleted, so you can review them before proceeding with actual deletion. +|===== + +==== Example request +To review your deletion request without actually deleting the Collection and its objects, set `dry_run` to `true` and `delete_children` to `true`. + +[source,CURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/collections/delete' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "collection_identifiers": [ + "6996b262-8733-4af6-8f8e-8d7faefb5be0" + ], + "delete_children": true, + "dry_run": true +}' +---- + +==== API response + +If the API request is successful, it gives you a preview of the deletion operation without actually deleting anything. + +* `metadata_deleted`: List of metadata objects that will be deleted +* `metadata_skipped`: List of metadata objects that will not be deleted for lack of permissions or other constraints + +[source,JSON] +---- +{"metadata_deleted":[{"type":"COLLECTION","identifiers":[{"id":"6996b262-8733-4af6-8f8e-8d7faefb5be0","name":"Docs Collection"}]},{"type":"LIVEBOARD","identifiers":[{"id":"278d2313-ac3a-44bb-b842-a4c9dff84e68","name":"Demo-lb"},{"id":"1bcdb2c1-e960-4f6b-bbf9-64f3e0cd33b9","name":"Demo-lb1"}]}],"metadata_skipped":[]} +---- + +==== Example request +To delete the Collection and the objects within it, set `dry_run` to `false` and `delete_children` to `true`. + +[source,CURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/collections/delete' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "collection_identifiers": [ + "6996b262-8733-4af6-8f8e-8d7faefb5be0" + ], + "delete_children": true, + "dry_run": false +}' +---- + +==== API response +If the API request is successful, it deletes the Collection and all objects within it for which you have delete permission. + +[source,JSON] +---- +{"metadata_deleted":[{"type":"COLLECTION","identifiers":[{"id":"6996b262-8733-4af6-8f8e-8d7faefb5be0","name":"Docs Collection"}]},{"type":"LIVEBOARD","identifiers":[{"id":"278d2313-ac3a-44bb-b842-a4c9dff84e68","name":"Demo-lb"},{"id":"1bcdb2c1-e960-4f6b-bbf9-64f3e0cd33b9","name":"Demo-lb1"}]}],"metadata_skipped":[]} +---- + +== Additional references + + +* For information about creating and managing Collections via ThoughtSpot UI, see link:https://docs.thoughtspot.com/cloud/latest/collections[Collections in ThoughtSpot, window=_blank] + + diff --git a/modules/ROOT/pages/common/nav.adoc b/modules/ROOT/pages/common/nav.adoc index 75f4b11a4..a7b87b8d4 100644 --- a/modules/ROOT/pages/common/nav.adoc +++ b/modules/ROOT/pages/common/nav.adoc @@ -65,7 +65,6 @@ *** link:{{navprefix}}/embed-ai-search-analytics[Embed AI Search and Analytics] **** link:{{navprefix}}/embed-spotter[Embed Spotter experience] **** link:{{navprefix}}/embed-spotter-agent[Embed Spotter Agent] -**** link:{{navprefix}}/embed-nls[Embed Natural Language Search (legacy interface)] *** link:{{navprefix}}/full-embed[Embed full application] **** link:{{navprefix}}/full-app-customize[Customize your embed] **** link:{{navprefix}}/customize-nav-controls[Customize navigation panels] @@ -102,6 +101,7 @@ **** link:{{navprefix}}/embed-events[Using embed events] **** link:{{navprefix}}/host-events[Using host events] **** link:{{navprefix}}/context-aware-event-routing[Context-based execution of host events] +**** link:{{navprefix}}/hostEventsV2-migration[Migrating from Host Event v1 to Host Events v2 framework] **** link:{{navprefix}}/api-search-intercept[API intercept and data fetch requests] *** link:{{navprefix}}/custom-action-intro[Custom actions] **** link:{{navprefix}}/customize-actions[Custom actions through the UI] @@ -175,6 +175,7 @@ include::generated/typedoc/CustomSideNav.adoc[] ** link:{{navprefix}}/spotter-api[Spotter APIs ^BETA^] ** link:{{navprefix}}/audit-logs[Audit logs] ** link:{{navprefix}}/tml[TML] +** link:{{navprefix}}/collections[Collections ^BETA^] ** link:{{navprefix}}/connections[Connections] *** link:{{navprefix}}/connection-config[Connection configuration] ** link:{{navprefix}}/rest-apiv2-getstarted[REST API v2.0] @@ -218,7 +219,7 @@ include::generated/typedoc/CustomSideNav.adoc[] ** link:{{navprefix}}/v1v2-comparison[REST v1 and v2.0 comparison] ** link:{{navprefix}}/graphql-guide[GraphQL API ^Beta^] ** link:{{navprefix}}/webhooks[Webhooks] -*** link:{{navprefix}}/webhooks-comm-channel[Configure webhook communication channel] +*** link:{{navprefix}}/webhooks-comm-channel[Configure and monitor webhook communication channels] *** link:{{navprefix}}/webhooks-s3-integration[Deliver Liveboard reports to AWS S3 Storage] *** link:{{navprefix}}/webhooks-lb-schedule[Deliver Liveboard reports to external application] *** link:{{navprefix}}/webhooks-lb-payload[Webhook response payload] @@ -242,6 +243,7 @@ include::generated/typedoc/CustomSideNav.adoc[] **** link:{{navprefix}}/git-provider-integration[Git provider integration] **** link:{{navprefix}}/modify-tml[TML modification] *** link:{{navprefix}}/publish-data-overview[Publish content to Orgs] +**** link:{{navprefix}}/parameterize-metadata[Parameterize metadata] **** link:{{navprefix}}/publish-to-orgs[Publish objects to Orgs] *** link:{{navprefix}}/git-integration[Deploy with GitHub APIs (legacy)] **** link:{{navprefix}}/git-configuration[Configure GitHub integration] diff --git a/modules/ROOT/pages/customize-email-apis.adoc b/modules/ROOT/pages/customize-email-apis.adoc index 818b33f6f..67db22f91 100644 --- a/modules/ROOT/pages/customize-email-apis.adoc +++ b/modules/ROOT/pages/customize-email-apis.adoc @@ -62,45 +62,47 @@ In your `POST` request body, include the following parameters: [source,CURL] ---- curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/customization/email' \ - -H 'Accept: application/json' \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer {AUTH_TOKEN}' \ - --data-raw '{ - { - "template_properties": { - "cta_button_bg_color": "", - "cta_text_font_color": "", - "primary_bg_color": "", - "Logo_url": - "https://storage.pardot.com/710713/1642089901EbkRibJq/TS_fullworkmark_darkmode.png", - "font_family": "", - "product_name": "ThoughtSpot", - "footer_address": "444 Castro St, Suite 1000 Mountain View, CA 94041", - "footer_phone": "(800) 508-7008", - "replacement_value_for_liveboard": "Dashboard", - "replacement_value_for_answer": "Chart", - "replacement_value_for_spot_iq": "AI Insights", - "hide_footer_phone": false, - "hide_footer_address": false, - "hide_product_name": false, - "hide_manage_notification": false, - "hide_mobile_app_nudge": false, - "hide_privacy_policy": false, - "hide_ts_vocabulary_definitions": false, - "hide_error_message": false, - "hide_unsubscribe_link": false, - "hide_notification_status": false, - "hide_modify_alert": false, - "company_website_url": "https://your-website.com/" - "company_privacy_policy_url" : "https://link-to-privacy-policy.com/" - }, - "org_identifier": "-1" -} - +--url 'https://{ThoughtSpot-Host}/api/rest/2.0/customization/email' \ +-H 'Accept: application/json' \ +-H 'Content-Type: application/json' \ +-H 'Authorization: Bearer {AUTH_TOKEN}' \ +--data-raw '{ +"template_properties": { + "cta_button_bg_color": "", + "cta_text_font_color": "", + "primary_bg_color": "", + "logo_url": "https://storage.pardot.com/710713/1642089901EbkRibJq/TS_fullworkmark_darkmode.png", + "font_family": "", + "product_name": "ThoughtSpot", + "footer_address": "444 Castro St, Suite 1000 Mountain View, CA 94041", + "footer_phone": "(800) 508-7008", + "replacement_value_for_liveboard": "Dashboard", + "replacement_value_for_answer": "Chart", + "replacement_value_for_spot_iq": "AI Insights", + "hide_footer_phone": false, + "hide_footer_address": false, + "hide_product_name": false, + "hide_manage_notification": false, + "hide_mobile_app_nudge": false, + "hide_privacy_policy": false, + "hide_ts_vocabulary_definitions": false, + "hide_error_message": false, + "hide_unsubscribe_link": false, + "hide_notification_status": false, + "hide_modify_alert": false, + "company_website_url": "https://your-website.com/", + "company_privacy_policy_url": "https://link-to-privacy-policy.com/", + "contact_support_url": "https://link-to-contact-support.com/", + "hide_contact_support_url": false, + "hide_logo_url": false +}, +"org_identifier": "-1" +}' ---- + + [.widthAuto] [.bordered] image:./images/email-template.png[JSON actions explained] diff --git a/modules/ROOT/pages/data-report-v2-api.adoc b/modules/ROOT/pages/data-report-v2-api.adoc index 5d5c314ca..2e76d4253 100644 --- a/modules/ROOT/pages/data-report-v2-api.adoc +++ b/modules/ROOT/pages/data-report-v2-api.adoc @@ -272,7 +272,7 @@ For *XLSX* downloads [earlyAccess eaBackground]#Early Access#, * A maximum of 255 tabs per .xlsx workbook are allowed. * It does not support any additional parameters to customize the page orientation and `include_cover_page`, `include_filter_page`, logo, footer text, and page numbers. * Charts are exported as tabular data. Downloaded reports may include columns not seen in the visualization if they were used as tokens in the underlying search query. -* Unlike the pivot tables that are downloaded for any pivot table Answer in the ThoughtSpot UI, pivot tables generated in .xlsx workbooks using this API endpoint are exported as their underlying raw data. The .xlsx currently does not support the pivot table format. +* Pivot tables generated in .xlsx workbooks using this API endpoint retain their complete visual formatting and structural integrity. To enable this on your ThoughtSpot instance, contact ThoughtSpot Support. ===== Sample API payload for XLSX downloads diff --git a/modules/ROOT/pages/embed-pinboard.adoc b/modules/ROOT/pages/embed-pinboard.adoc index 452730976..bcfa4315a 100644 --- a/modules/ROOT/pages/embed-pinboard.adoc +++ b/modules/ROOT/pages/embed-pinboard.adoc @@ -113,7 +113,7 @@ Parameters such as `hideLiveboardHeader`, `hideTabPanel`, `isLiveboardHeaderStic [.widthAuto] image::./images/liveboard_view_config_callouts_2.png[LiveboardViewConfig parameters] -The `hideLiveboardHeader` property removes the entire header area above the Liveboard, including filters and the overall Liveboard menu, which is a common pattern for "read-only' use cases or rebuilding your own menus and buttons using xref:embed-events.adoc[HostEvents]. +The `hideLiveboardHeader` property removes the entire header area above the Liveboard, including filters and the overall Liveboard menu, which is a common pattern for "read-only" use cases or rebuilding your own menus and buttons using xref:embed-events.adoc[HostEvents]. The following constructor will disable the __sticky header__, while showing the Liveboard title, which would be hidden by default: @@ -216,199 +216,43 @@ You can also pin a visualization to a Liveboard tab using the **Pin** action on === Customize filters -To view specific data across the tables and charts on an embedded Liveboard, users can use Liveboard filter options. You can embed a Liveboard with filters already applied or xref:runtime-filters.adoc[define runtime filters] in the Visual Embed SDK and apply filters during load time. +To view specific data across the tables and charts on an embedded Liveboard, users can use Liveboard filter options. By default, Liveboard filters cannot be applied at load. You can either embed a Liveboard that already includes filters or use the xref:runtime-filters.adoc[runtime filters] feature in the Visual Embed SDK to apply filters during load time. -Embedding application users can also apply filters across visualizations using the link:https://docs.thoughtspot.com/cloud/latest/liveboard-filters-cross[cross-filter feature, window=_blank]. - -The Visual Embed SDK provides the following host events to trigger an action to get or update filters: - -* link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_getfilters[`HostEvent.GetFilters`] -* link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_updatefilters[`HostEvent.UpdateFilters`] -* link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_updateruntimefilters[`HostEvent.UpdateRuntimeFilters`] -* link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_updatecrossfilter[`HostEvent.UpdateCrossFilter`] - -==== Date filters - -For `DATE` and `DATE_TIME` data types, you must provide the date and time values in the Epoch time format when xref:runtime-filters.adoc#_apply_runtime_filters_on_embedded_objects[applying or updating runtime filters] via SDK or REST API. - -However, when updating filters using `HostEvent.UpdateFilters`, you must include the date filter `type` along with the time period to apply any rolling or fixed time windows. - -[NOTE] -==== -* For `PERIOD` filters, you must include the `datePeriod` attribute in the date filter object. -* To specify the exact date, date range, you can use the date format such as `YYYY-MM-DD`, `YYYY/MM/DD`. If using epoch format, ensure that they are specified as numbers and not as strings. For example, `[1743465599, 1754006399]`. -==== - -The following table lists the supported filter types and examples for each type: - -[width="100%" cols="3,5,8"] -[options='header'] -|===== -|Type| Description | Example - -| `YESTERDAY` | Specify the `type` as `YESTERDAY`. a| -[source,JavaScript] ----- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "EQ", - values: [""], - type: "YESTERDAY" - } - }); ----- -| `TODAY` | Specify the `type` as `TODAY`. a| -[source,JavaScript] ----- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "EQ", - values: [""], - type: "TODAY" - } - }); ----- -| `TOMORROW` | Specify the `type` as `TOMORROW`. a| +=== Customizing filter visibility +To hide filters in an embedded Liveboard, you can use the following options: +* Set `hideLiveboardHeader` to `true` to hide the entire header area, including filters and the Liveboard menu. You can then trigger filter interactions programmatically using host events. ++ [source,JavaScript] ---- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "EQ", - values: [""], - type: "TOMORROW" - } - }); ----- - -|`EXACT_DATE` | Allows filtering column data to show details for the exact date, before or after the date. For example, to filter data for dates greater than `2023/07/31`, specify `2023/07/31` as value, with the filter operator as `GT`. a| [source,JavaScript] ----- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "GT", - values: ["2023-07-31"], - type: "EXACT_DATE" - } - }); +const embed = new LiveboardEmbed('#embed', { + ... // other liveboard view config + hideLiveboardHeader:true, +}); ---- -|`EXACT_DATE_RANGE` |Specify the start date and end date in the `values` array. Ensure that the start date is lower than the end date. For example, `"2023-01-31","2023-03-31"`. a| +* If the Liveboard compact header is enabled, set `hideIrrelevantChipsInLiveboardTabs` to `true` to hide filters that are not relevant to the current tab in an embedded Liveboard. ++ [source,JavaScript] ---- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "BW_INC", - values: ["2023-01-31","2023-03-31"], - type: "EXACT_DATE_RANGE" - } - }); ----- - -|`LAST_N_PERIOD` |Specify the period. You must include the `datePeriod` attribute based on the time period specified in the filter object. Valid values for `datePeriod` are `SECOND`, `MINUTE`, `HOUR`, `DAY`, WEEK`, `MONTH`, `QUARTER`, and `YEAR`. For example, to filter column data by last 2 weeks, set `datePeriod` to `WEEK` and `values` to `2`. - -a|[source,JavaScript] ----- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "EQ", - values: [2], - datePeriod: "WEEK", - type: "LAST_N_PERIOD" - } - }); ----- - -|`NEXT_N_PERIOD` | Specify the period. You must include the `datePeriod` attribute based on the time period specified in the filter object. Valid values for `datePeriod` are `SECOND`, `MINUTE`, `HOUR`, `DAY`, WEEK`, `MONTH`, `QUARTER`, and `YEAR`. For example, to filter column data by next 2 months, set `datePeriod` to `MONTH` and `values` to `2`. - -a|[source,JavaScript] ----- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "EQ", - values: [2], - datePeriod: "MONTH", - type: "NEXT_N_PERIOD" - } - }); ----- - -| `THIS_PERIOD` | Specify the period. You must include the `datePeriod` attribute based on the time period specified in the filter object. Valid values for `datePeriod` are `SECOND`, `MINUTE`, `HOUR`, `DAY`, WEEK`, `MONTH`, `QUARTER`, and `YEAR`. - -a|[source,JavaScript] ----- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "EQ", - values: [""], - datePeriod: "MONTH", - type: "THIS_PERIOD" - } - }); +const embed = new LiveboardEmbed('#embed', { + ... // other liveboard view config + isLiveboardCompactHeaderEnabled: true, + hideIrrelevantChipsInLiveboardTabs: true, +}); ---- -| `PERIOD_TO_DATE` |Specify the period. You must include the `datePeriod` attribute based on the time period specified in the filter object. Valid values for `datePeriod` are `WEEK`, `MONTH`, `QUARTER`, and `YEAR`. - -a|[source,JavaScript] ----- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "EQ", - values: [""], - datePeriod: "QUARTER", - type: "PERIOD_TO_DATE" - } - }); ----- -|`YEAR_ONLY` |Specify the year. For example, 2023. -a|[source,JavaScript] ----- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "EQ", - values: ["2023"], - type: "YEAR_ONLY" - } - }); ----- +==== Updating filters +Use the following host events in the Visual Embed SDK to update filters: -| `MONTH_YEAR` |Specify the month and year in the `values` array. For example, `"July","2023"`. -a|[source,JavaScript] ----- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "EQ", - values: ["July","2023"], - type: "MONTH_YEAR" - } - }); ----- +* link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_updatefilters[`HostEvent.UpdateFilters`] to update Liveboard filters +* link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_updateruntimefilters[`HostEvent.UpdateRuntimeFilters`] to update runtime filters +* link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_updatecrossfilter[`HostEvent.UpdateCrossFilter`] -|`QUARTER_YEAR` | Specify the quarter and year in the `values` array. For example, `"Q1","2023"`. +For more information and examples, see xref:filters_overview.adoc#_updating_filters_using_host_events[Updating filters] and xref:filters_overview.adoc#_updating_date_filters[Updating date filters]. -a|[source,JavaScript] ----- -liveboardEmbed.trigger(HostEvent.UpdateFilters, { - filter: { - column: "date", - oper: "EQ", - values: ["Q1","2023"], - type: "QUARTER_YEAR" - } - }); ----- -|===== +//// ==== Customize filter visibility in Liveboard tabs Filters and parameters that are not relevant to the visualizations in a tab can be hidden by default on an embedded Liveboard. This feature is disabled by default on ThoughtSpot embedded instances. To enable this feature, set `hideIrrelevantChipsInLiveboardTabs` to `true`. @@ -431,6 +275,8 @@ const liveboardEmbed = new LiveboardEmbed(document.getElementById('ts-embed'), { }); ---- +//// + //// diff --git a/modules/ROOT/pages/embed-spotter.adoc b/modules/ROOT/pages/embed-spotter.adoc index f505d1a76..0ab813019 100644 --- a/modules/ROOT/pages/embed-spotter.adoc +++ b/modules/ROOT/pages/embed-spotter.adoc @@ -14,7 +14,13 @@ To embed Spotter, you need the following access and setup: * Access to a ThoughtSpot instance with the Spotter feature. If you want a specific version of Spotter enabled, work with your ThoughtSpot administrator to enable the xref:embed-ai-analytics.adoc#_feature_status_and_availability_in_embed_mode[required features and settings] on your instance. * Your host application domain is added to xref:security-settings.adoc[ThoughtSpot CSP and CORS allowlists]. -* Your application project has access to the xref:api-changelog.adoc[latest version of the Visual Embed SDK]. +* Your application project has access to the xref:api-changelog.adoc[latest version of the Visual Embed SDK]. + + +[NOTE] +==== +For Spotter embedding that uses cookieless authentication, use the Visual Embed SDK v1.45.0 or later with ThoughtSpot Cloud 26.2.0.cl or a later version. To enable proactive token refresh, set the `refreshAuthTokenOnNearExpiry` parameter to `true`. + +Spotter workflows can run longer, so set the authentication token expiry to at least 10 minutes to avoid authorization errors. +==== == Import the SDK package Import the `SpotterEmbed` SDK library to your application environment: @@ -175,6 +181,7 @@ image::./images/spotter3-leagcy-interface-automode.png[Spotter 3 interface] When Auto mode is enabled, **Preview data** and **Data Model instructions** options will not be available. ==== + ==== New chat interface Spotter 3 experience is available with a new prompt interface that includes additional features and user elements to enrich your Spotter experience. @@ -190,41 +197,41 @@ const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { }); ---- -==== Chat history panel +[.widthAuto] +[.bordered] +image::./images/spotter3-new-interface.png[Spotter 3 new interface] -You can also include the *Chat history* panel to allow your users to access the chat history from their previous sessions. To enable chat history features, set the `enablePastConversationsSidebar` attributes to `true`. +==== Chat history panel -//// -Additionally, you can customize the chat history sidebar using the settings available in the xref:SpotterSidebarViewConfig.adoc[SpotterSidebarViewConfig] interface and `spotterSidebarConfig` properties. +You can also include the *Chat history* panel to allow your users to access the chat history from their previous sessions. +To enable chat history features, set the `enablePastConversationsSidebar` attributes to `true`. Additionally, you can also customize the appearance and contents of the chat history panel using the configuration parameters available in the xref:SpotterSidebarViewConfig.adoc[`SpotterSidebarViewConfig`] interface and the xref:SpotterEmbedViewConfig#_spottersidebarconfig[spotterSidebarConfig] object. [source,JavaScript] ---- +import { + SpotterEmbed, + SpotterEmbedViewConfig, + SpotterSidebarViewConfig +} from '@thoughtspot/visual-embed-sdk'; + const embed = new SpotterEmbed('#tsEmbed', { - // ...other embed view configuration options - // Configuration for the Spotter sidebar UI - spotterSidebarConfig: { - enablePastConversationsSidebar: true, // Show chat history sideabr - spotterSidebarTitle: 'My Conversations', // Set the title of the sidebar - spotterSidebarDefaultExpanded: true, // Expand Spotter chat history sidebar by default on load - }, + // ...other embed view configuration options + // Configuration for the Spotter sidebar UI + spotterSidebarConfig: { + enablePastConversationsSidebar: true, // Show chat history sidebar + spotterSidebarTitle: 'My Conversations', // Update the title of the sidebar + spotterSidebarDefaultExpanded: true, // Expand Spotter chat history sidebar by default on load + }, }) ---- -//// -[source,JavaScript] ----- -const spotterEmbed = new SpotterEmbed(document.getElementById('ts-embed'), { - // Enable the sidebar for accessing past Spotter conversations - enablePastConversationsSidebar: true -}); ----- +[NOTE] +==== +The standalone `enablePastConversationsSidebar` attribute is deprecated in v1.47.0 and can no longer be used to enable or disable the chat history. +==== -[.widthAuto] -[.bordered] -image::./images/spotter3-new-interface.png[Spotter 3 new interface] - ==== MCP connectors and resource selection icon A connector is an external MCP server or tool, such as Google Drive, Slack, Notion, Confluence, or Jira, which can be used as a data source in Spotter sessions. ThoughtSpot administrators can configure connectors to enable Spotter users to include both structured and unstructured data in their conversation sessions. @@ -338,9 +345,35 @@ The following figures show the customized Spotter icon: [.bordered] image::./images/spotter-icon-customization.png[Spotter icon customization] -=== Hiding the Spotter icon and ThoughtSpot branding in the reasoning interface -If you want to hide the Spotter icon from the prompt response page and reasoning interface, or if you want to remove ThoughtSpot branding, you can use the CSS rules with selectors, as shown in this example: +=== Hiding the Spotter icon and ThoughtSpot branding chat interface +To hide the Spotter logo and branding in the chat interface, use the following parameters in the `SpotterChatViewConfig` interface: + +* `hideToolResponseCardBranding` + +When set to `true`, hides the ThoughtSpot logo and icon in tool response cards. The branding label prefix is controlled separately via `toolResponseCardBrandingLabel`. + +* `toolResponseCardBrandingLabel` + +Custom label to replace the `ThoughtSpot` prefix in tool response cards. Set to an empty string (`''`) to hide the prefix entirely. +Example:: ++ +[source,JavaScript] +---- +import { + SpotterEmbed, + SpotterEmbedViewConfig, + SpotterChatViewConfig +} from '@thoughtspot/visual-embed-sdk'; + +spotterChatConfig: { + //Hide the default logo and label on tool response cards in Spotter chat UI + hideToolResponseCardBranding: true, + // Set a custom label to display as the branding on tool response cards + toolResponseCardBrandingLabel: 'CompanyName', +} +---- + + +//// [source,JavaScript] ---- init({ @@ -370,6 +403,7 @@ init({ } }); ---- +//// [#spotterMenuActions] === Customizing menu actions and elements diff --git a/modules/ROOT/pages/events-context-aware-routing.adoc b/modules/ROOT/pages/events-context-aware-routing.adoc index f230949e4..3dad6545b 100644 --- a/modules/ROOT/pages/events-context-aware-routing.adoc +++ b/modules/ROOT/pages/events-context-aware-routing.adoc @@ -11,7 +11,7 @@ This guide explains how developers embedding ThoughtSpot in their applications c == Overview Host events in a single‑layer UI, such as a standalone visualization, Answer, or Liveboard page, typically result in a single visible action. Because only one surface is available to handle a given host event, the events are effectively routed to that page; for example, `HostEvent.OpenFilter` in a single‑layer Liveboard or Search embed opens the filter panel for the specified column on that page. -In a multi‑layer UI, such as a visualization or Spotter overlay opened on top of a Liveboard,some host events can lead to ambiguous results. Multiple components may register handlers for the same event type, so a single call can invoke more than one handler or may return errors. Some examples of the multi-layer UI scenarios include: +In a multi‑layer UI, such as a visualization or Spotter overlay opened on top of a Liveboard, some host events can lead to ambiguous results. Multiple components may register handlers for the same event type, so a single call can invoke more than one handler or may return errors. Some examples of the multi-layer UI scenarios include: * An embedded Liveboard with multiple visualizations, each with its own menu and actions. * Spotter overlay on top of a Liveboard, with its own visualization and menu actions. @@ -76,6 +76,17 @@ The available contexts are: * `answer` - The Explore or Drill dialogs opened from a visualization or search Answer. * `other` - Fallback for generic or app-level interactions not tied to a specific context. For example, the home page and list pages in a full application embed. +You can also retrieve current context by listening to the `EmbedEvent.EmbedPageContextChanged`. + +[source,JavaScript] +---- +liveboardEmbed.on('EmbedPageContextChanged', (payload) => { + console.log('Context changed:', payload); + const { currentContext, stack } = payload.data + console.log('Current page:', currentContext.name); +}); +---- + ==== Page context stack in an embedded Liveboard The Visual Embed SDK maintains an ordered page context stack for each embedded interface. Every page component or overlay registers its context when it mounts and unregisters when it unmounts. @@ -471,16 +482,49 @@ appEmbed.trigger( ); ---- + + == Validation and error handling + Ensure that the xref:EmbedEvent.adoc#_error[EmbedEvent.Error] is subscribed in your embed. This allows your embed to emit an event when an error occurs. Verify the error type and code for host event validation errors. For more information, see xref:EmbedErrorDetailsEvent.adoc[EmbedErrorDetailsEvent]. -Your host events may return errors in the following scenarios: +When the Host Events v2 framework is enabled, the event execution returns errors in the following scenarios: -* When a matching handler is not present in the specified context. + -Verify the host event type, payload, and context type. +* No matching handler for the event type in the current context. + +Verify if the action is available in the context and if required, specify the target context in the host event object. +* Missing required parameters. Verify the host event type, payload, and context type. * If a required attribute is missing, for example, `vizId` in Spotter context. Add the `vizId` and retry. * Verify the visualizations and objects specified in the host event are present and visible in the embed view. If not, adjust the UI experience (scroll, navigate, open a dialog) before calling the host event. +=== Listening for Subscribed events +When the Host Events v2 framework is enabled, the embedded ThoughtSpot app emits the `subscribed` signal whenever it registers an internal handler for a Host Event. + +For a given Host Event type, such as OpenFilter, this is exposed as ` Subscribed`. + +* `OpenFilter Subscribed` +* `Edit Subscribed` +* `SaveAnswer Subscribed` + +These events indicate that ThoughtSpot has subscribed its internal handler(s) and the corresponding host event is now ready to trigger from the host application. This helps you avoid race conditions such as: + +* Triggering events before the embed UI has fully loaded and event handler is subscribed. +* Relying on `setTimeout` delays to wait until events are ready. + + +//// +==== Listening to context changes + +You can also listen to the context changes via `EmbedEvent.EmbedPageContextChanged` and retrieve the current context from a user session. + +[source,JavaScript] +---- +liveboardEmbed.on(EmbedEvent.EmbedPageContextChanged, (payload) => { +console.log("Current context:", payload.currentContext); +console.log("Full stack:", payload.stack); +}); +---- +//// + == Best practices and recommendations When building integrations that rely on context and app interactions via host events, consider the following recommendations: @@ -500,18 +544,10 @@ When building integrations that rely on context and app interactions via host ev ** The SDK executes handlers only for the resolved context. If the event is invalid for that context or no handler exists, it returns an error. * Log or surface error messages from host events during development and testing. -//// -==== Listening to context changes -You can also listen to the context changes via EmbedEvent.EmbedPageContextChanged and retrieve the current context from a user session. -[source,JavaScript] ----- -liveboardEmbed.on(EmbedEvent.EmbedPageContextChanged, (payload) => { -console.log("Current context:", payload.currentContext); -console.log("Full stack:", payload.stack); -}); ----- -//// + + + == Related resources diff --git a/modules/ROOT/pages/filters_overview.adoc b/modules/ROOT/pages/filters_overview.adoc index d2e3e16c1..42ab9c701 100644 --- a/modules/ROOT/pages/filters_overview.adoc +++ b/modules/ROOT/pages/filters_overview.adoc @@ -6,13 +6,143 @@ :page-pageid: filters-overview :page-description: ThoughtSpot has several layers of filters which have an order of precedence and different events -ThoughtSpot provides multiple types of filters for various xref:intro-thoughtspot-objects.adoc[object types], which can be applied in a layered fashion. +ThoughtSpot Embedded provides a robust filtering framework for Liveboards, Answers, visualizations, and other ThoughtSpot objects with multiple filter types and layered application logic. Filters can be configured using the Visual Embed SDK events and parameters when embedding, applied at runtime, or via UI-driven workflows. +== Filter types and application layers +The behavior of each filter type and the mechanism for setting filters can differ widely. +There are different types of filters, which can be applied in the following order: + +1. xref:rls-rules.adoc[**Row-level security (RLS) Rules**] + +Rules are defined at the table level and applied during query generation to all objects derived from that table. Rules can be defined based on the logged-in user, their group memberships, or custom variables. + +RLS rules secure data and cannot be altered by the logged-in user. + +RLS rules can also be used, along with custom variables and the JSON Web Token (JWT) generated for the user, to implement xref:abac_rls-variables.adoc[Attribute-Based Access Control (ABAC)]. + +2. **Data Model filters** + +Models can have parameters, formulas, and filters. + +Embedding application users cannot affect the formulas or filters, which are always applied, but Parameters used in a formula can be set by other methods. + +If the user can edit the parameter, use the runtime parameters layer to programmatically set its value. + +3. xref:runtime-filters.adoc[Runtime filters] and xref:runtime-parameters.adoc[Runtime Parameters] + +You can define xref:runtime-filters.adoc[runtime filters] and xref:runtime-parameters.adoc[runtime parameters] within the browser for a given object at load time. Filters and parameters can be set using the Visual Embed SDK, REST API, or URL query parameters and updated via host events in the Visual Embed SDK. ++ +[NOTE] +==== +Runtime filters do not display as UI filter components. +==== + +4. link:https://docs.thoughtspot.com/cloud/latest/liveboard-filters[Liveboard filters, window=_blank] + +Liveboard filters apply to all visualizations on the Liveboard and are visible as UI components at the top of a Liveboard page. When a filter is clicked, a modal with filter options appropriate for the data type is displayed. + +Liveboard users can add or modify filters as needed. If you are embedding a Liveboard that includes preset filters, you can programmatically update, reset, or remove filters using the `HostEvent.UpdateFilters`. + +5. link:https://docs.thoughtspot.com/cloud/latest/liveboard-filters-cross[Liveboard cross filters, window=_blank] + +Cross filters are ad-hoc filters based on user selection. These filters are used for brushing and linking Liveboard visualizations. + +Cross filters are supported only on attribute columns. + +6. link:https://docs.thoughtspot.com/cloud/latest/filters[Search query filters, window=_blank] + +Set via the search query string in Answers and visualizations, not visible as UI filter components on a Liveboard, but can be viewed in **Explore** or *Edit* modes. + +The lowest layer of filters is defined in the search query for a given Answer or visualization on a Liveboard. + +The link:https://docs.thoughtspot.com/cloud/latest/filters[filter terms, window=_blank] are saved as part of the `search_query` of the object, visible in TML. + +== Filter attributes +When specifying a column for filtering, you must use the exact column name as defined in the model. Filters can be applied to string, number, boolean, Date, Datetime, and time data types. +For the `DATE` and `DATE_TIME` data types, some filter types may require the date and time values to be specified in the Epoch time format. + +All operations result in a `WHERE` clause being applied to the queries generated by ThoughtSpot, or no query being issued if the logic is always false. + +A data filter object in ThoughtSpot typically includes the following attributes: + +`column`, `columnName`, or `columnId`:: +The name of the column to filter on. For example, `item type` or `product`. The column value must match the actual column name in the ThoughtSpot model. If the model uses column aliases, use the base column name, not the alias. This attribute is defined as `col1`, `col2`, `col3` in the object URLs and REST API requests, as `columnName` in the `runtimeFilters` array in the Visual Embed SDK. The filter object for host events in the SDK allows `column` or `columnName`. ++ +If there are multiple columns with the same name, you can use the `WORKSHEET_NAME::COLUMN_NAME` format; for example, `"(Sample) Retail - Apparel::city"`. + +`oper` or `operator`:: +The supported operators include: ++ +[width="80%" cols="1,2,2"] +[options='header'] +|=== +|Operator|Description|Number of Values + +| `EQ` +| equals +| 1 + +| `NE` +| not equal to +| 1 + +| `LT` +| less than +| 1 + +| `LE` +| less than or equal to +| 1 + +| `GT` +| greater than +| 1 + +| `GE` +| greater than or equal to +| 1 + +| `CONTAINS` +| contains +| 2 + +| `BEGINS_WITH` +| begins with +| 1 + +| `ENDS_WITH` +| ends with +| 1 + +| `BW_INC_MAX` +| between inclusive of the higher value +| 2 + +| `BW_INC_MIN` +| between inclusive of the lower value +| 2 + +| `BW_INC` +| between inclusive +| 2 + +| `BW` +| between non-inclusive +| 2 + +|`IN` +|is included in this list of values +|multiple +|`NOT_IN` +|is not included in this list of values +|multiple +|=== + +values:: +An array of one or more values to filter by. The values must match the data type of the column. + +type:: +Specifies the type for date filters. Supported types include `YESTERDAY`, `TODAY`, `TOMORROW`, `EXACT_DATE`, `EXACT_DATE_RANGE`, `LAST_N_PERIOD`, `NEXT_N_PERIOD`, `THIS_PERIOD`, `PERIOD_TO_DATE`, `YEAR_ONLY`, `MONTH_YEAR`, and `QUARTER_YEAR`. + +[NOTE] +==== +* To specify the exact date or date range, you can use the date format such as `YYYY-MM-DD`, `YYYY/MM/DD`. If using epoch format, ensure that they are specified as numbers and not as strings. For example, `[1743465599, 1754006399]`. +* For `PERIOD` filters, you must include the `datePeriod` attribute in the date filter object. +* For rolling date filters with **Last ** and **Next **, you can specify whether to include or exclude the current period. +==== + +//// == Order of filter layers The behavior of each filter type and the mechanism for setting filters can differ widely. There are different types of filters, which can be applied in the following order: -1. xref:rls-rules.adoc[Row-level security (RLS) Rules] + +1. xref:rls-rules.adoc[Row-level security (RLS) Rules]+ Tied to the logged-in user and their group memberships. Completely secure and cannot be altered by the logged-in user. 2. xref:abac-user-parameters.adoc[Attribute-Based Access Control (ABAC) filter rules] + Filters and Parameter rules applied on a Model and assigned to a token. @@ -26,60 +156,42 @@ Filters used for brushing and linking Liveboard visualizations Set via the search query string, not visible as UI filter components on a Liveboard, but can be viewed in **Explore** or *Edit* modes. All types of filters result in some form of `WHERE` clause being applied to the resulting queries generated by ThoughtSpot, or no query being issued if the resulting logic is always false. +//// -== RLS Rules -xref:rls-rules.adoc[RLS rules] are defined at the ThoughtSpot Table object level. - -Once in place, they always apply within the query generation layer. - -Multiple RLS Rules are appended to the query via `OR` logic, rather than `AND`. - +//// == ABAC filter rules Filters and parameter values defined via xref:abac-user-parameters.adoc[ABAC token] that apply at the data model layer are locked-in and always apply until changed or removed by a new token request. The ABAC filter rules and runtime filters are converted into SQL with the same logic: - + 1. clauses are appended via `AND` 2. filters are applied to exact matching Model Column names Any data restrictions resulting from filter rules will be seen in the visible filter UI of the Liveboard filters and `search_query` filters layers, but there is no visible filter UI directly related to these filtering layers. +//// -=== Data Model filters -Models can have Parameters, formulas, and filters. - -End users cannot affect the formulas or filters, which are always applied, but any Parameters that are used in a formula can be set by these other methods. - -To create an adjustable formula-filter that is secure, use the ABAC filtering layer to set the value of the parameter programmatically. +== Applying filters before and after load -If the user can edit the Parameter, use the runtime Parameters layer to set the Parameter value. +* xref:runtime-filters.adoc[Runtime filters] can be applied at load via Visual Embed SDK, REST API, or URL parameters. +* Liveboard filters cannot be applied at load. However, they can be updated using `HostEvent.UpdateFilters` in the SDK. +* Search query filters can be applied at load by specifying them in the initial search query when embedding an Answer or Spotter session. For example, in Spotter embed, you can use the `searchQuery` property to set a pre-defined search (including filters) at load. ++ +When you view an Answer or visualization in *Edit* mode, the filter UI for search query filters appears above the chart or table. These filters are not shown on a Liveboard. If a Liveboard filter is applied to the same column as a search query filter, the Liveboard filter will override the search query filter values. -== Runtime filters and Parameters -You can define xref:runtime-filters.adoc[runtime filters] and xref:runtime-parameters.adoc[runtime parameters] within the browser for a given object at load time. - -Filters and parameters set for ABAC token cannot be overridden by setting runtime filters or Parameters in the browser. - -== Liveboard filters -link:https://docs.thoughtspot.com/cloud/latest/liveboard-filters[Liveboard filters, window=_blank] display at the top of a Liveboard. When clicked, a modal filtering dialog appears with filter options appropriate for the data type. - -The author of a Liveboard can set default values for Liveboard filters and other options on each filter when editing the Liveboard. +=== Cross filters +Liveboard users can apply filters across all visualizations based on the current selection using the *Filter* menu option from the contextual menu. For more information, see link:https://docs.thoughtspot.com/cloud/latest/liveboard-filters-cross[Liveboard cross filter, window=_blank]. -The entire header where the Liveboard filters display link:https://developers.thoughtspot.com/docs/Interface_LiveboardViewConfig#_hideliveboardheader[can be hidden] and then their interaction triggered via events: +If the column already has a Liveboard filter and the user applies cross filters, the cross filter replaces the values in the currently applied Liveboard filter. If there is no Liveboard filter applied to a column and the user applies a cross filter, a new filter chip with cross filter values is displayed in the header area. This filter chip is removed when the cross filter is cleared. -[source,JavaScript] ----- -const embed = new LiveboardEmbed('#embed', { - ... // other liveboard view config - hideLiveboardHeader:true, -}); ----- +Whenever any user action affects a cross filter, a link:https://developers.thoughtspot.com/docs/Enumeration_EmbedEvent#_crossfilterchanged[EmbedEvent.CrossFilterChanged] fires, which can then be used to trigger a specific action. -=== Events +== Updating filters using host events There is no programmatic way to adjust the filter values before loading the Liveboard, but there are events that can adjust the values after the Liveboard is rendered. === OpenFilter event -If you have hidden the Liveboard header, you can trigger the opening of the filter modal dialog by using the link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_openfilter[HostEvent.OpenFilter]: +If you have hidden the Liveboard header, you can trigger the action of opening a filter modal dialog using link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_openfilter[HostEvent.OpenFilter]: [source,JavaScript] ---- @@ -88,7 +200,7 @@ LiveboardEmbed.trigger(HostEvent.OpenFilter, ---- === UpdateFilters event -The link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_updatefilters[HostEvent.UpdateFilters] directly updates the values of the target Liveboard filter: +The link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_updatefilters[HostEvent.UpdateFilters] directly updates the values of the target of an existing filter that's currently applied on a Liveboard: [source,JavaScript] ---- @@ -102,22 +214,17 @@ liveboardEmbed.trigger(HostEvent.UpdateFilters, { }); ---- -The Liveboard filter exists already on the Liveboard for the `HostEvent.UpdateFilters` to work. - -For more information and examples, see xref:embed-pinboard.adoc#_filters[Liveboard filters]. - === GetFilters and GetParameters events If you want to build your own filter UI within the embedding app, you can find out details of the Liveboard and runtime filters that are defined using the link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_getfilters[HostEvent.GetFilters]. There is an equivalent link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_getparameters[HostEvent.GetParameters] to get the currently set Parameter values: [source,JavaScript] ---- const data = await liveboardEmbed.trigger(HostEvent.GetFilters); - console.log('data', data); +console.log('data', data); liveboardEmbed.trigger(HostEvent.GetParameters).then((parameter) => { - console.log('parameters', parameter); + console.log('parameters', parameter); }); - ---- Note that `HostEvent.GetFilters` and `HostEvent.GetParameters` return a promise directly rather than taking a callback function as their second argument. @@ -127,14 +234,6 @@ You can also listen for the user's interactions with the filters using the link: There is an equivalent EmbedEvent for Parameters called link:https://developers.thoughtspot.com/docs/Enumeration_EmbedEvent#_parameterchanged[EmbedEvent.ParameterChanged]. -== Liveboard cross filters -Liveboard users can apply filters across all visualizations based on the current selection using the *Filter* menu option from the contextual menu. For more information, see link:https://docs.thoughtspot.com/cloud/latest/liveboard-filters-cross[Liveboard cross filter, window=_blank]. - -If the column already has a Liveboard filter and the user applies cross filters, the cross filter replaces the values in the currently applied Liveboard filter. If there is no Liveboard filter applied to a column and user applies a cross filter, a new filter chip with cross filter values is displayed in the header area. This filter chip is removed when the cross filter is cleared. - -=== CrossFilterChanged event -Whenever any user action affects a cross filter, a link:https://developers.thoughtspot.com/docs/Enumeration_EmbedEvent#_crossfilterchanged[EmbedEvent.CrossFilterChanged] fires, which can be listened to for register details about the action that happened. - === UpdateCrossFilter event You can programmatically trigger an action to update a cross filter using link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_updatecrossfilter[HostEvent.UpdateCrossFilter]: @@ -149,19 +248,223 @@ liveboardEmbed.trigger(HostEvent.UpdateCrossFilter, { }); ---- -== Search query filters +== Updating date filters +To update date filters in an embedded Liveboard, visualization, or saved answer, use `HostEvent.UpdateFilters`. -The lowest layer of filters is defined as part of the search query for a given Answer or visualization on a Liveboard. +When updating filters using `HostEvent.UpdateFilters`, you must include the date filter `type` along with the time period to apply a rolling or fixed time windows. -The link:https://docs.thoughtspot.com/cloud/latest/filters[filter terms, window=_blank] are saved as part of the `search_query` of the object, visible in TML. +[NOTE] +==== +* For `PERIOD` filters, you must include the `datePeriod` attribute in the date filter object. +* To specify the exact date or date range, you can use the date format such as `YYYY-MM-DD`, `YYYY/MM/DD`. If using epoch format, ensure that they are specified as numbers and not as strings. For example, `[1743465599, 1754006399]`. +==== + +The following table lists the supported filter types and examples for each type: + +[width="100%" cols="3,5,8"] +[options='header'] +|===== +|Type| Description | Example + +| `YESTERDAY` | Specify the `type` as `YESTERDAY`. a| +[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "EQ", + values: [""], + type: "YESTERDAY" + } + }); +---- +| `TODAY` | Specify the `type` as `TODAY`. a| +[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "EQ", + values: [""], + type: "TODAY" + } + }); +---- +| `TOMORROW` | Specify the `type` as `TOMORROW`. a| + +[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "EQ", + values: [""], + type: "TOMORROW" + } + }); +---- + +|`EXACT_DATE` | Allows filtering column data to show details for the exact date, before or after the date. For example, to filter data for dates greater than `2023/07/31`, specify `2023/07/31` as value, with the filter operator as `GT`. a| [source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "GT", + values: ["2023-07-31"], + type: "EXACT_DATE" + } + }); +---- +|`EXACT_DATE_RANGE` |Specify the start date and end date in the `values` array. Ensure that the start date is lower than the end date. For example, `"2023-01-31","2023-03-31"`. a| -When viewing an Answer or a visualization in the *Edit* mode, you will see the filter UI for `search_query` filters above the chart or table. These filters are not visible on a Liveboard. +[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "BW_INC", + values: ["2023-01-31","2023-03-31"], + type: "EXACT_DATE_RANGE" + } + }); +---- + +|`LAST_N_PERIOD` |Specify the period. You must include the `datePeriod` attribute based on the time period specified in the filter object. Valid values for `datePeriod` are `SECOND`, `MINUTE`, `HOUR`, `DAY`, `WEEK`, `MONTH`, `QUARTER`, and `YEAR`. For example, to filter column data by last 2 weeks, set `datePeriod` to `WEEK` and `values` to `2`. + +a|[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "EQ", + values: [2], + datePeriod: "WEEK", + type: "LAST_N_PERIOD", + includeCurrentPeriod: true, + } + }); +---- + +|`NEXT_N_PERIOD` | Specify the period. You must include the `datePeriod` attribute based on the time period specified in the filter object. Valid values for `datePeriod` are `SECOND`, `MINUTE`, `HOUR`, `DAY`, `WEEK`, `MONTH`, `QUARTER`, and `YEAR`. For example, to filter column data by next 2 months, set `datePeriod` to `MONTH` and `values` to `2`. + +a|[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "EQ", + values: [2], + datePeriod: "MONTH", + type: "NEXT_N_PERIOD", + includeCurrentPeriod: false, + } + }); +---- + +| `THIS_PERIOD` | Specify the period. You must include the `datePeriod` attribute based on the time period specified in the filter object. Valid values for `datePeriod` are `SECOND`, `MINUTE`, `HOUR`, `DAY`, `WEEK`, `MONTH`, `QUARTER`, and `YEAR`. + +a|[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "EQ", + values: [""], + datePeriod: "MONTH", + type: "THIS_PERIOD" + } + }); +---- + +| `PERIOD_TO_DATE` |Specify the period. You must include the `datePeriod` attribute based on the time period specified in the filter object. Valid values for `datePeriod` are `WEEK`, `MONTH`, `QUARTER`, and `YEAR`. + +a|[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "EQ", + values: [""], + datePeriod: "QUARTER", + type: "PERIOD_TO_DATE" + } + }); +---- +|`YEAR_ONLY` |Specify the year. For example, 2023. +a|[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "EQ", + values: ["2023"], + type: "YEAR_ONLY" + } + }); +---- + +| `MONTH_YEAR` |Specify the month and year in the `values` array. For example, `"July","2023"`. +a|[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "EQ", + values: ["July","2023"], + type: "MONTH_YEAR" + } + }); +---- + +|`QUARTER_YEAR` | Specify the quarter and year in the `values` array. For example, `"Q1","2023"`. + +a|[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filter: { + column: "date", + oper: "EQ", + values: ["Q1","2023"], + type: "QUARTER_YEAR" + } + }); +---- +|===== + +== Updating runtime filters + +For information about runtime filters update, see xref:runtime-filters.adoc#_adjust_runtime_filters_using_sdk_events[Runtime filters documentation]. + +== Removing filters +To remove a specific filter, pass the empty values array, as shown in the following examples: + +*Runtime filters* +[source,JavaScript] +---- +liveboardEmbed.trigger(HostEvent.UpdateRuntimeFilters, [{ + columnName: "item type", + operator: RuntimeFilterOp.EQ, + values: [" "] // replace the values +}]); +---- + +*Liveboard filters* + +---- +liveboardEmbed.trigger(HostEvent.UpdateFilters, { + filters: [{ + column: "state", + oper: "EQ", + values: [" "] // sets empty values + }] + }); +---- -=== Liveboard filters override search query filters +Setting empty values via `HostEvent.UpdateFilters` removes only the filter values; it does not remove or hide the filter chips from the Liveboard. -When viewing a visualization on a Liveboard, any Liveboard filter on the same column as a `search_query` filter will fully override the values. +//// === Events -There is no specific event to update `search_query filters` in the `SearchEmbed` component or the Liveboard edit mode. +There is no specific event to update `search_query filters` in the `SearchEmbed` component or the Liveboard edit mode. You can set your app to listen to link:https://developers.thoughtspot.com/docs/Enumeration_EmbedEvent#_querychanged[EmbedEvent.QueryChanged] and trigger the link:https://developers.thoughtspot.com/docs/Enumeration_HostEvent#_gettml[HostEvent.GetTML] event to get a new TML generated for the `search_query` string after an update. diff --git a/modules/ROOT/pages/full-app-customize.adoc b/modules/ROOT/pages/full-app-customize.adoc index c13a13eb1..07366a97a 100644 --- a/modules/ROOT/pages/full-app-customize.adoc +++ b/modules/ROOT/pages/full-app-customize.adoc @@ -342,16 +342,26 @@ For information about the home page components and the related customization set == Customize the default loading page and navigation routes In full application embedding, the home page is set as the default landing page when the embedded app loads. You can xref:set-default-page.adoc[customize the default landing page settings] using the `pageId` or `path` attribute. -== Customize list pages -A list page in ThoughtSpot refers to a page that displays a list of objects, such as Answers, Liveboards, and Liveboard schedules. The list pages include columns for sorting, filtering, tagging, and performing bulk actions such as marking favorites, sharing, or deleting objects. +== Customize list page experience +A list page in ThoughtSpot refers to a page that displays a list of objects, such as Answers, Liveboards, and Liveboard schedules. The list pages include columns for sorting, filtering, tagging, sharing, or deleting objects. -To customize the columns in list pages such as *Liveboards* and *Answers*, use the xref:AppViewConfig.adoc#_hiddenlistcolumns[hiddenListColumns] attribute. Valid values that correspond to the column names on the list pages are: +=== List layouts +If your embed has the V3 navigation and homepage experience enabled, the ListPage v3 experience will be enabled by default. -* `ListPageColumns.Author` to show or hide the *Author* column -* `ListPageColumns.Favourite` to show or hide the *Favourite* column -* `ListPageColumns.DateSort` to show or hide the *Last modified* column -* `ListPageColumns.Tags` to show or hide the *Tags* column -* `ListPageColumns.Share` to show or hide the *Share* links in the column +The list layouts in full app embedding typically include columns such as *Name*, *Author*, *Favorites*, *Tags*, *Last Viewed* and more. For Liveboard lists, a *Verified* column is available to filter the list by verified objects. In addition to these columns, the ListPage v3 experience includes the **Views** column and the following enhancements: + +* Sorting options for **Name**, **Author**, and **Views** columns. +* Filter addition by clicking the column header without opening the filter modal. This option is available for **Favorites**, **Views** columns, and **Verified** columns. + +=== Include or exclude columns from list layouts +To customize the columns in list pages such as *Liveboards* and *Answers*, use the xref:AppViewConfig.adoc#_hiddenlistcolumns[hiddenListColumns] attribute with the following List page IDs: + +* `ListPageColumns.Author` to show or hide the *Author* column. +* `ListPageColumns.DateSort` to show or hide the *Last modified* column. +* `ListPageColumns.Favorites` to show or hide the *Favorites* column. +* `ListPageColumns.Share` to show or hide the *Share* links in the column. +* `ListPageColumns.Tags` to show or hide the *Tags* column. +* `ListPageColumns.Verified` to show or hide the *Verified* column in Liveboard lists. The following example hides specific columns using the `hiddenListColumns` array: @@ -375,7 +385,7 @@ const embed = new AppEmbed("#embed", { [NOTE] ==== -The `hiddenListColumns: [ListPageColumns.Share]` hides the *Share* column, but doesn't remove the *Share* button above the list. To hide both the column and the *Share* (xref:Action.adoc#_share[Action.Share]) button above the list, use the `hiddenActions` or `visibleActions` array. +The `hiddenListColumns: [ListPageColumns.Share]` hides the *Share* column, but doesn't remove the *Share* button that appears above the list on selecting an object. To hide both the column and the *Share* button, use xref:Action.adoc#_share[Action.Share] in the `hiddenActions` array. ==== == Additional customization controls diff --git a/modules/ROOT/pages/hosteventsv2-migration.adoc b/modules/ROOT/pages/hosteventsv2-migration.adoc new file mode 100644 index 000000000..1b19c7d0f --- /dev/null +++ b/modules/ROOT/pages/hosteventsv2-migration.adoc @@ -0,0 +1,166 @@ += Migrating from Host Event v1 to Host Events v2 framework +:toc: true +:toclevels: 2 + +:page-title: Migrating from Host Events v1 to Host Events v2 framework +:page-pageid: hostEventsV2-migration +:page-description: Using the page context feature in the Visual Embed SDK, you can now implement context-aware routing of host events in a multi-modal embedding experience + +This guide explains how developers can migrate their existing host events implementation to the new Host Events v2 framework. + +== Overview + +Host Events v2 is an enhanced, xref:events-context-aware-routing.adoc[context‑aware event framework] for ThoughtSpot Embed. It introduces stricter payload validation, standardized event structure and payload, and better routing for complex embedded UX flows, while remaining backward compatible with most existing v1 integrations. + +When you migrate your host event implementation to the Host Events v2 framework, it enables the following: + +* Enforces xref:events-context-aware-routing.adoc#_using_page_context_in_host_events[context‑aware routing], so that events are routed to the appropriate UI layer in embedded experiences with multi-layered UI contexts. ++ +The V2 framework supports the page context feature, which allows developers to explicitly set a target context for host event execution or automatically route the event to the top-most active UI layer based on the user's current context. + +* Validates event payloads more strictly; for example, types, required fields, allowed values. +* Standardizes event structures to reduce ambiguity and improve compatibility. + +[NOTE] +==== +Currently, the Host Events V2 framework is in beta and not enabled by default on ThoughtSpot Embedded instances. +==== + +=== Host Events v1 and v2 comparison +The following table lists the host event behavior in v1 and v2 framework: + +[cols="30,35,35", options="header"] +|==== +|Area|Host Events V1 behavior|Host Events V2 behavior + +|**Payload Validation**| Events with missing fields or ambiguous attributes may result in silent failures or inconsistent behaviour. +|Enforces strict payload validation. +|*Context‑aware routing*|Events may fire regardless of the current UI context. |Events are routed only from valid contexts. +|*Event schema and naming*|Non-standardized.|Event names and payloads are standardized: Enforces clear top‑level fields, such as +eventType+, +context+, +payload+ and consistent format across embed types. +||| +|==== + +== Migration steps +To get started with the migration: + +* xref:hosteventsv2-migration.adoc#_plan_your_migration_and_rollout[Plan your migration and rollout] +* xref:hosteventsv2-migration.adoc#_enable_host_events_v2[Update your code to use the v2 framework] +* xref:hosteventsv2-migration.adoc#_validate_event_execution_and_routing[Validate event execution and routing] +* xref:hosteventsv2-migration.adoc#_roll_out_the_changes[Roll out the changes to production environments] + +=== Plan your migration and rollout + +Migrating your implementation from Host Events V1 to V2 framework does not introduce breaking changes. Your existing implementation may continue to work after migration depending on the complexity of workflows and customizations in your setup. However, you may notice the following changes: + +* Stricter runtime validation errors in the browser console if payloads are malformed. +* Events may fail to process or produce errors when the active context doesn't match the event's requirements, or when no handler exists for the event in the current context. + + +Invalid configuration example:: +In a Liveboard embed, if you try to pin a visualization by sending its `vizId` while a Spotter modal is open, the event will not work. This is because the context switches to Spotter, and the **Pin** action is executed in the Spotter context, where the provided `vizId` is not available. + +No matching handler example:: +In a Liveboard embed, if you trigger an event that has no handler in the current context, for example, `HostEvent.LiveboardInfo`, while a Spotter modal or any other modal is open, the event will not be processed because the handler does not exist in that context. + +Missing context example:: +In a Liveboard embed, if you trigger `HostEvent.Pin` without parameters or context, the event will execute the intended action only if the top-most active layer is a visualization or Spotter page. If the top-most layer is the Liveboard page, the **Pin** action will fail because it requires a valid context, such as a visualization or Answer layer. Without this, the framework cannot determine what to pin, leading to an error or no action taken. + +Therefore, ThoughtSpot recommends creating an inventory of host events configured in your embed and reviewing the implementation. + +=== Update your code to use the v2 framework + +Enable Host Events v2 in a non‑production environment by setting the `useHostEventsV2` to `true` in your embed code. + +[source,] +---- +const embed = new appEmbed('#tsEmbed', { + // other embed view config + useHostEventsV2: true +}) +---- + +=== Validate event execution and routing +Validate host events execution in embedded view, in single-layer and multi-layer UI interactions. For example: + +. Open an embedded search, run queries, view answers. +. If you have configured `HostEvent.OpenFilter`, `HostEvent.Pin`, or other such events, switch between the Liveboard, Answer, and Spotter views and verify the host event execution and payload. +. Validate custom integrations such as delivering a payload to an external application or interactions triggered via custom buttons and actions, +. Note the events that do not execute. If the event triggers a payload, you may want to validate the structure of the payload to ensure that there are no changes that might affect or break your integration. + +==== Adjust your configuration +During validation, if you find the events that do not execute: + +. Try setting an explicit target context and validate the workflow. +. Check console log for validation errors. +. Update your code. +. Adjust your configuration to include required parameters and context definitions. ++ +For example, if your embed triggers `HostEvent.Pin` without specifying a visualization ID, after migrating to the V2 framework, the **Pin** action will only execute if the top-most active layer is a visualization or Spotter page. To execute the *Pin* action from the Liveboard layer, you must specify the visualization ID and set the target context to Liveboard. + ++ +[source,] +---- +import { + HostEvent, + ContextType +} from '@thoughtspot/visual-embed-sdk'; + +appEmbed.trigger( + HostEvent.Pin, { + vizId: '8fbe44a8-46ad-4b16-8d39-184b2fada490', + newVizName: 'Sales by item type', + liveboardId: '2ed8192a-1e9d-47d1-810d-52b14cb0e9fe', + }, + ContextType.Liveboard, +); +---- + +. Add error handling or logging around failed validations where needed. +. If you still see breaking changes, contact ThoughtSpot Support. + +===== Additional examples + +Some host events such as `HostEvent.OpenFilter` support multiple contexts. You can explicitly set the context to target event execution on a specific UI layer, or let the SDK apply the event to the top-most active layer if a matching handler is found: + +[source,JavaScript] +---- +import { + HostEvent, + ContextType +} from '@thoughtspot/visual-embed-sdk'; + +// Trigger the OpenFilter host event to open the filter panel for a specific column in the Liveboard context. + +appEmbed.trigger( + HostEvent.OpenFilter, + { column: { columnId: '' } }, + ContextType.Liveboard +); +---- + +If you want to set a specific `vizId` as the target object for events such as `HostEvent.Save`, ensure that the ID matches the object in specified context; otherwise, the event may not execute as expected. + +[source,JavaScript] +---- +import { + HostEvent, + ContextType +} from '@thoughtspot/visual-embed-sdk'; + +appEmbed.trigger( + HostEvent.Save, + { vizId: }, // ID of the visualization. + ContextType.Liveboard // Executes the save action in the Liveboard context. +); +---- + +=== Roll out the changes +To roll out the new changes to your production environment: + +. After testing, enable `useHostEventsV2` in production via your embed configuration. +. Copy code changes from your dev/testing environment to production instance. +. Monitor client-side logs and browser console to ensure the events are processed without any validation errors. + +== Related resources + +* For information about host events and the supported enumeration members in the SDK, see xref:events-hostEvents.adoc[Using host events] and xref:HostEvent.adoc[HostEvent]. +* For information about triggering actions in React embed components, see xref:react-components_lesson-04.adoc[Event listeners for React components]. diff --git a/modules/ROOT/pages/metadata-parameterization.adoc b/modules/ROOT/pages/metadata-parameterization.adoc index 293bbacca..603d17164 100644 --- a/modules/ROOT/pages/metadata-parameterization.adoc +++ b/modules/ROOT/pages/metadata-parameterization.adoc @@ -3,7 +3,7 @@ :toclevels: 2 :page-title: parameterize metadata objects -:page-pageid: parameterze-metdata +:page-pageid: parameterize-metadata :page-description: Use the metadata parameterization APIs to assign dynamic values via variables to connection or table properties In ThoughtSpot, metadata parameterization refers to the process of assigning variables to certain properties and fields within metadata objects such as Connections and Tables. These variables can have different values assigned for each Org context, which are applied dynamically at runtime, rather than relying on hardcoded static values. @@ -19,8 +19,8 @@ Metadata parameterization with variables allows administrators to reuse and prop You can update the properties of a Connection or Table to parameterize or remove parameterization by using one of the following options: * Use REST APIs + -To parameterize the properties of a metadata object, send an xref:metadata-parameterization.adoc#_remove_parameterization_using_rest_api[API request to the `/api/rest/2.0/metadata/parameterize` endpoint]. + -To remove parameterization, use the xref:metadata-parameterization.adoc#_remove_parameterization_using_rest_api[the `/api/rest/2.0/metadata/parameterize` API endpoint]. +To parameterize the properties of a metadata object, send an xref:metadata-parameterization.adoc#_parameterize_object_properties[API request to the `/api/rest/2.0/metadata/parameterize-fields` endpoint]. + +To remove parameterization, use the xref:metadata-parameterization.adoc#_remove_parameterization[the `/api/rest/2.0/metadata/unparameterize` API endpoint]. * Edit the TML representation of the object + You can edit the TML object directly and assign variables. + For example, to parameterize the properties of a Table, open the TML of the Table object in the edit mode and assign the variables to the properties as shown here: @@ -34,8 +34,13 @@ table: db_table: "${TABLE_VAR}" ---- -== Parameterize object properties using REST API -To parameterize properties of a metadata object, send a `POST` request to the +++/api/rest/2.0/metadata/parameterize+++ API endpoint, with the following attributes in the request body. +== Parameterize object properties +To parameterize one or more properties of a metadata object, use `/api/rest/2.0/metadata/parameterize-fields` API endpoint. + +[NOTE] +==== +The legacy endpoint `/api/rest/2.0/metadata/parameterize` is deprecated in 26.4.0.cl and later versions, and is replaced with the `/api/rest/2.0/metadata/parameterize-fields` endpoint. +==== === Request parameters In your `POST` request body, include the following parameters: @@ -46,10 +51,9 @@ In your `POST` request body, include the following parameters: |Parameter|Description |`metadata_type` __Optional__ a| __String__. Type of the metadata object. Valid values are: -* `LOGICAL_TABLE` + -Use this option for Tables -* `CONNECTION` + -Use this option for data connection objects. +* `LOGICAL_TABLE` for tables +* `CONNECTION` for connections +* `CONNECTION_CONFIG` for connection configuration objects Note that this attribute is __optional__ if a GUID is specified as `metadata_identifier` in the request. If you have specified the object name instead of the GUID, and multiple objects in your Org share that name, make sure to specify the metadata type. @@ -59,7 +63,7 @@ Note that this attribute is __optional__ if a GUID is specified as `metadata_ide * `ATTRIBUTE` for Tables * `CONNECTION_PROPERTY` for Connections -|`field_name` a|__String__. The name of the field to parameterize. +|`field_name` a|__Array of strings__. A JSON array of the name fields to parameterize. For tables, use one of the following names, depending on the property that you want to parameterize: @@ -69,6 +73,8 @@ For tables, use one of the following names, depending on the property that you w For connection objects, specify the exact name of the field or property to parameterize. For example, `accountName`, `role`, and `warehouse`. +For connection configuration objects, you can parameterize only `impersonate_user` field. + |`variable_identifier` a| __String__. ID or name of the variable. |===== @@ -77,14 +83,18 @@ For connection objects, specify the exact name of the field or property to param [source,cURL] ---- curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/metadata/parameterize' \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/metadata/parameterize-fields' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {AUTH_TOKEN}' \ --data-raw '{ "metadata_identifier": "eefd754f-7146-432d-9ad6-2c730264ecc8", "field_type": "ATTRIBUTE", - "field_name": "schemaName", + "field_names": [ + "schemaName", + "databaseName", + "tableName" + ], "variable_identifier": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "metadata_type": "LOGICAL_TABLE" }' @@ -92,8 +102,8 @@ curl -X POST \ If the API request is successful, ThoughtSpot returns a 204 response indicating that the variable has been successfully assigned to the specified object. -== Remove parameterization using REST API -To remove the variables assigned to a Connection or Table and restore static values, send a `POST` request to the +++/api/rest/2.0/metadata/unparameterize+++ API endpoint, with the following attributes in the request body. +== Remove parameterization +To remove the variables assigned to a Connection or Table and restore static values, use the `/api/rest/2.0/metadata/unparameterize` API endpoint. === Request parameters In your `POST` request body, include the following parameters: @@ -104,10 +114,9 @@ In your `POST` request body, include the following parameters: |Parameter|Description |`metadata_type` __Optional__ a| __String__. Type of the metadata object. Valid values are: -* `LOGICAL_TABLE` + -Use this option for Tables -* `CONNECTION` + -Use this option for data connection objects +* `LOGICAL_TABLE` for tables +* `CONNECTION` for connections +* `CONNECTION_CONFIG` for connection configuration objects Note that this attribute is __optional__ if a GUID is specified as `metadata_identifier` in the request. If you have specified the object name instead of the GUID, and multiple objects in your Org share that name, make sure to specify the metadata type. @@ -128,6 +137,9 @@ For Table attributes, use one of the following options: * `tableName` For connection objects, specify the name of the field or property for which you want to restore a static value. + +For connection configuration objects, you can update only the `impersonate_user` field. + |`value` a| __String__. Value to assign to the object property. This will assign a static value and remove the variable from the object property. |===== diff --git a/modules/ROOT/pages/publish-api.adoc b/modules/ROOT/pages/publish-api.adoc index 9d8f65d5d..ccfc3510f 100644 --- a/modules/ROOT/pages/publish-api.adoc +++ b/modules/ROOT/pages/publish-api.adoc @@ -6,11 +6,13 @@ :page-pageid: publish-to-orgs :page-description: Use the publish APIs to publish a master object from a primary Org to destination Orgs on a ThoughtSpot instance +To publish objects programmatically from the Primary Org to one or several target Orgs in a single API call, use the `POST /api/rest/2.0/security/metadata/publish` API endpoint. + +//// The publishing feature simplifies and automates content distribution from the Primary Org to one or several target Orgs in a multi-tenant instance. For large-scale deployments requiring the same analytics content, with the underlying Table or Connection properties that vary per Org, use xref:variables.adoc[variables] to parameterize the object properties. This ensures that the same object can be used across all target Orgs, with variable values dynamically adjusted to each Org's specific context. - -To publish objects programmatically from the Primary Org to one or several target Orgs in a single API call, use the +++/api/rest/2.0/security/metadata/publish +++ API endpoint. +//// == Before you begin @@ -20,7 +22,7 @@ To publish objects programmatically from the Primary Org to one or several targe == Publish objects The publish API allows publishing objects such as Liveboards, Answers, Tables, and Model from the Primary Org to one or several destination Orgs. The API doesn't support publishing Connections. -To publish an object to one or several Orgs, send a `POST` request to the `/api/rest/2.0/security/metadata/publish` API endpoint, with the following parameters in the request body. +To publish an object to one or several Orgs, use the `/api/rest/2.0/security/metadata/publish` API endpoint. === Request parameters In your `POST` request body, include the following parameters: @@ -29,12 +31,15 @@ In your `POST` request body, include the following parameters: [options='header'] |===== |Parameter|Description -|`metadata` a| __Array of strings__. Array of metadata objects to publish. Specify the ID and type of metadata in each array. The supported metadata object types are: +|`metadata` a| __Array of strings__. Array of metadata objects to publish. -* `LIVEBOARD` for Liveboards -* `LOGICAL_TABLES` + -For Models and Tables -* `ANSWER` for Answers +Include the following parameters for each entry in the `metadata` array: + +* `identifier`: Specify the ID and type of metadata in each array. +* `type`: Specify one of the following values: +** `LIVEBOARD` for Liveboards +** `LOGICAL_TABLES` for Models and Tables +** `ANSWER` for Answers |`org_identifiers` a|__Array of strings__. Array of Org names or IDs to which you want to publish the object. |`skip_validation` a|__Boolean__. When set to `true`, it skips validation of objects before publishing. By default, it's set to `false`. @@ -47,7 +52,7 @@ For Models and Tables curl -X POST \ --url 'https://{ThoughtSpot-Host}/api/rest/2.0/security/metadata/publish' \ -H 'Content-Type: application/json' \ - -H 'Authorization: Authorization: Bearer {AUTH_TOKEN}' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ --data-raw '{ "metadata": [ { @@ -78,7 +83,7 @@ When the object in the Primary Org is updated, the changes are automatically pro == Remove published objects -To remove published objects from the target Orgs, send a `POST` request to the +++/api/rest/2.0/security/metadata/unpublish+++ API endpoint, with the following attributes in the request body. +To remove published objects from the target Orgs, use `POST /api/rest/2.0/security/metadata/unpublish` API endpoint. === Request parameters In your `POST` request body, include the following parameters: @@ -88,12 +93,15 @@ In your `POST` request body, include the following parameters: |===== |Parameter|Description -|`metadata` a|__Array of strings__. Array of the published objects to remove from the Orgs. Specify the ID and type of metadata. The supported metadata object types are: +|`metadata` a|__Array of strings__. Array of the published objects to remove from the Orgs. + +Include the following parameters for each entry in the `metadata` array: -* `LIVEBOARD` for Liveboards + -* `LOGICAL_TABLES` + -For Models and Tables -* `ANSWER` for Answers +* `identifier`: Specify the ID and type of metadata. +* `type`: Specify one of the following values: +** `LIVEBOARD` for Liveboards +** `LOGICAL_TABLES` for Models and Tables +** `ANSWER` for Answers |`org_identifiers` a|__Array of strings__. Specify the Orgs from which you want to remove the published object. @@ -112,7 +120,7 @@ Exercise caution when using this option, because it may break the association wi curl -X POST \ --url 'https://{ThoughtSpot-Host}//api/rest/2.0/security/metadata/unpublish' \ -H 'Content-Type: application/json' \ - -H 'Authorization: Authorization: Bearer {AUTH_TOKEN}' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ --data-raw '{ "include_dependencies": true, "metadata": [ diff --git a/modules/ROOT/pages/publishing-overview.adoc b/modules/ROOT/pages/publishing-overview.adoc index 31899b3e3..2c749075e 100644 --- a/modules/ROOT/pages/publishing-overview.adoc +++ b/modules/ROOT/pages/publishing-overview.adoc @@ -4,7 +4,7 @@ :page-title: Publishing data :page-pageid: publish-data-overview -:page-description: Use the publishing feature to distrubute and propagete objects to Orgs within a ThoughtSpot instance. +:page-description: Use the publishing feature to distribute and propagate objects to Orgs within a ThoughtSpot instance. [earlyAccess eaBackground]#Early Access# @@ -12,12 +12,14 @@ The publishing feature enables administrators to efficiently manage and distribu Unlike the deployment method that relies on TML import and Git integration, publishing allows administrators to create an object in the Primary Org and publish it directly to target Orgs without generating duplicate copies. It also allows dynamic customization of the underlying Table or Connection properties using variables. -Starting with the 10.10.0.cl release, ThoughtSpot provides a set of REST APIs for administrators to create and assign variables, parameterize object properties, and publish objects from the Primary Org to other Orgs on their instances. +ThoughtSpot provides a set of REST APIs for administrators to create and assign variables, parameterize object properties, and publish objects from the Primary Org to other Orgs on their instances. +//// [IMPORTANT] ==== Publishing to Orgs is an Early Access feature and is disabled by default on ThoughtSpot instances. To enable this feature on your instance, contact ThoughtSpot Support. ==== +//// == When to use publishing feature @@ -80,20 +82,23 @@ Note the following feature limitations in the beta version: * Objects can be published only from the Primary Org to other Orgs. * In the target Orgs, published objects are available in read-only mode. The original object in the Primary Org remains editable only by the cluster administrator. * Git integration is not supported for published objects. +* Cohort publishing is not supported. +* Custom calendars with different metadata across Orgs are not supported. + +//// [NOTE] ==== ThoughtSpot is actively working on enhancements to support critical features and key user scenarios. Some of these existing limitations will be addressed in upcoming releases. ==== -//// * Cohort publishing is not supported. * Custom calendars with different metadata across Orgs are not supported. //// == Publishing workflow -The content publishing process with the new publishing method involves the following steps: +The publishing workflow using REST APIs involves the following steps: . xref:intro-thoughtspot-objects.adoc#_content_creation_workflow[Step 1: Create a master object] + This step involves building Answers and Liveboard from a Model or data object in Primary Org. Ensure that the object references Tables or Connections that can be parameterized with variables. Note that parameterizing default system tables is not supported. @@ -102,7 +107,7 @@ This step involves building Answers and Liveboard from a Model or data object in Create a variable for each Org using the `/api/rest/2.0/template/variables/create` API endpoint. For example, you can create a variable for table attributes, such as schema, database, or table name, and assign the variable to the relevant table properties using the metadata parameterization API endpoint. When you publish the object, the object properties with the variables are dynamically assigned appropriate values configured for the Org. . xref:metadata-parameterization.adoc[Step 3: Parameterize metadata objects] + -Replace the static values of object properties with variables created from the previous step. You can use the `/api/rest/2.0/metadata/parameterize` API endpoint or directly edit the TML to assign variables to the relevant properties. This step is required to enable the use of the same metadata object across different Orgs, with the actual values being supplied at runtime for each Org. +Replace the static values of object properties with variables created from the previous step. You can use the `/api/rest/2.0/metadata/parameterize-fields` API endpoint or directly edit the TML to assign variables to the relevant properties. This step is required to enable the use of the same metadata object across different Orgs, with the actual values being supplied at runtime for each Org. . xref:publish-api.adoc[Step 4: Publish the objects] + Publish the objects from the source Org (Primary Org) to target Orgs using the publish metadata API (`/api/rest/2.0/security/metadata/publish`). diff --git a/modules/ROOT/pages/rest-api-java-sdk.adoc b/modules/ROOT/pages/rest-api-java-sdk.adoc index 86a73784c..3fa7aa2e9 100644 --- a/modules/ROOT/pages/rest-api-java-sdk.adoc +++ b/modules/ROOT/pages/rest-api-java-sdk.adoc @@ -28,7 +28,7 @@ If you are using Maven, add the REST API Java SDK as a dependency to the POM.xml com.thoughtspot rest-api-sdk - 2.17.0 + 2.22.0 compile ---- @@ -42,7 +42,7 @@ If you are using Gradle, add the REST API Java SDK as a dependency to your build } dependencies { - implementation "com.thoughtspot:rest-api-sdk:2.17.0" + implementation "com.thoughtspot:rest-api-sdk:2.22.0" // Use the latest version of the SDK } ---- @@ -281,6 +281,7 @@ Note the recommendation of Java SDK: [options='header'] |==== |ThoughtSpot release version|Supported SDK version +a|ThoughtSpot Cloud: 26.4.0.cl | v2.23.0 or later a|ThoughtSpot Cloud: 26.3.0.cl | v2.22.0 or later a|ThoughtSpot Cloud: 26.2.0.cl | v2.21.0 or later a|ThoughtSpot Cloud: 10.15.0.cl | v2.20.0 or later diff --git a/modules/ROOT/pages/rest-api-sdk-libraries.adoc b/modules/ROOT/pages/rest-api-sdk-libraries.adoc index 332fa0659..306ab3862 100644 --- a/modules/ROOT/pages/rest-api-sdk-libraries.adoc +++ b/modules/ROOT/pages/rest-api-sdk-libraries.adoc @@ -10,6 +10,32 @@ ThoughtSpot provides native SDK libraries to help client applications call REST Currently, the REST API client libraries are available for xref:rest-api-sdk-typescript.adoc[TypeScript] and xref:rest-api-java-sdk.adoc[Java]. These SDKs provide language-specific client libraries to call APIs from client applications. + +== Community SDKs +You can use the following open-source, community-supported SDKs. + +[IMPORTANT] +==== +* ThoughtSpot reserves the right to publish its own SDKs to replace or improve upon these community-based SDKs based on customer feedback. +* These community SDKs may not be reviewed or updated periodically for accuracy or completeness, and are not included in ThoughtSpot product support. +* ThoughtSpot-supported SDKs may not be backward-compatible with these community-based SDKs. +==== + + +[width="100%" cols="2,4"] +[options='header'] +|==== +|SDK/ library|Purpose +|link:https://github.com/thoughtspot/thoughtspot_rest_api_python[thoughtspot_rest_api_python, window=_blank] |Python SDK for working with ThoughtSpot's REST APIs + + +**Language**: Python + + +|link:https://github.com/thoughtspot/thoughtspot_tml[thoughtspot_tml, window=_blank]| Package for working with ThoughtSpot Modeling Language (TML) files programmatically + + +**Language**: Python + +|==== + + == Additional resources For more information about REST APIs, use the following resources: @@ -17,4 +43,4 @@ For more information about REST APIs, use the following resources: * For information about supported authentication types, see xref:authentication.adoc[REST API v2 authentication]. * Browse through the +++REST API v2 Playground+++ before you start constructing your API requests. The playground offers an interactive portal with comprehensive information about the API endpoints, request and response workflows. * For information about supported API endpoints, see xref:rest-api-v2-reference.adoc[REST API v2 reference]. -* For information about new and deprecated features and enhancements, see xref:_rest_api_v2_0_changelog[REST API v2 Changelog]. +* For information about new and deprecated features and enhancements, see xref:rest-apiv2-changelog.adoc[REST API v2 Changelog]. diff --git a/modules/ROOT/pages/rest-api-sdk-typescript.adoc b/modules/ROOT/pages/rest-api-sdk-typescript.adoc index 5fa637c4f..e37f8da4b 100644 --- a/modules/ROOT/pages/rest-api-sdk-typescript.adoc +++ b/modules/ROOT/pages/rest-api-sdk-typescript.adoc @@ -203,6 +203,7 @@ Note the version recommendations for your ThoughtSpot instances: [options='header'] |==== |ThoughtSpot release version|Recommended SDK version +a|ThoughtSpot Cloud: 26.4.0.cl | v2.23.0 or later a|ThoughtSpot Cloud: 26.3.0.cl | v2.22.0 or later a|ThoughtSpot Cloud: 26.2.0.cl | v2.21.0 or later a|ThoughtSpot Cloud: 10.15.0.cl | v2.20.0 or later diff --git a/modules/ROOT/pages/rest-api-v2-reference.adoc b/modules/ROOT/pages/rest-api-v2-reference.adoc index 4297c9d02..f8153b523 100644 --- a/modules/ROOT/pages/rest-api-v2-reference.adoc +++ b/modules/ROOT/pages/rest-api-v2-reference.adoc @@ -16,7 +16,7 @@ Access to ThoughtSpot data is controlled based on xref:api-user-management.adoc# [div boxAuto] -- -[width="100%" cols="6,6,3"] +[width="100%" cols="6,6,>~"] [options='header'] |===== |API endpoint| Release version | Playground link @@ -133,11 +133,45 @@ ThoughtSpot Software: __10.7.0.sw or later__ a| +++Try it out+++ + +a|`POST /api/rest/2.0/collections/search` + +Gets a list of Collections available in ThoughtSpot. + +|ThoughtSpot Cloud: __26.4.0.cl or later__ + a| +++Try it out+++ + +a|`POST /api/rest/2.0/collections/{collection_identifier}/update` + + +Updates an existing Collection. + +|ThoughtSpot Cloud: __26.4.0.cl or later__ + a| +++Try it out +++ + +a|`POST /api/rest/2.0/collections/delete` + + +Deletes one or more Collections. + +|ThoughtSpot Cloud: __26.4.0.cl or later__ + a| +++Try it out +++ + +|===== +-- + == Connections [div boxAuto] -- -[width="100%" cols="6,4,2"] +[width="100%" cols="6,4,>~"] [options='header'] |===== |API endpoint| Release version | Playground link @@ -526,6 +560,21 @@ ThoughtSpot Software: __9.0.1.sw or later__ a| |===== -- +== Jobs + +[div boxAuto] +-- +[width="100%" cols="6,4,2"] +[options='header'] +|===== +|API endpoint| Release version | Playground link +a|`POST /api/rest/2.0/jobs/history/communication-channels/search` + +Gets information about the execution and delivery status for scheduled jobs such as webhook delivery. +|ThoughtSpot Cloud: __26.4.0.cl or later__ + a| +++Try it out+++ +|===== +-- + == Logs [div boxAuto] @@ -625,7 +674,12 @@ Gets details of metadata objects from ThoughtSpot. |ThoughtSpot Cloud: __9.0.0.cl or later__ + ThoughtSpot Software: __9.0.1.sw or later__ a| +++Try it out+++ -a| `POST /api/rest/2.0/metadata/parameterize` [beta betaBackground]^Beta^ + +a| `POST /api/rest/2.0/metadata/parameterize-fields` + +Allows you to parameterize multiple fields for a given metadata object. +a|ThoughtSpot Cloud: __26.4.0.cl or later__ a| ++++Try it out +++ + +a| `POST /api/rest/2.0/metadata/parameterize` [tag redBackground]#DEPRECATED# + Allows you to parameterize fields in metadata objects. a|ThoughtSpot Cloud: __10.9.0.cl or later__ a| +++Try it out +++ @@ -652,7 +706,6 @@ a| |===== -- - == Orgs [div boxAuto] @@ -910,6 +963,10 @@ a|`POST /api/rest/2.0/system/preferences/communication-channels/configure` + Allows configuring communication channel preferences. a|ThoughtSpot Cloud: __10.14.0.cl or later__ a| +++Try it out +++ +a|`POST /api/rest/2.0/system/communication-channels/validate` + +Validates a communication channel, for example, a webhook connection. +a|ThoughtSpot Cloud: __26.4.0.cl or later__ a| +++Try it out +++ + a|`POST /api/rest/2.0/system/preferences/communication-channels/search` + Allows searching communication channel preferences. a|ThoughtSpot Cloud: __10.14.0.cl or later__ a| +++Try it out +++ @@ -1143,7 +1200,7 @@ ThoughtSpot Software: __9.5.0.sw or later__ a| |===== |API endpoint| Release version | Playground link | `POST /api/rest/2.0/template/variables/create` + -Allows creating a template variable which can be used to parameterize fields in a metadata object. +Allows creating a template variable. a|ThoughtSpot Cloud: __10.9.0.cl or later__ a| +++Try it out +++ @@ -1164,13 +1221,24 @@ Allows updating properties of a template variable. a|ThoughtSpot Cloud: __10.9.0.cl or later__ a| +++Try it out +++ -| `POST /api/rest/2.0/template/variables/update-values` + +| `POST /api/rest/2.0/template/variables/{identifier}/update-values` + +Allows you to assign, modify, replace, or reset variable values, and define the Org and object scope for each set of variable values. + +a|ThoughtSpot Cloud: __26.4.0.cl or later__ a| ++++Try it out +++ + +| `POST /api/rest/2.0/template/variables/delete` + +Deletes one or more template variables. +a|ThoughtSpot Cloud: __26.4.0.cl or later__ a| ++++Try it out +++ + +| `POST /api/rest/2.0/template/variables/update-values` [tag redBackground]#DEPRECATED# + Allows updating properties one or several variable. a|ThoughtSpot Cloud: __10.9.0.cl or later__ a| +++Try it out +++ -| `POST /api/rest/2.0/template/variables/{identifier}/delete` + +| `POST /api/rest/2.0/template/variables/{identifier}/delete` [tag redBackground]#DEPRECATED# + Deletes a template variable. a|ThoughtSpot Cloud: __10.9.0.cl or later__ a| +++Try it out +++ diff --git a/modules/ROOT/pages/rest-apiv2-changelog.adoc b/modules/ROOT/pages/rest-apiv2-changelog.adoc index 21f45b227..77512158a 100644 --- a/modules/ROOT/pages/rest-apiv2-changelog.adoc +++ b/modules/ROOT/pages/rest-apiv2-changelog.adoc @@ -8,9 +8,77 @@ This changelog lists the features and enhancements introduced in REST API v2.0. For information about new features and enhancements available for embedded analytics, see xref:whats-new.adoc[What's New]. -== Version 26.4.0.cl +== Version 26.4.0.cl, April 2026 -For information about new REST API features and enhancements, see link:https://developers.thoughtspot.com/docs/26.4.0.cl?pageid=rest-v2-changelog[26.4.0.cl Developer Documentation, window=_blank]. +=== Variable API endpoints +The following endpoints are introduced for bulk delete and update operations for variables: + +* `POST /api/rest/2.0/template/variables/{identifier}/update-values` + +Assigns multiple values to a variable and sets the scope for variable values in a single API request. +* `POST /api/rest/2.0/template/variables/delete` + +Deletes one or more variables in a single API request. + +These new API endpoints replace the following legacy API endpoints deprecated in 26.4.0.cl. + +* `POST /api/rest/2.0/template/variables/{identifier}/delete` +* `POST /api/rest/2.0/template/variables/update-values` + +Your existing implementation with the legacy API endpoints will continue to work until further notice. However, these endpoints will be removed from ThoughtSpot in a future release. Hence, we recommend updating your workflows to use the API endpoints at your earliest convenience. + +For more information, see xref:variables.adoc[Variable API documentation]. + +=== Metadata parameterization +You can now parameterize multiple fields in a metadata object in a single API request using the `/api/rest/2.0/metadata/parameterize-fields` API endpoint. +This endpoint replaces the legacy `/api/rest/2.0/metadata/parameterize` endpoint, which is deprecated in 26.4.0.cl. + +For more information, see xref:metadata-parameterization.adoc[Metadata parameterization API documentation]. + +=== Webhook integration +This release introduces the following features and enhancements to the webhook integration workflows: + +Custom HTTP headers in webhook requests:: +Administrators can configure custom HTTP headers to send in webhook requests triggered by ThoughtSpot, in addition to the standard HTTP and authentication headers. You can specify these headers in the `additional_headers` attribute during webhook creation (`/api/rest/2.0/webhooks/create`) and update (`/api/rest/2.0/webhooks/{webhook_identifier}/update`) via REST APIs. + +Webhook connection validation:: +You can now validate a webhook connection by sending a test payload via an API request to the `/api/rest/2.0/system/communication-channels/validate` endpoint. The API returns a response indicating the connection and authentication status for a given webhook connection. + +Webhook monitoring:: +To monitor the status of webhook jobs and scheduled events, ThoughtSpot introduces the `/api/rest/2.0/jobs/history/communication-channels/search` API endpoint. + +For more information see xref:webhooks-comm-channel.adoc[Webhook configuration validation and monitoring]. + +=== Collections API endpoints + +The following APIs are introduced for Collections: + +* `POST /api/rest/2.0/collections/create` [beta betaBackground]^Beta^ + +Creates a new Collection +* `POST /api/rest/2.0/collections/search` [beta betaBackground]^Beta^ + +Search for a Collection in the existing Collections +* `POST /api/rest/2.0/collections/{collection_identifier}/update` [beta betaBackground]^Beta^ + +Updates an existing Collection +* `POST /api/rest/2.0/collections/delete` [beta betaBackground]^Beta^ + +Deletes a Collection + +For more information, see xref:collections.adoc[Collections]. + +=== Email customization API enhancements + +The `template_properties` parameter now has the `hide_logo_url` elements for email template customization. Set it to `true` to entirely hide the logo component in the ThoughtSpot notification emails. + +=== Spotter API enhancements +Spotter AI APIs now support the following error responses: + +* 401 Unauthorized: authentication token is missing, expired, or invalid. +* 403 Forbidden: the authenticated user does not have `CAN_USE_SPOTTER` privilege or view access to the underlying metadata sources. + +=== Pivot table .xlsx exports +The following API endpoints now support pivot tables in `.xlsx` downloads with full visual and structural parity: + +* `POST /api/rest/2.0/report/answer` +* `POST /api/rest/2.0/schedules/create` + +To enable pivot formatting on your ThoughtSpot instance, contact ThoughtSpot Support. == Version 26.3.0.cl, March 2026 @@ -18,7 +86,7 @@ For information about new REST API features and enhancements, see link:https://d The Webhook API allows configuring Amazon S3 buckets as a storage destination for webhook payload delivery. -* `/api/rest/2.0/webhooks/create` + +* `POST /api/rest/2.0/webhooks/create` + Configures storage destination for webhook delivery. * `POST /api/rest/2.0/webhooks/{webhook_identifier}/update` + Allows modifying storage configuration for a webhook. @@ -129,6 +197,8 @@ For more information, see xref:abac-user-parameters.adoc[ABAC via tokens]. === New API endpoints + + System:: This release introduces the following endpoints for configuring communication channel preferences. @@ -1025,6 +1095,3 @@ The ThoughtSpot Cloud 9.0.0.cl release introduces the REST API v2.0 endpoints an * xref:rest-api-v2-getstarted.adoc[Get started with REST API v2.0] * xref:rest-api-v2-reference.adoc[REST API v2.0 reference] * xref:rest-api-v1v2-comparison.adoc[REST API v1 and v2.0 comparison] - - - diff --git a/modules/ROOT/pages/spotter-apis.adoc b/modules/ROOT/pages/spotter-apis.adoc index 82dfe53fb..c13019ee4 100644 --- a/modules/ROOT/pages/spotter-apis.adoc +++ b/modules/ROOT/pages/spotter-apis.adoc @@ -391,7 +391,7 @@ curl -X POST \ "conversation_settings": { "enable_contextual_change_analysis": false, "enable_natural_language_answer_generation": true, - "enable_reasoning": false + "enable_reasoning": true } }' ---- diff --git a/modules/ROOT/pages/theme-builder.adoc b/modules/ROOT/pages/theme-builder.adoc index ea3e101a5..3f1fe53d4 100644 --- a/modules/ROOT/pages/theme-builder.adoc +++ b/modules/ROOT/pages/theme-builder.adoc @@ -1,31 +1,49 @@ -= Theme Builder += Theme builder :toc: true :toclevels: 2 -:page-title: Theme Builder +:page-title: Theme builder :page-pageid: theme-builder-doc :page-description: Understanding how to use the Theme Builder -Theme Builder provides a graphical interface to explore and preview CSS customization options for various ThoughtSpot components. You can adjust style settings and view the changes in real time before applying them to embedded ThoughtSpot components, such as Liveboard, Visualization, Search, Spotter, and full application experience. Theme Builder also allows you to import and export CSS variables with custom values in JSON format. +Theme builder provides a natural language, prompt-driven graphical interface to explore and preview CSS customization options for various ThoughtSpot components. You can adjust style settings and view changes in real time before applying them to embedded ThoughtSpot components, such as Liveboard, Visualization, Search, Spotter, and full application experience. -When Theme Builder is enabled on your ThoughtSpot instance, you can access it by navigating to *Develop* > *Customizations* > *Theme Builder*. +The Theme builder has two independent modes that integrate seamlessly.: + +* *AI mode* - AI Mode allows users to define style requirements using natural language prompts and brand assets — such as PDF guidelines or reference screenshots — to generate high-quality themes without manual CSS coding. +* *Manual mode* - Manual mode refines the AI-generated output, providing granular control through specific token, color, and icon adjustments. + +When Theme builder is enabled on your ThoughtSpot instance, you can access it by navigating to *Develop* > *Customizations* > *Theme Builder*. You can also access it from in-product help by clicking *Guides* > *Live Playgrounds* > *Theme Builder* in the ThoughtSpot UI. -//documentation site, or go to link:https://developers.thoughtspot.com/docs/theme-builder[https://developers.thoughtspot.com/docs/theme-builder, window=_blank]. + +== Before you begin +To streamline the Theme builder's workflow, it is helpful to understand how its different styling modes interact. + +* *AI mode* generates global styles and complex layouts based on natural language prompts. It will fill in any gaps not already defined by manual settings. +* *Manual mode* act as a direct override. Any setting done in the *Manual mode* takes priority over the changes done in the *AI mode*, and will not be overridden unless explicitly mentioned. +* By importing a JSON you can set up the theme with pre-defined style variables. Once an AI conversation starts, the *AI mode* will take the imported variables into account just like the *Manual mode*. The settings through the imported JSON will not be overridden unless explicitly mentioned. However, if the JSON is imported before the AI conversation starts, you may need to explicitly mention it in your prompt to ensure AI uses the JSON data. == Try out styles and load changes To try out the customization options: -. Go to *Develop* > *Customisations* > *Theme Builder*. -. Choose the desired embed component from the dropdown on the left panel. +. Go to *Develop* > *Customizations* > *Theme Builder*. +. Choose the desired embed component from the dropdown on the top navigation. + [.bordered] [.widthAuto] image::./images/tb-embed.png[Embed components menu] - -. Select the UI element or property to customize. For instance, if you want to edit the background color of the context menu, then click the dropdown for the *Context Menu*. Click on the text box for *Background* and select your desired color. +. Select *AI mode* to provide styling instructions in natural language or upload a reference file to update the theme. You can request UI changes using simple natural language instructions, such as 'Apply dark theme'. Some sample instructions and accompanying assets include: +.. Use the primary and secondary color codes defined in the attached PDF to update the global theme. +.. Update all buttons to rounded corners with a border-radius of 12px. Use white font on the primary brand color for the button text. +.. Extract the background color code from the header in the attached screenshot and apply it to the main application navigation bar. +.. Map the values in the typography and spacing objects from the attached JSON to the application's global CSS variables. + -If you want to the exact variable name of the element as in ThoughtSpot, hover over the name of the element in the left panel. +[.bordered] +[.widthAuto] +image::./images/tb-ai-mode.png[Theme buidler AI mode interface] + +. To further adjust the style settings, switch to the *Manual mode*. For instance, if you want to edit the background color of the checkboxes, then click the dropdown for the *Checkboxes*. Click on the text box for *Background Color* and select your desired color. + [.bordered] [.widthAuto] @@ -33,32 +51,49 @@ image::./images/tb-style-menu.png[Style components menu] . You will see the style customizations you just applied in real time, as the iframe refreshes automatically on each customization with your selected input. +[NOTE] +==== +* The *AI mode* and *Manual mode* operate independently, allowing you to choose the one that best fits your workflow. Using both is entirely optional. +* You can seamlessly switch between the *AI mode* and *Manual mode* until you achieve the desired style settings. +* Any changes done in the *Manual mode* will not be overwritten by the instructions in the *AI mode*, unless specified. +* To apply a style matching an image, the uploaded resource must be a standalone image file (such as a PNG or JPEG). The Theme builder cannot pick visual styles from images embedded within a PDF. It can only process the textual information in the PDF. +* Total file uploads are limited to a maximum of 10MB per chat input. +* If you navigate away from the Theme builder and return later, your style changes will be retained, but the chat history will be cleared. +==== + == Export CSS variables in JSON format To download a copy of the CSS variables in JSON: -. In the Theme Builder Playground, click *Export JSON*. + +. In the Theme builder Playground, click *Export JSON*. + . To copy the CSS variables, click *Copy JSON*. . To download the JSON to your local directory, click *Export*. You can use this exported JSON to implement the style in your embedded ThoughtSpot instance. +There is also an option to click the copy icon in the *AI mode* conversation response panel. +[.bordered] +[.widthAuto] +image::./images/copy-ai-mode.png[Copy JSON] + == Import CSS variables with custom specifications -Theme Builder also lets you iterate on existing themes that were previously created. You can use an existing style in Theme Builder, and add to it by importing the theme in JSON. To upload a set of CSS variables in JSON format: +Theme builder also lets you iterate on existing themes by importing a JSON. You can use an existing style in Theme builder, and add to it by importing the theme in JSON. +To ensure the AI uses your imported JSON data, reference it in your first prompt. For instance, a mention like 'Use the styles from the imported JSON'. + +To upload a set of CSS variables in JSON format: -. In the Theme Builder Playground, click *Import JSON* on the bottom of the left panel. +. In the Theme builder Playground, click *Import JSON* on the top navigation. + The Import JSON modal opens. + [.bordered] [.widthAuto] image::./images/json.png[Import JSON button] -. Paste the JSON with your custom specifications. Currently, the Theme Builder supports only the JSON styling variables. +. Paste the JSON with your custom specifications. The Theme builder supports only the JSON styling variables in this option, for other input based styling use the *AI mode*. . Click *Import*. + -If there are no errors, a success message appears at the bottom left and the iframe refreshes with the applied JSON. -If there are no errors, a success message appears at the bottom left, the iframe refreshes with the applied JSON, and the variable values are displayed on the left panel. +If there are no errors, a success message appears at the bottom, and the iframe refreshes with the applied JSON. == Additional resources diff --git a/modules/ROOT/pages/variables.adoc b/modules/ROOT/pages/variables.adoc index d733dd8fa..42469153d 100644 --- a/modules/ROOT/pages/variables.adoc +++ b/modules/ROOT/pages/variables.adoc @@ -41,13 +41,13 @@ The following REST API endpoints are available for variable creation and managem * `POST /api/rest/2.0/template/variables/create` + xref:variables.adoc#_create_a_variable[Creates a variable]. * `POST /api/rest/2.0/template/variables/{identifier}/update` + -Allows xref:variables.adoc#_update_properties_of_a_variable[updating the properties of a specific variable]. -* `POST /api/rest/2.0/template/variables/update-values` + -Allows xref:variables.adoc#_update_variable_values[assigning values to one or several variables]. +Allows xref:variables.adoc#_update_variable_name[updating variable name]. +* `POST /api/rest/2.0/template/variables/{identifier}/update-values` + +Allows xref:variables.adoc#_update_variable_values[assigning values to a variable]. * `POST /api/rest/2.0/template/variables/search` + xref:variables.adoc#_get_details_of_variables[Retrieves the variables available in your Org context]. -* `POST /api/rest/2.0/template/variables/{identifier}/delete` + -xref:variables.adoc#_delete_a_variable[Deletes the variable] specified in the API request. +* `POST /api/rest/2.0/template/variables/delete` + +xref:variables.adoc#_delete_a_variable[Deletes the variables] specified in the API request. [NOTE] @@ -55,6 +55,7 @@ xref:variables.adoc#_delete_a_variable[Deletes the variable] specified in the AP * Variable APIs for creating, deleting, searching, and assigning values can only be used by the ThoughtSpot instance administrator. * These APIs can only be used from the primary Org. ==== + //// [NOTE] ==== @@ -111,28 +112,8 @@ Date with time stamp. If you are creating a formula variable for specific timest + [NOTE] The `data_type` is required only for formula variables and is not supported for other variable types. - |===== -//// -|`values` __Optional__ a|__Array of strings__. Define the variable attributes. Although it's optional, make sure that you set the value for an Org before publishing content to that Org. - -The `values` array includes the following attributes: - -* `value` __String__ + -The value for the variable. For the primary Org, you can define the variable value as `Primary`. For destination Orgs, specify a separate value, for example, `Org1`. - -* `org_identifier` __String__ + -ID or name of the Org. For primary Org, specify `primaryOrg` or Org 0. - -* `principal_type` and `principal_identifier` __Optional__ + -Applicable if the variable type is set as `CONNECTION_PROPERTY_PER_PRINCIPAL`. Specify the principal type and the ID or principal to set connection properties per user or user group. -* `priority` __Optional__ + -Applicable if the variable type is set as `CONNECTION_PROPERTY_PER_PRINCIPAL`. The priority assigned to this value. If there are two matching values, the one with a higher priority will be used. -|===== - -//// - === Example request @@ -225,49 +206,18 @@ If the API request is successful, ThoughtSpot returns the variable details in th Note the variable ID and name for variable edits. The API returns an empty array for values because the values are not assigned to the variable. -* To assign values, use the `POST /api/rest/2.0/template/variables/update-values` API endpoint. +* To assign values, use the `/api/rest/2.0/template/variables/{identifier}/update-values` API endpoint. * To include formula variables in a JSON Web Token (JWT) token for xref:abac_rls-variables.adoc[ABAC implementation], use the `/api/rest/2.0/auth/token/custom` API endpoint. ++ +[NOTE] +==== +In ABAC implementation, you can assign the variable values during token generation. Before configuring variable values for JWT generation, ensure that the variables are already available in ThoughtSpot and check whether their scope and values via a xref:variables.adoc#_get_variables[variable search API request]. +==== -== Update properties of a variable - -To update the properties of a variable, send a `POST` request to the `api/rest/2.0/template/variables/{identifier}/update` API endpoint with the following parameters in the request body. In your API request, specify the variable ID in the `{identifier}` path parameter. - -=== Request parameters - -In your `POST` request body, include the following parameters: - -[width="100%" cols="1,1,4"] -[options='header'] -|===== -|Parameter|Type|Description -|`identifier` |Path |__String__. Name or ID of the variable to update. -|`name` |Form parameter|__String__. Name of the variable. -|===== +== Update variable name -//// -|`identifier` __String__| ID or name of the variable. Include the variable ID as a path parameter in the request body. -|`name` __String__ | New name for the variable. Specify a name if you want to rename the variable. -|`Operation` __String__ a| Specify the update operation type. The following options are available: +To update the properties the name of variable, use the `/api/rest/2.0/template/variables/{identifier}/update` API endpoint. In your API request, specify the variable ID in the `{identifier}` path parameter and the new name in the `POST` request body. -* `ADD` + -Adds new values. Use this operation type if you want to add new attributes to the variable. -* `REMOVE` + -Removes the values assigned to the variable specified in the API request. -* `REPLACE` + -Replaces the existing attributes with new values. -|values + -__Optional__ a|__Array of strings__. Modify the values of the variable specified in the API request. The `values` array includes the following attributes: - -* `value` __String__ + -The new value for the variable. for example, `staging1`. -* `org_identifier` __String__ + -ID or name of the Org. For primary Org, specify `primaryOrg` or Org 0. -* `principal_type` and `principal_identifier` __Optional__ + -Principal attributes such as user and user group. These attributes are applicable to the `CONNECTION_PROPERTY_PER_PRINCIPAL` variable type. -* `priority` __Optional__ + -The priority assigned to this value. Applicable to the `CONNECTION_PROPERTY_PER_PRINCIPAL` variable type. -|===== -//// === Example request The following example shows the request body for updating the name of a variable: @@ -284,52 +234,53 @@ curl -X POST \ If the update operation is successful, the API returns a 204 response to indicate that the variable was updated successfully. -== Define values and scope for variables - -To assign values to variables, use the `/api/rest/2.0/template/variables/update-values` API endpoint. +== Assign or update variable values -The API allows you to configure variable properties based on the type of variable you are trying to edit. For example, you can assign formula variables for a specific Org, Model, or user context. Similarly, for the `CONNECTION_PROPERTY_PER_PRINCIPAL` variable type, you can specify the principal type as user or user group and the ID of the principal object. +To assign values to a variable, use the `/api/rest/2.0/template/variables/{identifier}/update-values` API endpoint. For example, you can assign values for a formula variable and limit its scope to a specific Org, Model, or user context. Similarly, for the `CONNECTION_PROPERTY_PER_PRINCIPAL` variable type, you can define the principal type as user or user group, and specifiy the ID of the principal object. The API also allows you to edit, replace, or reset the values and scope assigned to a variable. [NOTE] ==== -In ABAC implementation, you can assign the variable values during token generation. Before configuring the token properties and variable values, verify the variables and their assignment status using the xref:variables.adoc#_get_variables[variable search API request]. +The `/api/rest/2.0/template/variables/{identifier}/update-values` API endpoint replaces the legacy `/api/rest/2.0/template/variables/update-values` endpoint. The legacy endpoint is deprecated in 26.4.0.cl and later. ==== === Request parameters -In your `POST` request body, you can include the following parameters: - -[width="100%" cols="1,2,5"] +[width="100%" cols="2,6"] [options='header'] |===== -|Parameter|Properties|Description -.4+|`variable_assignment` 2+| Includes parameters for setting values for a variable . This allows the same variable to have different values depending on which entity is being referenced. -|`variable_identifier` a| __Array of strings__. Specify the name or ID of the variable to which you want to assign values. -|`variable_values` a|__Array of strings__. Specify the values to assign. For example, `staging1`. -|`operation` a| Specify the update operation type. The following values are available: +|Parameter|Description +|`identifier` a| __String__. ID of the variable to assign values. This is path parameter and must be passed in the request URL. +|`operation` a| Specify the update operation type. The following values are available: * `ADD` + Adds new values. Use this operation type to assign values to the variable. -* `REPLACE` + -Replaces the existing attributes with new values. * `REMOVE` + Removes the values assigned to the variable. For example, you can remove the values assigned to a variable configured for an Org. +* `REPLACE` + +Replaces the existing attributes with new values. * `RESET` + Resets all values at the variable level. For example, if a variable is assigned to multiple entities such as Org, user, or user group, the reset operation clears the values assigned to the variable for all entities. -.5+|`variable_value_scope` 2+| Set the scope for variable values. These properties determine the entity level, such as Org, user, or user-group, for which the values will apply. -| `org_identifier` a|__String__ + -ID or name of the Org. For primary Org, specify `primaryOrg` or Org 0. Applicable to `TABLE_MAPPING`, `FORMULA_VARIABLE`, and `CONNECTION_PROPERTY` variable types. -|`principal_type` and `principal_identifier` + -__Optional__ a|__String__. Principal attributes such as user and user group. These attributes are applicable to the `CONNECTION_PROPERTY_PER_PRINCIPAL` variable type. -|`model_identifier` a| ID or name of the Model to which the variables configuration must be applied. Applicable to formula variables. -| `priority` + -__Optional__ a| -The priority assigned to this value. Applicable to the `CONNECTION_PROPERTY_PER_PRINCIPAL` variable type. + -Priority refers to the order of precedence when updating variable values for multiple entities in a single operation. If more than one entity matches the conditions during variable resolution,the system determines which entity’s value takes effect based on the value assigned to the `priority` parameter. -For example, if a variable is configured for both the user and their group, the system determines which value to based on the assigned priority. +|`variable_assignment` a|__Array of variable values__. You can assign one or several set of values, and define the scope and constraints for each set of variable values. + +Assign values:: +To assign variable values, specify the values in the `assigned_values` array. + +Define scope:: +To set the scope for these variable values, define the following properties. These properties determine the entity level, such as Org, user, or user-group, for which the values will apply. + +* `org_identifier`: __Optional__. ID or name of the Org. + +For primary Org, specify `primaryOrg` or Org 0. Applicable to `TABLE_MAPPING`, `FORMULA_VARIABLE`, and `CONNECTION_PROPERTY` variable types. + +* `principal_type` and `principal_identifier`: __Optional__. Principal attributes such as user and user group. +Applicable to the `CONNECTION_PROPERTY_PER_PRINCIPAL` variable type. + +* `model_identifier`: __Optional__. ID or name of the Model to which the variables configuration must be applied. Applicable to formula variables. + +* `priority`: __Optional__. Priority assigned to this value. If more than one entity matches the conditions during variable resolution, the system determines which entity’s value takes effect based on the value assigned to the `priority` parameter. For example, if a variable is configured for both the user and their group, the system determines which value to based on the assigned priority. + +Applicable to the `CONNECTION_PROPERTY_PER_PRINCIPAL` variable type. + || |===== @@ -342,42 +293,35 @@ The following example shows the request parameters to assign values to `TABLE_MA [source,cURL] ---- curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/template/variables/update-values' \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/template/variables/table_var/update-values' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {AUTH_TOKEN}' \ --data-raw '{ "variable_assignment": [ { - "variable_identifier": "schema_var", - "variable_values": [ - "SALES_SCHEMA_A" + "assigned_values": [ + "SALES_SCHEMA_A", ], - "operation": "ADD" + "org_identifier": "Primary" }, { - "variable_identifier": "db_var", - "variable_values": [ + "assigned_values": [ "SALES_DB_A" ], - "operation": "ADD" + "org_identifier": "Primary" }, { - "variable_identifier": "table_var", - "variable_values": [ + "assigned_values": [ "SALES_TABLE_A" ], - "operation": "ADD" + "org_identifier": "Primary" } ], - "variable_value_scope": [ - { - "org_identifier": "OrgA" - } - ] + "operation": "ADD" }' ---- -If the variable update operation is successful, you can use these variables in the Table TML or to xref:metadata-parameterization.adoc[parameterize Table properties]. +If the values are assigned successfully, the API returns 204 response code. You can use these variables in the Table TML or for xref:metadata-parameterization.adoc[parameterizing Table properties]. ==== Connection property variables The following example shows the request parameters to assign values to the `CONNECTION_PROPERTY` variables and set the variable scope to a specific Org: @@ -385,125 +329,73 @@ The following example shows the request parameters to assign values to the `CONN [source,cURL] ---- curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/template/variables/update-values' \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/template/variables/account_name_var/update-values' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {AUTH_TOKEN}' \ --data-raw '{ "variable_assignment": [ { - "variable_identifier": "account_name_var", - "variable_values": [ + "assigned_values": [ "orgA_account" ], - "operation": "ADD" + "org_identifier": "OrgA" }, { - "variable_identifier": "warehouse_var", - "variable_values": [ - "WH_A" + "assigned_values": [ + "OrgB_account" ], - "operation": "ADD" + "org_identifier": "OrgB" }, - { - "variable_identifier": "role_var", - "variable_values": [ - "analyst" - ], - "operation": "ADD" - } ], - "variable_value_scope": [ - { - "org_identifier": "OrgA" - } - ] + "operation": "ADD" }' ---- -If the variable update operation is successful, you can use these variables in the Connection TML or to xref:metadata-parameterization.adoc[parameterize connection properties]. +If the values are assigned successfully, the API returns 204 response code. You can use these variables in the Connection TML or for xref:metadata-parameterization.adoc[parameterizing connection properties]. ==== Formula variables -The following example shows the request parameters to assign values to formula variables and set their scope to a specific Org and data Model: +Formula variables assigned to Primary Org can be used across all Orgs. + +To avoid invalid data type errors, ensure that the values you assign to formula variables match the data type configured during variable creation. [source,cURL] ---- curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/template/variables/update-values' \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/template/variables/country_var/update-values' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {AUTH_TOKEN}' \ --data-raw '{ "variable_assignment": [ { - "variable_identifier": "region_var", - "variable_values": [ - "West" - ], - "operation": "ADD" - }, - { - "variable_identifier": "state_var", - "variable_values": [ - "california", - "nevada" + "assigned_values": [ + "Germany", + "Switzerland" ], - "operation": "ADD" + "org_identifier": "Primary" }, { - "variable_identifier": "category_var", - "variable_values": [ - "all" + "assigned_values": [ + "Singapore", + "Japan" ], - "operation": "ADD" - }, - { - "variable_identifier": "min_quantity_var", - "variable_values": [ - "10" - ], - "operation": "ADD" - }, - { - "variable_identifier": "start_date_var", - "variable_values": [ - "1711933200" - ], - "operation": "ADD" + "org_identifier": "OrgA" }, { - "variable_identifier": "end_date_var", - "variable_values": [ - "1743469200" + "assigned_values": [ + "Canada", + "Mexico" ], - "operation": "ADD" + "org_identifier": "OrgB" } ], - "variable_value_scope": [ - { - "org_identifier": "Org_NA", - "model_identifier": "80c969e7-3a36-48b7-923e-e2fb5c3fe88f", - "principal_type": "USER", - "principal_identifier": "tsuser" - - }, - { - "org_identifier": "Org_Sales", - "model_identifier": "cd252e5c-b552-49a8-821d-3eadaa049cca", - "principal_type": "USER", - "principal_identifier": "tsuser" - } - ] -}' + "operation": "ADD" +} ---- -To avoid invalid data type errors, ensure that the values you assign to formula variables match the data type configured during variable creation. - -Formula variables assigned to Primary Org can be used across all Orgs. +If the variable update is successful, the API returns 204 response code. you can use these variables in link:https://docs.thoughtspot.com/cloud/latest/rls-variables-reference[RLS rules, window=_blank]. -If the formula variable update is successful, you can use these variables in link:https://docs.thoughtspot.com/cloud/latest/rls-variables-reference[RLS rules, window=_blank] and xref:abac_rls-variables.adoc[ABAC via RLS with variables]. +You can also assign values and set the scope when creating a JWT for a given user. For more information, see xref:abac_rls-variables.adoc[ABAC via RLS with variables]. -=== Example response - -If the update operation is successful, the API returns a 204 response to indicate that the variable was updated successfully. == Get variables To get a list of variables or the details of a specific variable, send a `POST` request to the `+++/api/rest/2.0/template/variables/search+++` API endpoint. @@ -512,8 +404,8 @@ To search for a variable, specify the following parameters in your API request: * variable details + Details such as variable type, ID, and name pattern. For name pattern search, specify the partial name of the variable. For wildcard search, use `%`. -* variable value + -Variable parameters such as Org ID, Model ID, and ID and type of Principal object. +* value scope + +Attributes such as Org ID, Model ID, and ID and type of Principal object, which determine the scope of the variable values. * output format for response content + Specify one of the following values for output format: ** `METADATA_ONLY` (default) + @@ -536,10 +428,20 @@ curl -X POST \ -H 'Authorization: Bearer {AUTH_TOKEN}' \ --data-raw '{ "record_offset": 0, - "record_size": -1, - "output_format": "METADATA", + "record_size": 10, + "response_content": "METADATA", + "value_scope": [ + { + "org_identifier": "primary" + } + ], "variable_details": [ { + "identifier": "table_var", + "type": "TABLE_MAPPING" + }, + { + "identifier": "schema_var", "type": "TABLE_MAPPING" } ] @@ -555,14 +457,14 @@ If the request is successful, the API returns the variable data in the response: [ { "id": "f658cfd5-fa6f-4c33-a12f-ea46fa799666", - "name": "Table_var", + "name": "table_var", "variable_type": "TABLE_MAPPING", "sensitive": false, "values": null }, { "id": "7f52d7b1-38f1-4127-ad5a-a2a7f58064df", - "name": "Schema_var", + "name": "schema_var", "variable_type": "TABLE_MAPPING", "sensitive": false, "values": null @@ -572,18 +474,31 @@ If the request is successful, the API returns the variable data in the response: == Delete a variable -To delete a variable, send a `POST` request to the `/api/rest/2.0/template/variables/{identifier}/delete` API endpoint, with the variable ID in the path parameter. - -Note that you can delete only one variable at a time. +To delete one or more variables, use the `/api/rest/2.0/template/variables/delete` API endpoint. The API does not allow deleting formula variables if they are used in Models, RLS rules, user properties, or ABAC tokens. If the variable is used by an object in ThoughtSpot, make sure to remove the variable assignments and references before deleting it from ThoughtSpot. + +[NOTE] +==== +The legacy delete endpoint `/api/rest/2.0/template/variables/{identifier}/delete` is deprecated in 26.4.0.cl and later versions, and is replaced with the `/api/rest/2.0/template/variables/delete` endpoint. You can use the new endpoint to delete multiple variables in a single API request. +==== + + === Example request [source,cURL] ---- curl -X POST \ ---url 'https://{ThoughtSpot-Host}/api/rest/2.0/template/variables/180a9cd3-8605-445b-8b70-aa0bcef5dfb0/delete' \ --H 'Authorization: Bearer {AUTH_TOKEN}' + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/template/variables/delete' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "identifiers": [ + "table_var_1", + "table_var_2", + "table_var_3" + ] +} ---- If the API request is successful, ThoughtSpot returns a 204 response code. diff --git a/modules/ROOT/pages/webhooks-comm-channel.adoc b/modules/ROOT/pages/webhooks-comm-channel.adoc index 8cf21d13e..50442d032 100644 --- a/modules/ROOT/pages/webhooks-comm-channel.adoc +++ b/modules/ROOT/pages/webhooks-comm-channel.adoc @@ -1,4 +1,4 @@ -= Configure webhook communication channel += Configure, validate and monitor communication channels :toc: true :toclevels: 3 @@ -8,19 +8,14 @@ [beta betaBackground]^Beta^ -To provide flexibility and programmatic control for users who want to customize notifications and automate workflows based on Liveboard scheduling events, ThoughtSpot allows you to configure a webhook communication channel. +To provide flexibility and programmatic control for ThoughtSpot administrators and developers who want to customize notifications and automate workflows based on Liveboard scheduling events, use the webhook communication channel. -Use the following REST APIs to set and view communication channel preferences: - -* `POST /api/rest/2.0/system/preferences/communication-channels/configure` -* `POST /api/rest/2.0/system/preferences/communication-channels/search` +This document describes the steps to xref:webhooks-comm-channel.adoc#_configure_communication_channel_preferences[configure communication channel preferences], xref:webhooks-comm-channel.adoc#_validate_communication_channel_configuration[validate configuration], and xref:webhooks-comm-channel.adoc#_monitor_webhook_delivery_and_job_status[monitor the health and status of communication channels] using REST APIs. [NOTE] ==== -In the current release: - * REST APIs support webhook channel configuration for `LIVEBOARD_SCHEDULE` events only. -* You can configure only one webhook for the Liveboard schedule event per Org. +* You can configure only one webhook per Org for the Liveboard schedule event. ==== == Before you begin @@ -30,10 +25,12 @@ Check your application environment for the following prerequisites: * Ensure that you have access to a ThoughtSpot instance with the required permissions to set communication channel preferences, create and manage webhooks, and schedule Liveboard jobs. * Ensure that the REST APIs for setting communication channel preferences and configuring webhooks are enabled on your instance. If the APIs are not available on your instance, contact ThoughtSpot Support. +== Configure communication channel preferences -== Configure a webhook communication channel +To create a webhook channel, configure channel preferences, and retrieve the channel settings, use the following REST APIs: -To create a webhook communication channel for the Liveboard schedule event, use the communication channel preference REST API. +* xref:webhooks-comm-channel.adoc#_create_a_webhook_communication_channel[`POST /api/rest/2.0/system/preferences/communication-channels/configure`] + +* xref:webhooks-comm-channel.adoc#_view_the_communication_channel_preferences[`POST /api/rest/2.0/system/preferences/communication-channels/search`] === Create a webhook communication channel @@ -271,7 +268,236 @@ The following example shows the preferences returned for a specific Org: } ---- +== Validate communication channel configuration +To ensure that a communication channel configuration is properly configured and can receive events, use the `/api/rest/2.0/system/communication-channels/validate` API endpoint and validate the communication channel configuration. + +=== Request parameters + +[width="100%" cols="2,4"] +[options='header'] +|===== +|Parameter|Description + +|`channel_type` a|__String__. Type of communication channel to validate. Specify `WEBHOOK`. +|`channel_identifier`|__String__. ID or name of the communication channel. For webhook channels, specify the webhook ID. You can retrieve the webhook ID via an API request to the `POST /api/rest/2.0/webhooks/search` endpoint. +|`event_type` |__String__. Event type associated with the specified channel. For webhook channels, the supported event type is `LIVEBOARD_SCHEDULE`. +|===== + +=== Example request + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/system/communication-channels/validate' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "channel_type": "WEBHOOK", + "channel_identifier": "3791ad80-70e8-4222-bf11-fb8a5f1b5bf4", + "event_type": "LIVEBOARD_SCHEDULE" +}' +---- + +=== Example response + +If the validation is successful, the API returns a response indicating the webhook channel validation state. + +The following response shows validation status for a webhook channel: + +[source,JSON] +---- +{ + "channel_type":"WEBHOOK", + "channel_id":"9185f9be-f237-42bf-b452-c2dc897e1673", + "channel_name":"Zapier", + "event_type":"LIVEBOARD_SCHEDULE", + "job_id":"n.validation-0e55b1de-8c30-48d1-8c73-2f0365e03641", + "result_code":"SUCCESS", + "details":[ + { + "validation_step":"HTTP_CONNECTION_CHECK", + "status":"SUCCESS", + "http_status":200, + "error_message":null, + "aws_s3_info":null + } + ] +} +---- + +The following response shows the validation success and failure errors for a webhook channel with AWS s3 storage configuration: + +[source,JSON] +---- +{ + "channel_type":"WEBHOOK", + "channel_id":"52314c1c-8d1d-40d1-8dba-3f77d219b41a", + "channel_name":"nebula-webhooks-gcp-05012026-webhook1", + "event_type":"LIVEBOARD_SCHEDULE", + "job_id":"n.validation-37688eaf-6cb1-4f7e-a6f2-0658c1d678eb", + "result_code":"PARTIAL_SUCCESS", + "details":[ + { + "validation_step":"STORAGE_FILE_UPLOAD_CHECK", + "status":"FAILED", + "http_status":null, + "error_message":"failed to assume role 'arn:aws:iam::123456789012:role/ThoughtSpotDeliveryRole': operation error STS: AssumeRole, https response error StatusCode: 403, RequestID: 8ba1a7a1-65c2-4901-8d4a-bf150687e92c, api error AccessDenied: User: arn:aws:sts::418295724037:assumed-role/cell-89b3a1c7-coms-lambda-role/cell-89b3a1c7-coms-api is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::123456789012:role/ThoughtSpotDeliveryRole. Ensure the role's trust policy allows ThoughtSpot and the External ID matches", + "aws_s3_info":{ + "bucket_name":"my-webhook-files", + "file_name":"validation_dummy_20260330_131030.pdf", + "object_key":"webhooks/cluster-abc/org-1/user-123/liveboard/report.pdf" + } + }, + { + "validation_step":"HTTP_CONNECTION_CHECK", + "status":"SUCCESS", + "http_status":200, + "error_message":null, + "aws_s3_info":null + } + ] +} +---- + +== Monitor webhook delivery and job status +To monitor job status for communication channels such as webhook, use the `/api/rest/2.0/jobs/history/communication-channels/search` API endpoint. + + +=== Request parameters +In the API request, you must provide channel details such as channel type, ID, and event type, or specify the job ID. + + +[width="100%" cols="2,4"] +[options='header'] +|===== +|Parameter|Description + +|`channel_type` a|__String__. Type of communication channel to validate. Specify `WEBHOOK` for webhook channels. +|`job_ids` |__Array of strings__. One or more IDs of the job. To get the ID for a given webhook channel, check the API response from the `/api/rest/2.0/system/communication-channels/validate` endpoint. + +Required parameter if no channel identifier and event ID are specified in the API request. +|`channel_identifiers`|__String__. IDs or names of the communication channel. Required if no job ID is specified. +For webhook channels, specify the webhook ID. You can retrieve the webhook IDs from the `/api/rest/2.0/webhooks/search` API endpoint via an API request. +|`channel_status` a|__String__. Status of the channel or the job. Specify one of the following values: + +* `PENDING` + +Gets a list of all pending webhook deliveries that are currently queued but not yet attempted. +* `RETRY` + +Gets a list of webhook delivery jobs that are in the retry state. +* `SUCCESS` + +Gets a list of jobs that were delivered successfully. +* `FAILED` + +Gets a list of failed job deliveries. + + +|`events` + +__Optional__ a| Allows filtering API response by event type and ID. + +* `type` + +Event type for which the webhook delivery is triggered. Default is `LIVEBOARD_SCHEDULE`. +* `identifier` + +ID of the event. + +|`start_epoch_time_in_millis` |__Decimal__. Allows filtering API response by records that were created on or after the specified epoch milliseconds. +|===== + + +=== Example request +The following example shows the sample request with job ID. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/jobs/history/communication-channels/search' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer c2****************==' \ + --data-raw '{ + "channel_type": "WEBHOOK", + "job_ids": [ + "n.validation-0e55b1de-8c30-48d1-8c73-2f0365e03641" + ] +}' +---- + +=== Example response +If your request is successful, the API returns the job details for the specified job or channel ID. + +[source,JSON] +---- +{ + "jobs":[ + { + "id":"n.validation-0e55b1de-8c30-48d1-8c73-2f0365e03641", + "status":"SUCCESS", + "creation_time_in_millis":1774876441988, + "event":{ + "type":"LIVEBOARD_SCHEDULE", + "id":"validation-9185f9be-f237-42bf-b452-c2dc897e1673", + "name":null, + "run_id":null + }, + "recipients":null, + "detail":"", + "try_count":1 + } + ] +} +---- + +For failed jobs, the status is set to `FAILED`, and the `detail` parameter in the API response contains the error details. + +[source,JSON] +---- +{ + "jobs":[ + { + "id":"n.validation-900ea028-5254-4d38-a03c-26fb41aa632b", + "status":"FAILED", + "creation_time_in_millis":1774890524301, + "event":{ + "type":"LIVEBOARD_SCHEDULE", + "id":"validation-52314c1c-8d1d-40d1-8dba-3f77d219b41a", + "name":null, + "run_id":null + }, + "recipients":null, + "detail":"STORAGE_FILE_UPLOAD_CHECK (bucket: my-webhook-files): failed to assume role 'arn:aws:iam::123456789012:role/ThoughtSpotDeliveryRole': operation error STS: AssumeRole, https response error StatusCode: 403, RequestID: 25182019-58ca-4003-8048-6713bd7d7d4e, api error AccessDenied: User: arn:aws:sts::418295724037:assumed-role/cell-89b3a1c7-coms-lambda-role/cell-89b3a1c7-coms-api is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::123456789012:role/ThoughtSpotDeliveryRole. Ensure the role's trust policy allows ThoughtSpot and the External ID matches", + "try_count":1 + } + ] +} +---- + +//// +If the webhook channel has the S3 storage configured, the API returns the job status details for the specified webhook. + +[source,JSON] +---- +{ + "jobs":[ + { + "id":"n.validation-900ea028-5254-4d38-a03c-26fb41aa632b", + "status":"SUCCESS", + "creation_time_in_millis":1774890524301, + "event":{ + "type":"LIVEBOARD_SCHEDULE", + "id":"validation-52314c1c-8d1d-40d1-8dba-3f77d219b41a", + "name":null, + "run_id":null + }, + "recipients":null, + "detail":"", + "try_count":1 + } + ] +} +---- +//// + + == Additional resources -* Refer to the documentation on how to xref:webhooks-lb-schedule.adoc[deliver Liveboard reports to an external application using a webhook] -* Refer to the documentation on how to xref:webhooks-s3-storage.adoc[deliver content to AWS S3 storage using webhooks] +* xref:webhooks-lb-schedule.adoc[Deliver Liveboard reports to an external application]. +* xref:webhooks-s3-storage.adoc[Deliver Liveboard reports to AWS S3 storage bucket]. diff --git a/modules/ROOT/pages/webhooks-lb-schedule.adoc b/modules/ROOT/pages/webhooks-lb-schedule.adoc index 5e030c96a..9f4a1dd44 100644 --- a/modules/ROOT/pages/webhooks-lb-schedule.adoc +++ b/modules/ROOT/pages/webhooks-lb-schedule.adoc @@ -1,4 +1,4 @@ -= Deliver Liveboard reports to an external application using a webhook += Deliver Liveboard reports to an external application :toc: true :toclevels: 3 @@ -101,6 +101,20 @@ Hash algorithm used for signature verification. Shared secret used for HMAC signature generation. | `storage_destination` + __Optional__ | Configuration parameters for the S3 storage destination. For more information, see xref:webhooks-s3-storage.adoc[Deliver content to AWS S3 storage using webhooks]. +|`additional_headers` + +__Optional__ a|__Array of key-value pairs__. Allows including custom HTTP headers in every outbound webhook HTTP request that ThoughtSpot sends to the configured destination URL. When configured, ThoughtSpot sends these headers in addition to the authentication headers and standard HTTP headers such as `Content-Type`, `User-Agent`. + +You can use this parameter to pass arbitrary headers with custom metadata in key-value pairs, as required by the webhook receiver endpoint: + +[source,JSON] +---- +"additional_headers": [ + { + "key":"X-Custom-Header", + "value":"custom_value" + } +] +---- |===== ==== Example request @@ -155,7 +169,28 @@ __Integer__. Specifies the starting point (index) from which records should be r * `record_size` + __Integer__. Specifies the number of records to return in the response. Default is 50. | `sort_options` + -__Optional__| Enables sorting of the API response by a specific field in ascending or descending order. Specify the `field_name` and define the desired sort order. +__Optional__ a| Enables sorting of the API response by a specific field in ascending or descending order. + +To define a sorting criteria for the webhook records in API response, set the `field_name` to one of the following options: + +* `CREATED` + +Sorts the records by the webhook creation timestamp. +* `MODIFIED` + +Sorts the webhook object by the last modified timestamp. +* `NAME` + +Sorts the records alphabetically. + +To specify the sort order, set `order` to `ASC` for ascending order, or `DESC` for descending order. + +For example: + +[source,JSON] +---- +"sort_options": { + "field_name":"CREATED", + "order":"ASC" +} +---- |===== ==== Example request @@ -170,8 +205,6 @@ curl -X POST \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {AUTH_TOKEN}' \ --data-raw '{ - "record_offset": 0, - "record_size": 50, "org_identifier": "testOrg1", "event_type": "LIVEBOARD_SCHEDULE" }' @@ -184,40 +217,39 @@ If the API request is successful, ThoughtSpot returns the webhook configuration [source,JSON] ---- { - "webhooks": [ - { - "id": "873dd4e2-6493-490d-a649-ba9ea66b11f5", - "name": "webhook-lb-event", - "description": "Webhook for Liveboard schedule", - "org": { - "id": "2100019165", - "name": "testOrg1" - }, - "url": "https://webhook.site/view/6643eba5-9d3e-42a1-85e0-bb686ba1524d/29c02fc2-c1c6-4b20-8d62-e8d51cf8dfb3", - "url_params": null, - "events": [ - "LIVEBOARD_SCHEDULE" - ], - "authentication": null, - "signature_verification": null, - "creation_time_in_millis": 1761050197164, - "modification_time_in_millis": 1761051944507, - "created_by": { - "id": "08c6b203-ff6e-4ed8-b923-35ebbbfef27b", - "name": "UserA@UserA@example.com" - }, - "last_modified_by": { - "id": "08c6b203-ff6e-4ed8-b923-35ebbbfef27b", - "name": "UserA@UserA@example.com" + "webhooks":[ + { + "id":"27997a8a-cd33-485d-a039-b40b71d191a8", + "name":"webhook-lb-event", + "description": "Webhook for Liveboard schedule", + "org":{ + "id":"2100019165", + "name":"testOrg1" + }, + "url":"https://webhook-test-server-263n.onrender.com/", + "url_params":null, + "events":[ + "LIVEBOARD_SCHEDULE" + ], + "authentication":null, + "signature_verification":null, + "additional_headers":null, + "creation_time_in_millis":1773824614455, + "modification_time_in_millis":1773824614455, + "created_by":{ + "id":"4e6e5692-667e-487d-9672-f301ccc2ea77", + "name":"UserA@example.com" + }, + "last_modified_by":null, + "storage_destination":null } - } - ], - "pagination": { - "record_offset": 0, - "record_size": 50, - "total_count": 1, - "has_more": false - } + ], + "pagination":{ + "record_offset":0, + "record_size":50, + "total_count":1, + "has_more":false + } } ---- @@ -245,6 +277,8 @@ Events subscribed to the webhook. In the current release, ThoughtSpot supports o Authentication method and credentials that ThoughtSpot will use when sending HTTP requests to the webhook endpoint. * `signature_verification` + Signature verification parameters for the webhook endpoint to verify the authenticity of incoming requests. +* `additional_headers` + +Optional and custom HTTP headers in the webhook request triggered by ThoughtSpot. ==== Example request @@ -270,26 +304,24 @@ curl -X POST \ If the API request is successful, the API returns a 204 response code indicating a successful operation. -=== Delete a webhook +== Verify the integration -To delete a webhook, send a `POST` request to the `/api/rest/2.0/webhooks/delete` endpoint. +To verify the webhook configuration, send an API request to the `/api/rest/2.0/system/communication-channels/validate` API endpoint and check the connection status. -[NOTE] -==== -When you delete a webhook with S3 storage, the webhook endpoint is removed and any events or workflows configured to use that webhook can no longer deliver payloads. Files already stored in S3 are not deleted as part of webhook deletion; only the delivery mechanism is removed. -==== +If the validation returns errors, verify the configuration and xref:webhooks-lb-schedule.adoc#_update_the_properties_of_a_webhook[update the webhook properties]. -==== Request parameters -Specify the name or ID of the webhook to delete. +If the connection status is successful, trigger a webhook delivery to the configured destination and xref:webhooks-payload.adoc[verify the payload]. -[width="100%" cols="2,4"] -[options='header'] -|===== -|Parameter|Description -| `webhook_identifiers` |__Array of strings__. ID or name of the webhooks to delete. -|===== -==== Example request +//For testing purposes, you can use a URL from link:https://webhook.site/[Webhook.site^] as a webhook endpoint and check the payload when the Liveboard schedule event is triggered. + +== Monitor webhook delivery status +To monitor the webhook delivery and job status, use the `/api/rest/2.0/jobs/history/communication-channels/search` API endpoint. For more information, see xref:webhooks-comm-channel.adoc#_monitor_webhook_delivery_and_job_status[Monitor webhook delivery and job status]. + +== Delete a webhook +To delete a webhook, send a `POST` request with the webhook ID to the `/api/rest/2.0/webhooks/delete` API endpoint. + +=== Example request [source,cURL] ---- @@ -305,7 +337,7 @@ curl -X POST \ }' ---- -==== Example response +=== Example response If the API request is successful, the webhook is deleted, and the API returns the details of the deleted webhook in the response body. @@ -330,28 +362,21 @@ If the API request is successful, the webhook is deleted, and the API returns th ], "authentication": null, "signature_verification": null, + "additional_headers":null, "creation_time_in_millis": 1761184185887, "modification_time_in_millis": 1761184185887, "created_by": { "id": "08c6b203-ff6e-4ed8-b923-35ebbbfef27b", - "name": "UserA@UserA@example.com" + "name": "UserA@example.com" }, - "last_modified_by": null + "last_modified_by": null, + "storage_destination":null } ], "failed_webhooks": [] } ---- -== Verify the integration - -To verify the integration, trigger a webhook delivery and xref:webhooks-payload.adoc[verify the payload]. - -For testing purposes, you can use a URL from link:https://webhook.site/[Webhook.site^] as a webhook endpoint and check the payload when the Liveboard schedule event is triggered. - -=== Contents of the webhook payload -See xref:webhooks-payload.adoc[Webhook payload]. - == Additional resources * xref:webhooks-comm-channel.adoc[Configure webhook communication channel] * link:https://docs.thoughtspot.com/cloud/latest/liveboard-schedule[Scheduling Liveboard jobs^] diff --git a/modules/ROOT/pages/webhooks-s3-storage.adoc b/modules/ROOT/pages/webhooks-s3-storage.adoc index ea793770f..66be263e3 100644 --- a/modules/ROOT/pages/webhooks-s3-storage.adoc +++ b/modules/ROOT/pages/webhooks-s3-storage.adoc @@ -1,4 +1,4 @@ -= Deliver content to AWS S3 storage using webhooks += Deliver Liveboard reports to AWS S3 Storage] :toc: true :toclevels: 3 @@ -225,6 +225,21 @@ __String__. IAM role ARN. For example, `arn:aws:iam::999888777666:role/thoughtsp __String__. The External ID string in IAM role trust policies that grant access to your AWS resources. For example, `ts-webhook-x7k9m2p4q1`. This parameter is required for AWS-hosted instances and is not applicable to GCP-hosted ThoughtSpot instances. * `path_prefix` __Optional__ + __String__. S3 prefix for the folder. For example, `thoughtspot/`. + +|`additional_headers` + +__Optional__ a|__Array of key-value pairs__. Allows including custom HTTP headers in every outbound webhook HTTP request that ThoughtSpot sends to the configured destination URL. When configured, ThoughtSpot sends these headers in addition to the authentication headers and standard HTTP headers such as `Content-Type`, `User-Agent`. + +You can use this parameter to pass arbitrary headers with custom metadata in key-value pairs, as required by the webhook receiver endpoint: + +[source,JSON] +---- +"additional_headers": [ + { + "key":"X-Custom-Header", + "value":"custom_value" + } +] +---- |==== ==== API request @@ -302,7 +317,88 @@ If the API request is successful, ThoughtSpot returns the webhook configuration } ---- -=== Update the properties of a webhook +=== View webhook configuration details + +To view the webhook configuration details, send a `POST` request to the `/api/rest/2.0/webhooks/search` API endpoint. + +If the API request is sent without parameters in the request body, ThoughtSpot returns the webhooks configured for the Org context in ThoughtSpot. + +==== Example request + +The following example shows the request body to fetch webhook properties: + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/webhooks/search' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "org_identifier": "testOrg1", + "webhook_identifier": "3791ad80-70e8-4222-bf11-fb8a5f1b5bf4", + "event_type": "LIVEBOARD_SCHEDULE" +}' +---- + +==== Example response +If the webhook ID is valid, the API returns the following response: + +[source,JSON] +---- +{ + "webhooks":[ + { + "id":"3791ad80-70e8-4222-bf11-fb8a5f1b5bf4", + "name":"webhook_s3", + "description":null, + "org":{ + "id":"2100019165", + "name":"docstest" + }, + "url":"https://webhook.site/6643eba5-9d3e-42a1-85e0-bb686ba1524d", + "url_params":null, + "events":[ + "LIVEBOARD_SCHEDULE" + ], + "authentication":null, + "signature_verification":null, + "additional_headers":null, + "creation_time_in_millis":1772127694740, + "modification_time_in_millis":1772127859128, + "created_by":{ + "id":"08c6b203-ff6e-4ed8-b923-35ebbbfef27b", + "name":"shashikala.subramanya@thoughtspot.com" + }, + "last_modified_by":{ + "id":"08c6b203-ff6e-4ed8-b923-35ebbbfef27b", + "name":"shashikala.subramanya@thoughtspot.com" + }, + "storage_destination":{ + "storage_type":"AWS_S3", + "storage_config":{ + "aws_s3_config":{ + "bucket_name":"my-company-data-exports", + "region":"us-east-1", + "role_arn":"arn:aws:iam::999888777666:role/thoughtspot-s3-upload", + "external_id":"ts-webhook-x7k9m2p4q1", + "path_prefix":"thoughtspot/" + } + } + } + } + ], + "pagination":{ + "record_offset":0, + "record_size":50, + "total_count":1, + "has_more":false + } +} +---- + + +=== Update the webhook configuration properties To update the S3 storage details configured for a webhook, send a `POST` request to the `/api/rest/2.0/webhooks/{webhook_identifier}/update` API endpoint. @@ -368,8 +464,69 @@ curl -X POST \ If the API request is successful, the API returns a 204 response code indicating a successful operation. -== Verify the integration +== Validate webhook channel configuration +To validate the communication channel configuration, use the `/api/rest/2.0/system/communication-channels/validate` API endpoint. + +For this API request, you'll need the webhook channel ID. To get the webhook ID, use the `/api/rest/2.0/webhooks/search` API endpoint. + +=== Example request +The following example sends validation request for a specific webhook channel with the S3 storage configuration. + +[source,cURL] +---- +curl -X POST \ + --url 'https://{ThoughtSpot-Host}/api/rest/2.0/system/communication-channels/validate' \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer {AUTH_TOKEN}' \ + --data-raw '{ + "channel_type": "WEBHOOK", + "channel_identifier": "3791ad80-70e8-4222-bf11-fb8a5f1b5bf4", + "event_type": "LIVEBOARD_SCHEDULE" +}' +---- + +=== Example response + +If the webhook ID is valid, the API returns the validation status for the specified webhook channel. + +The following response shows the validation errors for a webhook channel that has the AWS S3 storage destination configured: +[source,JSON] +---- +{ + "channel_type":"WEBHOOK", + "channel_id":"52314c1c-8d1d-40d1-8dba-3f77d219b41a", + "channel_name":"nebula-webhooks-gcp-05012026-webhook1", + "event_type":"LIVEBOARD_SCHEDULE", + "job_id":"n.validation-37688eaf-6cb1-4f7e-a6f2-0658c1d678eb", + "result_code":"PARTIAL_SUCCESS", + "details":[ + { + "validation_step":"STORAGE_FILE_UPLOAD_CHECK", + "status":"FAILED", + "http_status":null, + "error_message":"failed to assume role 'arn:aws:iam::123456789012:role/ThoughtSpotDeliveryRole': operation error STS: AssumeRole, https response error StatusCode: 403, RequestID: 8ba1a7a1-65c2-4901-8d4a-bf150687e92c, api error AccessDenied: User: arn:aws:sts::418295724037:assumed-role/cell-89b3a1c7-coms-lambda-role/cell-89b3a1c7-coms-api is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::123456789012:role/ThoughtSpotDeliveryRole. Ensure the role's trust policy allows ThoughtSpot and the External ID matches", + "aws_s3_info":{ + "bucket_name":"my-webhook-files", + "file_name":"validation_dummy_20260330_131030.pdf", + "object_key":"webhooks/cluster-abc/org-1/user-123/liveboard/report.pdf" + } + }, + { + "validation_step":"HTTP_CONNECTION_CHECK", + "status":"SUCCESS", + "http_status":200, + "error_message":null, + "aws_s3_info":null + } + ] +} +---- + +If the API returns validation errors, check your webhook configuration and update the S3 storage properties. For more information about configuration errors, see the xref:webhooks-s3-storage.adoc#_configuration_errors[troubleshooting] section. + +== Verify the integration Webhook delivery to an S3 storage destination includes the following sequence of events: . ThoughtSpot requests temporary AWS credentials by calling `sts:AssumeRole` (AWS setup) or `sts:AssumeRoleWithWebIdentity` (GCP) with your specified Role ARN and External ID. @@ -377,15 +534,21 @@ Webhook delivery to an S3 storage destination includes the following sequence of . If the request is valid, AWS STS issues temporary credentials, valid for approximately an hour. . ThoughtSpot uses these credentials to upload files to your designated S3 bucket. -To test the integration: +Before testing the integration, validate the webhook connection using the `/api/rest/2.0/system/communication-channels/validate` API endpoint and check the connection status. + +If the validation returns errors, verify the configuration and xref:webhooks-s3-storage.adoc#_update_the_webhook_configuration_properties[update your webhook configuration]. See the xref:webhooks-s3-storage.adoc#_troubleshooting_errors[troubleshooting section] for information on resolving configuring errors. +If the connection status is successful: . Trigger a Liveboard scheduled export to the configured S3 storage destination. . In your S3 bucket: * Confirm whether the webhook payload is delivered to the correct bucket and prefix. * Verify the attachments and timestamps in the AWS event logs. . If files are not delivered to your S3 bucket, check the logs for errors. -== Troubleshooting errors +== Monitor webhook delivery status +To monitor the webhook delivery and status, use the `/api/rest/2.0/jobs/history/communication-channels/search` API endpoint. For more information, see xref:webhooks-comm-channel.adoc#_monitor_webhook_delivery_and_job_status[Monitor webhook delivery and job status]. + +== Troubleshoot errors The common causes for webhook delivery failure are: @@ -423,6 +586,12 @@ To ensure that there is no mismatch in the configuration: === Configuration compatibility If you are using encryption, lifecycle policies, or special access controls, ensure that they are compatible with your webhook configuration. +== Webhook removal + +To delete a webhook, use the `/api/rest/2.0/webhooks/delete` REST API endpoint and specify the webhook ID in the `POST` request body. + +When you delete a webhook with S3 storage, the webhook endpoint is removed and any events or workflows configured to use that webhook can no longer deliver the payloads. Files already stored in S3 are not deleted as part of webhook deletion; only the delivery mechanism is removed. + == Additional resources * See also: xref:webhooks.adoc[Webhooks] and xref:webhooks-lb-schedule.adoc[Webhooks for Liveboard schedule events]. diff --git a/modules/ROOT/pages/whats-new.adoc b/modules/ROOT/pages/whats-new.adoc index fb872bcdc..0d6c259ee 100644 --- a/modules/ROOT/pages/whats-new.adoc +++ b/modules/ROOT/pages/whats-new.adoc @@ -10,7 +10,92 @@ This page lists new features, enhancements, and deprecated functionality in Thou == Version 26.4.0.cl -ThoughtSpot Cloud 26.4.0.cl release version is now available! For information about the new features and enhancements introduced in this release, see link:https://developers.thoughtspot.com/docs/26.4.0.cl?pageid=whats-new[26.4.0.cl Developer Documentation, window=_blank]. +=== Theme builder in AI mode + +The Theme Builder now has an AI mode that enables developers to explore and preview style customizations for their embedded application’s branding using natural language instructions and uploaded brand assets. You can execute style updates such as applying colors directly from a PDF branding guide, updating all button shapes with higher contrast, matching a header to a dark background based on a screenshot, or importing typography and spacing from a JSON file. In the AI mode, Theme builder interprets your intent and applies the changes instantly. + +For more information, see xref:theme-builder.adoc[Theme builder]. + +=== Webhook integration +In this release version, the following enhancements are introduced in the webhook configuration and delivery status monitoring workflows: + +Channel validation:: +Administrators can verify the connection status of a webhook channel by sending a test payload in a `POST` request to the `/api/rest/2.0/system/communication-channels/validate` REST API endpoint. For more information, see xref:webhooks-comm-channel.adoc#_validate_communication_channel_configuration[Webhook channel validation]. + +Monitor webhook delivery:: +Administrators can also monitor the status of a webhook delivery via a `POST /api/rest/2.0/jobs/history/communication-channels/search` API request. For more information, see xref:webhooks-comm-channel.adoc#_monitor_webhook_delivery_and_job_status[Monitor webhook delivery and job status]. + +Support for custom HTTP headers in webhook requests:: +When configuring or updating a webhook, you can now specify custom headers to include in every outbound request, in addition to the standard HTTP and authentication headers that ThoughtSpot sends. For more information, refer to the xref:webhooks-lb-schedule.adoc#_create_a_webhook[webhook documentation]. + +=== Spotter embed enhancements +You can now customize the appearance and contents of the chat history sidebar panel in Spotter embedding. + +You can also customize the branding and logo in the Spotter chat interface. + +For more information, see xref:embed-spotter.adoc#_chat_history_panel[Customizing chat history sidebar] and xref:embed-spotter.adoc#_hiding_the_spotter_icon_and_thoughtspot_branding_chat_interface[Hiding logo and brand label in Spotter chat interface]. + +=== Liveboard enhancements +The following enhancements are introduced in Liveboard export and filtering workflows. + +Embedding a personalized Liveboard view:: +You can now embed a saved personalized Liveboard view using the `personalizedViewId` and load it along with the `liveboardId` in your app. + +Centralized filter modal:: +Liveboard users can modify multiple filters and parameters in a single session using the centralized filter modal. This is an early access feature and disabled by default on ThoughtSpot embedded instances. To enable this feature on embedded Liveboards, set the `isCentralizedLiveboardFilterUXEnabled` to `true`. + +Current period inclusion in rolling date filters:: +The rolling date filters with the **Last ** and **Next ** filter types support including current period. Developers can disable, show, or hide this option using `isThisPeriodInDateFiltersEnabled` or `Action.IncludeCurrentPeriod`. + +Liveboard PNG export:: +The PNG export workflow in the `/api/rest/2.0/report/liveboard` REST API is enhanced to provide high-resolution PNG files. The legacy PNG workflow is deprecated in 26.4.0.cl. For more information about breaking changes and deprecation guidelines, see xref:deprecated-features.adoc[Deprecation announcements]. For information about the new PNG download workflow, see xref:data-report-v2-api.adoc#_liveboard_report_api[Liveboard report API documentation]. + +=== Full app embedding +In full application embedded deployments with the V3 navigation and home page experience, the default list page experience is set to ListPage v3 experience. + +The ListPage V3 experience provides a refreshed list layout and styling, including the following enhancements: + +* The **Views** column to show the number of views for each object. +* Sorting options for **Name**, **Author**, and **Views** columns. +* Filter addition by clicking the column header without opening the filter modal. This option is available for **Favorites**, **Views** columns, and **Verified** columns. + +For more information, see xref:full-app-customize.adoc#_customize_list_page_experience[List page customization]. + +=== Variable API enhancements +The variable REST API provides new API endpoints for the following bulk operations: + +* Bulk deletion: +You can now delete multiple variables in a single API request using the `/api/rest/2.0/template/variables/delete` endpoint. +* Batch update of variable values: +You can now assign and update multiple values to a variable in a single API request using the `/api/rest/2.0/template/variables/{identifier}/update-values` endpoint. + +[NOTE] +==== +The `/api/rest/2.0/template/variables/update-values` and `/api/rest/2.0/template/variables/{identifier}/delete` endpoints are now deprecated. Use the new `/api/rest/2.0/template/variables/{identifier}/update-values` and `/api/rest/2.0/template/variables/delete` endpoints for the variable update and delete operations instead. +==== + +For more information, see xref:variables.adoc[Variables documentation]. + +=== Metadata parameterization +You can now parameterize multiple properties of metadata objects using `POST /api/rest/2.0/metadata/parameterize-fields`. The legacy endpoint `/api/rest/2.0/metadata/parameterize` is deprecated in 26.4.0.cl and later versions, and is replaced with the new endpoint to allow updating multiple fields in a single API request. + +For more information, see xref:metadata-parameterization.adoc[Metadata parameterization documentation]. + +=== Collections [beta betaBackground]^Beta^ +ThoughtSpot embedded users can now use REST APIs v2 to organize different ThoughtSpot objects into organizational containers called *Collections*. These objects can be Liveboards, Answers, data models, tables, and even other Collections. + +For more information, see xref:collections.adoc[Collections]. + +[NOTE] +==== +These APIs are currently in beta and turned off by default on ThoughtSpot instances. To enable this feature on your instance, contact ThoughtSpot Support. +==== + +=== Visual Embed SDK +For information about the new features and enhancements introduced in Visual Embed SDK version 1.46.0, see the xref:api-changelog.adoc[Visual Embed changelog]. + +=== REST API v2 +For information about REST API v2 enhancements, see the xref:rest-apiv2-changelog.adoc[REST API v2.0 changelog]. == Version 26.3.0.cl diff --git a/src/configs/doc-configs.js b/src/configs/doc-configs.js index fd19eddc3..d0db4df1d 100644 --- a/src/configs/doc-configs.js +++ b/src/configs/doc-configs.js @@ -47,17 +47,17 @@ module.exports = { DEV: 'dev', }, VERSION_DROPDOWN: [ - { - label: '26.3.0.cl', - link: ' ', - subLabel: 'Cloud (Latest)', - iframeUrl: 'https://developer-docs-26-3-0-cl.vercel.app/docs/', - }, { label: '26.4.0.cl', link: '26.4.0.cl', - subLabel: 'Coming soon', + subLabel: 'Cloud (Latest)', iframeUrl: 'https://developer-docs-26-4-0-cl.vercel.app/docs/', + }, + { + label: '26.3.0.cl', + link: '26.3.0.cl', + subLabel: 'Cloud', + iframeUrl: 'https://developer-docs-26-3-0-cl.vercel.app/docs/', }, { label: '26.2.0.cl', @@ -65,19 +65,12 @@ module.exports = { subLabel: 'Cloud', iframeUrl: 'https://developer-docs-26-2-0-cl.vercel.app/docs/', }, - { label: '10.15.0.cl', link: '10.15.0.cl', subLabel: 'Cloud', iframeUrl: 'https://developer-docs-10-15-0-cl.vercel.app/docs/', }, - { - label: '10.14.0.cl', - link: '10.14.0.cl', - subLabel: 'Cloud', - iframeUrl: 'https://developer-docs-10-14-0-cl.vercel.app/docs/', - }, { label: '10.10.0.sw', link: '10.10.0.sw', diff --git a/static/doc-images/images/copy-ai-mode.png b/static/doc-images/images/copy-ai-mode.png new file mode 100644 index 000000000..50619c1ba Binary files /dev/null and b/static/doc-images/images/copy-ai-mode.png differ diff --git a/static/doc-images/images/tb-ai-mode.png b/static/doc-images/images/tb-ai-mode.png new file mode 100644 index 000000000..b2e09a15e Binary files /dev/null and b/static/doc-images/images/tb-ai-mode.png differ diff --git a/static/doc-images/images/tb-embed.png b/static/doc-images/images/tb-embed.png index 00791b88d..daf202043 100644 Binary files a/static/doc-images/images/tb-embed.png and b/static/doc-images/images/tb-embed.png differ diff --git a/static/doc-images/images/tb-style-menu.png b/static/doc-images/images/tb-style-menu.png index 26097bc09..a3c6f4e25 100644 Binary files a/static/doc-images/images/tb-style-menu.png and b/static/doc-images/images/tb-style-menu.png differ