@lightdash/cli 1.95.1 → 1.97.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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/vendor/template/.claude/skills/sdk-features/SKILL.md +6 -0
- package/dist/vendor/template/references/dashboard-blueprint.md +4 -0
- package/dist/vendor/template/references/pdf-downloads.md +2 -2
- package/dist/vendor/template/skill.md +39 -1
- package/package.json +3 -3
|
@@ -22,6 +22,7 @@ Users describe features by what they see in the Lightdash editor. Translate:
|
|
|
22
22
|
| drill down, click into a chart | `drill-down` | app code opt-in |
|
|
23
23
|
| "share this view", URL that restores state | `url-state` | app code opt-in |
|
|
24
24
|
| Google Sheets export | `gsheet-export` | app code opt-in |
|
|
25
|
+
| "delivery has all tabs", full data in scheduled deliveries | `delivery-render` | app code opt-in |
|
|
25
26
|
| external API data | `external-fetch` | app code opt-in |
|
|
26
27
|
| runs inside a dashboard tile | `viz-context` | required — see below |
|
|
27
28
|
| light/dark mode, "matches my Lightdash theme" | `follow-host-theme` | CSS tokens — see below |
|
|
@@ -92,6 +93,11 @@ re-rendering on every host toggle.
|
|
|
92
93
|
- `external-fetch`: `client.externalFetch(alias, opts)` calls an external
|
|
93
94
|
connection linked to this app. The connection must already be linked by the
|
|
94
95
|
host; you cannot add one from app code.
|
|
96
|
+
- `delivery-render`: `useDeliveryRender()` is `true` during scheduled-delivery
|
|
97
|
+
and delivery-preview capture renders. Gate tab/slide DATA mounting on it so
|
|
98
|
+
every tab's queries execute during capture while only the active tab stays
|
|
99
|
+
visible — never mount all tabs unconditionally (interactive loads must stay
|
|
100
|
+
lazy).
|
|
95
101
|
|
|
96
102
|
## After a template upgrade
|
|
97
103
|
|
|
@@ -75,6 +75,10 @@ per tab, tiles assigned by `tabUuid`, ordered by `order`. Skip tabs with
|
|
|
75
75
|
`hidden: true`. Single implicit tab (empty `tabs`) → a single page, no tab
|
|
76
76
|
chrome.
|
|
77
77
|
|
|
78
|
+
Gate each tab's data hooks on `useDeliveryRender()` (see "Tabs and
|
|
79
|
+
scheduled-delivery capture" in `skill.md`) so a scheduled delivery or its
|
|
80
|
+
preview captures every tab's data, not just the one open at capture time.
|
|
81
|
+
|
|
78
82
|
### Dashboard filters
|
|
79
83
|
|
|
80
84
|
Each rule in `filters.dimensions` is a `DashboardFilterRule`: `target`
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Client-side PDF downloads (html-to-image + jspdf)
|
|
2
2
|
|
|
3
|
-
> Read this for PDF Report templates or whenever the user asks for a PDF download.
|
|
3
|
+
> Read this for PDF Report templates, for any report/printable/document-shaped app, or whenever the user asks for a PDF download.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Every PDF or printable report app includes a visible Download PDF button — the app is incomplete without one, on first generation and after every edit. Use the pre-installed `html-to-image` and `jspdf` packages. Do not load PDF libraries from a CDN or ask to install packages.
|
|
6
6
|
|
|
7
7
|
PDF downloads are image-based: they preserve the visible report exactly, but the exported text is not selectable/searchable. Keep `window.print()` only as a secondary Print action if useful; the Download PDF button should save a file directly.
|
|
8
8
|
|
|
@@ -458,7 +458,9 @@ When the user asks for "Open in Google Sheets" (or any Sheets destination), read
|
|
|
458
458
|
|
|
459
459
|
### Client-side PDF downloads
|
|
460
460
|
|
|
461
|
-
|
|
461
|
+
A PDF or printable report app always includes a visible **Download PDF** button — the export action is part of the report shape, not an optional extra, and `window.print()` is only ever a secondary Print action. This applies whenever the app is report-shaped, whatever the request's wording: the PDF Report starter template, a "printable" / "document" / "report to share" ask, or an app that already renders `.pdf-page` sections. On edit turns, keep the existing Download PDF button working — an edit that removes it is a regression.
|
|
462
|
+
|
|
463
|
+
Before wiring the button, read `/app/references/pdf-downloads.md` — it has the required `html-to-image` + `jspdf` pattern and page-capture rules.
|
|
462
464
|
|
|
463
465
|
### Underlying data
|
|
464
466
|
|
|
@@ -745,6 +747,42 @@ Avoid — each of these inflates the screenshot:
|
|
|
745
747
|
</div>
|
|
746
748
|
```
|
|
747
749
|
|
|
750
|
+
### Tabs and scheduled-delivery capture
|
|
751
|
+
|
|
752
|
+
A tabbed layout normally mounts each tab's data-fetching hooks lazily — only the active tab queries. Scheduled deliveries (and their preview) capture the whole app in one headless pass with no user to click through tabs first, so a lazily-mounted tab ships with no data in the delivered screenshot.
|
|
753
|
+
|
|
754
|
+
Use `useDeliveryRender()` from `@lightdash/query-sdk` to mount every tab's data hooks during a capture render, while still showing only the active tab's UI:
|
|
755
|
+
|
|
756
|
+
```tsx
|
|
757
|
+
import { useDeliveryRender } from '@lightdash/query-sdk';
|
|
758
|
+
|
|
759
|
+
function AppTabs() {
|
|
760
|
+
const [activeTab, setActiveTab] = useUrlState('tab', 'overview');
|
|
761
|
+
const deliveryRender = useDeliveryRender();
|
|
762
|
+
|
|
763
|
+
return (
|
|
764
|
+
<Tabs value={activeTab} onValueChange={setActiveTab}>
|
|
765
|
+
<TabsList>
|
|
766
|
+
<TabsTrigger value="overview">Overview</TabsTrigger>
|
|
767
|
+
<TabsTrigger value="details">Details</TabsTrigger>
|
|
768
|
+
</TabsList>
|
|
769
|
+
{/* Each panel's useLightdash() calls run whenever it mounts — hidden
|
|
770
|
+
panels stay mounted in a capture render via forceMount. */}
|
|
771
|
+
<TabsContent value="overview" forceMount={deliveryRender || undefined}>
|
|
772
|
+
<OverviewPanel />
|
|
773
|
+
</TabsContent>
|
|
774
|
+
<TabsContent value="details" forceMount={deliveryRender || undefined}>
|
|
775
|
+
<DetailsPanel />
|
|
776
|
+
</TabsContent>
|
|
777
|
+
</Tabs>
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
**Never mount every tab unconditionally** — that runs every tab's queries on every interactive load, wasting warehouse spend for users who only ever open one tab. Gate the extra mounting strictly on `useDeliveryRender()`.
|
|
783
|
+
|
|
784
|
+
The same rule applies one level up: if the app opens on a landing, intro, or "press start" screen that mounts no data (slideshows, wizards, empty states), a capture render of the default view captures zero queries and the delivery fails. In a delivery render, mount the data-bearing components from the app's entry state — `useDeliveryRender()` must bypass any screen that gates data behind user interaction.
|
|
785
|
+
|
|
748
786
|
### Organization themes
|
|
749
787
|
|
|
750
788
|
If `/app/src/design/` exists, an organization theme is active: its assets and any appended theme instructions override parts of `frontend-design`'s direction. Read `/app/references/themes.md` before writing any UI code. If the directory doesn't exist, no theme is active and this doesn't apply.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightdash/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.97.0",
|
|
4
4
|
"description": "Lightdash CLI tool",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"unique-names-generator": "4.7.1",
|
|
42
42
|
"uuid": "11.1.1",
|
|
43
43
|
"yaml": "2.8.3",
|
|
44
|
-
"@lightdash/common": "1.
|
|
45
|
-
"@lightdash/warehouses": "1.
|
|
44
|
+
"@lightdash/common": "1.97.0",
|
|
45
|
+
"@lightdash/warehouses": "1.97.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/inquirer": "8.2.4",
|