diff --git a/CHANGELOG.md b/CHANGELOG.md index 6babe5a..7e2dc2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `dx -v` now prints the CLI version, matching the documented lowercase version flag. Version checks are also skipped for help/version output and global-option-only invocations, preventing update prompts from interfering with those commands. +### Updated + +- Updated the skill, the `dx reports create/update` help text, and the blank report template created on `dx reports init`, to include the relevant context about variable usage. + ## 0.5.5 - 2026-07-13 ### Updated diff --git a/skills/dx-cli/SKILL.md b/skills/dx-cli/SKILL.md index 88e35ff..c8bfe7d 100644 --- a/skills/dx-cli/SKILL.md +++ b/skills/dx-cli/SKILL.md @@ -74,6 +74,14 @@ Use this for any question about DX itself rather than the user's own data: produ **Exemption** — A time-bound approved pass on a failing check for a specific entity. A check result with a non-null `exemption_expires_at` is exempted: it may still be failing, but is not counted against the entity until the exemption expires. +### Data Studio terms + +**Report** — A saved collection of tiles (see `dx studio reports`), organized on a dedicated page for dashboards and sharing. + +**Tile** — A single saved query and chart configuration within a report. Each tile's SQL can reference report variables. + +**Variable** — A named, `$`-prefixed placeholder (e.g. `$team_ids`) that a report's tile SQL can reference for interactive filtering. **Built-in variables** (`$service_ids`, `$team_ids`, `$tag_ids`, `$user_ids`, `$repo_ids`, `$start_date`, `$end_date`) are provided out of the box and just need to be toggled on. **Custom variables** are account-defined dropdown filters backed by a SQL query that returns `value` and `label` columns. Variables cannot be managed through the CLI/API — enabling/disabling built-ins and adding/updating/deleting custom variables must be done in the Data Studio UI — but once enabled on a report, any tile's SQL (including tiles set via `dx studio reports create`/`update`) can reference them. + ## Reference Docs - [Catalog management](./references/catalog-management.md) — Entities and entity types: listing, inspecting, creating, updating, and deleting. diff --git a/skills/dx-cli/references/report-creation.md b/skills/dx-cli/references/report-creation.md index bdbd3d3..642eed8 100644 --- a/skills/dx-cli/references/report-creation.md +++ b/skills/dx-cli/references/report-creation.md @@ -118,3 +118,31 @@ Provide `editor_emails` only when `edit_access_type` is `specific_users`. Supported tile `chart_type` values are `line`, `pie`, `stacked_bar`, `scatter`, and `table`. `line`, `stacked_bar`, and `scatter` chart configs require `xAxis` and `yAxes`; `pie` chart configs require `labelColumn` and `valueColumn`; `table` chart configs can be `{}`. + +--- + +## Variables + +Tile `sql` can reference report variables to make a report interactive: place `$variable_name` anywhere in the query, and the selected value(s) are substituted in when the report runs. + +### Built-in variables + +- `$service_ids` — filter by specific services +- `$team_ids` — filter by team assignments +- `$tag_ids` — filter by attributes +- `$user_ids` — filter by individual users +- `$repo_ids` — filter by specific repositories +- `$start_date` and `$end_date` — filter by date range + +### Custom variables + +Custom variables are account-defined dropdown filters backed by a SQL query. Each has a title, a variable name (used as `$variable_name` in tile SQL), a description, and a SQL statement that must return exactly two columns: `value` (used in the substitution) and `label` (shown to users in the dropdown). + +### Limitation: no CLI/API management + +Variables cannot be created, updated, enabled, or disabled through this CLI or the API. There is no field for them in the report YAML. + +- Built-in variables are toggled on/off per report in the Data Studio UI. +- Custom variables are added, edited, and deleted per account in the Data Studio UI. + +Once a variable is enabled on a report (via the UI), any tile's `sql` — including tiles created or updated via `dx studio reports create`/`update` — can reference it as `$variable_name`. diff --git a/src/commandHelpers.ts b/src/commandHelpers.ts index 1a02289..d0eb3ec 100644 --- a/src/commandHelpers.ts +++ b/src/commandHelpers.ts @@ -129,6 +129,52 @@ export function createExampleText(examples: Example[]): string { return lines.join("\n"); } +export function createNoteText(paragraphs: string[]): string { + const width = getHelpWidth(); + const indent = " "; + const output = []; + + output.push(""); // separate from the rest of the help text + output.push("Notes:"); + + paragraphs.forEach((paragraph, index) => { + if (index > 0) { + output.push(""); // blank line between paragraphs + } + output.push(...wrapParagraph(paragraph, width, indent)); + }); + + return output.join("\n"); +} + +function getHelpWidth(): number { + return process.stdout.isTTY && process.stdout.columns + ? process.stdout.columns + : 80; +} + +function wrapParagraph(text: string, width: number, indent: string): string[] { + const words = text.split(/\s+/).filter(Boolean); + const lines: string[] = []; + let current = ""; + + for (const word of words) { + const candidate = current ? `${current} ${word}` : word; + if (current && indent.length + candidate.length > width) { + lines.push(`${indent}${current}`); + current = word; + } else { + current = candidate; + } + } + + if (current) { + lines.push(`${indent}${current}`); + } + + return lines; +} + function inferContext(command?: Command, argv?: string[]): CliContext { if (command) { return getContext(command); diff --git a/src/commands/studio/report-blank-template.yaml b/src/commands/studio/report-blank-template.yaml index 09df0b9..e5cbc6a 100644 --- a/src/commands/studio/report-blank-template.yaml +++ b/src/commands/studio/report-blank-template.yaml @@ -22,6 +22,11 @@ edit_access_type: read_only editor_emails: [] # Supported chart_type values: line, pie, stacked_bar, scatter, table +# +# Tile sql can reference report variables (e.g. $team_ids, $start_date, or a +# custom variable) as $variable_name. Variables themselves can't be managed +# from the CLI/API — enable built-in variables or add/edit custom ones for +# this report in the Data Studio UI, then reference them here. tiles: - title: "" sql: |- diff --git a/src/commands/studio/reports.ts b/src/commands/studio/reports.ts index 85b8e2c..2dfa5f6 100644 --- a/src/commands/studio/reports.ts +++ b/src/commands/studio/reports.ts @@ -5,6 +5,7 @@ import { parse as parseYaml, stringify as stringifyYaml } from "yaml"; import { createExampleText, + createNoteText, getContext, parsePositiveIntOption, wrapAction, @@ -16,6 +17,11 @@ import { buildRuntime } from "../../runtime.js"; import type { Runtime } from "../../types.js"; import * as ui from "../../ui.js"; +const VARIABLES_NOTE_TEXT = [ + "Tile SQL can reference report variables using `$variable_name` syntax. Built-in variables — $service_ids, $team_ids, $tag_ids, $user_ids, $repo_ids, $start_date, $end_date — filter by service, team, attribute, user, repo, and date range, respectively. Custom variables are account-defined dropdown filters backed by a SQL query.", + "Variables cannot be created, updated, enabled, or disabled via this CLI or the API. Built-in variables must be toggled, and custom variables must be added, edited, or removed, from the report's settings in the Data Studio UI. Once a variable is enabled on a report, its `$variable_name` can be used in any tile's SQL via --from-file/--from-stdin.", +]; + export function reportsCommand() { const reports = new Command() .name("reports") @@ -32,6 +38,7 @@ export function reportsCommand() { "--from-stdin", "Read YAML from stdin and create a report from its contents", ) + .addHelpText("afterAll", createNoteText(VARIABLES_NOTE_TEXT)) .addHelpText( "afterAll", createExampleText([ @@ -252,6 +259,7 @@ export function reportsCommand() { "--from-stdin", "Read YAML from stdin and update the report with its contents", ) + .addHelpText("afterAll", createNoteText(VARIABLES_NOTE_TEXT)) .addHelpText( "afterAll", createExampleText([