From d955a83cafda994e448f89be69e4ab77a3edba0e Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Thu, 9 Apr 2026 10:23:49 +0530 Subject: [PATCH 001/109] minor edits and typo fixes --- modules/ROOT/pages/locale-setting.adoc | 16 ++++++++++++---- modules/ROOT/pages/rest-apiv2-changelog.adoc | 2 +- modules/ROOT/pages/whats-new.adoc | 1 + 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/modules/ROOT/pages/locale-setting.adoc b/modules/ROOT/pages/locale-setting.adoc index 1c43f2a14..fb770a360 100644 --- a/modules/ROOT/pages/locale-setting.adoc +++ b/modules/ROOT/pages/locale-setting.adoc @@ -101,11 +101,19 @@ ThoughtSpot application users can set their locale preference on the Profile set For more information, see link:https://docs.thoughtspot.com/cloud/latest/locale[ThoughtSpot Product Documentation, window=_blank]. == Set locale via REST API -The following REST API v1 and v2 endpoints allow updating locale preference for ThoughtSpot users: +To configure locale settings for a user via REST API, ThoughtSpot administrator can use the `"use_browser_language": true` or `"preferred_locale": "en-US"` settings when creating, importing, or updating user using the following API endpoints: -* +++POST /api/rest/2.0/users/{user_identifier}/update +++ -* +++ POST /api/rest/2.0/users/create+++ -* xref:user-api.adoc#updatepreference-api[POST /tspublic/v1/user/updatepreference] +* +++ POST /api/rest/2.0/users/create+++ (user creation) +* +++POST /api/rest/2.0/users/{user_identifier}/update +++ (User update) +* +++ POST /api/rest/2.0/users/import+++ (User import) + +The `preferred_locale` parameter allows assigning a specific locale to the user, whereas the `use_browser_language` parameter determines whether the user's language preference should be set based on their browser's language settings. When both parameters are defined, the user's current locale preference is overridden and the browser's language takes precedence. + +To get details of the browser language settings for a given user, administrators can use the following API endpoints: + +* `POST /api/rest/2.0/users/search` + +* `POST /api/rest/2.0/users/activate` + +* `GET /api/rest/2.0/auth/session/user` + == Limitations diff --git a/modules/ROOT/pages/rest-apiv2-changelog.adoc b/modules/ROOT/pages/rest-apiv2-changelog.adoc index 7964b244c..77512158a 100644 --- a/modules/ROOT/pages/rest-apiv2-changelog.adoc +++ b/modules/ROOT/pages/rest-apiv2-changelog.adoc @@ -254,7 +254,7 @@ To update the properties of a specific variable, use the `/api/rest/2.0/template ==== Variables search API * The variables search API endpoint `/api/rest/2.0/template/variables/search` now includes the `value_scope` parameter that allows you to filter the API response by the objects to which the variable is mapped. -* Filtering API response by `EDITABLE_METADATA_AND_VALUES` output format is no longer supported. +* Filtering API response by `EDITABLE_METADATA_AND_VALUES` is no longer supported. === User API enhancements diff --git a/modules/ROOT/pages/whats-new.adoc b/modules/ROOT/pages/whats-new.adoc index 6e0d462a5..b2656886e 100644 --- a/modules/ROOT/pages/whats-new.adoc +++ b/modules/ROOT/pages/whats-new.adoc @@ -289,6 +289,7 @@ For more information, see xref:code-based-custom-actions.adoc[Code based custom You can now configure a xref:webhooks-lb-schedule.adoc[webhook for Liveboard schedule events] to automate notifications to external applications. This feature allows you to send Liveboard reports directly to a webhook endpoint and create your own custom emails or workflow. This feature is currently in beta and is not enabled by default. To enable it on your instance, contact ThoughtSpot Support. +==== === Template variables for publishing The variable APIs include several enhancements to streamline variable creation and update workflows. From 9608f8b8a5dd969eeda63a50f275a732839af6de Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Wed, 8 Apr 2026 11:55:48 +0530 Subject: [PATCH 002/109] Sidharth's feedback --- modules/ROOT/pages/collections.adoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/collections.adoc b/modules/ROOT/pages/collections.adoc index 0b19b1e08..d1638447d 100644 --- a/modules/ROOT/pages/collections.adoc +++ b/modules/ROOT/pages/collections.adoc @@ -33,7 +33,7 @@ In your `POST` request body, include the following parameters: |`name` a|__String__. Required. Specify a name for the Collection. |`description` a|__String__. Optional. A short description for the Collection. -|`metadata` a|__Array__. Required. The details for the metadata objects to be added to 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: @@ -85,6 +85,8 @@ If the API request is successful, a Collection with the given metadata objects w == 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: From bdbc415646a83bb15c48954e9cec14b91658dcd2 Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Thu, 9 Apr 2026 11:52:57 +0530 Subject: [PATCH 003/109] variable note update --- modules/ROOT/pages/variables.adoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/ROOT/pages/variables.adoc b/modules/ROOT/pages/variables.adoc index 544bb4506..e6c64eff5 100644 --- a/modules/ROOT/pages/variables.adoc +++ b/modules/ROOT/pages/variables.adoc @@ -50,6 +50,11 @@ xref:variables.adoc#_get_details_of_variables[Retrieves the variables available xref:variables.adoc#_delete_a_variable[Deletes the variables] specified in the API request. +[NOTE] +==== +* Variable APIs for creating, deleting, searching, and assigning values can only be used by the ThoughtSpot instance administrator or users with the **Can manage variables** role privilege. +* These APIs can only be used from the primary Org. +==== //// [NOTE] ==== From 8120daf8ae84e1facf30c4ba73bfc0bed4ffd501 Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Thu, 9 Apr 2026 12:00:39 +0530 Subject: [PATCH 004/109] variable api note and rbac page update --- modules/ROOT/pages/roles.adoc | 2 +- modules/ROOT/pages/variables.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/roles.adoc b/modules/ROOT/pages/roles.adoc index a4e0afd38..7ae0fc708 100644 --- a/modules/ROOT/pages/roles.adoc +++ b/modules/ROOT/pages/roles.adoc @@ -170,7 +170,7 @@ UI: *Can create/edit Connections*| Allows creating, editing, and managing link:h |Data objects|API: `CAN_MANAGE_WORKSHEET_VIEWS_TABLES` + UI: *Can manage data models* |Allows users to create, edit, delete, and manage Models, Tables, and Views. |Custom variables| API: `CAN_MANAGE_VARIABLES` + -UI: *Can manage variables* | Allows users to xref:variables.adoc[create and manage custom variables]. +UI: *Can manage variables* | Allows users to manage formula Variables in the current Org scope. |=== diff --git a/modules/ROOT/pages/variables.adoc b/modules/ROOT/pages/variables.adoc index e6c64eff5..41649e7c3 100644 --- a/modules/ROOT/pages/variables.adoc +++ b/modules/ROOT/pages/variables.adoc @@ -52,7 +52,7 @@ xref:variables.adoc#_delete_a_variable[Deletes the variables] specified in the A [NOTE] ==== -* Variable APIs for creating, deleting, searching, and assigning values can only be used by the ThoughtSpot instance administrator or users with the **Can manage variables** role privilege. +* 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. ==== //// From 2ba2121898d891146318bdc9054293c6f6a08d96 Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Sun, 12 Apr 2026 23:52:02 +0530 Subject: [PATCH 005/109] SCAL-302349 updates --- .../ROOT/pages/rest-api-sdk-libraries.adoc | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) 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]. From 381dbaa73b3e74984f4c9354c9380dc75945de66 Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Sun, 12 Apr 2026 23:52:37 +0530 Subject: [PATCH 006/109] SCAL-305744 updates --- modules/ROOT/pages/embed-spotter.adoc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/embed-spotter.adoc b/modules/ROOT/pages/embed-spotter.adoc index 60b161e99..73affc7c6 100644 --- a/modules/ROOT/pages/embed-spotter.adoc +++ b/modules/ROOT/pages/embed-spotter.adoc @@ -14,7 +14,15 @@ 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 ensure the authentication token expiry is set to at least 10 minutes to avoid authorization errors. +==== + == Import the SDK package Import the `SpotterEmbed` SDK library to your application environment: From 18de1291c00a20254faf68570199f06c0ece171d Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Sun, 12 Apr 2026 23:52:59 +0530 Subject: [PATCH 007/109] filters article update --- modules/ROOT/pages/embed-pinboard.adoc | 206 ++--------- modules/ROOT/pages/filters_overview.adoc | 413 ++++++++++++++++++++--- modules/ROOT/pages/whats-new.adoc | 2 +- 3 files changed, 388 insertions(+), 233 deletions(-) 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/filters_overview.adoc b/modules/ROOT/pages/filters_overview.adoc index 1be5a5c36..30345b54f 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 at the query generation layer 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 the parameter 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 required. 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 as part of 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 include a 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. + +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 Modeland 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] ---- @@ -102,7 +214,7 @@ liveboardEmbed.trigger(HostEvent.UpdateFilters, { }); ---- -The Liveboard filter exists already on the Liveboard for the `HostEvent.UpdateFilters` to work. +The Liveboard filter must already exist on the Liveboard for `HostEvent.UpdateFilters` to work. For more information and examples, see xref:embed-pinboard.adoc#_filters[Liveboard filters]. @@ -127,14 +239,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 +253,224 @@ 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| + +[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 + }] + }); +---- -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. +Setting empty values via `HostEvent.UpdateFilters` removes only the values applied to the filter and it doesn't remove or hide the filter chip from the Liveboard. -=== Liveboard filters override search query filters -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/whats-new.adoc b/modules/ROOT/pages/whats-new.adoc index b2656886e..0d6c259ee 100644 --- a/modules/ROOT/pages/whats-new.adoc +++ b/modules/ROOT/pages/whats-new.adoc @@ -45,7 +45,7 @@ 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 in embedded Liveboards support including current period in **Last ** and **Next **. Developers can disable, show, or hide this option using `isThisPeriodInDateFiltersEnabled` or `Action.IncludeCurrentPeriod`. +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]. From 64f541c16337efd8fcd2260a3e4959fe8c748e55 Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Mon, 13 Apr 2026 08:00:09 +0530 Subject: [PATCH 008/109] edits --- modules/ROOT/pages/embed-spotter.adoc | 5 ++--- modules/ROOT/pages/filters_overview.adoc | 28 ++++++++++-------------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/modules/ROOT/pages/embed-spotter.adoc b/modules/ROOT/pages/embed-spotter.adoc index 73affc7c6..ac233a553 100644 --- a/modules/ROOT/pages/embed-spotter.adoc +++ b/modules/ROOT/pages/embed-spotter.adoc @@ -18,9 +18,8 @@ To embed Spotter, you need the following access and setup: [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 ensure the authentication token expiry is set to at least 10 minutes to avoid authorization errors. +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. ==== diff --git a/modules/ROOT/pages/filters_overview.adoc b/modules/ROOT/pages/filters_overview.adoc index 30345b54f..43c8cbcc3 100644 --- a/modules/ROOT/pages/filters_overview.adoc +++ b/modules/ROOT/pages/filters_overview.adoc @@ -13,14 +13,14 @@ The behavior of each filter type and the mechanism for setting filters can diffe 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 at the query generation layer to all objects derived from that table. Rules can be defined based on the logged-in user, their group memberships, or custom variables. + +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 the parameter value. +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. @@ -32,22 +32,22 @@ 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 required. If you are embedding a Liveboard that includes preset filters, you can programmatically update, reset, or remove filters using the `HostEvent.UpdateFilters`. +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. +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 as part of the search query for a given Answer or visualization on a Liveboard. + +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 include a 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. +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: @@ -200,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] ---- @@ -214,22 +214,17 @@ liveboardEmbed.trigger(HostEvent.UpdateFilters, { }); ---- -The Liveboard filter must already exist on the Liveboard for `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. @@ -465,8 +460,7 @@ liveboardEmbed.trigger(HostEvent.UpdateFilters, { }); ---- -Setting empty values via `HostEvent.UpdateFilters` removes only the values applied to the filter and it doesn't remove or hide the filter chip from the Liveboard. - +Setting empty values via `HostEvent.UpdateFilters` removes only the filter values; it does not remove or hide the filter chips from the Liveboard. //// From 40ecc2bb5e685ca0df2beef3a1554871bd808850 Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Mon, 13 Apr 2026 08:07:53 +0530 Subject: [PATCH 009/109] edits --- modules/ROOT/pages/embed-spotter.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/ROOT/pages/embed-spotter.adoc b/modules/ROOT/pages/embed-spotter.adoc index ac233a553..0ab813019 100644 --- a/modules/ROOT/pages/embed-spotter.adoc +++ b/modules/ROOT/pages/embed-spotter.adoc @@ -22,7 +22,6 @@ For Spotter embedding that uses cookieless authentication, use the Visual Embed 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: From 6fc31163082a082ae8e185b70ec59cbf6f07f635 Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Mon, 13 Apr 2026 08:34:20 +0530 Subject: [PATCH 010/109] Spotter note --- modules/ROOT/pages/embed-spotter.adoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/embed-spotter.adoc b/modules/ROOT/pages/embed-spotter.adoc index 0ab813019..506a04e32 100644 --- a/modules/ROOT/pages/embed-spotter.adoc +++ b/modules/ROOT/pages/embed-spotter.adoc @@ -18,8 +18,9 @@ To embed Spotter, you need the following access and setup: [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. +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 we recommend setting the authentication token expiry to at least 10 minutes to avoid authorization errors. ==== == Import the SDK package From c783080a407ce846fd376ba1425d6dfc9c9106a2 Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Mon, 13 Apr 2026 08:48:20 +0530 Subject: [PATCH 011/109] heading update --- modules/ROOT/pages/embed-pinboard.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/embed-pinboard.adoc b/modules/ROOT/pages/embed-pinboard.adoc index bcfa4315a..eaae64319 100644 --- a/modules/ROOT/pages/embed-pinboard.adoc +++ b/modules/ROOT/pages/embed-pinboard.adoc @@ -218,7 +218,7 @@ You can also pin a visualization to a Liveboard tab using the **Pin** action on 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. -=== Customizing filter visibility +==== 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. From 84c93b6e73f2f81215608ffefaa584c734131c90 Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Mon, 13 Apr 2026 10:07:23 +0530 Subject: [PATCH 012/109] example fix --- modules/ROOT/pages/filters_overview.adoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/filters_overview.adoc b/modules/ROOT/pages/filters_overview.adoc index 43c8cbcc3..767b36fee 100644 --- a/modules/ROOT/pages/filters_overview.adoc +++ b/modules/ROOT/pages/filters_overview.adoc @@ -444,18 +444,19 @@ To remove a specific filter, pass the empty values array, as shown in the follow liveboardEmbed.trigger(HostEvent.UpdateRuntimeFilters, [{ columnName: "item type", operator: RuntimeFilterOp.EQ, - values: [" "] // replace the values + values: [] // set an empty array to clear runtime filters }]); ---- *Liveboard filters* +[source,JavaScript] ---- liveboardEmbed.trigger(HostEvent.UpdateFilters, { filters: [{ column: "state", oper: "EQ", - values: [" "] // sets empty values + values: [] // set an empty array to clear filters }] }); ---- From 49fa7f9ebe4579ea7ddee99fe80ecd86b98fec76 Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Mon, 13 Apr 2026 15:27:42 +0530 Subject: [PATCH 013/109] SCAL-302948 update --- modules/ROOT/pages/deprecated-features.adoc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/modules/ROOT/pages/deprecated-features.adoc b/modules/ROOT/pages/deprecated-features.adoc index 6054d8f76..64ed61f97 100644 --- a/modules/ROOT/pages/deprecated-features.adoc +++ b/modules/ROOT/pages/deprecated-features.adoc @@ -14,6 +14,8 @@ As ThoughtSpot applications evolve, some existing features will be deprecated an [options='header'] |===== |Feature|Impacted interface and release versions|Deprecation date |End of Support / removal from the product +a|xref:deprecated-features.adoc#hostEventv1[HostEvent v1 framework] +|ThoughtSpot Cloud 26.10.0.cl and later | October 2026 | March 2027 a|xref:deprecated-features.adoc#v1-v2-exp-fullApp-embed[V1 and V2 UI experience in full application embedding]|ThoughtSpot Cloud 26.8.0.cl and later | February 2026 | August 2026 a|xref:deprecated-features.adoc#PNGFlowDeprecation[Select PNG export options] a|ThoughtSpot Cloud 26.4.0.cl and later | April 2026 | August 2026 a|xref:deprecated-features.adoc#variableApis[Variable APIs] a|ThoughtSpot Cloud 26.4.0.cl and later | April 2026 | October 2026 @@ -85,6 +87,18 @@ a|xref:deprecated-features.adoc#_deprecated_parameter_in_rest_api_v2_0_authentic |||| |===== +[#hostEventv1] +== HostEvent v1 framework in Visual Embed SDK +Starting with ThoughtSpot 26.10.0.cl, the default Host Events behavior in the ThoughtSpot embedded application will be replaced with the HostEvent v2 framework. Embedding applications using the legacy HostEvent v1 framework will be automatically migrated to the HostEvent v2 framework, and the HostEvent v1 framework will be deprecated. + +Impact on your instance:: +Embedding applications with integrations and workflows that use HostEvent objects to trigger actions will benefit from enhanced event handling, routing behavior, and payload validation. If your embedded interface includes multi-layered interactions, event routing will be context-aware and deterministic. + +Recommended actions:: +If your embed uses the HostEvent v1 framework, ThoughtSpot recommends migrating to the HostEvent v2 framework in your development environments and evaluating the behavioral changes and impact on custom workflows and integrations. + +For migration guidelines, refer to the xref:hosteventsv2-migration.adoc[HostEvent v2 migration guide]. + +For information about using the HostEvents v2 framework in your embed, see xref:events-context-aware-routing.adoc[Context-based execution of host events]. + [#v1-v2-exp-fullApp-embed] == V1 and V2 navigation and home page experience in full app embed Starting with ThoughtSpot 26.8.0.cl, the V3 navigation and home page experience will be set as the default UI experience in full application embedding. The V1 and V2 navigation and home page experience will be deprecated and will no longer be supported. From e3b3e7082bdd22901a71125e3b99cb1b685cade0 Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Tue, 14 Apr 2026 16:36:53 +0530 Subject: [PATCH 014/109] rest api ref changes --- modules/ROOT/pages/collections.adoc | 6 +- modules/ROOT/pages/rest-api-v2-reference.adoc | 80 +++++++++++-------- 2 files changed, 53 insertions(+), 33 deletions(-) diff --git a/modules/ROOT/pages/collections.adoc b/modules/ROOT/pages/collections.adoc index d1638447d..c352c495b 100644 --- a/modules/ROOT/pages/collections.adoc +++ b/modules/ROOT/pages/collections.adoc @@ -1,4 +1,4 @@ -= Collections [beta betaBackground]^Beta^ += Collections :toc: true :toclevels: 1 :page-title: Collections @@ -9,10 +9,14 @@ 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 diff --git a/modules/ROOT/pages/rest-api-v2-reference.adoc b/modules/ROOT/pages/rest-api-v2-reference.adoc index f8153b523..d1f20daab 100644 --- a/modules/ROOT/pages/rest-api-v2-reference.adoc +++ b/modules/ROOT/pages/rest-api-v2-reference.adoc @@ -133,10 +133,10 @@ ThoughtSpot Software: __10.7.0.sw or later__ a| +++Try it out+++ - a|`POST /api/rest/2.0/connection/create` Creates a connection to the data warehouse specified in the API request. @@ -189,22 +182,6 @@ Creates a connection to the data warehouse specified in the API request. |ThoughtSpot Cloud: __9.2.0.cl or later__ + ThoughtSpot Software: __9.5.0.sw or later__ a| +++Try it out+++ -a|`POST /api/rest/2.0/connection/update` [tag redBackground]#DEPRECATED# + - -Updates a connection object. - -__Note: This API endpoint is deprecated in ThoughtSpot 10.4.0.cl and later versions. To update a connection, use `POST /api/rest/2.0/connections/{connection_identifier}/update`. __ - -|ThoughtSpot Cloud: __9.2.0.cl or later__ + -ThoughtSpot Software: __9.5.0.sw or later__ a| -+++Try it out +++ - -a| `POST /api/rest/2.0/connections/{connection_identifier}/update` + -Updates a connection object. -a|ThoughtSpot Cloud: __10.4.0.cl or later__ + -ThoughtSpot Software: __10.7.0.sw or later__ a| -+++Try it out +++ - a|`POST /api/rest/2.0/connection/delete` [tag redBackground]#DEPRECATED# + Deletes a connection object. @@ -220,12 +197,6 @@ a|ThoughtSpot Cloud: __10.4.0.cl or later__ + ThoughtSpot Software: __10.7.0.sw or later__ a| +++Try it out +++ -a| -`POST /api/rest/2.0/connections/fetch-connection-diff-status/{connection_identifier}` + -Validates the connection metadata differences between Cloud Data Warehouse and ThoughtSpot. -|ThoughtSpot Cloud: __9.10.5.cl or later__ + -ThoughtSpot Software: __10.0.0.sw or later__ -a|+++Try it out +++ a| `POST /api/rest/2.0/connections/download-connection-metadata-changes/{connection_identifier}` + Downloads connection metadata differences between Cloud Data Warehouse and ThoughtSpot. @@ -233,6 +204,51 @@ Downloads connection metadata differences between Cloud Data Warehouse and Thoug ThoughtSpot Software: __10.0.0.sw or later__ a| +++Try it out +++ + +a| +`POST /api/rest/2.0/connections/fetch-connection-diff-status/{connection_identifier}` + +Validates the connection metadata differences between Cloud Data Warehouse and ThoughtSpot. +|ThoughtSpot Cloud: __9.10.5.cl or later__ + +ThoughtSpot Software: __10.0.0.sw or later__ +a|+++Try it out +++ + +a|`POST /api/rest/2.0/connections/{connection_identifier}/revoke-refresh-tokens` + + +Revokes OAuth refresh tokens for users who no longer require access to a Cloud Data Warehouse (CDW). + +|ThoughtSpot Cloud: __26.2.0.cl or later__ + +a| +++Try it out+++ + +a|`POST /api/rest/2.0/connection/search` + + +Gets connection objects from ThoughtSpot. + +|ThoughtSpot Cloud: __9.2.0.cl or later__ + +ThoughtSpot Software: __9.5.0.sw or later__ a| +++Try it out+++ + +a|`POST /api/rest/2.0/connections/{connection_identifier}/resync-metadata` + + +Synchronizes connection metadata attributes from your Cloud Data Warehouse (CDW) with ThoughtSpot. + +|ThoughtSpot Cloud: __26.5.0.cl or later__ + +a| +++Try it out+++ + +a|`POST /api/rest/2.0/connection/update` [tag redBackground]#DEPRECATED# + + +Updates a connection object. + +__Note: This API endpoint is deprecated in ThoughtSpot 10.4.0.cl and later versions. To update a connection, use `POST /api/rest/2.0/connections/{connection_identifier}/update`. __ + +|ThoughtSpot Cloud: __9.2.0.cl or later__ + +ThoughtSpot Software: __9.5.0.sw or later__ a| ++++Try it out +++ + +a| `POST /api/rest/2.0/connections/{connection_identifier}/update` + +Updates a connection object. +a|ThoughtSpot Cloud: __10.4.0.cl or later__ + +ThoughtSpot Software: __10.7.0.sw or later__ a| ++++Try it out +++ + |===== -- == Connection Configuration From e7e411ae20ff7a5275bc1bdc7a6621cba4d55787 Mon Sep 17 00:00:00 2001 From: rani2655 <147147811+rani2655@users.noreply.github.com> Date: Tue, 14 Apr 2026 16:39:41 +0530 Subject: [PATCH 015/109] Revert "rest api ref changes" --- modules/ROOT/pages/collections.adoc | 6 +- modules/ROOT/pages/rest-api-v2-reference.adoc | 80 ++++++++----------- 2 files changed, 33 insertions(+), 53 deletions(-) diff --git a/modules/ROOT/pages/collections.adoc b/modules/ROOT/pages/collections.adoc index c352c495b..d1638447d 100644 --- a/modules/ROOT/pages/collections.adoc +++ b/modules/ROOT/pages/collections.adoc @@ -1,4 +1,4 @@ -= Collections += Collections [beta betaBackground]^Beta^ :toc: true :toclevels: 1 :page-title: Collections @@ -9,14 +9,10 @@ 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 diff --git a/modules/ROOT/pages/rest-api-v2-reference.adoc b/modules/ROOT/pages/rest-api-v2-reference.adoc index d1f20daab..f8153b523 100644 --- a/modules/ROOT/pages/rest-api-v2-reference.adoc +++ b/modules/ROOT/pages/rest-api-v2-reference.adoc @@ -133,10 +133,10 @@ ThoughtSpot Software: __10.7.0.sw or later__ a| +++Try it out+++ + a|`POST /api/rest/2.0/connection/create` Creates a connection to the data warehouse specified in the API request. @@ -182,6 +189,22 @@ Creates a connection to the data warehouse specified in the API request. |ThoughtSpot Cloud: __9.2.0.cl or later__ + ThoughtSpot Software: __9.5.0.sw or later__ a| +++Try it out+++ +a|`POST /api/rest/2.0/connection/update` [tag redBackground]#DEPRECATED# + + +Updates a connection object. + +__Note: This API endpoint is deprecated in ThoughtSpot 10.4.0.cl and later versions. To update a connection, use `POST /api/rest/2.0/connections/{connection_identifier}/update`. __ + +|ThoughtSpot Cloud: __9.2.0.cl or later__ + +ThoughtSpot Software: __9.5.0.sw or later__ a| ++++Try it out +++ + +a| `POST /api/rest/2.0/connections/{connection_identifier}/update` + +Updates a connection object. +a|ThoughtSpot Cloud: __10.4.0.cl or later__ + +ThoughtSpot Software: __10.7.0.sw or later__ a| ++++Try it out +++ + a|`POST /api/rest/2.0/connection/delete` [tag redBackground]#DEPRECATED# + Deletes a connection object. @@ -197,6 +220,12 @@ a|ThoughtSpot Cloud: __10.4.0.cl or later__ + ThoughtSpot Software: __10.7.0.sw or later__ a| +++Try it out +++ +a| +`POST /api/rest/2.0/connections/fetch-connection-diff-status/{connection_identifier}` + +Validates the connection metadata differences between Cloud Data Warehouse and ThoughtSpot. +|ThoughtSpot Cloud: __9.10.5.cl or later__ + +ThoughtSpot Software: __10.0.0.sw or later__ +a|+++Try it out +++ a| `POST /api/rest/2.0/connections/download-connection-metadata-changes/{connection_identifier}` + Downloads connection metadata differences between Cloud Data Warehouse and ThoughtSpot. @@ -204,51 +233,6 @@ Downloads connection metadata differences between Cloud Data Warehouse and Thoug ThoughtSpot Software: __10.0.0.sw or later__ a| +++Try it out +++ - -a| -`POST /api/rest/2.0/connections/fetch-connection-diff-status/{connection_identifier}` + -Validates the connection metadata differences between Cloud Data Warehouse and ThoughtSpot. -|ThoughtSpot Cloud: __9.10.5.cl or later__ + -ThoughtSpot Software: __10.0.0.sw or later__ -a|+++Try it out +++ - -a|`POST /api/rest/2.0/connections/{connection_identifier}/revoke-refresh-tokens` + - -Revokes OAuth refresh tokens for users who no longer require access to a Cloud Data Warehouse (CDW). - -|ThoughtSpot Cloud: __26.2.0.cl or later__ + -a| +++Try it out+++ - -a|`POST /api/rest/2.0/connection/search` + - -Gets connection objects from ThoughtSpot. - -|ThoughtSpot Cloud: __9.2.0.cl or later__ + -ThoughtSpot Software: __9.5.0.sw or later__ a| +++Try it out+++ - -a|`POST /api/rest/2.0/connections/{connection_identifier}/resync-metadata` + - -Synchronizes connection metadata attributes from your Cloud Data Warehouse (CDW) with ThoughtSpot. - -|ThoughtSpot Cloud: __26.5.0.cl or later__ + -a| +++Try it out+++ - -a|`POST /api/rest/2.0/connection/update` [tag redBackground]#DEPRECATED# + - -Updates a connection object. - -__Note: This API endpoint is deprecated in ThoughtSpot 10.4.0.cl and later versions. To update a connection, use `POST /api/rest/2.0/connections/{connection_identifier}/update`. __ - -|ThoughtSpot Cloud: __9.2.0.cl or later__ + -ThoughtSpot Software: __9.5.0.sw or later__ a| -+++Try it out +++ - -a| `POST /api/rest/2.0/connections/{connection_identifier}/update` + -Updates a connection object. -a|ThoughtSpot Cloud: __10.4.0.cl or later__ + -ThoughtSpot Software: __10.7.0.sw or later__ a| -+++Try it out +++ - |===== -- == Connection Configuration From 452410bc6b8b4dc1840c6ebb139474bb916e1582 Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Tue, 14 Apr 2026 16:42:42 +0530 Subject: [PATCH 016/109] PR re creation --- modules/ROOT/pages/rest-api-v2-reference.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/ROOT/pages/rest-api-v2-reference.adoc b/modules/ROOT/pages/rest-api-v2-reference.adoc index d1f20daab..bc48d8da8 100644 --- a/modules/ROOT/pages/rest-api-v2-reference.adoc +++ b/modules/ROOT/pages/rest-api-v2-reference.adoc @@ -1292,3 +1292,4 @@ a|ThoughtSpot Cloud: __10.14.0.cl or later__ a| +++Try it out +++ |===== -- + From bd54fbb6c0b69bd11af2e80076d786d153d2d79c Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Tue, 14 Apr 2026 16:54:38 +0530 Subject: [PATCH 017/109] formatting edits --- modules/ROOT/pages/rest-api-v2-reference.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/rest-api-v2-reference.adoc b/modules/ROOT/pages/rest-api-v2-reference.adoc index bc48d8da8..0b9248694 100644 --- a/modules/ROOT/pages/rest-api-v2-reference.adoc +++ b/modules/ROOT/pages/rest-api-v2-reference.adoc @@ -136,7 +136,7 @@ ThoughtSpot Software: __10.7.0.sw or later__ a| +++ Date: Tue, 14 Apr 2026 17:10:09 +0530 Subject: [PATCH 018/109] formatting edits --- modules/ROOT/pages/rest-api-v2-reference.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/ROOT/pages/rest-api-v2-reference.adoc b/modules/ROOT/pages/rest-api-v2-reference.adoc index 0b9248694..825f9c23d 100644 --- a/modules/ROOT/pages/rest-api-v2-reference.adoc +++ b/modules/ROOT/pages/rest-api-v2-reference.adoc @@ -287,6 +287,8 @@ a|ThoughtSpot Cloud: __10.12.0.cl or later__ + a| |===== -- + +//// == Custom calendars [div boxAuto] @@ -318,6 +320,8 @@ Updates a custom calendar. a|+++Try it out+++ |==== -- +//// + == Custom actions From a9d6111c4309917e8f96f76183d74d0c9923f44b Mon Sep 17 00:00:00 2001 From: ShashiSubramanya <76986173+ShashiSubramanya@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:29:12 +0530 Subject: [PATCH 019/109] deprecation note update --- modules/ROOT/pages/deprecated-features.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/ROOT/pages/deprecated-features.adoc b/modules/ROOT/pages/deprecated-features.adoc index 64ed61f97..7ba618704 100644 --- a/modules/ROOT/pages/deprecated-features.adoc +++ b/modules/ROOT/pages/deprecated-features.adoc @@ -89,15 +89,15 @@ a|xref:deprecated-features.adoc#_deprecated_parameter_in_rest_api_v2_0_authentic [#hostEventv1] == HostEvent v1 framework in Visual Embed SDK -Starting with ThoughtSpot 26.10.0.cl, the default Host Events behavior in the ThoughtSpot embedded application will be replaced with the HostEvent v2 framework. Embedding applications using the legacy HostEvent v1 framework will be automatically migrated to the HostEvent v2 framework, and the HostEvent v1 framework will be deprecated. +The HostEvent v1 framework will be deprecated in the ThoughtSpot Cloud 26.10.0.cl release version. The default behavior of host events and application workflows with the HostEvent v1 framework will be replaced with the HostEvent v2 framework. Impact on your instance:: Embedding applications with integrations and workflows that use HostEvent objects to trigger actions will benefit from enhanced event handling, routing behavior, and payload validation. If your embedded interface includes multi-layered interactions, event routing will be context-aware and deterministic. +Embedding applications with integrations and workflows that use HostEvent objects to trigger actions will experience improved event handling, routing behavior, and payload validation. If your embedded interface includes multi-layered interactions, event routing will be context-aware and deterministic. For more information, see xref:events-context-aware-routing.adoc[Context-based execution of host events]. Recommended actions:: -If your embed uses the HostEvent v1 framework, ThoughtSpot recommends migrating to the HostEvent v2 framework in your development environments and evaluating the behavioral changes and impact on custom workflows and integrations. + -For migration guidelines, refer to the xref:hosteventsv2-migration.adoc[HostEvent v2 migration guide]. + -For information about using the HostEvents v2 framework in your embed, see xref:events-context-aware-routing.adoc[Context-based execution of host events]. +If you are using the HostEvent v1 framework in your embed, ThoughtSpot recommends migrating to the HostEvent v2 framework in your development environment and evaluating the event behavior and impact on custom workflows and integrations. + +For migration and feature rollout guidelines, refer to the xref:hosteventsv2-migration.adoc[HostEvent v2 migration guide]. [#v1-v2-exp-fullApp-embed] == V1 and V2 navigation and home page experience in full app embed From 1817a64c8697f3ffba58b3f43a1ba3bbb7df1b0a Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Wed, 15 Apr 2026 14:34:45 +0530 Subject: [PATCH 020/109] sync metadata and wysiwig --- modules/ROOT/pages/rest-apiv2-changelog.adoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/ROOT/pages/rest-apiv2-changelog.adoc b/modules/ROOT/pages/rest-apiv2-changelog.adoc index 77512158a..1924b1b0d 100644 --- a/modules/ROOT/pages/rest-apiv2-changelog.adoc +++ b/modules/ROOT/pages/rest-apiv2-changelog.adoc @@ -8,6 +8,18 @@ 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.5.0.cl, May 2026 + +=== Connections API +You can now synchronize connection metadata attributes from your Cloud Data Warehouse (CDW) with ThoughtSpot by sending a request to `POST /api/rest/2.0/connections/{connection_identifier}/resync-metadata` API endpoint. + +=== Liveboard report API enhancements +The `POST /api/rest/2.0/report/liveboard` API endpoint enhances the pdf downloads by introducing the following parameters: + +* `page_size = Continuous` for a seamless PDF export that matches the full length of your Liveboard. Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. +* `zoom_level` offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. + + == Version 26.4.0.cl, April 2026 === Variable API endpoints From 3f81bb8d8d47d8ec163859aef35ffb9a8c985ae9 Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Wed, 15 Apr 2026 15:27:30 +0530 Subject: [PATCH 021/109] wysiwig --- modules/ROOT/pages/data-report-v2-api.adoc | 6 ++++++ modules/ROOT/pages/rest-apiv2-changelog.adoc | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/data-report-v2-api.adoc b/modules/ROOT/pages/data-report-v2-api.adoc index 2e76d4253..0b906146f 100644 --- a/modules/ROOT/pages/data-report-v2-api.adoc +++ b/modules/ROOT/pages/data-report-v2-api.adoc @@ -293,6 +293,12 @@ curl -X POST \ For *PDF* downloads, you can specify additional parameters to customize the page orientation and include or exclude the cover page, logo, footer text, and page numbers. +You can now also download continuous pdfs which matches the full length of your Liveboard, without breaking them into multiple A4 pages. + +* `page_size = Continuous` [beta betaBackground]^Beta^ Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. +* `zoom_level` [beta betaBackground]^Beta^ offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. This can be set only when `page_size = CONTINUOUS`. Valid values are integers in the range of 45 and 175. + + ===== Sample API payload for XLSX downloads [source,cURL] diff --git a/modules/ROOT/pages/rest-apiv2-changelog.adoc b/modules/ROOT/pages/rest-apiv2-changelog.adoc index 1924b1b0d..cf2b2b437 100644 --- a/modules/ROOT/pages/rest-apiv2-changelog.adoc +++ b/modules/ROOT/pages/rest-apiv2-changelog.adoc @@ -16,8 +16,8 @@ You can now synchronize connection metadata attributes from your Cloud Data Ware === Liveboard report API enhancements The `POST /api/rest/2.0/report/liveboard` API endpoint enhances the pdf downloads by introducing the following parameters: -* `page_size = Continuous` for a seamless PDF export that matches the full length of your Liveboard. Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. -* `zoom_level` offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. +* `page_size = CONTINUOUS` for a seamless PDF export that matches the full length of your Liveboard. Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. +* `zoom_level` offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. This can be set only when `page_size = CONTINUOUS`. == Version 26.4.0.cl, April 2026 From 15cbb5fe84781b34bcf98a90e4b48d262a7254c3 Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Wed, 15 Apr 2026 22:55:31 +0530 Subject: [PATCH 022/109] wysiwig --- modules/ROOT/pages/data-report-v2-api.adoc | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/modules/ROOT/pages/data-report-v2-api.adoc b/modules/ROOT/pages/data-report-v2-api.adoc index 0b906146f..fe6a8cbeb 100644 --- a/modules/ROOT/pages/data-report-v2-api.adoc +++ b/modules/ROOT/pages/data-report-v2-api.adoc @@ -295,9 +295,11 @@ For *PDF* downloads, you can specify additional parameters to customize the page You can now also download continuous pdfs which matches the full length of your Liveboard, without breaking them into multiple A4 pages. -* `page_size = Continuous` [beta betaBackground]^Beta^ Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. +* `page_size = CONTINUOUS` [beta betaBackground]^Beta^ Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. * `zoom_level` [beta betaBackground]^Beta^ offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. This can be set only when `page_size = CONTINUOUS`. Valid values are integers in the range of 45 and 175. +Contact ThoughtSpot support to enable these settings for PNG downloads on your ThoughtSpot instance. + ===== Sample API payload for XLSX downloads @@ -314,13 +316,16 @@ curl -X POST \ "254c6e30-680c-41ea-aa4d-bb059f745462" ], "pdf_options": { -"include_cover_page": true, -"include_custom_logo": true, -"include_filter_page": true, -"include_page_number": true, -"page_orientation": "LANDSCAPE", -"page_footer_text": "Sample footer text" -} + "page_size": "CONTINUOUS", + "zoom_level": 105, + "include_cover_page": true, + "include_custom_logo": true, + "include_filter_page": true, + "include_page_number": true, + "page_orientation": "PORTRAIT", + "truncate_table": false, + "page_footer_text": "Sample footer text" + } }' ---- From b63169cf4453bf9c342ea82b4b66179976e283fc Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Wed, 15 Apr 2026 23:08:53 +0530 Subject: [PATCH 023/109] wysiwig --- modules/ROOT/pages/data-report-v2-api.adoc | 25 +++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/modules/ROOT/pages/data-report-v2-api.adoc b/modules/ROOT/pages/data-report-v2-api.adoc index fe6a8cbeb..6b7132fb8 100644 --- a/modules/ROOT/pages/data-report-v2-api.adoc +++ b/modules/ROOT/pages/data-report-v2-api.adoc @@ -298,24 +298,23 @@ You can now also download continuous pdfs which matches the full length of your * `page_size = CONTINUOUS` [beta betaBackground]^Beta^ Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. * `zoom_level` [beta betaBackground]^Beta^ offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. This can be set only when `page_size = CONTINUOUS`. Valid values are integers in the range of 45 and 175. -Contact ThoughtSpot support to enable these settings for PNG downloads on your ThoughtSpot instance. +Contact ThoughtSpot support to enable these settings for PDF downloads on your ThoughtSpot instance. -===== Sample API payload for XLSX downloads +===== Sample API payload for PDF downloads [source,cURL] ---- -curl -X POST \ - --url 'https://{ThoughtSpot-Host}/api/rest/2.0/report/liveboard' \ - -H 'Authorization: Bearer {access-token}'\ - -H 'Content-Type: application/json' \ +curl -X POST 'https://{ThoughtSpot-Host}/api/rest/2.0/report/liveboard' \ +--header 'Authorization: Bearer {access-token}' \ +--header 'Content-Type: application/json' \ --data-raw '{ -"metadata_identifier": "416052fd-ad22-4d48-be0a-e43b53109957", -"file_format": "PDF", -"visualization_identifiers": [ -"254c6e30-680c-41ea-aa4d-bb059f745462" -], -"pdf_options": { + "metadata_identifier": "416052fd-ad22-4d48-be0a-e43b53109957", + "file_format": "PDF", + "visualization_identifiers": [ + "254c6e30-680c-41ea-aa4d-bb059f745462" + ], + "pdf_options": { "page_size": "CONTINUOUS", "zoom_level": 105, "include_cover_page": true, @@ -325,7 +324,7 @@ curl -X POST \ "page_orientation": "PORTRAIT", "truncate_table": false, "page_footer_text": "Sample footer text" - } + } }' ---- From 7052f5838f43fb3d469e3743fd395ecf20980490 Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Fri, 17 Apr 2026 19:20:07 +0530 Subject: [PATCH 024/109] wysiwig --- modules/ROOT/pages/data-report-v2-api.adoc | 2 ++ modules/ROOT/pages/rest-apiv2-changelog.adoc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/data-report-v2-api.adoc b/modules/ROOT/pages/data-report-v2-api.adoc index 6b7132fb8..f14aaa7ac 100644 --- a/modules/ROOT/pages/data-report-v2-api.adoc +++ b/modules/ROOT/pages/data-report-v2-api.adoc @@ -296,6 +296,8 @@ For *PDF* downloads, you can specify additional parameters to customize the page You can now also download continuous pdfs which matches the full length of your Liveboard, without breaking them into multiple A4 pages. * `page_size = CONTINUOUS` [beta betaBackground]^Beta^ Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. ++ +When `page_size = CONTINUOUS`, the `include_filter_page` option works to show/hide the filter section in the PDF page (in CONTINUOUS PDF, we don't have a separate filter page, but the filters are included on the same page at the top). * `zoom_level` [beta betaBackground]^Beta^ offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. This can be set only when `page_size = CONTINUOUS`. Valid values are integers in the range of 45 and 175. Contact ThoughtSpot support to enable these settings for PDF downloads on your ThoughtSpot instance. diff --git a/modules/ROOT/pages/rest-apiv2-changelog.adoc b/modules/ROOT/pages/rest-apiv2-changelog.adoc index cf2b2b437..703de4ee4 100644 --- a/modules/ROOT/pages/rest-apiv2-changelog.adoc +++ b/modules/ROOT/pages/rest-apiv2-changelog.adoc @@ -13,7 +13,7 @@ This changelog lists the features and enhancements introduced in REST API v2.0. === Connections API You can now synchronize connection metadata attributes from your Cloud Data Warehouse (CDW) with ThoughtSpot by sending a request to `POST /api/rest/2.0/connections/{connection_identifier}/resync-metadata` API endpoint. -=== Liveboard report API enhancements +=== Liveboard report API enhancements [beta betaBackground]^Beta^ The `POST /api/rest/2.0/report/liveboard` API endpoint enhances the pdf downloads by introducing the following parameters: * `page_size = CONTINUOUS` for a seamless PDF export that matches the full length of your Liveboard. Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. From efce7e3ecc09f416a7f3b685cd0214309befdbc4 Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Sun, 19 Apr 2026 18:27:20 +0530 Subject: [PATCH 025/109] changes picked from 26.4 --- .../ROOT/pages/callback-response-payload.adoc | 4526 ++++++++++++++++- 1 file changed, 4525 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/callback-response-payload.adoc b/modules/ROOT/pages/callback-response-payload.adoc index f40f6e312..f88028857 100644 --- a/modules/ROOT/pages/callback-response-payload.adoc +++ b/modules/ROOT/pages/callback-response-payload.adoc @@ -743,6 +743,201 @@ The following example shows the data payload for a callback custom action in the === Liveboard +The following example shows the data payload for a callback for code based custom action for the primary action on a Liveboard: + +[source,JSON] +---- +{ + "type": "customAction", + "data": { + "liveboardId": "87328d32-2bf0-4fc4-ac51-a738712d7e79", + "id": "my-liveboard-custom-action", + "pinboardDetails": { + "__typename": "Pinboard", + "authorDisplayName": "rani.gangwar", + "authorGuid": "0000083e-e253-10af-aa97-5e45d512ebbd", + "containers": [ + { + "__typename": "Container", + "answerId": "4d5e51cf-71e1-4765-8e6e-9f9d01bcf95d", + "chartType": "COLUMN", + "dataSourceIds": [ + "cd252e5c-b552-49a8-821d-3eadaa049cca" + ], + "description": "", + "groupContainerIds": null, + "id": "6fda068c-92f7-4744-8fa5-ac01b0812d6b", + "isTimeSeriesKpi": false, + "name": "Total sales by product", + "noteTile": null, + "refVizId": "f6a2ee16-4035-4d83-9b27-64a7d1af2e32", + "referencedParameters": [], + "referencedVizType": 1, + "type": "PINNED_ANSWER" + } + ], + "dateCreated": 1773813596421, + "dateModified": 1773815813982, + "defaultPersonalisedView": null, + "description": "", + "id": "87328d32-2bf0-4fc4-ac51-a738712d7e79", + "inScopeParameters": [], + "isDiscoverable": false, + "isFavorite": false, + "layout": [ + { + "__typename": "ContainerLayout", + "height": 4, + "id": "6fda068c-92f7-4744-8fa5-ac01b0812d6b", + "width": 6, + "x": 0, + "y": 0 + } + ], + "liveboardStyle": { + "__typename": "LiveboardStyleConfig", + "componentOverrides": [], + "defaultStyle": { + "__typename": "LiveboardStyle", + "compositeStyle": null, + "configStyle": { + "__typename": "LiveboardConfigStyle", + "gridColumnCount": "12", + "groupGutter": "8px", + "hideGroupDescription": true, + "hideGroupDivider": false, + "hideGroupTileDescription": false, + "hideGroupTitle": false, + "hideTileDescription": false, + "kpiHeroFontSize": "M", + "lbGutter": "16px" + }, + "pureStyle": { + "__typename": "LiveboardPureStyle", + "axisDataLabelColor": "#5E5E5E", + "axisTitleColor": "#5E5E5E", + "borderRadius": "16px", + "filterChipActiveBgColor": "#C0C6CF", + "filterChipActiveTextColor": "#1D232F", + "filterChipBgColor": "#EAEDF2", + "filterChipHoverBgColor": "#DBDFE7", + "filterChipHoverTextColor": "#1D232F", + "filterChipTextColor": "#1D232F", + "groupBgColor": "#FFFFFF", + "groupBorderColor": "#EAEDF2", + "groupDescriptionFontColor": "#4A515E", + "groupPadding": "8px", + "groupTileBgColor": "#FFFFFF", + "groupTileBorderColor": "#EAEDF2", + "groupTileDescriptionFontColor": "#4A515E", + "groupTilePadding": "4px", + "groupTileTitleFontColor": "#4A515E", + "groupTileTitleFontSize": "14px", + "groupTileTitleFontWeight": "medium", + "groupTitleFontColor": "#1D232F", + "groupTitleFontSize": "16px", + "groupTitleFontWeight": "medium", + "headerActionButtonActiveColor": "#C0C6CF", + "headerActionButtonBgColor": "#EAEDF2", + "headerActionButtonFontColor": "#1D232F", + "headerActionButtonHoverColor": "#DBDFE7", + "headerBadgeActiveColor": "#163772", + "headerBadgeBgColor": "#2770EF", + "headerBadgeFontColor": "#FFFFFF", + "headerBadgeHoverColor": "#2359B6", + "headerBadgeModifiedBgColor": "#777E8B", + "headerBgColor": "#FFFFFF", + "headerFontColor": "#1D232F", + "iconSize": "24px", + "kpiAnalyseFontColor": "#2770EF", + "kpiComparisonFontColor": "#777E8B", + "kpiDeltaBadgeNegativeBgColor": "#FFEBEC", + "kpiDeltaBadgeNegativeFontColor": "#E22B3D", + "kpiDeltaBadgePositiveBgColor": "#E0F8EF", + "kpiDeltaBadgePositiveFontColor": "#06BF7F", + "kpiNumberFontColor": "#1D232F", + "lbBgColor": "#F6F8FA", + "lbBgDotColor": "#C0C6CF", + "legendHoverBackground": "#E5EEFD", + "legendTextColor": "#5E5E5E", + "noteBodyFontColor": "#1D232F", + "noteHeadingFontColor": "#1D232F", + "parameterChipActiveBgColor": "#323946", + "parameterChipActiveTextColor": "#FFFFFF", + "parameterChipBgColor": "#777E8B", + "parameterChipHoverBgColor": "#4A515E", + "parameterChipHoverTextColor": "#FFFFFF", + "parameterChipTextColor": "#FFFFFF", + "tabActiveBorderColor": "#2770EF", + "tileBgColor": "#FFFFFF", + "tileBorderColor": "#EAEDF2", + "tileDescriptionFontColor": "#4A515E", + "tilePadding": "8px", + "tileTitleFontColor": "#1D232F", + "tileTitleFontSize": "16px", + "tileTitleFontWeight": "medium" + } + } + }, + "modifiedBy": "0000083e-e253-10af-aa97-5e45d512ebbd", + "name": "Docs copy of (Sample) Sales Performance", + "orderedChips": [], + "orderedTabIds": [], + "parameters": [], + "permissions": { + "__typename": "PinboardPermissions", + "columnPermissions": [], + "containersPermission": [ + { + "__typename": "ContainerPermission", + "answerId": "4d5e51cf-71e1-4765-8e6e-9f9d01bcf95d", + "permission": { + "__typename": "ObjectPermission", + "dataSourceAccessLevel": "READ_ONLY", + "dataSourceNamesWithNoAccess": [], + "objectAccessLevel": "MODIFY" + } + } + ], + "dataSourcePermissions": [ + { + "__typename": "PermissionObject", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel", + "permission": "READ_ONLY" + } + ], + "pinboardLevelPermission": { + "__typename": "ObjectPermission", + "columnIdsWithNoAccess": null, + "dataSourceAccessLevel": "READ_ONLY", + "dataSourceNamesWithNoAccess": [], + "objectAccessLevel": "MODIFY" + }, + "pinboardPermission": { + "__typename": "PermissionObject", + "id": "87328d32-2bf0-4fc4-ac51-a738712d7e79", + "permission": "MODIFY" + } + }, + "pinboardFilter": null, + "pinboardGenerationNumber": "4646949", + "pinboardSignature": "-6032047147599776089", + "tabs": [], + "tags": [] + }, + "userGuid": "0000083e-e253-10af-aa97-5e45d512ebbd", + "currentOrgId": 0 + }, + "status": "end", + "answerService": { + "thoughtSpotHost": "", + "tmlOverride": {}, + "answer": {} + } +} +---- + The following example shows the data payload for a callback custom action in the *More* menu of a Liveboard visualization: [source,JSON] @@ -1315,4 +1510,4333 @@ The following example shows the data payload of callback custom action in the co } } ----- \ No newline at end of file +---- + + +=== Spotter + +The following example shows the data payload for a code based custom action for the *More* menu in Spotter: + +.Data payload +[%collapsible] +==== +[source,JSON] +---- +{ + "type": "customAction", + "data": { + "id": "my-custom-action", + "embedAnswerData": { + "__typename": "ChartViz", + "clientState": {}, + "cohorts": [], + "description": "", + "displayDescription": "", + "displayMode": "CHART_MODE", + "displayName": "", + "dynamicDescription": "", + "dynamicName": "", + "filterGroups": [ + { + "__typename": "FilterGroup", + "columnInfo": { + "__typename": "FilterColumn", + "aggregationType": "NONE", + "calendarGuid": "", + "dataType": "CHAR", + "description": null, + "formulaId": "", + "isAggregateApplied": false, + "isMasked": null, + "isStrictDateColumn": false, + "name": "product", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "displayName": "product", + "guid": "085f9694-0d02-479e-973a-d216336e5253" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "timeBucket": "NO_BUCKET", + "type": "ATTRIBUTE" + }, + "displayName": null, + "filters": [ + { + "__typename": "Filter", + "dateFilterContent": [], + "filterContent": [ + { + "__typename": "FilterContent", + "filterType": "EQ", + "negate": false, + "value": [ + { + "__typename": "FilterContentValue", + "key": "f2 jackets" + } + ] + } + ], + "filterId": "7d0a505f-8289-5c79-b7f0-bc2f118d90d0" + } + ], + "groupId": { + "__typename": "FilterGroupId", + "answerColumnId": "bba4be57-6156-48a3-9e69-a2775237772a", + "dataSourceId": null, + "logicalColumnId": null + }, + "isEditable": true, + "isMandatory": null, + "isSingleValue": null, + "sourceContainerId": null + }, + { + "__typename": "FilterGroup", + "columnInfo": { + "__typename": "FilterColumn", + "aggregationType": "NONE", + "calendarGuid": "", + "dataType": "CHAR", + "description": null, + "formulaId": "", + "isAggregateApplied": false, + "isMasked": null, + "isStrictDateColumn": false, + "name": "zip code", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "displayName": "zip code", + "guid": "6f09ed23-a8d8-4017-8887-e3fd983cc58c" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "timeBucket": "NO_BUCKET", + "type": "ATTRIBUTE" + }, + "displayName": null, + "filters": [ + { + "__typename": "Filter", + "dateFilterContent": [], + "filterContent": [ + { + "__typename": "FilterContent", + "filterType": "EQ", + "negate": false, + "value": [ + { + "__typename": "FilterContentValue", + "key": "63144" + } + ] + } + ], + "filterId": "e1581fc4-3ea1-5d8a-8b47-679d9559dda8" + } + ], + "groupId": { + "__typename": "FilterGroupId", + "answerColumnId": "b870f86f-8947-450d-b4e9-56bc9d2562a6", + "dataSourceId": null, + "logicalColumnId": null + }, + "isEditable": true, + "isMandatory": null, + "isSingleValue": null, + "sourceContainerId": null + }, + { + "__typename": "FilterGroup", + "columnInfo": { + "__typename": "FilterColumn", + "aggregationType": "NONE", + "calendarGuid": "bfa39848-ba4f-46d8-80fd-b695064e61b7", + "dataType": "DATE", + "description": null, + "formulaId": "", + "isAggregateApplied": false, + "isMasked": null, + "isStrictDateColumn": false, + "name": "date", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "displayName": "date", + "guid": "a0314a96-e56c-4dc2-af0d-ee14a444e4fe" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "timeBucket": "NO_BUCKET", + "type": "ATTRIBUTE" + }, + "displayName": null, + "filters": [ + { + "__typename": "Filter", + "dateFilterContent": [ + { + "__typename": "DateFilterContent", + "dateFilter": { + "__typename": "DateFilterValue", + "datePeriod": "DAY", + "dateRange": { + "__typename": "FilterDateRange", + "highEpoch": "1773792000", + "lowEpoch": "1773705600" + }, + "epoch": null, + "forEachPeriod": "NUM_DATE_PERIODS", + "hasUnprocessedTemporalValues": false, + "includeCurrentPeriod": false, + "monthName": "", + "number": 0, + "op": "EQ", + "quarterName": "", + "type": "YESTERDAY", + "weekDayName": "", + "yearName": "" + }, + "negate": false + } + ], + "filterContent": [ + { + "__typename": "FilterContent", + "filterType": "BW_INC_MIN", + "negate": false, + "value": [ + { + "__typename": "FilterContentValue", + "key": "1773705600" + }, + { + "__typename": "FilterContentValue", + "key": "1773792000" + } + ] + } + ], + "filterId": "0a32e1f0-7a0a-5785-8c6c-13bb5dfa6a28" + } + ], + "groupId": { + "__typename": "FilterGroupId", + "answerColumnId": "21ee5724-10b2-41ee-8008-a6cc1129959b", + "dataSourceId": null, + "logicalColumnId": null + }, + "isEditable": true, + "isMandatory": null, + "isSingleValue": null, + "sourceContainerId": null + } + ], + "formulas": [], + "hashKey": "", + "headlineVisibilityMap": [ + { + "__typename": "HeadlineVisibility", + "columnId": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isVisible": true + } + ], + "id": "60d9622c-6028-498c-8269-426d09cf6780", + "inScopeParameters": [], + "incompeleteAnswerDetails": { + "__typename": "IncompeleteAnswerDetails", + "brokenTokenDetails": null + }, + "metadata": { + "__typename": "AnswerMetadata", + "author": "", + "authorId": "0000083e-e253-10af-aa97-5e45d512ebbd", + "createdAt": null, + "generationNum": "-1", + "isDiscoverable": false, + "isHidden": false, + "modifiedAt": null, + "tags": [], + "type": "" + }, + "name": "Total sales", + "orderedChips": [ + { + "__typename": "Chip", + "objectId": "b870f86f-8947-450d-b4e9-56bc9d2562a6", + "type": "FILTER" + }, + { + "__typename": "Chip", + "objectId": "21ee5724-10b2-41ee-8008-a6cc1129959b", + "type": "FILTER" + }, + { + "__typename": "Chip", + "objectId": "bba4be57-6156-48a3-9e69-a2775237772a", + "type": "FILTER" + } + ], + "parameters": [], + "pathAnalysisConfig": null, + "permission": { + "__typename": "ObjectPermission", + "dataSourceAccessLevel": "READ_ONLY", + "dataSourceNamesWithNoAccess": [], + "objectAccessLevel": "MODIFY" + }, + "phrases": [ + { + "__typename": "SagePhrase", + "isAmbiguous": false, + "isComplete": true, + "tokens": [ + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1", + "name": "sales" + }, + "dataType": "DOUBLE", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "sales", + "typeEnum": "MEASURE", + "dataType": "DOUBLE", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1", + "outputGuid": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "sales", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "hasSpaceAfter": true, + "canonicalForm": "sales", + "idxInPrevQuery": 0, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "sales", + "trailingWhitespace": " ", + "type": "MEASURE" + } + ], + "type": "AGGREGATED_COLUMN_PHRASE" + }, + { + "__typename": "SagePhrase", + "isAmbiguous": false, + "isComplete": true, + "tokens": [ + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "085f9694-0d02-479e-973a-d216336e5253", + "name": "product" + }, + "dataType": "CHAR", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "product", + "typeEnum": "ATTRIBUTE", + "dataType": "CHAR", + "guid": "085f9694-0d02-479e-973a-d216336e5253", + "outputGuid": "bba4be57-6156-48a3-9e69-a2775237772a", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "product", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "hasSpaceAfter": true, + "canonicalForm": "product", + "idxInPrevQuery": 1, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "product", + "trailingWhitespace": " ", + "type": "ATTRIBUTE" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "", + "name": null + }, + "dataType": "UNKNOWN", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "=", + "typeEnum": "OPERATOR", + "hasSpaceAfter": true, + "canonicalForm": "=", + "idxInPrevQuery": 2, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": null, + "name": null + }, + "text": "=", + "trailingWhitespace": " ", + "type": "OPERATOR" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "085f9694-0d02-479e-973a-d216336e5253", + "name": "product" + }, + "dataType": "CHAR", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "'f2 jackets'", + "typeEnum": "VALUE", + "dataType": "CHAR", + "matchType": "EXACT", + "guid": "085f9694-0d02-479e-973a-d216336e5253", + "outputGuid": "bba4be57-6156-48a3-9e69-a2775237772a", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "product", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "valueMatch": true, + "requiresDelimiters": true, + "hasSpaceAfter": true, + "canonicalForm": "'f2 jackets'", + "idxInPrevQuery": 3, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + }, + "isCohort": false + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "'f2 jackets'", + "trailingWhitespace": " ", + "type": "VALUE" + } + ], + "type": "FILTER_PHRASE" + }, + { + "__typename": "SagePhrase", + "isAmbiguous": false, + "isComplete": true, + "tokens": [ + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "6f09ed23-a8d8-4017-8887-e3fd983cc58c", + "name": "zip code" + }, + "dataType": "CHAR", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "zip code", + "typeEnum": "ATTRIBUTE", + "dataType": "CHAR", + "guid": "6f09ed23-a8d8-4017-8887-e3fd983cc58c", + "outputGuid": "b870f86f-8947-450d-b4e9-56bc9d2562a6", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "zip code", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "hasSpaceAfter": true, + "canonicalForm": "zip code", + "idxInPrevQuery": 4, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "zip code", + "trailingWhitespace": " ", + "type": "ATTRIBUTE" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "", + "name": null + }, + "dataType": "UNKNOWN", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "=", + "typeEnum": "OPERATOR", + "hasSpaceAfter": true, + "canonicalForm": "=", + "idxInPrevQuery": 5, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": null, + "name": null + }, + "text": "=", + "trailingWhitespace": " ", + "type": "OPERATOR" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "6f09ed23-a8d8-4017-8887-e3fd983cc58c", + "name": "zip code" + }, + "dataType": "CHAR", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "'63144'", + "typeEnum": "VALUE", + "dataType": "CHAR", + "matchType": "EXACT", + "guid": "6f09ed23-a8d8-4017-8887-e3fd983cc58c", + "outputGuid": "b870f86f-8947-450d-b4e9-56bc9d2562a6", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "zip code", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "valueMatch": true, + "requiresDelimiters": true, + "hasSpaceAfter": true, + "canonicalForm": "'63144'", + "idxInPrevQuery": 6, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + }, + "isCohort": false + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "'63144'", + "trailingWhitespace": " ", + "type": "VALUE" + } + ], + "type": "FILTER_PHRASE" + }, + { + "__typename": "SagePhrase", + "isAmbiguous": false, + "isComplete": true, + "tokens": [ + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "a0314a96-e56c-4dc2-af0d-ee14a444e4fe", + "name": "date" + }, + "dataType": "DATE", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "date", + "typeEnum": "ATTRIBUTE", + "dataType": "DATE", + "guid": "a0314a96-e56c-4dc2-af0d-ee14a444e4fe", + "outputGuid": "21ee5724-10b2-41ee-8008-a6cc1129959b", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "date", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "hasSpaceAfter": true, + "canonicalForm": "date", + "idxInPrevQuery": 7, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "date", + "trailingWhitespace": " ", + "type": "ATTRIBUTE" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "", + "name": null + }, + "dataType": "UNKNOWN", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "=", + "typeEnum": "OPERATOR", + "hasSpaceAfter": true, + "canonicalForm": "=", + "idxInPrevQuery": 8, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": null, + "name": null + }, + "text": "=", + "trailingWhitespace": " ", + "type": "OPERATOR" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "a0314a96-e56c-4dc2-af0d-ee14a444e4fe", + "name": "date" + }, + "dataType": "DATE", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "yesterday", + "typeEnum": "VALUE", + "dataType": "DATE", + "matchType": "EXACT", + "guid": "a0314a96-e56c-4dc2-af0d-ee14a444e4fe", + "outputGuid": "21ee5724-10b2-41ee-8008-a6cc1129959b", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "date", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "valueMatch": false, + "hasSpaceAfter": true, + "canBeExtended": false, + "dateFilter": { + "type": "YESTERDAY", + "op": "EQ" + }, + "canonicalForm": "yesterday", + "idxInPrevQuery": 9, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + }, + "isCohort": false + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "yesterday", + "trailingWhitespace": " ", + "type": "VALUE" + } + ], + "type": "FILTER_PHRASE" + } + ], + "phrasesTimestamp": "1773817179992", + "queryableDataSource": "RDBMS_SNOWFLAKE", + "selectedColumns": [ + { + "__typename": "SelectedColumn", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "selectedFormulas": [], + "sortInfo": [], + "sources": [ + { + "__typename": "Source", + "author": { + "__typename": "EntityHeader", + "displayName": "System User", + "guid": "67e15c06-d153-4924-a4cd-ff615393b60f" + }, + "header": { + "__typename": "EntityHeader", + "description": null, + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "isAccessible": true, + "schema": { + "__typename": "EntityHeader", + "description": null, + "displayName": null, + "guid": null + } + } + ], + "suggestedDisplayMode": "CHART_MODE", + "visualizations": [ + { + "__typename": "TableViz", + "clientState": {}, + "columns": [ + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "legacyMetricDefinition": null + } + ], + "id": "aeedf2f8-8f90-42c3-b681-eb96d97038a0", + "sortInfo": [], + "topInfo": [], + "visualOverrides": { + "__typename": "TableVisualOverrides", + "overrides": null + }, + "vizProp": { + "__typename": "TableVizProps", + "columnProperties": [], + "density": null, + "orderedColumnIds": [], + "showGridSummary": null, + "showTableFooter": null, + "tableVizPropVersion": "V1", + "theme": null, + "widthState": [], + "wrapTableHeader": null + } + }, + { + "__typename": "HeadlineViz", + "aggregationType": [ + "SUM" + ], + "headlineColumn": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "id": "d8164286-f1f9-450f-99cb-c5e8c260e1b2", + "possibleAggregations": [ + "SUM", + "AVERAGE", + "STD_DEVIATION", + "VARIANCE", + "MIN", + "MAX" + ], + "showPossibleAggregates": false, + "sortInfo": [], + "title": "Headline Total sales", + "visualOverrides": { + "__typename": "HeadlineVisualOverrides", + "overrides": null + }, + "vizProp": { + "__typename": "HeadlineVizProps", + "columnProperty": null, + "headlineVizPropVersion": "V1" + } + }, + { + "__typename": "ChartViz", + "clientState": {}, + "columns": [ + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "legacyMetricDefinition": null + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "NONE", + "baseColumnType": "VIZ_SPECIFIC_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "MEASURE_NAMES", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "CHAR", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "dd8bb852-d70d-4269-9bae-11953323d7bd", + "isAdditive": false, + "isAggregateApplied": false, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Measure names", + "referencedColumns": [], + "referencedTables": [], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "ATTRIBUTE", + "uniqueValues": null + }, + "legacyMetricDefinition": null + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "NONE", + "baseColumnType": "VIZ_SPECIFIC_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "MEASURE_VALUES", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "55ea0d3d-84fa-4734-b929-5f9a39f2d35d", + "isAdditive": false, + "isAggregateApplied": false, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Measure values", + "referencedColumns": [], + "referencedTables": [], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": null + }, + "legacyMetricDefinition": null + } + ], + "config": { + "__typename": "ChartConfig", + "axisConfig": [ + { + "__typename": "AxisConfig", + "category": [], + "color": [], + "measureValues": [], + "size": null, + "sort": [], + "x": [], + "y": [ + { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + } + ] + } + ], + "chartType": "KPI", + "customChartConfig": null, + "customChartGuid": "", + "customChartManifest": null, + "isLocked": false + }, + "customVisualProps": {}, + "id": "60d9622c-6028-498c-8269-426d09cf6780", + "sortInfo": [], + "sortOrder": [], + "topInfo": [], + "visualOverrides": { + "__typename": "ChartVisualOverrides", + "defaults": null, + "overrides": null + }, + "vizProp": { + "__typename": "ChartVizProps", + "axisProperties": [ + { + "__typename": "AxisObj", + "id": "c6619d19-d1ff-4103-b9e1-c0f34920e5c6", + "properties": { + "__typename": "AxisProperties", + "axisType": "Y", + "customProps": null, + "dynamicTitle": null, + "format": null, + "isOpposite": false, + "linkedColumns": [ + "bac67a4f-2e89-456a-8b62-6df830ff4e1b" + ], + "name": null, + "yAxisRange": null + } + }, + { + "__typename": "AxisObj", + "id": "36440c20-e309-4ea4-a7f6-ef3ac3ce9937", + "properties": { + "__typename": "AxisProperties", + "axisType": "X", + "customProps": null, + "dynamicTitle": null, + "format": null, + "isOpposite": null, + "linkedColumns": [], + "name": null, + "yAxisRange": null + } + } + ], + "chartProperties": { + "__typename": "ChartProperties", + "allLabels": null, + "axisExtremes": null, + "chartSpecific": { + "__typename": "ChartSpecificProperties", + "customProps": null, + "dataFieldArea": null, + "hidePivotSummaries": null, + "isHeatmapOverlayed": null, + "isStackedAsPercent": null, + "markersEnabled": null, + "pivotState": null, + "pivotSummariesState": { + "__typename": "PivotSummariesState", + "showColumnGrandTotals": null, + "showColumnTotals": null, + "showRowGrandTotals": null, + "showRowTotals": null + }, + "showPivotSummaryPrior": null, + "stackedAsPercentFormat": null, + "summaryFormat": null, + "summaryMode": null, + "useFlatLayout": null + }, + "dataSize": null, + "gridLines": null, + "isZoomed": null, + "kpiDisplayProperties": { + "__typename": "KpiDisplayProperties", + "changeInterpretation": "UPWARD_IS_GOOD", + "kpiDisplayColorArray": [], + "showChange": true, + "showChangeAs": "PERCENT" + }, + "legendPosition": null, + "mapviewport": null, + "responsiveLayoutDisabled": null, + "responsiveLayoutPreference": null, + "showLegend": null, + "showLinearRegressionLine": null, + "showStackedLabels": null, + "visibleSeriesNames": [] + }, + "columnProperties": [ + { + "columnId": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + }, + { + "columnId": "dd8bb852-d70d-4269-9bae-11953323d7bd", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + }, + { + "columnId": "55ea0d3d-84fa-4734-b929-5f9a39f2d35d", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + } + ], + "customColorSelectorArray": [], + "multiColorSeriesColors": [], + "seriesColors": [], + "systemMultiColorSeriesColors": [], + "systemSeriesColors": [], + "tooltipConfig": null, + "version": "V4DOT2" + } + } + ], + "columns": [ + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "dataType": "DOUBLE", + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "displayName": "sales" + } + ], + "type": "MEASURE" + } + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "dataType": "CHAR", + "id": "dd8bb852-d70d-4269-9bae-11953323d7bd", + "name": "Measure names", + "referencedColumns": [], + "type": "ATTRIBUTE" + } + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "dataType": "DOUBLE", + "id": "55ea0d3d-84fa-4734-b929-5f9a39f2d35d", + "name": "Measure values", + "referencedColumns": [], + "type": "MEASURE" + } + } + ], + "config": { + "__typename": "ChartConfig", + "chartType": "KPI" + }, + "data": [ + { + "columnDataLite": [ + { + "columnDataType": "DOUBLE", + "columnId": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "dataValue": [ + 0 + ] + } + ], + "completionRatio": 1, + "queryPerfStats": { + "timeTakenCdw": [ + { + "queryName": "f3e44987-e43a-31b5-86bf-18efd9a417d1", + "queryTimeTaken": "391" + }, + { + "queryName": "0802bc97-9223-497c-9092-6ca75e4ed873", + "queryTimeTaken": "475" + } + ], + "timeTakenDatamanager": "488" + }, + "samplingRatio": 1, + "totalRowCount": "1" + } + ], + "user": { + "userName": "rani.gangwar@thoughtspot.com", + "userGUID": "0000083e-e253-10af-aa97-5e45d512ebbd", + "userEmail": "rani.gangwar@thoughtspot.com" + }, + "reportBookMetadata": { + "id": "44aadbc7-3b75-4897-9b2b-2a6ecad4fe31", + "description": "", + "metadata": { + "__typename": "AnswerMetadata", + "author": "", + "authorId": "0000083e-e253-10af-aa97-5e45d512ebbd", + "createdAt": null, + "generationNum": "-1", + "isDiscoverable": false, + "isHidden": false, + "modifiedAt": null, + "tags": [], + "type": "" + }, + "name": "Total sales", + "suggestedDisplayMode": "CHART_MODE", + "visualizations": [ + { + "__typename": "TableViz", + "clientState": {}, + "columns": [ + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "legacyMetricDefinition": null + } + ], + "id": "aeedf2f8-8f90-42c3-b681-eb96d97038a0", + "sortInfo": [], + "topInfo": [], + "visualOverrides": { + "__typename": "TableVisualOverrides", + "overrides": null + }, + "vizProp": { + "__typename": "TableVizProps", + "columnProperties": [], + "density": null, + "orderedColumnIds": [], + "showGridSummary": null, + "showTableFooter": null, + "tableVizPropVersion": "V1", + "theme": null, + "widthState": [], + "wrapTableHeader": null + } + }, + { + "__typename": "HeadlineViz", + "aggregationType": [ + "SUM" + ], + "headlineColumn": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "id": "d8164286-f1f9-450f-99cb-c5e8c260e1b2", + "possibleAggregations": [ + "SUM", + "AVERAGE", + "STD_DEVIATION", + "VARIANCE", + "MIN", + "MAX" + ], + "showPossibleAggregates": false, + "sortInfo": [], + "title": "Headline Total sales", + "visualOverrides": { + "__typename": "HeadlineVisualOverrides", + "overrides": null + }, + "vizProp": { + "__typename": "HeadlineVizProps", + "columnProperty": null, + "headlineVizPropVersion": "V1" + } + }, + { + "__typename": "ChartViz", + "clientState": {}, + "columns": [ + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "legacyMetricDefinition": null + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "NONE", + "baseColumnType": "VIZ_SPECIFIC_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "MEASURE_NAMES", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "CHAR", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "dd8bb852-d70d-4269-9bae-11953323d7bd", + "isAdditive": false, + "isAggregateApplied": false, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Measure names", + "referencedColumns": [], + "referencedTables": [], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "ATTRIBUTE", + "uniqueValues": null + }, + "legacyMetricDefinition": null + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "NONE", + "baseColumnType": "VIZ_SPECIFIC_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "MEASURE_VALUES", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "55ea0d3d-84fa-4734-b929-5f9a39f2d35d", + "isAdditive": false, + "isAggregateApplied": false, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Measure values", + "referencedColumns": [], + "referencedTables": [], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": null + }, + "legacyMetricDefinition": null + } + ], + "config": { + "__typename": "ChartConfig", + "axisConfig": [ + { + "__typename": "AxisConfig", + "category": [], + "color": [], + "measureValues": [], + "size": null, + "sort": [], + "x": [], + "y": [ + { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + } + ] + } + ], + "chartType": "KPI", + "customChartConfig": null, + "customChartGuid": "", + "customChartManifest": null, + "isLocked": false + }, + "customVisualProps": {}, + "id": "60d9622c-6028-498c-8269-426d09cf6780", + "sortInfo": [], + "sortOrder": [], + "suggestedConfig": [ + { + "__typename": "ChartConfig", + "axisConfig": [ + { + "__typename": "AxisConfig", + "category": [], + "color": [], + "measureValues": [], + "size": null, + "sort": [], + "x": [], + "y": [ + { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + } + ] + } + ], + "chartType": "KPI", + "customChartConfig": null, + "customChartGuid": "", + "customChartManifest": null, + "isLocked": false + } + ], + "topInfo": [], + "visualOverrides": { + "__typename": "ChartVisualOverrides", + "defaults": null, + "overrides": null + }, + "vizProp": { + "__typename": "ChartVizProps", + "axisProperties": [ + { + "__typename": "AxisObj", + "id": "c6619d19-d1ff-4103-b9e1-c0f34920e5c6", + "properties": { + "__typename": "AxisProperties", + "axisType": "Y", + "customProps": null, + "dynamicTitle": null, + "format": null, + "isOpposite": false, + "linkedColumns": [ + "bac67a4f-2e89-456a-8b62-6df830ff4e1b" + ], + "name": null, + "yAxisRange": null + } + }, + { + "__typename": "AxisObj", + "id": "36440c20-e309-4ea4-a7f6-ef3ac3ce9937", + "properties": { + "__typename": "AxisProperties", + "axisType": "X", + "customProps": null, + "dynamicTitle": null, + "format": null, + "isOpposite": null, + "linkedColumns": [], + "name": null, + "yAxisRange": null + } + } + ], + "chartProperties": { + "__typename": "ChartProperties", + "allLabels": null, + "axisExtremes": null, + "chartSpecific": { + "__typename": "ChartSpecificProperties", + "customProps": null, + "dataFieldArea": null, + "hidePivotSummaries": null, + "isHeatmapOverlayed": null, + "isStackedAsPercent": null, + "markersEnabled": null, + "pivotState": null, + "pivotSummariesState": { + "__typename": "PivotSummariesState", + "showColumnGrandTotals": null, + "showColumnTotals": null, + "showRowGrandTotals": null, + "showRowTotals": null + }, + "showPivotSummaryPrior": null, + "stackedAsPercentFormat": null, + "summaryFormat": null, + "summaryMode": null, + "useFlatLayout": null + }, + "dataSize": null, + "gridLines": null, + "isZoomed": null, + "kpiDisplayProperties": { + "__typename": "KpiDisplayProperties", + "changeInterpretation": "UPWARD_IS_GOOD", + "kpiDisplayColorArray": [], + "showChange": true, + "showChangeAs": "PERCENT" + }, + "legendPosition": null, + "mapviewport": null, + "responsiveLayoutDisabled": null, + "responsiveLayoutPreference": null, + "showLegend": null, + "showLinearRegressionLine": null, + "showStackedLabels": null, + "visibleSeriesNames": [] + }, + "columnProperties": [ + { + "columnId": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + }, + { + "columnId": "dd8bb852-d70d-4269-9bae-11953323d7bd", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + }, + { + "columnId": "55ea0d3d-84fa-4734-b929-5f9a39f2d35d", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + } + ], + "customColorSelectorArray": [], + "multiColorSeriesColors": [], + "seriesColors": [], + "systemMultiColorSeriesColors": [], + "systemSeriesColors": [], + "tooltipConfig": null, + "version": "V4DOT2" + } + } + ], + "headerMetadata": { + "id": "44aadbc7-3b75-4897-9b2b-2a6ecad4fe31", + "name": "Total sales", + "description": "", + "isNewAnswer": true, + "isHidden": false, + "displayMode": "CHART_MODE" + } + }, + "isAnswerUnsaved": { + "hasUnsavedChanges": false + } + }, + "operation": "GetChartWithData", + "session": { + "genNo": 2, + "sessionId": "4caa0015-b33e-4bb0-a193-b0cc99e79272", + "acSession": { + "sessionId": "1cb7a49a-704a-4d83-969e-56880708af25", + "genNo": 1 + } + }, + "query": "query GetChartWithData($session: BachSessionIdInput!, $batchSize: Int, $offset: Int! = 0, $deadline: Int!, $shouldFetchExtraColumnsData: Boolean, $singlePointKpi: SinglePointKpiParamsInput) {\n getAnswer(session: $session) {\n id {\n sessionId\n }\n answer {\n id\n queryableDataSource\n \n permission {\n ...permission\n }\n visualizations {\n id\n ... on ChartViz {\n data(\n deadline: $deadline\n pagination: {isClientPaginated: true, size: $batchSize, offset: $offset}\n shouldFetchExtraColumnsData: $shouldFetchExtraColumnsData\n singlePointKpi: $singlePointKpi\n )\n ...chartVizWithoutSuggestedConfig\n }\n }\n }\n }\n}\n\nfragment permission on ObjectPermission {\n objectAccessLevel\n dataSourceAccessLevel\n dataSourceNamesWithNoAccess\n}\n\nfragment chartVizWithoutSuggestedConfig on ChartViz {\n id\n sortOrder {\n columnId\n order\n isUserSorted\n sortAscending\n }\n columns {\n ...vizColumn\n }\n clientState\n customVisualProps\n vizProp {\n ...chartVizProps\n }\n config {\n ...chartConfig\n }\n sortInfo {\n columnId\n sortAscending\n category\n customOrder\n }\n topInfo {\n columnId\n sortAscending\n }\n visualOverrides {\n ...chartVisualOverrides\n }\n}\n\nfragment vizColumn on VizColumn {\n column {\n ...answerColumn\n }\n legacyMetricDefinition {\n row {\n color\n plotAsBand\n range {\n max\n min\n }\n }\n }\n}\n\nfragment answerColumn on AnswerColumn {\n id\n name\n type\n baseColumnType\n chartSpecificColumnType\n formulaId\n columnProps {\n version\n columnProperties {\n format {\n ...formatConfig\n }\n sortConfig\n }\n }\n dataType\n isAggregateApplied\n aggregationType\n formatPattern\n isGroupBy\n isUserDefinedTitle\n isAdditive\n showGrowth\n customCalendarType\n formatType\n calendarGuid\n format {\n pattern\n currencyFormat {\n column\n type\n isoCode\n }\n }\n referencedColumns {\n guid\n displayName\n description\n }\n referencedTables {\n guid\n displayName\n description\n }\n legacySheetProperties\n legacyColumnFormatProperties\n timeBucket\n geoConfig {\n type\n fixedValue\n columnGuid\n customFileGuid\n geometryType\n parent {\n type\n fixedValue\n columnGuid\n customFileGuid\n geometryType\n }\n }\n customOrder\n uniqueValues\n isMandatory\n isStrictDateColumn\n isTimeBucketRestricted\n dynamicTitle\n}\n\nfragment formatConfig on FormatConfig {\n category\n numberFormatConfig {\n decimals\n negativeValueFormat\n removeTrailingZeroes\n toSeparateThousands\n unit\n }\n percentageFormatConfig {\n decimals\n removeTrailingZeroes\n }\n currencyFormatConfig {\n decimals\n locale\n removeTrailingZeroes\n toSeparateThousands\n unit\n }\n customFormatConfig {\n format\n }\n isCategoryEditable\n}\n\nfragment chartVizProps on ChartVizProps {\n version\n axisProperties {\n id\n properties {\n axisType\n format {\n ...formatConfig\n }\n isOpposite\n customProps\n linkedColumns\n dynamicTitle\n name\n yAxisRange {\n max\n min\n }\n }\n }\n chartProperties {\n allLabels\n axisExtremes {\n x {\n max\n min\n }\n y {\n max\n min\n }\n }\n chartSpecific {\n customProps\n pivotState {\n columnExpandedPaths {\n paths\n }\n rowExpandedPaths {\n paths\n }\n fields {\n dataField\n sortBy\n sortBySummaryField\n sortBySummaryPath\n sortOrder\n expanded\n area\n }\n }\n useFlatLayout\n dataFieldArea\n hidePivotSummaries\n showPivotSummaryPrior\n pivotSummariesState {\n ...pivotSummariesState\n }\n isHeatmapOverlayed\n isStackedAsPercent\n markersEnabled\n stackedAsPercentFormat {\n ...formatConfig\n }\n summaryFormat {\n ...formatConfig\n }\n summaryMode\n }\n dataSize\n gridLines {\n xGridlineEnabled\n yGridlineEnabled\n }\n isZoomed\n mapviewport {\n center\n zoomLevel\n extent\n }\n responsiveLayoutDisabled\n responsiveLayoutPreference\n showLinearRegressionLine\n showStackedLabels\n visibleSeriesNames\n showLegend\n legendPosition\n kpiDisplayProperties {\n showChange\n showChangeAs\n changeInterpretation\n kpiDisplayColorArray\n }\n }\n columnProperties {\n columnId\n columnProperty {\n dataLabels\n conditionalFormatting {\n ...conditionalFormatting\n }\n handleMissingValues\n excludeNullValues\n customProps\n kpiColumnProperties {\n showAbbreviatedPreviousDate\n abbreviatedPreviousDate\n showSparkline\n showComparisonDate\n showCurrentDateLabel\n showPreviousDateLabel\n showPreviousValue\n handleNullData\n }\n }\n }\n customColorSelectorArray\n seriesColors {\n color\n serieName\n }\n multiColorSeriesColors {\n serieName\n colorMap {\n serieName\n color\n }\n }\n systemSeriesColors {\n color\n serieName\n }\n systemMultiColorSeriesColors {\n serieName\n colorMap {\n serieName\n color\n }\n }\n tooltipConfig {\n columnIds\n }\n}\n\nfragment pivotSummariesState on PivotSummariesState {\n showRowTotals\n showColumnTotals\n showRowGrandTotals\n showColumnGrandTotals\n}\n\nfragment conditionalFormatting on ConditionalFormatting {\n rows {\n comparisonType\n lhsColumnId\n rhsColumnId\n comparisonParameterId\n isHighlightRow\n backgroundFormatType\n value\n operator\n fontProperties {\n bold\n color\n italic\n strikeThrough\n underline\n }\n gradientBackgroundAttrs {\n isAutoScaled\n backgroundFormatRange\n backgroundFormatMidpoint\n colors\n }\n plotAsBand\n rangeValues {\n max\n min\n }\n solidBackgroundAttrs {\n color\n }\n }\n}\n\nfragment chartConfig on ChartConfig {\n chartType\n isLocked\n customChartGuid\n customChartManifest {\n ...customChartManifest\n }\n customChartConfig {\n ...customChartConfig\n }\n axisConfig {\n x {\n ...answerColumn\n }\n y {\n ...answerColumn\n }\n color {\n ...answerColumn\n }\n size {\n ...answerColumn\n }\n category {\n ...answerColumn\n }\n sort {\n ...answerColumn\n }\n measureValues {\n ...answerColumn\n }\n }\n}\n\nfragment customChartManifest on CustomChartManifest {\n id\n name\n description\n sourceUrl\n chartAppAccessToken\n iconUrl\n}\n\nfragment customChartConfig on CustomChartConfig {\n key\n dimensions {\n ...columnDrivenChartConfigDimension\n ...axisDrivenChartConfigDimension\n }\n}\n\nfragment columnDrivenChartConfigDimension on ColumnDrivenChartConfigDimension {\n key\n columns\n}\n\nfragment axisDrivenChartConfigDimension on AxisDrivenChartConfigDimension {\n key\n axes {\n ...flatAxis\n ...mergedAxis\n ...dualAxis\n }\n}\n\nfragment flatAxis on FlatAxis {\n column\n}\n\nfragment mergedAxis on MergedAxis {\n columns\n}\n\nfragment dualAxis on DualAxis {\n primary {\n ...flatAxis\n ...mergedAxis\n }\n secondary {\n ...flatAxis\n ...mergedAxis\n }\n}\n\nfragment chartVisualOverrides on ChartVisualOverrides {\n defaults {\n colorPalette {\n colors\n }\n }\n overrides {\n legendProperties {\n showLegend\n position\n }\n dataLabelProperties {\n allLabels\n stackLabelsProperties {\n isVisible\n }\n columnDataLabelProperties {\n columnId\n properties {\n isVisible\n filter {\n value\n operator\n }\n }\n }\n }\n axisProperties {\n linkedColumns\n properties {\n isNameVisible\n isLabelVisible\n yAxisRange {\n max\n min\n }\n }\n }\n displayProperties {\n summariesState {\n ...summariesState\n }\n regressionLineProperties {\n enabled\n }\n gridLineProperties {\n xGridlineEnabled\n yGridlineEnabled\n }\n }\n columnProperties {\n columnId\n properties {\n color\n conditionalFormatting {\n ...conditionalFormatting\n }\n }\n }\n }\n}\n\nfragment summariesState on SummariesState {\n showRowTotals\n showColumnTotals\n showRowGrandTotals\n showColumnGrandTotals\n}", + "convId": "RCDc8oDF94ri", + "messageId": "_0vAOWsBMY7g", + "callId": "GGiI0gYm4Ij2" + }, + "status": "end", + "answerService": { + "session": { + "genNo": 2, + "sessionId": "4caa0015-b33e-4bb0-a193-b0cc99e79272", + "acSession": { + "sessionId": "1cb7a49a-704a-4d83-969e-56880708af25", + "genNo": 1 + } + }, + "thoughtSpotHost": "", + "tmlOverride": {}, + "answer": { + "__typename": "ChartViz", + "clientState": {}, + "cohorts": [], + "description": "", + "displayDescription": "", + "displayMode": "CHART_MODE", + "displayName": "", + "dynamicDescription": "", + "dynamicName": "", + "filterGroups": [ + { + "__typename": "FilterGroup", + "columnInfo": { + "__typename": "FilterColumn", + "aggregationType": "NONE", + "calendarGuid": "", + "dataType": "CHAR", + "description": null, + "formulaId": "", + "isAggregateApplied": false, + "isMasked": null, + "isStrictDateColumn": false, + "name": "product", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "displayName": "product", + "guid": "085f9694-0d02-479e-973a-d216336e5253" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "timeBucket": "NO_BUCKET", + "type": "ATTRIBUTE" + }, + "displayName": null, + "filters": [ + { + "__typename": "Filter", + "dateFilterContent": [], + "filterContent": [ + { + "__typename": "FilterContent", + "filterType": "EQ", + "negate": false, + "value": [ + { + "__typename": "FilterContentValue", + "key": "f2 jackets" + } + ] + } + ], + "filterId": "7d0a505f-8289-5c79-b7f0-bc2f118d90d0" + } + ], + "groupId": { + "__typename": "FilterGroupId", + "answerColumnId": "bba4be57-6156-48a3-9e69-a2775237772a", + "dataSourceId": null, + "logicalColumnId": null + }, + "isEditable": true, + "isMandatory": null, + "isSingleValue": null, + "sourceContainerId": null + }, + { + "__typename": "FilterGroup", + "columnInfo": { + "__typename": "FilterColumn", + "aggregationType": "NONE", + "calendarGuid": "", + "dataType": "CHAR", + "description": null, + "formulaId": "", + "isAggregateApplied": false, + "isMasked": null, + "isStrictDateColumn": false, + "name": "zip code", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "displayName": "zip code", + "guid": "6f09ed23-a8d8-4017-8887-e3fd983cc58c" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "timeBucket": "NO_BUCKET", + "type": "ATTRIBUTE" + }, + "displayName": null, + "filters": [ + { + "__typename": "Filter", + "dateFilterContent": [], + "filterContent": [ + { + "__typename": "FilterContent", + "filterType": "EQ", + "negate": false, + "value": [ + { + "__typename": "FilterContentValue", + "key": "63144" + } + ] + } + ], + "filterId": "e1581fc4-3ea1-5d8a-8b47-679d9559dda8" + } + ], + "groupId": { + "__typename": "FilterGroupId", + "answerColumnId": "b870f86f-8947-450d-b4e9-56bc9d2562a6", + "dataSourceId": null, + "logicalColumnId": null + }, + "isEditable": true, + "isMandatory": null, + "isSingleValue": null, + "sourceContainerId": null + }, + { + "__typename": "FilterGroup", + "columnInfo": { + "__typename": "FilterColumn", + "aggregationType": "NONE", + "calendarGuid": "bfa39848-ba4f-46d8-80fd-b695064e61b7", + "dataType": "DATE", + "description": null, + "formulaId": "", + "isAggregateApplied": false, + "isMasked": null, + "isStrictDateColumn": false, + "name": "date", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "displayName": "date", + "guid": "a0314a96-e56c-4dc2-af0d-ee14a444e4fe" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "timeBucket": "NO_BUCKET", + "type": "ATTRIBUTE" + }, + "displayName": null, + "filters": [ + { + "__typename": "Filter", + "dateFilterContent": [ + { + "__typename": "DateFilterContent", + "dateFilter": { + "__typename": "DateFilterValue", + "datePeriod": "DAY", + "dateRange": { + "__typename": "FilterDateRange", + "highEpoch": "1773792000", + "lowEpoch": "1773705600" + }, + "epoch": null, + "forEachPeriod": "NUM_DATE_PERIODS", + "hasUnprocessedTemporalValues": false, + "includeCurrentPeriod": false, + "monthName": "", + "number": 0, + "op": "EQ", + "quarterName": "", + "type": "YESTERDAY", + "weekDayName": "", + "yearName": "" + }, + "negate": false + } + ], + "filterContent": [ + { + "__typename": "FilterContent", + "filterType": "BW_INC_MIN", + "negate": false, + "value": [ + { + "__typename": "FilterContentValue", + "key": "1773705600" + }, + { + "__typename": "FilterContentValue", + "key": "1773792000" + } + ] + } + ], + "filterId": "0a32e1f0-7a0a-5785-8c6c-13bb5dfa6a28" + } + ], + "groupId": { + "__typename": "FilterGroupId", + "answerColumnId": "21ee5724-10b2-41ee-8008-a6cc1129959b", + "dataSourceId": null, + "logicalColumnId": null + }, + "isEditable": true, + "isMandatory": null, + "isSingleValue": null, + "sourceContainerId": null + } + ], + "formulas": [], + "hashKey": "", + "headlineVisibilityMap": [ + { + "__typename": "HeadlineVisibility", + "columnId": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isVisible": true + } + ], + "id": "60d9622c-6028-498c-8269-426d09cf6780", + "inScopeParameters": [], + "incompeleteAnswerDetails": { + "__typename": "IncompeleteAnswerDetails", + "brokenTokenDetails": null + }, + "metadata": { + "__typename": "AnswerMetadata", + "author": "", + "authorId": "0000083e-e253-10af-aa97-5e45d512ebbd", + "createdAt": null, + "generationNum": "-1", + "isDiscoverable": false, + "isHidden": false, + "modifiedAt": null, + "tags": [], + "type": "" + }, + "name": "Total sales", + "orderedChips": [ + { + "__typename": "Chip", + "objectId": "b870f86f-8947-450d-b4e9-56bc9d2562a6", + "type": "FILTER" + }, + { + "__typename": "Chip", + "objectId": "21ee5724-10b2-41ee-8008-a6cc1129959b", + "type": "FILTER" + }, + { + "__typename": "Chip", + "objectId": "bba4be57-6156-48a3-9e69-a2775237772a", + "type": "FILTER" + } + ], + "parameters": [], + "pathAnalysisConfig": null, + "permission": { + "__typename": "ObjectPermission", + "dataSourceAccessLevel": "READ_ONLY", + "dataSourceNamesWithNoAccess": [], + "objectAccessLevel": "MODIFY" + }, + "phrases": [ + { + "__typename": "SagePhrase", + "isAmbiguous": false, + "isComplete": true, + "tokens": [ + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1", + "name": "sales" + }, + "dataType": "DOUBLE", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "sales", + "typeEnum": "MEASURE", + "dataType": "DOUBLE", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1", + "outputGuid": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "sales", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "hasSpaceAfter": true, + "canonicalForm": "sales", + "idxInPrevQuery": 0, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "sales", + "trailingWhitespace": " ", + "type": "MEASURE" + } + ], + "type": "AGGREGATED_COLUMN_PHRASE" + }, + { + "__typename": "SagePhrase", + "isAmbiguous": false, + "isComplete": true, + "tokens": [ + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "085f9694-0d02-479e-973a-d216336e5253", + "name": "product" + }, + "dataType": "CHAR", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "product", + "typeEnum": "ATTRIBUTE", + "dataType": "CHAR", + "guid": "085f9694-0d02-479e-973a-d216336e5253", + "outputGuid": "bba4be57-6156-48a3-9e69-a2775237772a", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "product", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "hasSpaceAfter": true, + "canonicalForm": "product", + "idxInPrevQuery": 1, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "product", + "trailingWhitespace": " ", + "type": "ATTRIBUTE" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "", + "name": null + }, + "dataType": "UNKNOWN", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "=", + "typeEnum": "OPERATOR", + "hasSpaceAfter": true, + "canonicalForm": "=", + "idxInPrevQuery": 2, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": null, + "name": null + }, + "text": "=", + "trailingWhitespace": " ", + "type": "OPERATOR" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "085f9694-0d02-479e-973a-d216336e5253", + "name": "product" + }, + "dataType": "CHAR", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "'f2 jackets'", + "typeEnum": "VALUE", + "dataType": "CHAR", + "matchType": "EXACT", + "guid": "085f9694-0d02-479e-973a-d216336e5253", + "outputGuid": "bba4be57-6156-48a3-9e69-a2775237772a", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "product", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "valueMatch": true, + "requiresDelimiters": true, + "hasSpaceAfter": true, + "canonicalForm": "'f2 jackets'", + "idxInPrevQuery": 3, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + }, + "isCohort": false + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "'f2 jackets'", + "trailingWhitespace": " ", + "type": "VALUE" + } + ], + "type": "FILTER_PHRASE" + }, + { + "__typename": "SagePhrase", + "isAmbiguous": false, + "isComplete": true, + "tokens": [ + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "6f09ed23-a8d8-4017-8887-e3fd983cc58c", + "name": "zip code" + }, + "dataType": "CHAR", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "zip code", + "typeEnum": "ATTRIBUTE", + "dataType": "CHAR", + "guid": "6f09ed23-a8d8-4017-8887-e3fd983cc58c", + "outputGuid": "b870f86f-8947-450d-b4e9-56bc9d2562a6", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "zip code", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "hasSpaceAfter": true, + "canonicalForm": "zip code", + "idxInPrevQuery": 4, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "zip code", + "trailingWhitespace": " ", + "type": "ATTRIBUTE" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "", + "name": null + }, + "dataType": "UNKNOWN", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "=", + "typeEnum": "OPERATOR", + "hasSpaceAfter": true, + "canonicalForm": "=", + "idxInPrevQuery": 5, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": null, + "name": null + }, + "text": "=", + "trailingWhitespace": " ", + "type": "OPERATOR" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "6f09ed23-a8d8-4017-8887-e3fd983cc58c", + "name": "zip code" + }, + "dataType": "CHAR", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "'63144'", + "typeEnum": "VALUE", + "dataType": "CHAR", + "matchType": "EXACT", + "guid": "6f09ed23-a8d8-4017-8887-e3fd983cc58c", + "outputGuid": "b870f86f-8947-450d-b4e9-56bc9d2562a6", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "zip code", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "valueMatch": true, + "requiresDelimiters": true, + "hasSpaceAfter": true, + "canonicalForm": "'63144'", + "idxInPrevQuery": 6, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + }, + "isCohort": false + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "'63144'", + "trailingWhitespace": " ", + "type": "VALUE" + } + ], + "type": "FILTER_PHRASE" + }, + { + "__typename": "SagePhrase", + "isAmbiguous": false, + "isComplete": true, + "tokens": [ + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "a0314a96-e56c-4dc2-af0d-ee14a444e4fe", + "name": "date" + }, + "dataType": "DATE", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "date", + "typeEnum": "ATTRIBUTE", + "dataType": "DATE", + "guid": "a0314a96-e56c-4dc2-af0d-ee14a444e4fe", + "outputGuid": "21ee5724-10b2-41ee-8008-a6cc1129959b", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "date", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "hasSpaceAfter": true, + "canonicalForm": "date", + "idxInPrevQuery": 7, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "date", + "trailingWhitespace": " ", + "type": "ATTRIBUTE" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "", + "name": null + }, + "dataType": "UNKNOWN", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "=", + "typeEnum": "OPERATOR", + "hasSpaceAfter": true, + "canonicalForm": "=", + "idxInPrevQuery": 8, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + } + }, + "source": { + "__typename": "SourceInfo", + "id": null, + "name": null + }, + "text": "=", + "trailingWhitespace": " ", + "type": "OPERATOR" + }, + { + "__typename": "SageToken", + "column": { + "__typename": "ColumnInfo", + "columnGuid": "a0314a96-e56c-4dc2-af0d-ee14a444e4fe", + "name": "date" + }, + "dataType": "DATE", + "hasSpaceAfter": true, + "isExtensible": false, + "isFromCohort": false, + "isFromFormula": false, + "recognizedTokenJson": { + "token": "yesterday", + "typeEnum": "VALUE", + "dataType": "DATE", + "matchType": "EXACT", + "guid": "a0314a96-e56c-4dc2-af0d-ee14a444e4fe", + "outputGuid": "21ee5724-10b2-41ee-8008-a6cc1129959b", + "joinPath": [ + { + "rootTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "leafTable": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + } + ], + "tokenMetadata": { + "name": "date", + "table": { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "rootTables": [ + { + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + } + ], + "isFormula": false + }, + "valueMatch": false, + "hasSpaceAfter": true, + "canBeExtended": false, + "dateFilter": { + "type": "YESTERDAY", + "op": "EQ" + }, + "canonicalForm": "yesterday", + "idxInPrevQuery": 9, + "whiteSpaceSuffix": { + "type": "SINGLE_SPACE" + }, + "isCohort": false + }, + "source": { + "__typename": "SourceInfo", + "id": "cd252e5c-b552-49a8-821d-3eadaa049cca", + "name": "(Sample) Retail - Apparel" + }, + "text": "yesterday", + "trailingWhitespace": " ", + "type": "VALUE" + } + ], + "type": "FILTER_PHRASE" + } + ], + "phrasesTimestamp": "1773817179992", + "queryableDataSource": "RDBMS_SNOWFLAKE", + "selectedColumns": [ + { + "__typename": "SelectedColumn", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "selectedFormulas": [], + "sortInfo": [], + "sources": [ + { + "__typename": "Source", + "author": { + "__typename": "EntityHeader", + "displayName": "System User", + "guid": "67e15c06-d153-4924-a4cd-ff615393b60f" + }, + "header": { + "__typename": "EntityHeader", + "description": null, + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + }, + "isAccessible": true, + "schema": { + "__typename": "EntityHeader", + "description": null, + "displayName": null, + "guid": null + } + } + ], + "suggestedDisplayMode": "CHART_MODE", + "visualizations": [ + { + "__typename": "TableViz", + "clientState": {}, + "columns": [ + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "legacyMetricDefinition": null + } + ], + "id": "aeedf2f8-8f90-42c3-b681-eb96d97038a0", + "sortInfo": [], + "topInfo": [], + "visualOverrides": { + "__typename": "TableVisualOverrides", + "overrides": null + }, + "vizProp": { + "__typename": "TableVizProps", + "columnProperties": [], + "density": null, + "orderedColumnIds": [], + "showGridSummary": null, + "showTableFooter": null, + "tableVizPropVersion": "V1", + "theme": null, + "widthState": [], + "wrapTableHeader": null + } + }, + { + "__typename": "HeadlineViz", + "aggregationType": [ + "SUM" + ], + "headlineColumn": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "id": "d8164286-f1f9-450f-99cb-c5e8c260e1b2", + "possibleAggregations": [ + "SUM", + "AVERAGE", + "STD_DEVIATION", + "VARIANCE", + "MIN", + "MAX" + ], + "showPossibleAggregates": false, + "sortInfo": [], + "title": "Headline Total sales", + "visualOverrides": { + "__typename": "HeadlineVisualOverrides", + "overrides": null + }, + "vizProp": { + "__typename": "HeadlineVizProps", + "columnProperty": null, + "headlineVizPropVersion": "V1" + } + }, + { + "__typename": "ChartViz", + "clientState": {}, + "columns": [ + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "legacyMetricDefinition": null + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "NONE", + "baseColumnType": "VIZ_SPECIFIC_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "MEASURE_NAMES", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "CHAR", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "dd8bb852-d70d-4269-9bae-11953323d7bd", + "isAdditive": false, + "isAggregateApplied": false, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Measure names", + "referencedColumns": [], + "referencedTables": [], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "ATTRIBUTE", + "uniqueValues": null + }, + "legacyMetricDefinition": null + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "NONE", + "baseColumnType": "VIZ_SPECIFIC_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "MEASURE_VALUES", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "55ea0d3d-84fa-4734-b929-5f9a39f2d35d", + "isAdditive": false, + "isAggregateApplied": false, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Measure values", + "referencedColumns": [], + "referencedTables": [], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": null + }, + "legacyMetricDefinition": null + } + ], + "config": { + "__typename": "ChartConfig", + "axisConfig": [ + { + "__typename": "AxisConfig", + "category": [], + "color": [], + "measureValues": [], + "size": null, + "sort": [], + "x": [], + "y": [ + { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + } + ] + } + ], + "chartType": "KPI", + "customChartConfig": null, + "customChartGuid": "", + "customChartManifest": null, + "isLocked": false + }, + "customVisualProps": {}, + "id": "60d9622c-6028-498c-8269-426d09cf6780", + "sortInfo": [], + "sortOrder": [], + "topInfo": [], + "visualOverrides": { + "__typename": "ChartVisualOverrides", + "defaults": null, + "overrides": null + }, + "vizProp": { + "__typename": "ChartVizProps", + "axisProperties": [ + { + "__typename": "AxisObj", + "id": "c6619d19-d1ff-4103-b9e1-c0f34920e5c6", + "properties": { + "__typename": "AxisProperties", + "axisType": "Y", + "customProps": null, + "dynamicTitle": null, + "format": null, + "isOpposite": false, + "linkedColumns": [ + "bac67a4f-2e89-456a-8b62-6df830ff4e1b" + ], + "name": null, + "yAxisRange": null + } + }, + { + "__typename": "AxisObj", + "id": "36440c20-e309-4ea4-a7f6-ef3ac3ce9937", + "properties": { + "__typename": "AxisProperties", + "axisType": "X", + "customProps": null, + "dynamicTitle": null, + "format": null, + "isOpposite": null, + "linkedColumns": [], + "name": null, + "yAxisRange": null + } + } + ], + "chartProperties": { + "__typename": "ChartProperties", + "allLabels": null, + "axisExtremes": null, + "chartSpecific": { + "__typename": "ChartSpecificProperties", + "customProps": null, + "dataFieldArea": null, + "hidePivotSummaries": null, + "isHeatmapOverlayed": null, + "isStackedAsPercent": null, + "markersEnabled": null, + "pivotState": null, + "pivotSummariesState": { + "__typename": "PivotSummariesState", + "showColumnGrandTotals": null, + "showColumnTotals": null, + "showRowGrandTotals": null, + "showRowTotals": null + }, + "showPivotSummaryPrior": null, + "stackedAsPercentFormat": null, + "summaryFormat": null, + "summaryMode": null, + "useFlatLayout": null + }, + "dataSize": null, + "gridLines": null, + "isZoomed": null, + "kpiDisplayProperties": { + "__typename": "KpiDisplayProperties", + "changeInterpretation": "UPWARD_IS_GOOD", + "kpiDisplayColorArray": [], + "showChange": true, + "showChangeAs": "PERCENT" + }, + "legendPosition": null, + "mapviewport": null, + "responsiveLayoutDisabled": null, + "responsiveLayoutPreference": null, + "showLegend": null, + "showLinearRegressionLine": null, + "showStackedLabels": null, + "visibleSeriesNames": [] + }, + "columnProperties": [ + { + "columnId": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + }, + { + "columnId": "dd8bb852-d70d-4269-9bae-11953323d7bd", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + }, + { + "columnId": "55ea0d3d-84fa-4734-b929-5f9a39f2d35d", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + } + ], + "customColorSelectorArray": [], + "multiColorSeriesColors": [], + "seriesColors": [], + "systemMultiColorSeriesColors": [], + "systemSeriesColors": [], + "tooltipConfig": null, + "version": "V4DOT2" + } + } + ], + "columns": [ + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "dataType": "DOUBLE", + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "displayName": "sales" + } + ], + "type": "MEASURE" + } + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "dataType": "CHAR", + "id": "dd8bb852-d70d-4269-9bae-11953323d7bd", + "name": "Measure names", + "referencedColumns": [], + "type": "ATTRIBUTE" + } + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "dataType": "DOUBLE", + "id": "55ea0d3d-84fa-4734-b929-5f9a39f2d35d", + "name": "Measure values", + "referencedColumns": [], + "type": "MEASURE" + } + } + ], + "config": { + "__typename": "ChartConfig", + "chartType": "KPI" + }, + "data": [ + { + "columnDataLite": [ + { + "columnDataType": "DOUBLE", + "columnId": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "dataValue": [ + 0 + ] + } + ], + "completionRatio": 1, + "queryPerfStats": { + "timeTakenCdw": [ + { + "queryName": "f3e44987-e43a-31b5-86bf-18efd9a417d1", + "queryTimeTaken": "391" + }, + { + "queryName": "0802bc97-9223-497c-9092-6ca75e4ed873", + "queryTimeTaken": "475" + } + ], + "timeTakenDatamanager": "488" + }, + "samplingRatio": 1, + "totalRowCount": "1" + } + ], + "user": { + "userName": "rani.gangwar@thoughtspot.com", + "userGUID": "0000083e-e253-10af-aa97-5e45d512ebbd", + "userEmail": "rani.gangwar@thoughtspot.com" + }, + "reportBookMetadata": { + "id": "44aadbc7-3b75-4897-9b2b-2a6ecad4fe31", + "description": "", + "metadata": { + "__typename": "AnswerMetadata", + "author": "", + "authorId": "0000083e-e253-10af-aa97-5e45d512ebbd", + "createdAt": null, + "generationNum": "-1", + "isDiscoverable": false, + "isHidden": false, + "modifiedAt": null, + "tags": [], + "type": "" + }, + "name": "Total sales", + "suggestedDisplayMode": "CHART_MODE", + "visualizations": [ + { + "__typename": "TableViz", + "clientState": {}, + "columns": [ + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "legacyMetricDefinition": null + } + ], + "id": "aeedf2f8-8f90-42c3-b681-eb96d97038a0", + "sortInfo": [], + "topInfo": [], + "visualOverrides": { + "__typename": "TableVisualOverrides", + "overrides": null + }, + "vizProp": { + "__typename": "TableVizProps", + "columnProperties": [], + "density": null, + "orderedColumnIds": [], + "showGridSummary": null, + "showTableFooter": null, + "tableVizPropVersion": "V1", + "theme": null, + "widthState": [], + "wrapTableHeader": null + } + }, + { + "__typename": "HeadlineViz", + "aggregationType": [ + "SUM" + ], + "headlineColumn": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "id": "d8164286-f1f9-450f-99cb-c5e8c260e1b2", + "possibleAggregations": [ + "SUM", + "AVERAGE", + "STD_DEVIATION", + "VARIANCE", + "MIN", + "MAX" + ], + "showPossibleAggregates": false, + "sortInfo": [], + "title": "Headline Total sales", + "visualOverrides": { + "__typename": "HeadlineVisualOverrides", + "overrides": null + }, + "vizProp": { + "__typename": "HeadlineVizProps", + "columnProperty": null, + "headlineVizPropVersion": "V1" + } + }, + { + "__typename": "ChartViz", + "clientState": {}, + "columns": [ + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + }, + "legacyMetricDefinition": null + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "NONE", + "baseColumnType": "VIZ_SPECIFIC_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "MEASURE_NAMES", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "CHAR", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "dd8bb852-d70d-4269-9bae-11953323d7bd", + "isAdditive": false, + "isAggregateApplied": false, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Measure names", + "referencedColumns": [], + "referencedTables": [], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "ATTRIBUTE", + "uniqueValues": null + }, + "legacyMetricDefinition": null + }, + { + "__typename": "VizColumn", + "column": { + "__typename": "AnswerColumn", + "aggregationType": "NONE", + "baseColumnType": "VIZ_SPECIFIC_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "MEASURE_VALUES", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "55ea0d3d-84fa-4734-b929-5f9a39f2d35d", + "isAdditive": false, + "isAggregateApplied": false, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Measure values", + "referencedColumns": [], + "referencedTables": [], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": null + }, + "legacyMetricDefinition": null + } + ], + "config": { + "__typename": "ChartConfig", + "axisConfig": [ + { + "__typename": "AxisConfig", + "category": [], + "color": [], + "measureValues": [], + "size": null, + "sort": [], + "x": [], + "y": [ + { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + } + ] + } + ], + "chartType": "KPI", + "customChartConfig": null, + "customChartGuid": "", + "customChartManifest": null, + "isLocked": false + }, + "customVisualProps": {}, + "id": "60d9622c-6028-498c-8269-426d09cf6780", + "sortInfo": [], + "sortOrder": [], + "suggestedConfig": [ + { + "__typename": "ChartConfig", + "axisConfig": [ + { + "__typename": "AxisConfig", + "category": [], + "color": [], + "measureValues": [], + "size": null, + "sort": [], + "x": [], + "y": [ + { + "__typename": "AnswerColumn", + "aggregationType": "SUM", + "baseColumnType": "SAGE_COLUMN", + "calendarGuid": "", + "chartSpecificColumnType": "UNDEFINED", + "columnProps": { + "__typename": "AnswerColumnProps", + "columnProperties": null, + "version": "V1" + }, + "customCalendarType": null, + "customOrder": [], + "dataType": "DOUBLE", + "dynamicTitle": "", + "format": null, + "formatPattern": null, + "formatType": null, + "formulaId": "", + "geoConfig": null, + "id": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "isAdditive": true, + "isAggregateApplied": true, + "isGroupBy": false, + "isMandatory": false, + "isStrictDateColumn": false, + "isTimeBucketRestricted": false, + "isUserDefinedTitle": false, + "legacyColumnFormatProperties": null, + "legacySheetProperties": null, + "name": "Total sales", + "referencedColumns": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "sales", + "guid": "de1b3cfd-1725-400a-b6c7-0cd0f2b70bf1" + } + ], + "referencedTables": [ + { + "__typename": "EntityHeader", + "description": "", + "displayName": "(Sample) Retail - Apparel", + "guid": "cd252e5c-b552-49a8-821d-3eadaa049cca" + } + ], + "showGrowth": false, + "timeBucket": "NO_BUCKET", + "type": "MEASURE", + "uniqueValues": "-1" + } + ] + } + ], + "chartType": "KPI", + "customChartConfig": null, + "customChartGuid": "", + "customChartManifest": null, + "isLocked": false + } + ], + "topInfo": [], + "visualOverrides": { + "__typename": "ChartVisualOverrides", + "defaults": null, + "overrides": null + }, + "vizProp": { + "__typename": "ChartVizProps", + "axisProperties": [ + { + "__typename": "AxisObj", + "id": "c6619d19-d1ff-4103-b9e1-c0f34920e5c6", + "properties": { + "__typename": "AxisProperties", + "axisType": "Y", + "customProps": null, + "dynamicTitle": null, + "format": null, + "isOpposite": false, + "linkedColumns": [ + "bac67a4f-2e89-456a-8b62-6df830ff4e1b" + ], + "name": null, + "yAxisRange": null + } + }, + { + "__typename": "AxisObj", + "id": "36440c20-e309-4ea4-a7f6-ef3ac3ce9937", + "properties": { + "__typename": "AxisProperties", + "axisType": "X", + "customProps": null, + "dynamicTitle": null, + "format": null, + "isOpposite": null, + "linkedColumns": [], + "name": null, + "yAxisRange": null + } + } + ], + "chartProperties": { + "__typename": "ChartProperties", + "allLabels": null, + "axisExtremes": null, + "chartSpecific": { + "__typename": "ChartSpecificProperties", + "customProps": null, + "dataFieldArea": null, + "hidePivotSummaries": null, + "isHeatmapOverlayed": null, + "isStackedAsPercent": null, + "markersEnabled": null, + "pivotState": null, + "pivotSummariesState": { + "__typename": "PivotSummariesState", + "showColumnGrandTotals": null, + "showColumnTotals": null, + "showRowGrandTotals": null, + "showRowTotals": null + }, + "showPivotSummaryPrior": null, + "stackedAsPercentFormat": null, + "summaryFormat": null, + "summaryMode": null, + "useFlatLayout": null + }, + "dataSize": null, + "gridLines": null, + "isZoomed": null, + "kpiDisplayProperties": { + "__typename": "KpiDisplayProperties", + "changeInterpretation": "UPWARD_IS_GOOD", + "kpiDisplayColorArray": [], + "showChange": true, + "showChangeAs": "PERCENT" + }, + "legendPosition": null, + "mapviewport": null, + "responsiveLayoutDisabled": null, + "responsiveLayoutPreference": null, + "showLegend": null, + "showLinearRegressionLine": null, + "showStackedLabels": null, + "visibleSeriesNames": [] + }, + "columnProperties": [ + { + "columnId": "bac67a4f-2e89-456a-8b62-6df830ff4e1b", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + }, + { + "columnId": "dd8bb852-d70d-4269-9bae-11953323d7bd", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + }, + { + "columnId": "55ea0d3d-84fa-4734-b929-5f9a39f2d35d", + "columnProperty": { + "__typename": "ChartVizColumnProperties", + "conditionalFormatting": null, + "customProps": null, + "dataLabels": null, + "excludeNullValues": null, + "handleMissingValues": null, + "kpiColumnProperties": { + "__typename": "KpiColumnProperties", + "abbreviatedPreviousDate": null, + "handleNullData": null, + "showAbbreviatedPreviousDate": null, + "showComparisonDate": true, + "showCurrentDateLabel": true, + "showPreviousDateLabel": true, + "showPreviousValue": true, + "showSparkline": true + } + } + } + ], + "customColorSelectorArray": [], + "multiColorSeriesColors": [], + "seriesColors": [], + "systemMultiColorSeriesColors": [], + "systemSeriesColors": [], + "tooltipConfig": null, + "version": "V4DOT2" + } + } + ], + "headerMetadata": { + "id": "44aadbc7-3b75-4897-9b2b-2a6ecad4fe31", + "name": "Total sales", + "description": "", + "isNewAnswer": true, + "isHidden": false, + "displayMode": "CHART_MODE" + } + }, + "isAnswerUnsaved": { + "hasUnsavedChanges": false + } + } + } +} +---- +==== \ No newline at end of file From 703af83870c14beae0e06c3d3624d80d1d3a5f23 Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Mon, 20 Apr 2026 10:20:42 +0530 Subject: [PATCH 026/109] added sdk changelog, removed beta for wysiwig --- modules/ROOT/pages/api-changelog.adoc | 10 ++++++++++ modules/ROOT/pages/data-report-v2-api.adoc | 8 +++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/modules/ROOT/pages/api-changelog.adoc b/modules/ROOT/pages/api-changelog.adoc index 22cb4c719..238655792 100644 --- a/modules/ROOT/pages/api-changelog.adoc +++ b/modules/ROOT/pages/api-changelog.adoc @@ -8,6 +8,16 @@ This changelog lists only the changes introduced in the Visual Embed SDK. For information about new features and enhancements available for embedded analytics, see xref:whats-new.adoc[What's New]. +== Version 1.48.x, May 2026 +[width="100%" cols="1,4"] +|==== +|[tag greenBackground]#NEW FEATURE# a|**Continuous PDF report** + +When set to `true`, the `isContinuousLiveboardPDFEnabled` enables Liveboard tab to render on a single page that matches the exact UI layout you see in ThoughtSpot. This update addresses the issue where visualizations for PDF downloads were split across multiple A4 pages +regardless of how they appear on screen. This feature is enabled by default on ThoughtSpot Embedded instances. You need to explicitly set it to `false` if you want to revert to the old paginated PDF behavior. + +|==== + == Version 1.47.x, April 2026 [width="100%" cols="1,4"] |==== diff --git a/modules/ROOT/pages/data-report-v2-api.adoc b/modules/ROOT/pages/data-report-v2-api.adoc index f14aaa7ac..75b921e52 100644 --- a/modules/ROOT/pages/data-report-v2-api.adoc +++ b/modules/ROOT/pages/data-report-v2-api.adoc @@ -295,12 +295,10 @@ For *PDF* downloads, you can specify additional parameters to customize the page You can now also download continuous pdfs which matches the full length of your Liveboard, without breaking them into multiple A4 pages. -* `page_size = CONTINUOUS` [beta betaBackground]^Beta^ Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. +* `page_size = CONTINUOUS` Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. + -When `page_size = CONTINUOUS`, the `include_filter_page` option works to show/hide the filter section in the PDF page (in CONTINUOUS PDF, we don't have a separate filter page, but the filters are included on the same page at the top). -* `zoom_level` [beta betaBackground]^Beta^ offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. This can be set only when `page_size = CONTINUOUS`. Valid values are integers in the range of 45 and 175. - -Contact ThoughtSpot support to enable these settings for PDF downloads on your ThoughtSpot instance. +When `page_size = CONTINUOUS`, the `include_filter_page` option works to show/hide the filter section in the PDF page (in a continuous PDF, there is no separate filter page, but the filters are included on the same page at the top). +* `zoom_level` offers various download size options to suit the viewer's screen dimensions, thereby enhancing legibility. This can be set only when `page_size = CONTINUOUS`. Valid values are integers in the range of 45 and 175. ===== Sample API payload for PDF downloads From 58fde9d3207a55240ff63cf6744926e4944b6560 Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Tue, 21 Apr 2026 10:16:05 +0530 Subject: [PATCH 027/109] label for sw --- modules/ROOT/pages/rest-api-v2-reference.adoc | 45 ++++++++++++------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/modules/ROOT/pages/rest-api-v2-reference.adoc b/modules/ROOT/pages/rest-api-v2-reference.adoc index 825f9c23d..f756feb1c 100644 --- a/modules/ROOT/pages/rest-api-v2-reference.adoc +++ b/modules/ROOT/pages/rest-api-v2-reference.adoc @@ -144,25 +144,29 @@ a|`POST /api/rest/2.0/collections/create` + Creates a new Collection. -|ThoughtSpot Cloud: __26.4.0.cl or later__ + a| +++Try it out+++ +|ThoughtSpot Cloud: __26.4.0.cl or later__ + +ThoughtSpot Software: __Not available__ + 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+++ +|ThoughtSpot Cloud: __26.4.0.cl or later__ + +ThoughtSpot Software: __Not available__ + 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 +++ +|ThoughtSpot Cloud: __26.4.0.cl or later__ + +ThoughtSpot Software: __Not available__ + 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 +++ +|ThoughtSpot Cloud: __26.4.0.cl or later__ + +ThoughtSpot Software: __Not available__ + a| +++Try it out +++ |===== -- @@ -263,26 +267,30 @@ a|`POST /api/rest/2.0/connection-configurations/create` Creates a connection configuration to the connection object specified in the API request. -|ThoughtSpot Cloud: __10.12.0.cl or later__ + a| +++Try it out+++ +|ThoughtSpot Cloud: __10.12.0.cl or later__ + +ThoughtSpot Software: __26.3.0.sw or later__ + a| +++Try it out+++ a|`POST /api/rest/2.0/connection-configurations/search` + Gets the connection configuration for the specified connection object. -|ThoughtSpot Cloud: __10.12.0.cl or later__ + a| +++Try it out+++ +|ThoughtSpot Cloud: __10.12.0.cl or later__ + +ThoughtSpot Software: __26.3.0.sw or later__ + a| +++Try it out+++ a|`POST /api/rest/2.0/connection-configurations/{configuration_identifier}/update` + Updates the connection configuration object. -|ThoughtSpot Cloud: __10.12.0.cl or later__ + a| +|ThoughtSpot Cloud: __10.12.0.cl or later__ + +ThoughtSpot Software: __26.3.0.sw or later__ + a| +++Try it out +++ a| `POST /api/rest/2.0/connection-configurations/delete` + Deletes the connection configuration object. -a|ThoughtSpot Cloud: __10.12.0.cl or later__ + a| +a|ThoughtSpot Cloud: __10.12.0.cl or later__ + +ThoughtSpot Software: __26.3.0.sw or later__ + a| +++Try it out +++ |===== -- @@ -503,33 +511,38 @@ a|`POST /api/rest/2.0/customization/email` + Creates the customized configuration for the notification emails. -|ThoughtSpot Cloud: __10.10.0.cl or later__ a| +++Try it out+++ +|ThoughtSpot Cloud: __10.10.0.cl or later__ + +ThoughtSpot Software: __Not available__ a| +++Try it out+++ a|`POST /api/rest/2.0/customization/email/delete` Deletes the existing customized configuration set for the notification emails. -|ThoughtSpot Cloud: __10.10.0.cl or later__ a| +++Try it out+++ +|ThoughtSpot Cloud: __10.10.0.cl or later__ + +ThoughtSpot Software: __Not available__ a| +++Try it out+++ a|`POST /api/rest/2.0/customization/email/search` + Searches the customized configuration set for the notification emails. -|ThoughtSpot Cloud: __10.10.0.cl or later__ a| +|ThoughtSpot Cloud: __10.10.0.cl or later__ + +ThoughtSpot Software: __Not available__ a| +++Try it out +++ a|`POST /api/rest/2.0/customization/email/update` + Updates an existing email customization set for the notification emails. -|ThoughtSpot Cloud: __10.12.0.cl or later__ a| +|ThoughtSpot Cloud: __10.12.0.cl or later__ + +ThoughtSpot Software: __Not available__ a| +++Try it out +++ a|`POST /api/rest/2.0/customization/email/validate` + Validates the customized configuration set for the notification emails. -|ThoughtSpot Cloud: __10.10.0.cl or later__ a| +|ThoughtSpot Cloud: __10.10.0.cl or later__ + +ThoughtSpot Software: __Not available__ a| +++Try it out +++ |===== -- @@ -993,11 +1006,13 @@ a|ThoughtSpot Cloud: __10.14.0.cl or later__ a| +++Try it out +++ +a|ThoughtSpot Cloud: __26.2.0.cl or later__ + +ThoughtSpot Software: __26.3.0.sw or later__ a| +++Try it out +++ a|`POST /api/rest/2.0/system/security-settings/search` + Allows fetching security settings. -a|ThoughtSpot Cloud: __26.2.0.cl or later__ a| +++Try it out +++ +a|ThoughtSpot Cloud: __26.2.0.cl or later__ + +ThoughtSpot Software: __26.3.0.sw or later__ a| +++Try it out +++ |===== From e3da4c708d53ed346e7ea6ee2684185dd2e96a60 Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Tue, 21 Apr 2026 12:35:24 +0530 Subject: [PATCH 028/109] removed beta EA labels --- modules/ROOT/pages/common/nav.adoc | 2 +- modules/ROOT/pages/rest-apiv2-changelog.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/common/nav.adoc b/modules/ROOT/pages/common/nav.adoc index 14bbf13e4..eb6d3886e 100644 --- a/modules/ROOT/pages/common/nav.adoc +++ b/modules/ROOT/pages/common/nav.adoc @@ -175,7 +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}}/collections[Collections] ** link:{{navprefix}}/connections[Connections] *** link:{{navprefix}}/connection-config[Connection configuration] ** link:{{navprefix}}/rest-apiv2-getstarted[REST API v2.0] diff --git a/modules/ROOT/pages/rest-apiv2-changelog.adoc b/modules/ROOT/pages/rest-apiv2-changelog.adoc index 703de4ee4..cf2b2b437 100644 --- a/modules/ROOT/pages/rest-apiv2-changelog.adoc +++ b/modules/ROOT/pages/rest-apiv2-changelog.adoc @@ -13,7 +13,7 @@ This changelog lists the features and enhancements introduced in REST API v2.0. === Connections API You can now synchronize connection metadata attributes from your Cloud Data Warehouse (CDW) with ThoughtSpot by sending a request to `POST /api/rest/2.0/connections/{connection_identifier}/resync-metadata` API endpoint. -=== Liveboard report API enhancements [beta betaBackground]^Beta^ +=== Liveboard report API enhancements The `POST /api/rest/2.0/report/liveboard` API endpoint enhances the pdf downloads by introducing the following parameters: * `page_size = CONTINUOUS` for a seamless PDF export that matches the full length of your Liveboard. Unlike the A4 format, which introduces forced page breaks between visualizations, this continuous flow maintains your exact design and intended layout. From 3819daf531cfb9b57a8b148042f3c3146ea80843 Mon Sep 17 00:00:00 2001 From: Rani Gangwar Date: Tue, 21 Apr 2026 15:29:30 +0530 Subject: [PATCH 029/109] misc edits --- modules/ROOT/pages/common/nav.adoc | 2 +- modules/ROOT/pages/data-report-v2-api.adoc | 2 +- modules/ROOT/pages/spottercode-integration.adoc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ROOT/pages/common/nav.adoc b/modules/ROOT/pages/common/nav.adoc index eb6d3886e..bb4b08ed6 100644 --- a/modules/ROOT/pages/common/nav.adoc +++ b/modules/ROOT/pages/common/nav.adoc @@ -107,11 +107,11 @@ **** link:{{navprefix}}/customize-actions[Custom actions through the UI] ***** link:{{navprefix}}/custom-action-url[URL actions] ***** link:{{navprefix}}/custom-action-callback[Callback actions] -***** link:{{navprefix}}/custom-action-payload[Callback response payload] ***** link:{{navprefix}}/edit-custom-action[Set the position of a custom action] ***** link:{{navprefix}}/add-action-viz[Add a local action to a visualization] ***** link:{{navprefix}}/add-action-worksheet[Add a local action to a model] **** link:{{navprefix}}/code-based-custom-action[Code based custom actions] +**** link:{{navprefix}}/custom-action-payload[Callback response payload] *** link:{{navprefix}}/customize-links[Customize links] *** link:{{navprefix}}/set-locale[Customize locale] *** link:{{navprefix}}/custom-domain-config[Custom domain configuration] diff --git a/modules/ROOT/pages/data-report-v2-api.adoc b/modules/ROOT/pages/data-report-v2-api.adoc index 75b921e52..3f007147a 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. -* 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. +* New 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/spottercode-integration.adoc b/modules/ROOT/pages/spottercode-integration.adoc index d48781583..05ebd5f8e 100644 --- a/modules/ROOT/pages/spottercode-integration.adoc +++ b/modules/ROOT/pages/spottercode-integration.adoc @@ -27,7 +27,7 @@ You can add the SpotterCode MCP Server URL to Cursor using the one-click install ---- cursor://anysphere.cursor-deeplink/mcp/install?name=SpotterCode&config=eyJ1cmwiOiJodHRwczovL3Nwb3R0ZXJjb2RlLnRob3VnaHRzcG90LmFwcC9tY3AifQ== ---- - ++ . On clicking this link, Cursor opens the MCP server installation page to add SpotterCode. + [.widthAuto] From 98768ce43473a470af4f242af8f4967c5cc9e24d Mon Sep 17 00:00:00 2001 From: ShashiSubramanya Date: Fri, 24 Apr 2026 20:36:05 +0530 Subject: [PATCH 030/109] ux changes, copy as markdown, secondary header, markdown build and other updates --- gatsby-node.js | 56 ++ package-lock.json | 651 +++++++++++++++++++ package.json | 7 +- src/assets/styles/admonition.scss | 2 +- src/assets/styles/index.scss | 32 +- src/assets/styles/variables.scss | 172 +++-- src/components/AnnouncementBanner/index.scss | 74 ++- src/components/AnnouncementBanner/index.tsx | 40 +- src/components/Breadcrums/index.scss | 2 +- src/components/CopyPageDropdown/index.scss | 138 ++++ src/components/CopyPageDropdown/index.tsx | 177 +++++ src/components/DevDocTemplate/index.tsx | 67 +- src/components/Docmap/index.scss | 260 +++++--- src/components/Document/helper.tsx | 142 ++-- src/components/Document/index.scss | 167 +++-- src/components/Document/index.tsx | 26 +- src/components/Dropdown/index.scss | 2 +- src/components/Header/index.scss | 304 ++++++--- src/components/Header/index.tsx | 143 ++-- src/components/LeftSidebar/index.scss | 59 +- src/components/SecondaryHeader/index.scss | 64 ++ src/components/SecondaryHeader/index.tsx | 105 +++ src/components/WasThisHelpful/index.scss | 173 +++++ src/components/WasThisHelpful/index.tsx | 122 ++++ 24 files changed, 2511 insertions(+), 474 deletions(-) create mode 100644 src/components/CopyPageDropdown/index.scss create mode 100644 src/components/CopyPageDropdown/index.tsx create mode 100644 src/components/SecondaryHeader/index.scss create mode 100644 src/components/SecondaryHeader/index.tsx create mode 100644 src/components/WasThisHelpful/index.scss create mode 100644 src/components/WasThisHelpful/index.tsx diff --git a/gatsby-node.js b/gatsby-node.js index 3cb3567e4..2b08a9a1d 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -6,6 +6,62 @@ const { } = require('./src/configs/doc-configs'); const { getDocLinkFromEdge } = require('./src/utils/gatsby-utils.js'); +/* ── Build-time Markdown generation ─────────────────────────────────────── + * For every asciidoc node, convert the already-generated HTML to clean + * Markdown using cheerio (DOM pre-processing) + turndown (HTML→MD). + * The result is stored as `fields.markdownBody` on each node and exposed + * in GraphQL so CopyPageDropdown can use it instead of scraping the DOM. + */ +exports.onCreateNode = ({ node, actions }) => { + if (node.internal.type !== 'Asciidoc') return; + + const { createNodeField } = actions; + const TurndownService = require('turndown'); + const cheerio = require('cheerio'); + + const html = node.html || ''; + const title = node.document?.title || node.pageAttributes?.title || ''; + + /* Load HTML into cheerio for pre-processing */ + const $ = cheerio.load(html, { decodeEntities: false }); + + /* Remove anchor icon links that Asciidoctor injects next to headings */ + $('a.anchor').remove(); + + /* Remove the embedded TOC — it adds noise to Markdown */ + $('#toc').remove(); + + /* Convert admonition tables to readable text blocks */ + $('.admonitionblock').each((_, el) => { + const type = $(el).attr('class').match(/\b(note|tip|warning|caution|important)\b/i)?.[1]?.toUpperCase() || 'NOTE'; + const content = $(el).find('td.content').text().trim(); + $(el).replaceWith(`

${type}: ${content}

`); + }); + + /* Get the cleaned HTML */ + const cleanedHtml = $('body').html() || ''; + + /* Configure turndown */ + const td = new TurndownService({ + headingStyle: 'atx', + bulletListMarker: '-', + codeBlockStyle: 'fenced', + fence: '```', + }); + + /* GFM table plugin — renders tables as proper Markdown pipe tables */ + const { tables } = require('turndown-plugin-gfm'); + td.use(tables); + + const markdownBody = td.turndown(cleanedHtml); + + createNodeField({ + node, + name: 'markdownBody', + value: markdownBody, + }); +}; + exports.onPostBuild = () => { fsExtra.copyFileSync( `${__dirname}/robots.txt`, diff --git a/package-lock.json b/package-lock.json index e4e9d1f23..0565c77d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "dependencies": { "@vercel/analytics": "^1.0.2", "algoliasearch": "^4.10.5", + "cheerio": "^1.2.0", "classnames": "^2.3.1", "eventemitter3": "^4.0.7", "gatsby-plugin-vercel": "^1.0.3", @@ -17,6 +18,8 @@ "lodash": "^4.17.21", "mixpanel-browser": "^2.45.0", "react-helmet": "^6.1.0", + "turndown": "^7.2.4", + "turndown-plugin-gfm": "^1.0.2", "use-deep-compare-effect": "^1.8.1" }, "devDependencies": { @@ -4419,6 +4422,12 @@ "node": ">=12.0.0" } }, + "node_modules/@mixmark-io/domino": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", + "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==", + "license": "BSD-2-Clause" + }, "node_modules/@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", @@ -9168,6 +9177,238 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio-select/node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio-select/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/cheerio-select/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/cheerio-select/node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/cheerio-select/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/cheerio/node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -11049,6 +11290,44 @@ "iconv-lite": "^0.6.2" } }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/encoding-sniffer/node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/encoding/node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -22401,6 +22680,94 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parse5-parser-stream/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/parseley": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.7.0.tgz", @@ -27706,6 +28073,25 @@ "node": "*" } }, + "node_modules/turndown": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.4.tgz", + "integrity": "sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==", + "license": "MIT", + "dependencies": { + "@mixmark-io/domino": "^2.2.0" + }, + "engines": { + "node": ">=18", + "npm": ">=9" + } + }, + "node_modules/turndown-plugin-gfm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.2.tgz", + "integrity": "sha512-vwz9tfvF7XN/jE0dGoBei3FXWuvll78ohzCZQuOb+ZjWrs3a0XhQVomJEb2Qh4VHTPNRO4GPZh0V7VRbiWwkRg==", + "license": "MIT" + }, "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", @@ -27945,6 +28331,15 @@ "node": ">=0.10.0" } }, + "node_modules/undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -32399,6 +32794,11 @@ "json5": "^2.2.1" } }, + "@mixmark-io/domino": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@mixmark-io/domino/-/domino-2.2.0.tgz", + "integrity": "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==" + }, "@mrmlnc/readdir-enhanced": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", @@ -35847,6 +36247,157 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "requires": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "dependencies": { + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + } + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + }, + "dependencies": { + "entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==" + } + } + }, + "parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "requires": { + "entities": "^6.0.0" + }, + "dependencies": { + "entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==" + } + } + }, + "whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==" + } + } + }, + "cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "requires": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "dependencies": { + "css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + } + }, + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + } + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + } + } + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -37300,6 +37851,33 @@ } } }, + "encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "requires": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "dependencies": { + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "requires": { + "iconv-lite": "0.6.3" + } + } + } + }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -45928,6 +46506,61 @@ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, + "parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "requires": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "dependencies": { + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "requires": { + "domelementtype": "^2.3.0" + } + }, + "entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==" + }, + "parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "requires": { + "entities": "^6.0.0" + } + } + } + }, + "parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "requires": { + "parse5": "^7.0.0" + }, + "dependencies": { + "entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==" + }, + "parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "requires": { + "entities": "^6.0.0" + } + } + } + }, "parseley": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.7.0.tgz", @@ -49873,6 +50506,19 @@ "safe-buffer": "^5.0.1" } }, + "turndown": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.4.tgz", + "integrity": "sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==", + "requires": { + "@mixmark-io/domino": "^2.2.0" + } + }, + "turndown-plugin-gfm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.2.tgz", + "integrity": "sha512-vwz9tfvF7XN/jE0dGoBei3FXWuvll78ohzCZQuOb+ZjWrs3a0XhQVomJEb2Qh4VHTPNRO4GPZh0V7VRbiWwkRg==" + }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", @@ -50037,6 +50683,11 @@ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==" }, + "undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==" + }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", diff --git a/package.json b/package.json index d0759507f..0ca56ddee 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "dependencies": { "@vercel/analytics": "^1.0.2", "algoliasearch": "^4.10.5", + "cheerio": "^1.2.0", "classnames": "^2.3.1", "eventemitter3": "^4.0.7", "gatsby-plugin-vercel": "^1.0.3", @@ -30,6 +31,8 @@ "lodash": "^4.17.21", "mixpanel-browser": "^2.45.0", "react-helmet": "^6.1.0", + "turndown": "^7.2.4", + "turndown-plugin-gfm": "^1.0.2", "use-deep-compare-effect": "^1.8.1" }, "devDependencies": { @@ -74,7 +77,6 @@ "identity-obj-proxy": "^3.0.0", "jest": "^26.6.3", "jsdom": "^17.0.0", - "sass": "^1.80.6", "prettier": "2.1.2", "react": "^18.0.0", "react-dom": "^18.0.0", @@ -83,6 +85,7 @@ "react-resize-detector": "^9.x.0", "react-test-renderer": "^18.0.x", "react-use-flexsearch": "^0.1.1", + "sass": "^1.80.6", "ts-jest": "^26.5.5", "ts-node": "^10.9.1", "tsx": "^4.7.1", @@ -105,4 +108,4 @@ "globals": { "window": {} } -} \ No newline at end of file +} diff --git a/src/assets/styles/admonition.scss b/src/assets/styles/admonition.scss index 70e082a27..2e1ea68d8 100644 --- a/src/assets/styles/admonition.scss +++ b/src/assets/styles/admonition.scss @@ -80,4 +80,4 @@ position: relative; width: 100%; } -} +} \ No newline at end of file diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index b836d5cde..cb273727d 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -44,6 +44,8 @@ body { } } +$secondary-header-height: 44px; + main { display: flow-root; background-color: var(--body-background-color); @@ -51,7 +53,11 @@ main { main { display: flex; - height: calc(100lvh - $header-height); + height: calc(100lvh - #{$header-height} - #{$secondary-header-height}); +} + +.withHeaderFooter main { + height: calc(100lvh - #{$header-height} - #{$secondary-header-height}); } * { @@ -583,16 +589,18 @@ button { } } +/* Admonition */ + .admonitionblock.note { border-left: 5px solid var(--var-note-color); td.content { - border: none !important; - border-radius: 0 !important; + border: 0 !important; + border-radius: 0.5 !important; box-shadow: none !important; } td.icon { left: 20px !important; - top: 5px !important; + top: 10px !important; } } .admonitionblock.important { @@ -608,7 +616,7 @@ button { } } .admonitionblock.warning { - border-left: 5px solid var(--var-important-color); + border-left: 5px solid $warning-color; td.content { border: none !important; border-radius: 0 !important; @@ -620,6 +628,20 @@ button { } } +.admonitionblock.tip { + border-left: 5px solid $tip-color; + td.content { + border: 0 !important; + border-radius: 0.5 !important; + box-shadow: none !important; + } + td.icon { + left: 20px !important; + top: 10px !important; + } +} + + .videoContainer { border-radius: 10px; overflow-x: auto; diff --git a/src/assets/styles/variables.scss b/src/assets/styles/variables.scss index 8147c15a1..d59a47f4c 100644 --- a/src/assets/styles/variables.scss +++ b/src/assets/styles/variables.scss @@ -1,4 +1,15 @@ $gutter: 0; + +/* ThoughtSpot brand palette */ +$ts-black: #000000; +$ts-grey: #f1f4f8; +$ts-blue: #0568fa; +$ts-navy: #012676; +$ts-cyan: #74daff; +$ts-teal: #6dbec4; +$ts-purple: #dcadff; +$ts-yellow: #fcde18; + /*Colors*/ $gray-80: #323946; $white: #fff; @@ -6,7 +17,7 @@ $darkblue: #2770ef; $secondarycolor: #2770ef; $lightgrey: #eaedf2; $darkgrey: #777e8b; -$hovercolor: rgba(113, 161, 244, 0.12); +$hovercolor: rgba(5, 104, 250, 0.1); $text-container-background: rgba(192, 198, 207, 0.12); $disabledcolor: #a5acb9; $result-container-max-height: 320px; @@ -32,17 +43,17 @@ $font-weight-normal: 300; $font-weight-bold: 600; $line-height-normal: 31px; $line-height-button: 16px; -$line-height-doc: 1.6rem; +$line-height-doc: 1.75rem; $line-height-result-title: 20px; $line-height-result-footer: 18px; $font-size-x-small: 11px; $font-size-small: 12px; $font-size-home: 13px; -$font-size-normal: 14px; +$font-size-normal: 15px; $font-size-table: 14px; -$font-size-doc: 14px; +$font-size-doc: 15px; $font-size-code: 13px; -$line-height-code: 1.4rem; +$line-height-code: 1.5rem; $font-size-large: 36px; $font-size-404: 1.25rem; $padding-md: 24px; @@ -127,6 +138,7 @@ $important-on-color: $color-white; $note-on-color: $color-white; $tip-on-color: $color-white; $panel-background: $color-smoke-30; + /* fonts */ $rem-base: 18; $body-font-size-desktop: 1.125em; /* 18px */ @@ -143,6 +155,7 @@ $admonition-font-factor-p: 16; $admonition-content-line-height: 24px; $admonition-font-factor-pre: 15; + /*Tag variables*/ $beta-border-radius: 6px; $beta-padding: 2px 4px; @@ -160,28 +173,46 @@ $tag-color-white: var(--body-background-color); $tag-color-light: $lightgrey; :root { + /* Brand tokens */ + --ts-black: #000000; + --ts-grey: #f1f4f8; + --ts-blue: #0568fa; + --ts-navy: #012676; + --ts-cyan: #74daff; + --ts-teal: #6dbec4; + --ts-purple: #dcadff; + --ts-yellow: #fcde18; + --body-background-color: #fff; --primary-color: #1d232f; --header-primary-color: #fff; - --header-color: #000000; - --header-border-color: #000000; - --header-link-color: #404040; - --nav-bar-color: #f6f8fa; + --header-color: #08072C; + --header-border-color: #08072C; + --header-link-color: rgba(255, 255, 255, 0.85); + --nav-bar-color: #f1f4f8; + --secondary-header-bg: #f1f4f8; + --secondary-header-border: #e2e8f0; + --secondary-header-text: #374151; + --secondary-header-active: #0568fa; --breadcrums-font-color: #5f6368; --announcement-block-color: #e1e1e1; + --announcement-text-color: #1d232f; --admonition-background: #fff; - --code-block-color: #283142; - --code-text-color: #eceff1; + --code-block-color: #0d1117; + --code-block-light: #f6f8fa; + --code-text-color: #e6edf3; --code-text-bg: #f6f8fa; - --side-nav-text: #404040; - --text-color-code-lang: #999; - --icon-color: #999; + --side-nav-text: #374151; + --side-nav-active-bg: rgba(5, 104, 250, 0.08); + --side-nav-active-text: #0568fa; + --text-color-code-lang: #8b949e; + --icon-color: #6b7280; --back-button-color: #1d232f; --back-button-background: #eaedf2; - --block-background: #eaedf2; - --border-color: #c0c6cf; + --block-background: #f1f4f8; + --border-color: #d1d5db; --table-header-color: #fff; - --border-color-tr: #e6e6e6; + --border-color-tr: #e5e7eb; --scrollbar-color: #a5acb9; --color-jet-70: #d14; --highlight-purple: #9334e6; @@ -195,61 +226,78 @@ $tag-color-light: $lightgrey; --highlight-darkred: #900; --highlight-lilac: #d7aefb; --highlight-violet: #990073; - --secondary-color: #2770ef; - --header-background-color: #1d232f; - --var-note-color: #1d232f; + --secondary-color: #0568fa; + --header-background-color: #012676; + --var-note-color: #0568fa; --var-important-color: #E22B3D; - --var-docmap-nested-color: #777E8B; - --box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 12%), 0 0px 6px 0 rgba(0, 0, 0, 11%); - --box-shadow-hover: 0 16px 20px 0 rgba(0, 0, 0, 12%), - 0 16px 20px 0 rgba(0, 0, 0, 12%); + --var-docmap-nested-color: #6b7280; + --box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + --box-shadow-hover: 0 4px 6px -1px rgba(0, 0, 0, 0.1), + 0 2px 4px -1px rgba(0, 0, 0, 0.06); + --sidebar-connector-color: #d1d5db; + --copy-btn-bg: #f3f4f6; + --copy-btn-hover: #e5e7eb; + --was-helpful-bg: #f9fafb; + --was-helpful-border: #e5e7eb; } #wrapper[data-theme='dark'], #docsModal[data-theme='dark'] { - --body-background-color: #21252c; - --header-color: #323946; - --header-border-color: #777e8b; - --header-link-color: #1d232f; - --nav-bar-color: #21252c; - --primary-color: #e8eaed; - --header-primary-color: #1d232f; - --breadcrums-font-color: #a5acb9; + --body-background-color: #0d1117; + --header-color: #21252c; + --header-border-color: #21252c; + --header-link-color: rgba(255, 255, 255, 0.85); + --nav-bar-color: #161b22; + --secondary-header-bg: #161b22; + --secondary-header-border: #30363d; + --secondary-header-text: #c9d1d9; + --secondary-header-active: #74daff; + --primary-color: #e6edf3; + --header-primary-color: #e6edf3; + --breadcrums-font-color: #8b949e; --announcement-block-color: #3c4356; - --admonition-background: #3c4356; - --code-block-color: #3c4356; - --code-text-bg: #3c4356; - --code-text-color: #fff; - --side-nav-text: #fff; - --text-color-code-lang: #fff; - --icon-color: #fff; - --back-button-color: #fff; - --table-header-color: #3c4356; - --back-button-background: #a4abb8; - --block-background: none; - --border-color: #e8eaed; - --border-color-tr: #3c4356; - --scrollbar-color: #3c4356; - --color-jet-70: #e18114; - --highlight-purple: #40c4ff; - --highlight-green: aquamarine; - --highlight-lightgreen: #009926; - --highlight-lightblue: #90caf9; + --announcement-text-color: #e6edf3; + --admonition-background: #161b22; + --code-block-color: #161b22; + --code-block-light: #21262d; + --code-text-bg: #21262d; + --code-text-color: #e6edf3; + --side-nav-text: #c9d1d9; + --side-nav-active-bg: rgba(116, 218, 255, 0.12); + --side-nav-active-text: #74daff; + --text-color-code-lang: #8b949e; + --icon-color: #8b949e; + --back-button-color: #e6edf3; + --table-header-color: #21262d; + --back-button-background: #21262d; + --block-background: #161b22; + --border-color: #30363d; + --border-color-tr: #21262d; + --scrollbar-color: #30363d; + --color-jet-70: #ffa657; + --highlight-purple: #d2a8ff; + --highlight-green: #3fb950; + --highlight-lightgreen: #56d364; + --highlight-lightblue: #79c0ff; --highlight-darkblue: #9fa8da; --highlight-blue: #c5cae9; - --highlight-darkred: #ef9a9a; - --highlight-lilac: #8388fe; + --highlight-darkred: #ffa198; + --highlight-lilac: #b083f0; --highlight-violet: #f8bbd0; - --secondary-color: #8388fe; - --header-background-color: #787e8d; - --var-note-color: #e8eaed; - --var-important-color: #E22B3D; - --var-docmap-nested-color: #777e8b; + --secondary-color: #74daff; + --header-background-color: #012676; + --var-note-color: #74daff; + --var-important-color: #ff7b72; + --var-docmap-nested-color: #8b949e; + --sidebar-connector-color: #30363d; + --copy-btn-bg: #21262d; + --copy-btn-hover: #30363d; + --was-helpful-bg: #161b22; + --was-helpful-border: #30363d; - --box-shadow: 0 2px 2px 0 rgba(255, 255, 255, 12%), - 0 0px 6px 0 rgba(255, 255, 255, 11%); - --box-shadow-hover: 0 16px 20px 0 rgb(255 255 255 / 6%), - 0 16px 20px 0 rgb(255 255 255 / 6%); + --box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px 0 rgba(0, 0, 0, 0.3); + --box-shadow-hover: 0 4px 6px -1px rgba(0, 0, 0, 0.4), + 0 2px 4px -1px rgba(0, 0, 0, 0.3); } $header-height: 65px; diff --git a/src/components/AnnouncementBanner/index.scss b/src/components/AnnouncementBanner/index.scss index bff42281f..d51358a79 100644 --- a/src/components/AnnouncementBanner/index.scss +++ b/src/components/AnnouncementBanner/index.scss @@ -1,38 +1,82 @@ +@import '../../assets/styles/variables.scss'; + .announcementBanner { width: 100%; - border-bottom: 1px solid var(--border-color); - background: #dce5f9; - color: var(--primary-color); + background: var(--announcement-block-color, #e1e1e1); + color: var(--announcement-text-color, #1d232f); + border-bottom: 1px solid rgba(0, 0, 0, 0.08); + + .announcementBanner__content { + color: var(--announcement-text-color, #1d232f); + } + + .announcementBanner__link { + color: var(--secondary-color, #0568fa); + font-weight: 600; + text-decoration: underline; + } + + .announcementBanner__close { + color: var(--announcement-text-color, #1d232f); + opacity: 0.7; + + &:hover { + opacity: 1; + } + } } .announcementBanner__inner { display: flex; - gap: 12px; align-items: center; justify-content: center; - padding-top: 10px; - padding-bottom: 10px; + gap: 12px; + padding-top: 9px; + padding-bottom: 9px; + position: relative; } .announcementBanner__content { - font-size: 15px; - line-height: 21px; + font-size: 14px; + line-height: 20px; text-align: center; flex: 1 1 auto; font-weight: 500; - color: #4b5563; } .announcementBanner__link { - color: #1a73e8; - text-decoration: underline; - font-size: 15px; + font-size: 14px; +} + +.announcementBanner__close { + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: none; + cursor: pointer; + padding: 4px; + border-radius: 4px; + flex-shrink: 0; + transition: background 0.15s ease; + + &:hover { + background: rgba(0, 0, 0, 0.1); + } + + .close-icon { + width: 16px; + height: 16px; + } } @media screen and (max-width: 767px) { .announcementBanner__inner { - flex-direction: column; - align-items: flex-start; + flex-direction: row; + align-items: center; } -} + .announcementBanner__content { + text-align: left; + } +} diff --git a/src/components/AnnouncementBanner/index.tsx b/src/components/AnnouncementBanner/index.tsx index e88c22e38..08018477c 100644 --- a/src/components/AnnouncementBanner/index.tsx +++ b/src/components/AnnouncementBanner/index.tsx @@ -1,24 +1,54 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; +import { MdClose } from '@react-icons/all-files/md/MdClose'; +import { IconContext } from '@react-icons/all-files'; import './index.scss'; +type BannerVariant = 'release' | 'info'; + type AnnouncementBannerProps = { enabled?: boolean; message: React.ReactNode; + variant?: BannerVariant; + dismissKey?: string; }; const AnnouncementBanner = (props: AnnouncementBannerProps) => { - const { enabled = true, message } = props; + const { enabled = true, message, variant = 'release', dismissKey = 'announcement-banner' } = props; + const [dismissed, setDismissed] = useState(false); + + useEffect(() => { + const isDismissed = sessionStorage.getItem(dismissKey) === 'dismissed'; + setDismissed(isDismissed); + }, [dismissKey]); - if (!enabled) return null; + const handleDismiss = () => { + sessionStorage.setItem(dismissKey, 'dismissed'); + setDismissed(true); + }; + + if (!enabled || dismissed) return null; return ( -
+
{message}
+
); }; export default AnnouncementBanner; - diff --git a/src/components/Breadcrums/index.scss b/src/components/Breadcrums/index.scss index c053c5d89..52de02678 100644 --- a/src/components/Breadcrums/index.scss +++ b/src/components/Breadcrums/index.scss @@ -1,7 +1,7 @@ @import '../../assets/styles/variables.scss'; .breadcrumsWrapper { - padding: 20px 0 20px; + padding: 10px 0 25px; .breadcrumb { margin: 0; diff --git a/src/components/CopyPageDropdown/index.scss b/src/components/CopyPageDropdown/index.scss new file mode 100644 index 000000000..f04c2de8f --- /dev/null +++ b/src/components/CopyPageDropdown/index.scss @@ -0,0 +1,138 @@ +@import '../../assets/styles/variables.scss'; + +.copy-page-dropdown { + position: relative; + display: inline-block; + + &__trigger { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 6px 12px; + font-size: 13px; + font-weight: 500; + color: var(--primary-color); + background: var(--body-background-color); + border: 1px solid var(--border-color, #d1d5db); + border-radius: 6px; + cursor: pointer; + font-family: 'Optimo-Plain', sans-serif; + transition: all 0.15s ease; + white-space: nowrap; + + &:hover { + border-color: var(--secondary-color, #0568fa); + color: var(--secondary-color, #0568fa); + } + + &.copied { + color: #16a34a; + border-color: #16a34a; + } + + .copy-page-icon { + width: 14px; + height: 14px; + } + + .copy-chevron { + width: 13px; + height: 13px; + transition: transform 0.15s ease; + } + + &[aria-expanded='true'] .copy-chevron { + transform: rotate(180deg); + } + } + + &__menu { + position: absolute; + top: calc(100% + 6px); + right: 0; + background: var(--body-background-color); + border: 1px solid var(--border-color, #d1d5db); + border-radius: 8px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); + min-width: 240px; + padding: 6px; + z-index: 50; + animation: cpDropFadeIn 0.12s ease; + } + + &__item { + display: flex; + align-items: flex-start; + gap: 10px; + width: 100%; + padding: 9px 12px; + font-size: 13px; + font-weight: 400; + color: var(--primary-color); + background: transparent; + border: none; + border-radius: 5px; + cursor: pointer; + font-family: 'Optimo-Plain', sans-serif; + text-align: left; + transition: background 0.1s ease; + + &:hover { + background: var(--block-background, #f1f4f8); + + .copy-page-dropdown__item-label { + color: var(--secondary-color, #0568fa); + } + + .menu-item-icon { + color: var(--secondary-color, #0568fa); + } + } + + .menu-item-icon { + width: 14px; + height: 14px; + color: var(--icon-color, #6b7280); + flex-shrink: 0; + margin-top: 2px; + } + } + + &__item-text { + display: flex; + flex-direction: column; + gap: 1px; + } + + &__item-label { + font-size: 13px; + font-weight: 500; + color: var(--primary-color); + line-height: 1.4; + transition: color 0.1s ease; + } + + &__item-sub { + font-size: 11.5px; + color: var(--icon-color, #6b7280); + line-height: 1.3; + font-weight: 400; + } + + &__separator { + height: 1px; + background: var(--border-color, #e5e7eb); + margin: 4px 8px; + } +} + +@keyframes cpDropFadeIn { + from { + opacity: 0; + transform: translateY(-4px); + } + to { + opacity: 1; + transform: translateY(0); + } +} diff --git a/src/components/CopyPageDropdown/index.tsx b/src/components/CopyPageDropdown/index.tsx new file mode 100644 index 000000000..cb9fa794d --- /dev/null +++ b/src/components/CopyPageDropdown/index.tsx @@ -0,0 +1,177 @@ +import React, { useState, useRef, useEffect } from 'react'; +import { IconContext } from '@react-icons/all-files'; +import { FiCopy } from '@react-icons/all-files/fi/FiCopy'; +import { FiChevronDown } from '@react-icons/all-files/fi/FiChevronDown'; +import { FiExternalLink } from '@react-icons/all-files/fi/FiExternalLink'; +import './index.scss'; + +type CopyPageDropdownProps = { + pageTitle?: string; + markdownBody?: string; +}; + +const CopyPageDropdown = (props: CopyPageDropdownProps) => { + const { pageTitle, markdownBody } = props; + const [open, setOpen] = useState(false); + const [copied, setCopied] = useState(false); + const ref = useRef(null); + + useEffect(() => { + const handleClickOutside = (e: MouseEvent) => { + if (ref.current && !ref.current.contains(e.target as Node)) { + setOpen(false); + } + }; + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + }, []); + + const getPageMarkdown = (): string => { + const sourceUrl = typeof window !== 'undefined' ? window.location.href : ''; + const header = sourceUrl ? `Source: ${sourceUrl}\n\n` : ''; + + /* Prefer build-time Markdown — clean headings, no chain icons */ + if (markdownBody) { + return `${header}${markdownBody}`; + } + + /* Fallback: browser scrape (used if GraphQL field is missing) */ + const title = pageTitle || (typeof document !== 'undefined' ? document.title : ''); + const contentEl = typeof document !== 'undefined' + ? (document.querySelector('.documentView') as HTMLElement) + : null; + if (!contentEl) return `# ${title}\n\n${sourceUrl}`; + + const tmp = document.createElement('div'); + tmp.innerHTML = contentEl.innerHTML; + tmp.querySelectorAll('script, style, a.anchor').forEach(el => el.remove()); + const text = (tmp.innerText || tmp.textContent || '').replace(/\n{3,}/g, '\n\n').trim(); + return `# ${title}\n\n${header}${text}`; + }; + + const handleCopyMarkdown = async () => { + try { + const md = getPageMarkdown(); + await navigator.clipboard.writeText(md); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch { + /* Fallback */ + const ta = document.createElement('textarea'); + ta.value = getPageMarkdown(); + document.body.appendChild(ta); + ta.select(); + document.execCommand('copy'); + document.body.removeChild(ta); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } + setOpen(false); + }; + + const handleOpenInAI = (aiService: 'chatgpt' | 'claude') => { + const pageUrl = window.location.href; + const prompt = encodeURIComponent( + `Read ${pageUrl} so I can ask questions about it.` + ); + const url = aiService === 'chatgpt' + ? `https://chatgpt.com/?q=${prompt}` + : `https://claude.ai/new?q=${prompt}`; + + window.open(url, '_blank', 'noopener,noreferrer'); + setOpen(false); + }; + + const handleViewMarkdown = () => { + const md = getPageMarkdown(); + const blob = new Blob([md], { type: 'text/plain' }); + const blobUrl = URL.createObjectURL(blob); + window.open(blobUrl, '_blank'); + setTimeout(() => URL.revokeObjectURL(blobUrl), 10000); + setOpen(false); + }; + + return ( +
+ + + {open && ( +
+ + + + + + +
+ + +
+ )} +
+ ); +}; + +export default CopyPageDropdown; diff --git a/src/components/DevDocTemplate/index.tsx b/src/components/DevDocTemplate/index.tsx index c432d67b2..96992103f 100644 --- a/src/components/DevDocTemplate/index.tsx +++ b/src/components/DevDocTemplate/index.tsx @@ -14,6 +14,7 @@ import { Seo } from '../Seo'; import { queryStringParser, isPublicSite } from '../../utils/app-utils'; import { passThroughHandler, fetchChild } from '../../utils/doc-utils'; import Header from '../Header'; +import SecondaryHeader, { DocCategory, CATEGORY_PAGEIDS } from '../SecondaryHeader'; import LeftSidebar from '../LeftSidebar'; import Docmap from '../Docmap'; import Document from '../Document'; @@ -94,6 +95,7 @@ const DevDocTemplate: FC = (props) => { const [breadcrumsData, setBreadcrumsData] = useState( fetchChild(initialNavContentData) || [], ); + const [activeCategory, setActiveCategory] = useState('embedding'); const [showSearch, setShowSearch] = useState(false); const [leftNavOpen, setLeftNavOpen] = useState(false); const [keyword, updateKeyword] = useState(''); @@ -101,11 +103,16 @@ const DevDocTemplate: FC = (props) => { if (typeof window !== 'undefined') return isPublicSite(location.search); return true; }); - const checkout = - typeof window !== 'undefined' - ? localStorage.getItem('theme') === 'dark' - : null; - const [isDarkMode, setDarkMode] = useState(checkout); + const [isDarkMode, setDarkMode] = useState(() => { + if (typeof window === 'undefined') return false; + /* themeMode is only written when the user explicitly clicks the toggle. + If absent, follow OS preference fresh every load. */ + const explicitChoice = localStorage.getItem('themeMode'); + if (explicitChoice) return explicitChoice === 'dark'; + const prefersDark = window.matchMedia?.('(prefers-color-scheme: dark)').matches ?? false; + localStorage.setItem('theme', prefersDark ? 'dark' : 'light'); + return prefersDark; + }); const [key, setKey] = useState(''); const isCustomPage = _.values(CUSTOM_PAGE_ID).some( @@ -133,6 +140,15 @@ const DevDocTemplate: FC = (props) => { const isAskDocsPage = params[TS_PAGE_ID_PARAM] === CUSTOM_PAGE_ID.ASK_DOCS; + /* Detect active category from current page ID */ + useEffect(() => { + const currentPageId = curPageNode.pageAttributes.pageid; + const found = (Object.entries(CATEGORY_PAGEIDS) as [DocCategory, string[]][]).find( + ([, pageIds]) => pageIds.includes(currentPageId), + ); + if (found) setActiveCategory(found[0]); + }, [curPageNode.pageAttributes.pageid]); + useEffect(() => { // based on query params set if public site is open or not setIsPublicSiteOpen(isPublicSite(location.search)); @@ -151,7 +167,16 @@ const DevDocTemplate: FC = (props) => { useEffect(() => { if (isBrowser()) { - setDarkMode(localStorage.getItem('theme') === 'dark'); + /* Correct SSR mismatch on first hydration */ + const explicitChoice = localStorage.getItem('themeMode'); + let isDark: boolean; + if (explicitChoice) { + isDark = explicitChoice === 'dark'; + } else { + isDark = window.matchMedia?.('(prefers-color-scheme: dark)').matches ?? false; + localStorage.setItem('theme', isDark ? 'dark' : 'light'); + } + setDarkMode(isDark); setKey('dark'); } }, []); @@ -433,6 +458,7 @@ const DevDocTemplate: FC = (props) => { docContent={docContent} breadcrumsData={breadcrumsData} isPublicSiteOpen={isPublicSiteOpen} + markdownBody={curPageNode.fields?.markdownBody} />
{shouldShowRightNav && ( @@ -487,6 +513,12 @@ const DevDocTemplate: FC = (props) => { ); }; + const isEmbeddedContext = () => { + if (!isBrowser()) return false; + const urlParams = new URLSearchParams(location.search); + return urlParams.get('context') === 'embedded' || !isPublicSiteOpen; + }; + const getClassName = () => { let cName = isDarkMode ? 'dark ' : ''; if (isPublicSiteOpen) cName += 'withHeaderFooter'; @@ -494,6 +526,10 @@ const DevDocTemplate: FC = (props) => { return cName; }; + const getWrapperClassName = () => { + return isEmbeddedContext() ? 'embedded-mode' : ''; + }; + const getCloudLatestVersion = () => { const cloudLatest = VERSION_DROPDOWN?.find( (v) => v?.subLabel && v.subLabel.toLowerCase().includes('cloud (latest)'), @@ -570,12 +606,15 @@ const DevDocTemplate: FC = (props) => { HOME_ANNOUNCEMENT_BANNER?.linkHref, ); + const bannerDismissKey = `announcement-${HOME_ANNOUNCEMENT_BANNER?.linkText || 'banner'}`; + return ( <>
@@ -597,6 +636,8 @@ const DevDocTemplate: FC = (props) => { {shouldShowAnnouncementBanner() && ( {HOME_ANNOUNCEMENT_BANNER?.linkHref && @@ -626,13 +667,17 @@ const DevDocTemplate: FC = (props) => { } /> )} +
} style={ !isPublicSiteOpen - ? { height: '100lvh' } - : { height: 'calc(100lvh - 65px)' } + ? { height: 'calc(100lvh - 44px)' } + : { height: 'calc(100lvh - 65px - 44px)' } } > {isPlayGround ? ( @@ -677,6 +722,9 @@ export const query = graphql` description } html + fields { + markdownBody + } } navNode: asciidoc(pageAttributes: { pageid: { eq: $navId } }) { document { @@ -718,4 +766,7 @@ type AsciiDocNode = { description?: string; }; html: string; + fields?: { + markdownBody?: string; + }; }; diff --git a/src/components/Docmap/index.scss b/src/components/Docmap/index.scss index 18282a2d4..f716d2234 100644 --- a/src/components/Docmap/index.scss +++ b/src/components/Docmap/index.scss @@ -1,100 +1,160 @@ -@import '../../assets/styles/variables.scss'; - -.docmapLinks { - width: -webkit-fill-available; - font-size: 14px; - height: 100lvh; - - .tocTitle { - margin: 0; - color: $disabledcolor; - line-height: $line-height-normal; - padding-left: 0; - } - div > ul > { - li { - border-left: 2px solid #d9d9d9; - padding-bottom: 25px !important; - } - li::before { - content: ''; - border-radius: 50%; - padding: 2px 6px; - background: #d9d9d9; - position: relative; - left: -7px; - height: 7px; - } - .active::before { - background: var(--secondary-color) !important; - } - } - - div { - ul { - margin-top: 10px; - list-style-type: none; - padding-left: 0; - background-color: var(--border-color) solid; - - li { - display: flex; - flex-wrap: wrap; - padding-bottom: 15px; - - a { - color: var(--primary-color); - font-weight: $font-weight-normal; - display: flex; - flex-grow: 1; - width: 80%; - margin: -2px 0 0 7px; - } - - a:hover { - color: var(--secondary-color); - } - - ul { - padding-left: $padding-nested-ul; - padding-top: 5px; - li a{ - color: var(--var-docmap-nested-color); - } - } - } - } - } - - #toctitle { - display: none; - } -} - -.defaultStyle { - color: var(--primary-color); - padding: 8px 0; - display: inline-block; -} - -.activeTag { - color: var(--secondary-color) !important; -} - -@media screen and (min-width: $tablet-resolution-min) and (max-width: $tablet-resolution-max) { - .docmapLinks { - display: none; - } - .header-banner .header-banner-text { - width: 100% !important; - } - .searchInputBanner .searchInputContainer { - width: 100% !important; - } -} - -@media screen and (max-width: $tablet-resolution-max) { - .docmapLinks { - display: none; - } -} +@import '../../assets/styles/variables.scss'; + +.docmapLinks { + width: 100%; + font-size: 14px; + + .tocTitle { + margin: 0 0 14px 0; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.07em; + text-transform: uppercase; + color: var(--icon-color, #6b7280); + padding: 0; + line-height: 1; + } + + /* Root list — vertical timeline with connector line */ + div > ul { + list-style: none; + margin: 0; + padding: 0; + border-left: 2px solid var(--border-color, #e5e7eb); + margin-left: 6px; + + > li { + position: relative; + padding: 0 0 14px 20px; + + /* Dot on connector line */ + &::before { + content: ''; + position: absolute; + left: -5px; + top: 7px; + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--border-color, #d1d5db); + transition: background 0.15s ease; + } + + &.active::before, + &:has(a.active)::before { + background: var(--secondary-color, #0568fa); + } + + > a { + display: block; + color: var(--primary-color); + font-size: 14px; + font-weight: 500; + line-height: 1.5; + text-decoration: none; + padding: 2px 0; + transition: color 0.15s ease; + + &:hover { + color: var(--secondary-color, #0568fa); + } + + &.active { + color: var(--secondary-color, #0568fa); + font-weight: 600; + } + } + + /* Nested ul — sub-sections */ + ul { + list-style: none; + margin: 8px 0 0 0; + padding: 0 0 0 12px; + + li { + padding: 5px 0; + + a { + display: block; + color: var(--var-docmap-nested-color, #6b7280); + font-size: 13px; + font-weight: 400; + line-height: 1.45; + text-decoration: none; + transition: color 0.15s ease; + + &:hover { + color: var(--secondary-color, #0568fa); + } + + &.active { + color: var(--secondary-color, #0568fa); + font-weight: 600; + } + } + } + } + } + } + + div { + ul { + margin-top: 0; + + li { + display: block; + flex-wrap: unset; + padding-bottom: 0; + + a { + width: auto; + margin: 0; + flex-grow: unset; + } + + a:hover { + color: var(--secondary-color); + } + + ul { + padding-top: 2px; + li a { + color: var(--var-docmap-nested-color); + } + } + } + } + } + + #toctitle { + display: none; + } +} + +.defaultStyle { + color: var(--primary-color); + padding: 8px 0; + display: inline-block; +} + +.activeTag { + color: var(--secondary-color) !important; +} + +@media screen and (min-width: $tablet-resolution-min) and (max-width: $tablet-resolution-max) { + .docmapLinks { + display: none; + } + .header-banner .header-banner-text { + width: 100% !important; + } + .searchInputBanner .searchInputContainer { + width: 100% !important; + } +} + +@media screen and (max-width: $tablet-resolution-max) { + .docmapLinks { + display: none; + } +} diff --git a/src/components/Document/helper.tsx b/src/components/Document/helper.tsx index a1351b3fc..86287fb78 100644 --- a/src/components/Document/helper.tsx +++ b/src/components/Document/helper.tsx @@ -1,6 +1,6 @@ import React from 'react'; import hljs from 'highlight.js'; -import { RiFileCopyFill } from '@react-icons/all-files/ri/RiFileCopyFill'; +import { FiCopy } from '@react-icons/all-files/fi/FiCopy'; import t from '../../utils/lang-utils'; import { getHTMLFromComponent } from '../../utils/react-utils'; import selectors from '../../constants/selectorsContant'; @@ -10,48 +10,97 @@ export const enableCopyToClipboard = ( ...args: HTMLElement[] ) => { element.addEventListener('click', () => { - const textareaElement = document.createElement('textarea'); - textareaElement.value = (args[0] as HTMLElement).innerText; - element.parentElement.appendChild(textareaElement); - textareaElement.select(); - document.execCommand('copy'); - element.parentElement.removeChild(textareaElement); + const text = (args[0] as HTMLElement).innerText; + + /* Copy to clipboard — prefer modern API, fall back to execCommand */ + if (navigator.clipboard) { + navigator.clipboard.writeText(text).catch(() => { + const ta = document.createElement('textarea'); + ta.value = text; + document.body.appendChild(ta); + ta.select(); + document.execCommand('copy'); + document.body.removeChild(ta); + }); + } else { + const ta = document.createElement('textarea'); + ta.value = text; + document.body.appendChild(ta); + ta.select(); + document.execCommand('copy'); + document.body.removeChild(ta); + } + + /* Tooltip appended inside the button so it floats via absolute positioning */ + if (element.querySelector('.tooltip')) return; const divElement = document.createElement('div'); divElement.classList.add('tooltip'); const spanElement = document.createElement('span'); spanElement.classList.add('tooltiptext'); spanElement.innerText = t('CODE_COPY_BTN_AFTER_CLICK_TEXT'); divElement.appendChild(spanElement); - element.parentElement.appendChild(divElement); - /* To remove copy tooltip */ + element.appendChild(divElement); setTimeout(() => { - element.parentElement.removeChild(divElement); - }, 500); + if (element.contains(divElement)) { + element.removeChild(divElement); + } + }, 1500); }); }; export const customizeDocContent = () => { - /* To get all the code blocks from document */ + /* + * Restructure code blocks to have a permanent header bar: + * lang label (left) · copy button (right) + * + * Before:
...
+ * After:
+ *
+ * JS + * + *
+ *
...
+ *
+ * + * Guard against double-processing on re-render. + */ document.querySelectorAll(selectors.codeBlocks).forEach((tag) => { + const pre = tag.parentElement; + if (!pre || pre.parentElement?.classList.contains('code-block-wrapper')) return; + + /* ── Header bar ── */ + const header = document.createElement('div'); + header.classList.add('code-block-header'); + + /* Language label (left) */ + const langSpan = document.createElement('span'); + const rawLang = tag.getAttribute('data-lang') || ''; + langSpan.classList.add('lang'); + langSpan.innerText = rawLang; + header.appendChild(langSpan); + + /* Copy button (right) */ const buttonElement = document.createElement('button'); buttonElement.setAttribute('class', 'copyButton'); - enableCopyToClipboard(buttonElement, tag as HTMLElement); + buttonElement.setAttribute('aria-label', t('CODE_COPY_BTN_HOVER_TEXT')); + buttonElement.setAttribute('title', t('CODE_COPY_BTN_HOVER_TEXT')); + const imageElement = document.createElement('span'); - imageElement.innerHTML = getHTMLFromComponent( - , - 'copyIcon', - ); + imageElement.innerHTML = getHTMLFromComponent(, 'copyIcon'); buttonElement.appendChild(imageElement); - const spanElement = document.createElement('span'); - spanElement.innerText = tag.getAttribute('data-lang'); - spanElement.classList.add('lang'); - const wrapperDiv = document.createElement('div'); - wrapperDiv.classList.add('wrapperContainer'); - wrapperDiv.appendChild(spanElement); - wrapperDiv.appendChild(buttonElement); - tag.parentElement.appendChild(wrapperDiv); + + enableCopyToClipboard(buttonElement, tag as HTMLElement); + header.appendChild(buttonElement); + + /* ── Wrap pre in code-block-wrapper ── */ + const wrapper = document.createElement('div'); + wrapper.classList.add('code-block-wrapper'); + pre.parentNode?.insertBefore(wrapper, pre); + wrapper.appendChild(header); + wrapper.appendChild(pre); }); - /* Add copy buttons to marked table cells */ + + /* Add copy buttons to marked table cells (unchanged) */ document .querySelectorAll('.copy-cell-table table, table.copy-cell-table') .forEach((table) => { @@ -59,9 +108,8 @@ export const customizeDocContent = () => { .querySelectorAll('tbody tr td:nth-child(2)') .forEach((cell) => { const cellElement = cell as HTMLElement; - if (cellElement.querySelector('.tableCopyButton')) { - return; - } + if (cellElement.querySelector('.tableCopyButton')) return; + cellElement.classList.add('tableCopyCell'); const contentWrapper = document.createElement('div'); contentWrapper.classList.add('tableCopyContent'); @@ -69,33 +117,26 @@ export const customizeDocContent = () => { contentWrapper.appendChild(cellElement.firstChild); } cellElement.appendChild(contentWrapper); + const buttonElement = document.createElement('button'); buttonElement.setAttribute('class', 'tableCopyButton'); - buttonElement.setAttribute( - 'aria-label', - t('CODE_COPY_BTN_HOVER_TEXT'), - ); - buttonElement.setAttribute( - 'title', - t('CODE_COPY_BTN_HOVER_TEXT'), - ); + buttonElement.setAttribute('aria-label', t('CODE_COPY_BTN_HOVER_TEXT')); + buttonElement.setAttribute('title', t('CODE_COPY_BTN_HOVER_TEXT')); + enableCopyToClipboard(buttonElement, contentWrapper); const imageElement = document.createElement('span'); - imageElement.innerHTML = getHTMLFromComponent( - , - 'copyIcon', - ); + imageElement.innerHTML = getHTMLFromComponent(, 'copyIcon'); buttonElement.appendChild(imageElement); cellElement.appendChild(buttonElement); }); }); - /* To highlight code snippets */ + + /* Syntax highlight */ document.querySelectorAll('pre code').forEach((block) => { hljs.highlightBlock(block as HTMLElement); }); }; -// Checks if the HTML element is in viewport. const isInViewport = (el: HTMLElement) => { const rect = el.getBoundingClientRect(); return rect.top >= 0 && rect.left >= 0; @@ -104,28 +145,21 @@ const isInViewport = (el: HTMLElement) => { export const addScrollListener = () => { document.addEventListener('scroll', () => { const subLinks = document.querySelectorAll(selectors.docmapLinks); - // console.log(subLinks); let flag = false; subLinks.forEach((link, i: number) => { const href = (link as HTMLAnchorElement).href; const hash = href.split('#')[1]; if (hash) { - const targetElement = document.getElementById(hash) - ?.parentElement; + const targetElement = document.getElementById(hash)?.parentElement; if (targetElement) { - const isVisible = isInViewport( - targetElement as HTMLElement, - ); + const isVisible = isInViewport(targetElement as HTMLElement); if (isVisible && !flag) { link.classList.add('active'); link.parentElement?.classList.add('active'); if ( - link?.parentElement?.parentElement?.parentElement - ?.tagName === 'LI' + link?.parentElement?.parentElement?.parentElement?.tagName === 'LI' ) { - link?.parentElement?.parentElement?.parentElement?.classList?.add( - 'active', - ); + link?.parentElement?.parentElement?.parentElement?.classList?.add('active'); } flag = !flag; } else { diff --git a/src/components/Document/index.scss b/src/components/Document/index.scss index ff4d74ec1..c7efbcdc7 100644 --- a/src/components/Document/index.scss +++ b/src/components/Document/index.scss @@ -7,6 +7,12 @@ width: calc(98%); color: var(--primary-color); + .document-toolbar { + float: right; + margin-left: 16px; + padding-top: 6px; + } + .documentView { min-height: 75vh; // padding: $padding-md $padding-md 0; @@ -46,13 +52,14 @@ code { background: var(--code-text-bg); font-family: $font-family-code; - font-size: 13px; - border: 0.5px solid #C0C6CF; - padding: 2px 4px 2px 4px; + font-size: 12.5px; + border: 1px solid var(--border-color); + border-radius: 4px; + padding: 2px 5px; color: var(--primary-color); a { - color: var(--primary-color); + color: var(--secondary-color); } } } @@ -69,68 +76,136 @@ margin: 0 5px 0 5px; } + /* ── Code block wrapper — holds header bar + pre ─────────────────── */ + .code-block-wrapper { + margin: 16px 0; + border-radius: 8px; + border: 1px solid var(--border-color); + overflow: hidden; + } + + /* ── Code block header bar ────────────────────────────────────────── */ + .code-block-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 7px 12px; + background: rgba(255, 255, 255, 0.05); + border-bottom: 1px solid var(--border-color); + + .lang { + font-size: 12px; + font-weight: 600; + letter-spacing: 0.05em; + text-transform: uppercase; + color: var(--text-color-code-lang, #8b949e); + font-family: $font-family-code; + } + + .copyButton { + display: inline-flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + padding: 0; + color: var(--text-color-code-lang, #8b949e); + background: transparent; + border: 1px solid rgba(255, 255, 255, 0.15); + border-radius: 5px; + cursor: pointer; + transition: background 0.15s ease, color 0.15s ease; + position: relative; + + &:hover { + background: rgba(255, 255, 255, 0.1); + color: #fff; + } + + .copyIcon { + height: 14px; + width: 14px; + display: block; + flex-shrink: 0; + } + + /* Tooltip floats below — absolutely positioned so it doesn't shift layout */ + .tooltip { + position: absolute; + top: calc(100% + 6px); + right: 0; + z-index: 10; + pointer-events: none; + + .tooltiptext { + display: block; + background: #1d232f; + color: #fff; + font-size: 11px; + padding: 3px 8px; + border-radius: 4px; + white-space: nowrap; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35); + } + } + } + } + pre { white-space: pre-wrap; - background: var(--code-block-color); + background: var(--code-block-color, #0d1117); color: var(--code-text-color); width: auto; - padding: 20px 10px 10px 10px; - display: flex; + /* Padding: extra top/bottom spacing as requested */ + padding: 20px 18px 20px 18px; + display: block; font-family: $font-family-code; - justify-content: space-between; overflow: auto; font-size: $font-size-code; max-height: 700px; line-height: $line-height-code; - box-shadow: var(--box-shadow); + border-radius: 0; + border: none; + box-shadow: none; + margin: 0; + + /* When NOT inside wrapper (e.g. admonition code), apply standalone style */ + &:not(.code-block-wrapper pre) { + border-radius: 8px; + border: 1px solid var(--border-color); + margin: 16px 0; + } } pre.highlight { - &:hover { - .wrapperContainer { - visibility: visible; - } - } - code { - max-width: 100%; + width: 100%; font-family: $font-family-code; - padding-top: 10px; + padding-top: 0; + display: block; } + } - .wrapperContainer { - max-width: 15%; - position: relative; - visibility: hidden; - padding: 25px; + /* Light mode: keep code blocks dark for better readability */ + #wrapper[data-theme='light'] & { + .code-block-wrapper { + border-color: #2d333b; - .lang { - position: absolute; - top: -20px; - padding: 5px; - right: 36px; - text-transform: uppercase; - color: var(--text-color-code-lang); - } - - .copyButton { - position: absolute; - top: -15px; - padding: 5px; - right: 0px; - border: 0; - background: transparent; + .code-block-header { + background: #22272e; + border-bottom-color: #2d333b; - img { - width: 15px; + .lang { color: #8b949e; } + .copyButton { + border-color: rgba(255, 255, 255, 0.15); + color: #8b949e; + &:hover { background: rgba(255, 255, 255, 0.1); color: #cdd9e5; } } } - - .tooltip { - position: absolute; - top: 15px; - right: -8px; - } + } + pre { + background: #1e2430; + color: #cdd9e5; } } diff --git a/src/components/Document/index.tsx b/src/components/Document/index.tsx index 1915e558c..916213f1b 100644 --- a/src/components/Document/index.tsx +++ b/src/components/Document/index.tsx @@ -4,6 +4,8 @@ import { customizeDocContent, addScrollListener } from './helper'; import Footer from '../Footer'; import Breadcrums from '../Breadcrums'; import LinkableHeader from '../LinkableHeader'; +import WasThisHelpful from '../WasThisHelpful'; +import CopyPageDropdown from '../CopyPageDropdown'; import { HOME_PAGE_ID } from '../../configs/doc-configs'; import parse, { HTMLReactParserOptions, domToReact, attributesToProps } from 'html-react-parser'; @@ -12,8 +14,9 @@ const Document = (props: { docTitle: string; docContent: string; isPublicSiteOpen: boolean; - shouldShowRightNav: boolean + shouldShowRightNav: boolean; breadcrumsData: any; + markdownBody?: string; }) => { useEffect(() => { customizeDocContent(); @@ -29,33 +32,42 @@ const Document = (props: { ['h2', 'h3', 'h4'].includes(domNode.name) && !domNode.parent?.attribs?.class?.includes('non-link') ) { - const props = attributesToProps(domNode.attribs); - return ( + const nodeProps = attributesToProps(domNode.attribs); + return ( {domToReact(domNode.children, options)} ) } + return undefined; } }; + const isHomePage = props.pageid === HOME_PAGE_ID; + return (
- {props.pageid !== HOME_PAGE_ID && ( + {!isHomePage && ( )} + {!isHomePage && ( +
+ +
+ )}
{parse(props.docContent, options)}
+ {!isHomePage && props.isPublicSiteOpen && ( + + )} {props.isPublicSiteOpen &&
}
); diff --git a/src/components/Dropdown/index.scss b/src/components/Dropdown/index.scss index 81c383205..0ee4cf5c6 100644 --- a/src/components/Dropdown/index.scss +++ b/src/components/Dropdown/index.scss @@ -1,7 +1,7 @@ @import '../../assets/styles/variables.scss'; .dropdownWrapper { - padding: 5px; + padding: 10px; .dropdown { overflow: hidden; @media screen and (min-width: $tablet-resolution-min) and (max-width: $tablet-resolution-max) { diff --git a/src/components/Header/index.scss b/src/components/Header/index.scss index beb35a8fc..be349e2ed 100644 --- a/src/components/Header/index.scss +++ b/src/components/Header/index.scss @@ -1,104 +1,200 @@ -@import '../../assets/styles/variables.scss'; - -header { - background: var(--header-color); - position: absolute; - top: 0; - left: 0; - width: 100%; - height: $header-height; - border-bottom: var(--header-border-color); - z-index: $header-zIndex; - - .logo-link{ - color: white; - } - - .thoughtspotLogo { - vertical-align: middle; - width: $header-logo-width; - padding-right: 20px; - } - - .headerWrapper { - display: flex; - justify-content: space-between; - padding: 5px 10px 10px 5px; - width: 100%; - } - - .logo { - padding-right: 0px; - } - - .docsWrapper { - margin-left: 20px; - padding-left: 20px; - color: $lightgrey; - cursor: pointer; - } - - .headerLink { - a { - margin-left: $header-link-margin; - padding-left: 40px; - padding-right: 20px; - cursor: pointer; - color: var(--header-link-color); - font-weight: bold; - } - @media (max-width: 820px) { - display: none; - } - } - .dropdownWrapper { - @media (max-width: $mobile-resolution-max) { - display: none; - } - } - .header-logo { - @media (max-width: 820px) { - flex-grow: 1; - } - } - - .headerLinkSelf { - a { - margin-left: $header-link-margin; - cursor: pointer; - color: $lightgrey; - } - @media (max-width: 820px) { - display: none; - } - } - .themeSwitcher { - cursor: pointer; - padding: 5px 20px 0 0; - } - .theme-version-wrapper { - display: flex; - flex-basis: 22%; - max-width: 220px; - } - .theme-icon, - .references .icon { - color: $white; - height: 1.25em; - width: 1.25em; - } - .references { - padding-top: 5px; - display: flex; - @media (max-width: $mobile-resolution-max) { - display: none; - } - .icon-item { - padding-right: 15px; - cursor: pointer; - :last-child { - padding-right: 0; - } - } - } -} +@import '../../assets/styles/variables.scss'; + +header { + background: var(--header-color, #08072C); + position: absolute; + top: 0; + left: 0; + width: 100%; + height: $header-height; + z-index: $header-zIndex; + + /* Embedded mode hides top header */ + .embedded-mode & { + display: none; + } + + .containerWrapper { + height: 100%; + padding: 0 20px; + display: flex; + align-items: center; + } + + .headerWrapper { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + gap: 12px; + } + + /* Logo — same size as original site */ + .header-logo { + flex-shrink: 0; + + @media (max-width: 820px) { + flex-grow: 1; + } + } + + .logo-link { + display: flex; + align-items: center; + color: white; + text-decoration: none; + } + + .logo { + margin: 5px; + padding: 5px 0 5px 5px; + } + + .thoughtspotLogo { + width: $header-logo-width; /* 273px — same as original */ + vertical-align: middle; + padding-right: 20px; + } + + /* Primary navigation */ + .header-nav { + display: flex; + align-items: center; + gap: 2px; + flex: 1; + padding-left: 8px; + + @media (max-width: 820px) { + display: none; + } + } + + .header-nav-link { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 6px 14px 0 0; + color: rgba(255, 255, 255, 0.85); + font-size: 15px; + font-weight: 700; + text-decoration: none; + border-radius: 6px; + border: none; + background: transparent; + cursor: pointer; + transition: background 0.15s ease, color 0.15s ease; + font-family: 'Optimo-Plain', sans-serif; + white-space: nowrap; + + &:hover { + background: rgba(255, 255, 255, 0.1); + color: #fff; + } + } + + /* Resources dropdown */ + .header-dropdown { + position: relative; + .header-chevron { + width: 14px; + height: 14px; + transition: transform 0.15s ease; + } + + &-trigger[aria-expanded='true'] .header-chevron { + transform: rotate(180deg); + } + + &-menu { + position: absolute; + top: calc(100% + 8px); + left: 0; + background: #1d1d1d; + border: 1px solid rgba(255, 255, 255, 0.12); + border-radius: 10px; + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5); + min-width: 200px; + padding: 6px; + z-index: 100; + animation: dropdownFadeIn 0.12s ease; + } + + &-item { + display: flex; + align-items: center; + gap: 10px; + padding: 9px 12px; + color: rgba(255, 255, 255, 0.85); + font-size: 14px; + text-decoration: none; + border-radius: 6px; + transition: background 0.1s ease; + + &:hover { + background: rgba(255, 255, 255, 0.08); + color: #fff; + } + + .dropdown-item-icon { + width: 15px; + height: 15px; + color: rgba(255, 255, 255, 0.5); + flex-shrink: 0; + } + + .external-link-icon { + width: 11px; + height: 11px; + color: rgba(255, 255, 255, 0.3); + margin-left: auto; + flex-shrink: 0; + } + } + } + + /* Right side — version + theme toggle */ + .header-right { + display: flex; + align-items: center; + gap: 8px; + flex-shrink: 0; + padding-right: 5px; + margin-right: 5px; + } + + /* Light / Dark toggle — icon only */ + .theme-toggle-btn { + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border-radius: 6px; + border: 1px solid rgba(255, 255, 255, 0.2); + background: transparent; + cursor: pointer; + color: rgba(255, 255, 255, 0.85); + transition: background 0.15s ease, color 0.15s ease; + + &:hover { + background: rgba(255, 255, 255, 0.08); + color: #fff; + } + + .theme-icon { + width: 15px; + height: 15px; + } + } +} + +@keyframes dropdownFadeIn { + from { + opacity: 0; + transform: translateY(-4px); + } + to { + opacity: 1; + transform: translateY(0); + } +} diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index 5706adb50..199b28aea 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -1,16 +1,18 @@ -import React from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { useResizeDetector } from 'react-resize-detector'; import { IconContext } from '@react-icons/all-files'; import { RiMoonClearLine } from '@react-icons/all-files/ri/RiMoonClearLine'; import { FiSun } from '@react-icons/all-files/fi/FiSun'; import { RiDiscordLine } from '@react-icons/all-files/ri/RiDiscordLine'; import { FiGithub } from '@react-icons/all-files/fi/FiGithub'; +import { FiChevronDown } from '@react-icons/all-files/fi/FiChevronDown'; +import { FiUsers } from '@react-icons/all-files/fi/FiUsers'; +import { FiHelpCircle } from '@react-icons/all-files/fi/FiHelpCircle'; +import { FiExternalLink } from '@react-icons/all-files/fi/FiExternalLink'; import TSLogo from '../../assets/svg/ts-logo-white-developer.svg'; import t from '../../utils/lang-utils'; import Dropdown from '../Dropdown'; -// import References from './references'; -import Menu from '../Menu'; import { MAX_MOBILE_RESOLUTION } from '../../constants/uiConstants'; import './index.scss'; @@ -20,38 +22,49 @@ const Header = (props: { isDarkMode: boolean; }) => { const { width, ref } = useResizeDetector(); + const [resourcesOpen, setResourcesOpen] = useState(false); + const resourcesRef = useRef(null); const isMaxMobileResolution = !(width < MAX_MOBILE_RESOLUTION); - const headerLinks = [ + useEffect(() => { + const handleClickOutside = (e: MouseEvent) => { + if (resourcesRef.current && !resourcesRef.current.contains(e.target as Node)) { + setResourcesOpen(false); + } + }; + document.addEventListener('mousedown', handleClickOutside); + return () => document.removeEventListener('mousedown', handleClickOutside); + }, []); + + const handleThemeToggle = () => { + const newDark = !props.isDarkMode; + props.setDarkMode(newDark); + localStorage.setItem('theme', newDark ? 'dark' : 'light'); + localStorage.setItem('themeMode', newDark ? 'dark' : 'light'); + }; + + const resourceLinks = [ { name: 'Community', - link: - 'https://community.thoughtspot.com/customers/s/topic/0TO3n000000erVyGAI/developers-embedding', - external: true, + link: 'https://community.thoughtspot.com/customers/s/topic/0TO3n000000erVyGAI/developers-embedding', + icon: FiUsers, }, { name: 'Support', link: 'https://www.thoughtspot.com/support', - external: true, + icon: FiHelpCircle, }, { name: 'GitHub', link: 'https://github.com/thoughtspot/visual-embed-sdk', - external: true, icon: FiGithub, }, { name: 'Discord', link: 'https://discord.gg/YBWP65W6te', - external: true, icon: RiDiscordLine, }, - // { - // name: 'Product documentation', - // link: 'https://docs.thoughtspot.com', - // external: true, - // }, ]; return ( @@ -61,6 +74,7 @@ const Header = (props: { ref={ref as React.RefObject} >
+ {/* Logo — retained as-is */} - -
- {isMaxMobileResolution && ( -
- + {/* Docs link — points to product docs home */} + + Docs + + + {/* Resources dropdown */} +
+ + {resourcesOpen && ( +
+ {resourceLinks.map((item) => { + const Icon = item.icon; + return ( + setResourcesOpen(false)} + > + + + + {item.name} + + + + + ); + })} +
+ )}
- )} + + )} + +
+ + {/* Light / Dark toggle only — Auto applied silently on first load */} + {isMaxMobileResolution && ( + + )}
- {/* */}
diff --git a/src/components/LeftSidebar/index.scss b/src/components/LeftSidebar/index.scss index 32d2cc3f0..ae823fe2e 100644 --- a/src/components/LeftSidebar/index.scss +++ b/src/components/LeftSidebar/index.scss @@ -51,46 +51,64 @@ .asideDisplay { display: block; } + .searchInputLeftNav { - margin-top: 30px; - padding-right: 30px; + margin-top: 16px; + padding-right: 16px; + .searchIconSmall { position: relative; left: 30px; - height: 20px; - width: 20px; + top: 1px; + height: 18px; + width: 18px; + color: var(--icon-color, #6b7280); } input { width: 100%; border: 1px solid var(--border-color); border-radius: 6px; - height: $height-search-input; - padding-left: $padding-left-search-input; - font-size: $font-size-normal; + height: 36px; + padding: 0 8px 0 $padding-left-search-input; + font-size: 14px; + line-height: 36px; color: var(--primary-color); font-family: $font-family-doc; - padding-bottom: 1px; background: var(--body-background-color); + box-sizing: border-box; + outline: none; + + &::placeholder { + color: var(--icon-color, #6b7280); + } + + &:focus { + border-color: var(--secondary-color, #0568fa); + box-shadow: 0 0 0 2px rgba(5, 104, 250, 0.12); + } } } .aside { padding: 0 0 0 10px; width: 100%; - border-right: 0.5px var(--border-color) solid; + border-right: 0.5px solid var(--border-color); left: $gutter; height: 100%; overflow-y: auto; - background: var(--nav-bar-color); + background: var(--nav-bar-color, #f1f4f8); .subHeading { margin: $gutter; padding-bottom: $padding-sm; padding-left: $padding-md; - font-size: $font-size-normal; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.07em; + text-transform: uppercase; width: 100%; - color: var(--side-nav-text); + color: var(--icon-color, #6b7280); } ul { @@ -102,7 +120,7 @@ .navWrapper { margin-bottom: 12px; - padding-top: 2px; + padding-top: 5px; & > .ulist { & > ul > li { @@ -173,8 +191,8 @@ top: 2px; float: right; } - } - } + } + } .navWrapper.withHeaderFooter { padding-bottom: 50px; @@ -182,14 +200,17 @@ } a { - font-size: $font-size-normal; + font-size: 14px; font-weight: $font-weight-normal; width: 100%; display: inline-block; + line-height: 1.4; } hr { - display: none; + border: none; + border-top: 1px solid var(--sidebar-connector-color, #d1d5db); + margin: 8px 8px 8px 0; } a[target='_blank'] { @@ -229,6 +250,7 @@ display: flex; justify-content: center; } + .node-child { padding-left: 15px; } @@ -247,9 +269,10 @@ .resizable-container { position: relative; height: 100%; + border: 0; } -.resizable{ +.resizable { height: 100%; } diff --git a/src/components/SecondaryHeader/index.scss b/src/components/SecondaryHeader/index.scss new file mode 100644 index 000000000..b0f361409 --- /dev/null +++ b/src/components/SecondaryHeader/index.scss @@ -0,0 +1,64 @@ +@import '../../assets/styles/variables.scss'; + +.secondary-header { + background: var(--nav-bar-color, #f1f4f8); + border-bottom: 1.5px solid var(--secondary-header-border, #e2e8f0); + position: sticky; + top: $header-height; + z-index: $header-zIndex - 1; + width: 100%; + height: 48px; + + &__inner { + padding: 0 25px; + } + + &__tabs { + display: flex; + align-items: center; + gap: 0; + list-style: none; + margin: 0; + padding: 0; + overflow-x: auto; + scrollbar-width: none; + + &::-webkit-scrollbar { + display: none; + } + } + + &__tab { + position: relative; + display: inline-flex; + align-items: center; + padding: 12px 20px 12px $padding-sm; + font-size: 14px; + font-weight: 600; + color: var(--secondary-header-text, #374151); + background: transparent; + border: none; + cursor: pointer; + white-space: nowrap; + font-family: 'Optimo-Plain', sans-serif; + transition: color 0.15s ease; + border-bottom: 2px solid transparent; + margin-bottom: -1px; + letter-spacing: 0.01em; + + &:hover { + color: var(--secondary-header-active, #0568fa); + } + + &.active { + color: var(--secondary-header-active, #0568fa); + border-bottom-color: var(--secondary-header-active, #0568fa); + font-weight: 700; + } + } +} + +/* When top header is hidden (embedded mode), secondary header sticks to top */ +.embedded-mode .secondary-header { + top: 0; +} diff --git a/src/components/SecondaryHeader/index.tsx b/src/components/SecondaryHeader/index.tsx new file mode 100644 index 000000000..35c0e2a0a --- /dev/null +++ b/src/components/SecondaryHeader/index.tsx @@ -0,0 +1,105 @@ +import React from 'react'; +import { navigate } from 'gatsby'; +import './index.scss'; + +export type DocCategory = + | 'all' + | 'embedding' + | 'mcp-server' + | 'spottercode' + | 'apis-sdk' + | 'whats-new'; + +export const CATEGORY_LABELS: Record = { + all: 'All docs', + embedding: 'Embedding', + 'mcp-server': 'MCP server', + spottercode: 'SpotterCode', + 'apis-sdk': 'APIs & SDK', + 'whats-new': "What's new", +}; + +/* + * Landing page for each category — the first page shown when a tab is clicked. + * These are the pageid values from the AsciiDoc source. + */ +export const CATEGORY_LANDING: Record = { + all: '/introduction', + embedding: '/introduction', + 'mcp-server': '/mcp-ts-server', + spottercode: '/spottercode', + 'apis-sdk': '/rest-api-v2', + 'whats-new': '/whats-new', +}; + +/* + * Page IDs that belong to each category. + * Used to auto-highlight the active tab when navigating directly to a page. + * + * Sidebar filtering note: + * The nav.adoc is a superset of all pages. To filter the sidebar per category, + * the nav.adoc would need to be split into per-category nav files (e.g. nav-embedding.adoc, + * nav-mcp.adoc) and the DevDocTemplate would pass the appropriate navId based on + * the active category. Until then, the sidebar shows all content and the secondary + * header acts as a jump-to-category navigation. + */ +export const CATEGORY_PAGEIDS: Record = { + all: [], + embedding: [ + 'introduction', 'embed-sdk', 'full-embed', 'search-embed', 'liveboard-embed', + 'viz-embed', 'app-embed', 'natural-language-search-embed', 'embed-events', + 'custom-actions', 'authentication', 'trusted-auth', 'saml-sso', 'oidc', + 'security-settings', 'custom-styles', 'runtime-filters', 'runtime-sort', + 'runtime-parameters', 'embed-nav', 'page-load-optimization', 'react-components', + 'web-components', 'pinboard-embed', 'faqs', 'migration', + ], + 'mcp-server': ['mcp-server', 'mcp-ts-server', 'mcp-intro'], + spottercode: ['spottercode', 'spotter-overview', 'spotter-code', 'spotter-apis'], + 'apis-sdk': [ + 'rest-api-v2', 'restV2-playground', 'graphql-play-ground', 'typedoc', + 'sdk-overview', 'rest-api-v1', + ], + 'whats-new': ['whats-new', 'changelog', 'release-notes', 'deprecations'], +}; + +const SecondaryHeader = (props: { + activeCategory: DocCategory; + onCategoryChange: (category: DocCategory) => void; +}) => { + const { activeCategory, onCategoryChange } = props; + + const categories: DocCategory[] = [ + 'embedding', 'mcp-server', 'spottercode', 'apis-sdk', 'whats-new', + ]; + + const handleClick = (cat: DocCategory) => { + onCategoryChange(cat); + const landing = CATEGORY_LANDING[cat]; + if (landing) { + navigate(landing); + } + }; + + return ( + + ); +}; + +export default SecondaryHeader; diff --git a/src/components/WasThisHelpful/index.scss b/src/components/WasThisHelpful/index.scss new file mode 100644 index 000000000..7876f85ee --- /dev/null +++ b/src/components/WasThisHelpful/index.scss @@ -0,0 +1,173 @@ +@import '../../assets/styles/variables.scss'; + +.was-helpful { + margin: 40px 0 20px; + padding: 20px 24px; + background: var(--was-helpful-bg, #f9fafb); + border: 1px solid var(--was-helpful-border, #e5e7eb); + border-radius: 10px; + + &__prompt { + font-size: 14px; + font-weight: 600; + color: var(--primary-color); + margin-bottom: 12px; + } + + &__actions { + display: flex; + gap: 8px; + align-items: center; + } + + &__btn { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 7px 16px; + font-size: 13px; + font-weight: 500; + border: 1px solid var(--border-color, #d1d5db); + border-radius: 6px; + background: var(--body-background-color); + color: var(--primary-color); + cursor: pointer; + font-family: 'Optimo-Plain', sans-serif; + transition: all 0.15s ease; + + &:hover { + border-color: var(--secondary-color, #0568fa); + color: var(--secondary-color, #0568fa); + background: rgba(5, 104, 250, 0.04); + } + + &.active { + border-color: var(--secondary-color, #0568fa); + background: rgba(5, 104, 250, 0.08); + color: var(--secondary-color, #0568fa); + } + + &--up.active { + border-color: #16a34a; + background: rgba(22, 163, 74, 0.08); + color: #15803d; + } + + &--down.active { + border-color: #dc2626; + background: rgba(220, 38, 38, 0.06); + color: #b91c1c; + } + } + + &__emoji { + font-size: 16px; + line-height: 1; + } + + &__followup { + margin-top: 16px; + border-top: 1px solid var(--border-color, #e5e7eb); + padding-top: 16px; + } + + &__followup-text { + font-size: 13px; + font-weight: 600; + color: var(--primary-color); + margin: 0 0 10px; + } + + &__form { + display: flex; + flex-direction: column; + gap: 10px; + } + + &__textarea { + width: 100%; + padding: 10px 12px; + font-size: 13px; + font-family: 'Optimo-Plain', sans-serif; + border: 1px solid var(--border-color, #d1d5db); + border-radius: 6px; + background: var(--body-background-color); + color: var(--primary-color); + resize: vertical; + outline: none; + transition: border-color 0.15s ease; + + &:focus { + border-color: var(--secondary-color, #0568fa); + box-shadow: 0 0 0 3px rgba(5, 104, 250, 0.1); + } + + &::placeholder { + color: var(--icon-color, #9ca3af); + } + } + + &__form-actions { + display: flex; + gap: 8px; + align-items: center; + } + + &__submit { + padding: 7px 18px; + font-size: 13px; + font-weight: 600; + background: var(--secondary-color, #0568fa); + color: #fff; + border: none; + border-radius: 6px; + cursor: pointer; + font-family: 'Optimo-Plain', sans-serif; + transition: opacity 0.15s ease; + + &:hover { + opacity: 0.9; + } + } + + &__skip { + padding: 7px 14px; + font-size: 13px; + font-weight: 500; + background: transparent; + color: var(--icon-color, #6b7280); + border: 1px solid var(--border-color, #d1d5db); + border-radius: 6px; + cursor: pointer; + font-family: 'Optimo-Plain', sans-serif; + transition: all 0.15s ease; + + &:hover { + color: var(--primary-color); + border-color: var(--primary-color); + } + } + + &__thanks { + font-size: 14px; + font-weight: 500; + color: #16a34a; + display: flex; + align-items: center; + gap: 8px; + + &::before { + content: '✓'; + display: inline-flex; + align-items: center; + justify-content: center; + width: 20px; + height: 20px; + background: #dcfce7; + border-radius: 50%; + font-size: 12px; + font-weight: 700; + flex-shrink: 0; + } + } +} diff --git a/src/components/WasThisHelpful/index.tsx b/src/components/WasThisHelpful/index.tsx new file mode 100644 index 000000000..7feaa918a --- /dev/null +++ b/src/components/WasThisHelpful/index.tsx @@ -0,0 +1,122 @@ +import React, { useState } from 'react'; +import './index.scss'; + +type FeedbackState = 'idle' | 'helpful' | 'not-helpful' | 'submitted'; + +/* + * Feedback submission hook. + * + * Currently logs to the browser console. + * To wire up a real endpoint, replace the console.log with a fetch() call: + * + * fetch('/api/feedback', { + * method: 'POST', + * headers: { 'Content-Type': 'application/json' }, + * body: JSON.stringify(payload), + * }); + * + * Common integrations: Google Analytics event, Segment track(), Airtable API, + * GitHub Discussions API, or a custom backend endpoint. + */ +const submitFeedback = (payload: { + url: string; + helpful: boolean; + comment?: string; +}) => { + console.log('[Feedback] Page feedback received:', payload); + /* ── Replace the line above with your endpoint call ── */ +}; + +const WasThisHelpful = () => { + const [state, setFeedbackState] = useState('idle'); + const [feedback, setFeedback] = useState(''); + + const pageUrl = typeof window !== 'undefined' ? window.location.href : ''; + + /* Thumbs up → immediately thank the user; no follow-up form */ + const handleThumbsUp = () => { + submitFeedback({ url: pageUrl, helpful: true }); + setFeedbackState('submitted'); + }; + + /* Thumbs down → show improvement text input */ + const handleThumbsDown = () => { + setFeedbackState('not-helpful'); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + submitFeedback({ url: pageUrl, helpful: false, comment: feedback }); + setFeedbackState('submitted'); + }; + + const handleSkip = () => { + submitFeedback({ url: pageUrl, helpful: false }); + setFeedbackState('submitted'); + }; + + if (state === 'submitted') { + return ( +
+
+ Thank you for your feedback! +
+
+ ); + } + + return ( +
+
+ Was this information helpful? +
+
+ + +
+ + {state === 'not-helpful' && ( +
+

What can we improve?

+
+