From d7c7aa708aadfb5ad7385af65b63c9b9dd4e37a2 Mon Sep 17 00:00:00 2001 From: Prashant Patil Date: Wed, 8 Jul 2026 15:32:35 +0530 Subject: [PATCH] SCAL-314115 code-based-custom-actions --- .../code-based-custom-actions/.gitignore | 24 + .../code-based-custom-actions/.stackblitzrc | 10 + .../code-based-custom-actions/README.md | 207 +++ .../code-based-custom-actions/index.html | 13 + .../package-lock.json | 1261 +++++++++++++++++ .../code-based-custom-actions/package.json | 18 + .../public/ts-logo.svg | 6 + .../code-based-custom-actions/src/main.ts | 156 ++ .../code-based-custom-actions/src/style.css | 100 ++ .../src/vite-env.d.ts | 12 + .../code-based-custom-actions/tsconfig.json | 24 + visual-embed/custom-actions/README.md | 18 +- 12 files changed, 1841 insertions(+), 8 deletions(-) create mode 100644 visual-embed/code-based-custom-actions/.gitignore create mode 100644 visual-embed/code-based-custom-actions/.stackblitzrc create mode 100644 visual-embed/code-based-custom-actions/README.md create mode 100644 visual-embed/code-based-custom-actions/index.html create mode 100644 visual-embed/code-based-custom-actions/package-lock.json create mode 100644 visual-embed/code-based-custom-actions/package.json create mode 100644 visual-embed/code-based-custom-actions/public/ts-logo.svg create mode 100644 visual-embed/code-based-custom-actions/src/main.ts create mode 100644 visual-embed/code-based-custom-actions/src/style.css create mode 100644 visual-embed/code-based-custom-actions/src/vite-env.d.ts create mode 100644 visual-embed/code-based-custom-actions/tsconfig.json diff --git a/visual-embed/code-based-custom-actions/.gitignore b/visual-embed/code-based-custom-actions/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/visual-embed/code-based-custom-actions/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/visual-embed/code-based-custom-actions/.stackblitzrc b/visual-embed/code-based-custom-actions/.stackblitzrc new file mode 100644 index 0000000..af7d79a --- /dev/null +++ b/visual-embed/code-based-custom-actions/.stackblitzrc @@ -0,0 +1,10 @@ +{ + "installDependencies": true, + "startCommand": "npm run dev", + "env": { + "VITE_TS_HOST": "https://training.thoughtspot.cloud", + "VITE_TS_USERNAME": "code-sandbox", + "VITE_TS_PASSWORD": "3mbed+#3xplz", + "VITE_LIVEBOARD_ID": "b504e160-3025-4508-a76a-1beb1f4b5eed" + } +} diff --git a/visual-embed/code-based-custom-actions/README.md b/visual-embed/code-based-custom-actions/README.md new file mode 100644 index 0000000..9e95050 --- /dev/null +++ b/visual-embed/code-based-custom-actions/README.md @@ -0,0 +1,207 @@ + + +# Code-Based Custom Actions + +> **Start here for anything about ThoughtSpot custom actions.** Code-based custom actions are the **recommended, default** way to add custom actions to an embed. Define them in your application code — no configuration in the ThoughtSpot UI — so they are version-controlled, portable across Orgs, and fully described by `position` + `target`. Only use **UI-created** custom actions (see the [`custom-actions`](../custom-actions) example) when you specifically need business users to manage actions from the ThoughtSpot Admin UI. + +A **custom action** adds your own menu item / button to an embedded ThoughtSpot **Answer, Liveboard, visualization, or Spotter** interface. Clicking it fires an event your app handles — to call an API, open a modal, navigate to another app, push data to a CRM, and so on — with the data context of what the user clicked. + +There are two ways to create them: + +| Approach | Where defined | When to use | +| --- | --- | --- | +| **Code-based** (this example) ✅ default | In your app code via the `customActions` config | Almost always. Portable, version-controlled, works across Orgs, no admin setup. | +| **UI-based** | ThoughtSpot Admin → Develop → Customizations → Actions | Only when non-developers must create/manage actions in the ThoughtSpot UI. | + +> If the **same primary-menu-bar** action is defined in both the UI and in code, only the **UI** action is shown. + +## How code-based custom actions work + +1. Declare a `customActions` array — either globally on `init()` (applies to every embed) or per-embed in the view config (scoped to that embed). +2. Each entry needs an `id`, a display `name`, a `position` (where it appears), and a `target` (what it applies to). +3. Listen for `EmbedEvent.CustomAction` and branch on the action `id`. + +```typescript +import { + init, AuthType, LiveboardEmbed, EmbedEvent, + CustomActionsPosition, CustomActionTarget, + type MessagePayload, type CustomActionPayload, +} from "@thoughtspot/visual-embed-sdk"; + +init({ + thoughtSpotHost: import.meta.env.VITE_TS_HOST, + authType: AuthType.Basic, // demo only — use trusted auth / SSO in production + username: import.meta.env.VITE_TS_USERNAME, + password: import.meta.env.VITE_TS_PASSWORD, +}); + +const embed = new LiveboardEmbed(document.getElementById("ts-embed")!, { + frameParams: { width: "100%", height: "100%" }, + liveboardId: import.meta.env.VITE_LIVEBOARD_ID, + + // Define custom actions entirely in code: + customActions: [ + { id: "export-to-crm", name: "Export to CRM", + position: CustomActionsPosition.PRIMARY, target: CustomActionTarget.LIVEBOARD }, + { id: "send-to-slack", name: "Send to Slack", + position: CustomActionsPosition.MENU, target: CustomActionTarget.VIZ }, + { id: "open-ticket", name: "Open support ticket", + position: CustomActionsPosition.CONTEXTMENU, target: CustomActionTarget.VIZ }, + ], +}); + +// Handle clicks. `payload.data` carries the action id + data context. +embed.on(EmbedEvent.CustomAction, (payload: MessagePayload) => { + const data = payload.data as CustomActionPayload & { id: string }; + if (data.id === "export-to-crm") { + console.log("Answer data:", data.embedAnswerData); + console.log("Clicked point:", data.contextMenuPoints?.clickedPoint); + // ...call your API / open a modal / navigate... + } +}); + +embed.render(); +``` + +## `CustomActionsPosition` — where the action appears + +| Value | Location | +| --- | --- | +| `CustomActionsPosition.PRIMARY` | A primary button in the toolbar | +| `CustomActionsPosition.MENU` | Inside the `...` (more options) menu | +| `CustomActionsPosition.CONTEXTMENU` | The right-click context menu (Answer / visualization; not Liveboard-level) | + +## `CustomActionTarget` — what the action applies to + +| Value | Applies to | Supported positions | +| --- | --- | --- | +| `CustomActionTarget.LIVEBOARD` | Liveboard level | `PRIMARY`, `MENU` | +| `CustomActionTarget.VIZ` | An individual visualization | `PRIMARY`, `MENU`, `CONTEXTMENU` | +| `CustomActionTarget.ANSWER` | Answer / Search page | `PRIMARY`, `MENU`, `CONTEXTMENU` | +| `CustomActionTarget.SPOTTER` | Spotter interface | `MENU`, `CONTEXTMENU` (no primary) | + +## Scoping where an action shows + +Each custom action can be restricted so it only appears in the right context: + +```typescript +{ + id: "viz-action", + name: "My Viz Action", + position: CustomActionsPosition.MENU, + target: CustomActionTarget.VIZ, + + // Restrict by metadata (specific answers / liveboards / vizzes): + metadataIds: { liveboardIds: ["liveboard-id-1"], vizIds: ["viz-id-1"] }, + + // Restrict by data model (models / columns): + dataModelIds: { modelIds: ["model-id-1"], modelColumnNames: ["model-id::Revenue"] }, + + // Restrict by access (groups / orgs): + groupIds: ["group-id-1"], + orgIds: ["org-id-1"], +} +``` + +## The `EmbedEvent.CustomAction` payload + +The `.on()` callback receives a `MessagePayload` whose `data` (typed as `CustomActionPayload` plus the action `id`) includes: + +- `id` — the `id` of the custom action that was clicked (branch on this). +- `embedAnswerData` — `{ name, id, columns, data, sources, ... }` of the underlying Answer/viz. +- `contextMenuPoints` — `{ clickedPoint, selectedPoints }` when triggered from a data point (context menu). +- `session` — the session context. +- `vizId` — the visualization id, where applicable. + +## `customActions` in `init()` vs per-embed + +- **`init({ customActions: [...] })`** — global; the actions apply to every embed created after init. +- **`new LiveboardEmbed(el, { customActions: [...] })`** — scoped to that one embed. Supported on `AppEmbed`, `LiveboardEmbed`, `SearchEmbed`, and `SpotterEmbed`. + +Use per-embed config (as this example does) when different embeds need different actions. + +## What this example does + +- Declares three code-based custom actions on a `LiveboardEmbed`: a toolbar button (`PRIMARY`/`LIVEBOARD`), a more-menu item (`MENU`/`VIZ`), and a right-click item (`CONTEXTMENU`/`VIZ`). +- Listens for `EmbedEvent.CustomAction` and logs each event — showing the action `id` and the full payload — into a side panel so you can inspect the data context. + +## Project Structure + +- `index.html` — Vite entry; mounts `#app` and loads `src/main.ts`. +- `src/main.ts` — SDK `init`, the `customActions` declaration, the `EmbedEvent.CustomAction` handler, and the event-log UI. +- `src/style.css` — layout (embed + event log panel). +- `src/vite-env.d.ts` — typed `import.meta.env` for the `VITE_*` variables. +- `.env` / `.stackblitzrc` — connection + auth values for the public demo instance. + +## Requirements + +- `@thoughtspot/visual-embed-sdk` **>= 1.43.0** +- ThoughtSpot **>= 10.14.0.cl** + +## Environment + +The committed `.env` targets the public ThoughtSpot training instance. To run against your own: + +``` +VITE_TS_HOST=https://your-instance.thoughtspot.cloud +VITE_TS_USERNAME=your-username +VITE_TS_PASSWORD=your-password +VITE_LIVEBOARD_ID=your-liveboard-id +``` + +## Technologies Used + +- TypeScript +- Vite +- ThoughtSpot Visual Embed SDK (`@thoughtspot/visual-embed-sdk`) + +## Demo + +Open in [StackBlitz](https://stackblitz.com/github/thoughtspot/developer-examples/tree/main/visual-embed/code-based-custom-actions) + +## Documentation + +- [Code-based custom actions](https://developers.thoughtspot.com/docs/code-based-custom-action) +- [Custom actions overview](https://developers.thoughtspot.com/docs/custom-action-intro) +- [EmbedConfig.customActions](https://developers.thoughtspot.com/docs/Interface_EmbedConfig#_customactions) +- [EmbedEvent.CustomAction](https://developers.thoughtspot.com/docs/Enumeration_EmbedEvent) + +## Run locally + +``` +$ git clone https://github.com/thoughtspot/developer-examples +$ cd visual-embed/code-based-custom-actions +``` +``` +$ npm i +``` +``` +$ npm run dev +``` + +### Technology labels + +- TypeScript +- Web diff --git a/visual-embed/code-based-custom-actions/index.html b/visual-embed/code-based-custom-actions/index.html new file mode 100644 index 0000000..8a8533b --- /dev/null +++ b/visual-embed/code-based-custom-actions/index.html @@ -0,0 +1,13 @@ + + + + + + + ThoughtSpot Code-Based Custom Actions — Visual Embed SDK + + +
+ + + diff --git a/visual-embed/code-based-custom-actions/package-lock.json b/visual-embed/code-based-custom-actions/package-lock.json new file mode 100644 index 0000000..8a6f693 --- /dev/null +++ b/visual-embed/code-based-custom-actions/package-lock.json @@ -0,0 +1,1261 @@ +{ + "name": "code-based-custom-actions", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "code-based-custom-actions", + "version": "0.0.0", + "dependencies": { + "@thoughtspot/visual-embed-sdk": "latest" + }, + "devDependencies": { + "typescript": "~5.7.2", + "vite": "^6.3.5" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@thoughtspot/visual-embed-sdk": { + "version": "1.50.0", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@thoughtspot/visual-embed-sdk/-/visual-embed-sdk-1.50.0.tgz", + "integrity": "sha512-ubt8Qw0N28QtCPJQamLSXt0imOtIXpJPPgByCxzP4oPWpJqSYRO2CFMkBUKzeVjuVEx+K8PAoDzzCQ2a1Yc6xw==", + "license": "ThoughtSpot Development Tools End User License Agreement", + "dependencies": { + "classnames": "^2.3.1", + "eventemitter3": "^4.0.7", + "lodash": "^4.18.1", + "mixpanel-browser": "2.47.0", + "ts-deepmerge": "^8.0.0", + "tslib": "^2.5.3", + "use-deep-compare-effect": "^1.8.1", + "yaml": "^2.9.0" + }, + "peerDependencies": { + "react": "> 16.8.0", + "react-dom": "> 16.8.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/mixpanel-browser": { + "version": "2.47.0", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/mixpanel-browser/-/mixpanel-browser-2.47.0.tgz", + "integrity": "sha512-Ldrva0fRBEIFWmEibBQO1PulfpJVF3pf28Guk09lDirDaSQqqU/xs9zQLwN2rL5VwVtsP1aD3JaCgaa98EjojQ==", + "license": "Apache-2.0" + }, + "node_modules/nanoid": { + "version": "3.3.15", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.16", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/postcss/-/postcss-8.5.16.tgz", + "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.2.7", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/rollup": { + "version": "4.62.2", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT", + "peer": true + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/ts-deepmerge": { + "version": "8.0.0", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/ts-deepmerge/-/ts-deepmerge-8.0.0.tgz", + "integrity": "sha512-133O+10nJmVI8w5xeVZPEv5PIrv7iaUae07wv1aH8XJH95Ur6YIhWAPhPyP1YPlbPS9fCVcNIZTu7m8urRVF0A==", + "license": "ISC", + "engines": { + "node": ">=14.13.1" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/use-deep-compare-effect": { + "version": "1.8.1", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/use-deep-compare-effect/-/use-deep-compare-effect-1.8.1.tgz", + "integrity": "sha512-kbeNVZ9Zkc0RFGpfMN3MNfaKNvcLNyxOAAd9O4CBZ+kCBXXscn9s/4I+8ytUER4RDpEYs5+O6Rs4PqiZ+rHr5Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "dequal": "^2.0.2" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "react": ">=16.13" + } + }, + "node_modules/vite": { + "version": "6.4.3", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/vite/-/vite-6.4.3.tgz", + "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://jfrog-colo.corp.thoughtspot.com/artifactory/api/npm/npm-virtual/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + } + } +} diff --git a/visual-embed/code-based-custom-actions/package.json b/visual-embed/code-based-custom-actions/package.json new file mode 100644 index 0000000..e18260f --- /dev/null +++ b/visual-embed/code-based-custom-actions/package.json @@ -0,0 +1,18 @@ +{ + "name": "code-based-custom-actions", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@thoughtspot/visual-embed-sdk": "latest" + }, + "devDependencies": { + "typescript": "~5.7.2", + "vite": "^6.3.5" + } +} diff --git a/visual-embed/code-based-custom-actions/public/ts-logo.svg b/visual-embed/code-based-custom-actions/public/ts-logo.svg new file mode 100644 index 0000000..c134264 --- /dev/null +++ b/visual-embed/code-based-custom-actions/public/ts-logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/visual-embed/code-based-custom-actions/src/main.ts b/visual-embed/code-based-custom-actions/src/main.ts new file mode 100644 index 0000000..5d65df0 --- /dev/null +++ b/visual-embed/code-based-custom-actions/src/main.ts @@ -0,0 +1,156 @@ +import './style.css'; +import { + init, + AuthType, + LiveboardEmbed, + EmbedEvent, + CustomActionsPosition, + CustomActionTarget, + type LiveboardViewConfig, + type MessagePayload, + type CustomActionPayload, +} from '@thoughtspot/visual-embed-sdk'; + +/** + * Code-based custom actions + * ------------------------- + * A *code-based* custom action is a menu item you define entirely in your + * application code via the Visual Embed SDK — no configuration in the + * ThoughtSpot UI required. This is the recommended (default) way to add custom + * actions: it is version-controlled, portable across Orgs, and lets you decide + * exactly WHERE the action appears (`position`) and WHAT it applies to + * (`target`). + * + * You declare them with the `customActions` array (available on `init()` + * globally, or per-embed in the view-config), then handle clicks by listening + * for `EmbedEvent.CustomAction`. + * + * position: CustomActionsPosition + * PRIMARY -> a primary button in the toolbar + * MENU -> inside the "..." more-options menu + * CONTEXTMENU -> the right-click context menu (Answer / visualization) + * + * target: CustomActionTarget + * LIVEBOARD | VIZ | ANSWER | SPOTTER + * + * Requires SDK >= 1.43.0 and ThoughtSpot >= 10.14.0.cl. + */ + +// 1. Initialize the SDK once. +// NOTE: AuthType.Basic with username/password is for DEMO only. +// In production use trusted auth or SSO — never ship credentials to the browser. +init({ + thoughtSpotHost: import.meta.env.VITE_TS_HOST, + authType: AuthType.Basic, + username: import.meta.env.VITE_TS_USERNAME, + password: import.meta.env.VITE_TS_PASSWORD, +}); + +// 2. Lay out the page first so the embed container exists in the DOM. +const app = document.querySelector('#app')!; +app.innerHTML = ` +
+

ThoughtSpot Code-Based Custom Actions

+

+ Custom actions defined entirely in code via customActions. + Click Export to CRM in the toolbar, Send to Slack + from a visualization's ... menu, or right-click a data point for + Open support ticket. +

+
+
+
+ +
+`; + +// 3. Declare the custom actions in code. +const viewConfig: LiveboardViewConfig = { + frameParams: { width: '100%', height: '100%' }, + liveboardId: import.meta.env.VITE_LIVEBOARD_ID, + customActions: [ + { + // Primary toolbar button on the Liveboard. + id: 'export-to-crm', + name: 'Export to CRM', + position: CustomActionsPosition.PRIMARY, + target: CustomActionTarget.LIVEBOARD, + }, + { + // Inside the "..." menu of an individual visualization. + id: 'send-to-slack', + name: 'Send to Slack', + position: CustomActionsPosition.MENU, + target: CustomActionTarget.VIZ, + }, + { + // Right-click context menu on a data point within a visualization. + id: 'open-ticket', + name: 'Open support ticket', + position: CustomActionsPosition.CONTEXTMENU, + target: CustomActionTarget.VIZ, + }, + ], +}; + +// 4. Render the embed. +const container = document.getElementById('ts-embed')!; +const embed = new LiveboardEmbed(container, viewConfig); + +// 5. Handle clicks. The payload carries the action `id` plus the data context +// of whatever the user clicked (columns, selected points, etc.). +embed.on(EmbedEvent.CustomAction, (payload: MessagePayload) => { + // For a code-based custom action, `payload.data` carries the action `id` + // alongside the CustomActionPayload data context (embedAnswerData, + // contextMenuPoints, session, ...). + const data = payload.data as CustomActionPayload & { id: string }; + const actionId = data.id; + logEvent(actionId, data); + + switch (actionId) { + case 'export-to-crm': + // e.g. POST the Liveboard context to your CRM. + break; + case 'send-to-slack': + // e.g. call your backend to post the viz to a Slack channel. + break; + case 'open-ticket': + // e.g. open a modal / navigate to your ticketing system with the + // clicked data point pre-filled. + break; + default: + // Not one of our custom actions — ignore. + break; + } +}); + +embed.on(EmbedEvent.Error, (e: unknown) => console.error('Embed error:', e)); + +embed.render(); + +// --- helpers: visualize which action fired and the payload it carried --- +function logEvent(actionId: string | undefined, detail: CustomActionPayload): void { + const list = document.getElementById('log-list'); + if (!list) return; + list.querySelector('.empty')?.remove(); + + const entry = document.createElement('div'); + entry.className = 'log-entry'; + entry.innerHTML = ` +
${actionId ?? '(unknown)'}
+
${escapeHtml(JSON.stringify(detail, null, 2))}
+ `; + list.prepend(entry); +} + +function escapeHtml(s: string): string { + return s + .replace(/&/g, '&') + .replace(//g, '>'); +} diff --git a/visual-embed/code-based-custom-actions/src/style.css b/visual-embed/code-based-custom-actions/src/style.css new file mode 100644 index 0000000..c2bf0e9 --- /dev/null +++ b/visual-embed/code-based-custom-actions/src/style.css @@ -0,0 +1,100 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + color: #1a1a2e; + background-color: #ffffff; +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + min-height: 100vh; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 1.5rem; +} + +.topbar h1 { + font-size: 1.8rem; + margin: 0 0 0.25rem; +} + +.topbar p { + margin: 0 0 1.25rem; + color: #555; + max-width: 70ch; +} + +.topbar code { + background: #f0f0f5; + padding: 0.1em 0.35em; + border-radius: 4px; + font-size: 0.9em; +} + +.layout { + display: grid; + grid-template-columns: 1fr 360px; + gap: 1rem; + align-items: stretch; +} + +@media (max-width: 900px) { + .layout { + grid-template-columns: 1fr; + } +} + +.embed { + height: 640px; + border: 1px solid #e0e0ea; + border-radius: 8px; + overflow: hidden; +} + +.log { + border: 1px solid #e0e0ea; + border-radius: 8px; + padding: 1rem; + overflow-y: auto; + max-height: 640px; +} + +.log h2 { + font-size: 1rem; + margin: 0 0 0.75rem; +} + +.log-list .empty { + color: #999; + font-size: 0.9rem; +} + +.log-entry { + border: 1px solid #ececf2; + border-radius: 6px; + padding: 0.6rem 0.75rem; + margin-bottom: 0.6rem; + background: #fafafd; +} + +.log-id { + font-weight: 600; + color: #646cff; + margin-bottom: 0.35rem; + font-size: 0.9rem; +} + +.log-entry pre { + margin: 0; + font-size: 0.75rem; + color: #333; + white-space: pre-wrap; + word-break: break-word; +} diff --git a/visual-embed/code-based-custom-actions/src/vite-env.d.ts b/visual-embed/code-based-custom-actions/src/vite-env.d.ts new file mode 100644 index 0000000..cf74f4f --- /dev/null +++ b/visual-embed/code-based-custom-actions/src/vite-env.d.ts @@ -0,0 +1,12 @@ +/// + +interface ImportMetaEnv { + readonly VITE_TS_HOST: string; + readonly VITE_TS_USERNAME: string; + readonly VITE_TS_PASSWORD: string; + readonly VITE_LIVEBOARD_ID: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/visual-embed/code-based-custom-actions/tsconfig.json b/visual-embed/code-based-custom-actions/tsconfig.json new file mode 100644 index 0000000..a4883f2 --- /dev/null +++ b/visual-embed/code-based-custom-actions/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/visual-embed/custom-actions/README.md b/visual-embed/custom-actions/README.md index 8c7abc2..fa76d8a 100644 --- a/visual-embed/custom-actions/README.md +++ b/visual-embed/custom-actions/README.md @@ -1,17 +1,19 @@ -# Custom Actions +# Custom Actions (UI-created) — callback patterns -This repository contains multiple examples of using ThoughtSpot [Custom Actions](https://developers.thoughtspot.com/docs/?pageid=customize-actions). A custom action is a type of extension that can be added to ThoughtSpot searches, answers and liveboards to give users additional capabilities. For example, an inventory manager might search ThoughtSpot for items that are low in stock and push a reorder directly from ThoughtSpot to their inventory system. +> ⚠️ **Adding custom actions?** Prefer **[code-based custom actions](../code-based-custom-actions)** — that is the default, recommended approach and the right starting point for almost every use case. This example is specifically about **handling callbacks for custom actions that were created in the ThoughtSpot Admin UI**, and richer callback workflows (returning JSON, detail panes, content linking). + +This repository contains multiple examples of consuming ThoughtSpot [Custom Actions](https://developers.thoughtspot.com/docs/?pageid=customize-actions) that were configured in the ThoughtSpot UI. A custom action is a type of extension that can be added to ThoughtSpot searches, answers and liveboards to give users additional capabilities. For example, an inventory manager might search ThoughtSpot for items that are low in stock and push a reorder directly from ThoughtSpot to their inventory system. This is a react.js application. See the `src/examples` folder for specific examples.