@lightdash/cli 3.90.0 → 3.91.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -165,6 +165,13 @@ order, `sortBy` describes result ordering, `totalColumnCount` exposes truncation
165
165
  `drillDown.open({ row, metric })` on selection. Either way Lightdash opens
166
166
  its drill dialog. Distinct from `drill-down`, which is the full-app query
167
167
  helper.
168
+ - `field-links`: result columns carry the semantic layer's `urls` link
169
+ patterns (`column.urls`), and `resolveColumnUrls({ column, row, columns,
170
+ format })` resolves them per cell. In every cell renderer — hand-written
171
+ tables and generic column loops such as underlying-data dialogs — render
172
+ the value as a link when it returns entries, styled visibly as a link
173
+ (underline and/or link color). Full rules in the data-app skill's
174
+ "Field links — `urls`" section.
168
175
  - `url-state`: `useUrlState(...)` syncs a piece of app state into the page URL
169
176
  so views can be shared and restored.
170
177
  - `app-state`: `useAppState(key, default)` remembers a value per person;
@@ -147,7 +147,18 @@ columns:
147
147
  url: "https://portal.example.com/users/${row.accounts.owner_id.raw }"
148
148
  ```
149
149
 
150
- **When a field you display declares `urls`, render its values as links built from those patterns** — in tables, underlying-data views, and anywhere the raw value is shown. Dashboards already do this; the app must match. Resolve placeholders yourself (simple substitution):
150
+ **When a field you display declares `urls`, render its values as links built from those patterns** — in tables, underlying-data views, and anywhere the raw value is shown. Dashboards already do this; the app must match.
151
+
152
+ Every query result's `columns` carry the patterns too (`column.urls`), and the SDK resolves them per cell — prefer this over hand-rolling, especially in generic column loops:
153
+
154
+ ```tsx
155
+ import { resolveColumnUrls } from '@lightdash/query-sdk';
156
+
157
+ const links = resolveColumnUrls({ column, row, columns, format });
158
+ // → [{ label, href }] with unresolvable patterns already skipped
159
+ ```
160
+
161
+ When you hand-roll instead (e.g. a hard-coded table where you know the field), resolve placeholders with simple substitution:
151
162
 
152
163
  - `${value.raw}` / `${value.formatted}` — the cell's own raw/formatted value.
153
164
  - `${row.<model>.<field>.raw}` (or `.formatted`) — another field in the same result row. **Add that field to the query** so it's present in the row.
@@ -526,6 +537,27 @@ Rules:
526
537
  - Whenever you show an underlying-data table/dialog, include a Download button in that table/dialog header. It should call `downloadUnderlyingData({ row, metric, fileType, values, limit, filename })`, track export state, and show a spinner or "Exporting..." label until the promise settles.
527
538
  - For underlying-data downloads, `limit: 'table'` uses the backend default underlying-data row limit, `limit: 'all'` exports all matching rows allowed by backend export caps, and a number requests that many rows.
528
539
  - This works for grouped SDK query rows. If you have heavily transformed or pivoted data client-side, keep the original source row around and pass that original row.
540
+ - **Render field links in the dialog's generic column loop.** Underlying-data columns carry `urls` (the field's link patterns), and `resolveColumnUrls` resolves them per cell — a cell with resolved links renders as a link (see [Field links — `urls`](#field-links--urls)):
541
+
542
+ ```tsx
543
+ import { resolveColumnUrls } from '@lightdash/query-sdk';
544
+
545
+ {result.columns.map((c) => {
546
+ const links = resolveColumnUrls({ column: c, row: r, columns: result.columns, format: result.format });
547
+ return (
548
+ <TableCell key={c.name}>
549
+ {links.length > 0 ? (
550
+ <a href={links[0].href} target="_blank" rel="noreferrer"
551
+ className="text-primary underline underline-offset-4">
552
+ {result.format(r, c.name)}
553
+ </a>
554
+ ) : (
555
+ result.format(r, c.name)
556
+ )}
557
+ </TableCell>
558
+ );
559
+ })}
560
+ ```
529
561
 
530
562
  ```tsx
531
563
  const revenueQuery = query('orders')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/cli",
3
- "version": "3.90.0",
3
+ "version": "3.91.0",
4
4
  "description": "Lightdash CLI tool",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -22,8 +22,8 @@
22
22
  "@actions/core": "1.11.1",
23
23
  "@aws-sdk/credential-providers": "3.995.0",
24
24
  "@casl/ability": "6.8.0",
25
- "@lightdash/common": "3.90.0",
26
- "@lightdash/warehouses": "3.90.0",
25
+ "@lightdash/common": "3.91.0",
26
+ "@lightdash/warehouses": "3.91.0",
27
27
  "@sidvind/better-ajv-errors": "7.0.0",
28
28
  "@types/columnify": "1.5.1",
29
29
  "ajv": "8.18.0",