Skip to content

Commit 23995ce

Browse files
feat: interactive checklist component for business user training page (#990)
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
1 parent 42f922c commit 23995ce

2 files changed

Lines changed: 268 additions & 21 deletions

File tree

guides/business-user-training-outcomes-checklist.mdx

Lines changed: 67 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,88 @@ title: "Business user training — outcomes checklist"
33
description: "What every business user should be able to do in Lightdash by the end of training."
44
---
55

6-
Work through these during onboarding and check items off as they're covered. Stuck on anything? Follow the docs link on each item, or ask your Lightdash admin or data team.
6+
import { Checklist, ChecklistItem } from '/snippets/checklist.jsx';
7+
8+
Work through these during onboarding and check items off as they're covered. Your progress is saved in your browser. Stuck on anything? Follow the docs link on each item, or ask your Lightdash admin or data team.
9+
10+
<Checklist storageKey="business-user-training">
711

812
## 01 — Understand metrics & dimensions
913

10-
- [ ] **Understand the Lightdash semantic layer**`Viewer` One governed source of truth — metrics and dimensions are defined once in the dbt project, so everyone works from the same definitions. [Docs — Lightdash semantic layer](/guides/lightdash-semantic-layer#lightdash-semantic-layer)
11-
- [ ] **Understand the difference between dimensions and metrics**[`Viewer`](/references/workspace/roles#project-roles) Dimensions describe and group; metrics aggregate and measure. [Docs — intro to metrics & dimensions](/get-started/exploring-data/intro-metrics-dimensions)
12-
- [ ] **Browse curated metrics in the Metrics Catalog**`Viewer` Go to Browse → Metrics Catalog to see every metric in one place — with descriptions, categories, and owners. [Docs — the Metrics Catalog](/guides/metrics-catalog/catalog)
13-
- [ ] **Explore a metric from the Metrics Catalog in one click**[`Interactive Viewer`](/references/workspace/roles#project-roles) Hit Explore on any metric for an instant time-series analysis — compare periods, filter, and segment. [Docs — the Metrics Catalog](/guides/metrics-catalog/catalog)
14+
<ChecklistItem id="semantic-layer">
15+
**Understand the Lightdash semantic layer**`Viewer` One governed source of truth — metrics and dimensions are defined once in the dbt project, so everyone works from the same definitions. [Docs — Lightdash semantic layer](/guides/lightdash-semantic-layer#lightdash-semantic-layer)
16+
</ChecklistItem>
17+
<ChecklistItem id="dims-vs-metrics">
18+
**Understand the difference between dimensions and metrics**[`Viewer`](/references/workspace/roles#project-roles) Dimensions describe and group; metrics aggregate and measure. [Docs — intro to metrics & dimensions](/get-started/exploring-data/intro-metrics-dimensions)
19+
</ChecklistItem>
20+
<ChecklistItem id="browse-metrics-catalog">
21+
**Browse curated metrics in the Metrics Catalog**`Viewer` Go to Browse → Metrics Catalog to see every metric in one place — with descriptions, categories, and owners. [Docs — the Metrics Catalog](/guides/metrics-catalog/catalog)
22+
</ChecklistItem>
23+
<ChecklistItem id="explore-from-catalog">
24+
**Explore a metric from the Metrics Catalog in one click**[`Interactive Viewer`](/references/workspace/roles#project-roles) Hit Explore on any metric for an instant time-series analysis — compare periods, filter, and segment. [Docs — the Metrics Catalog](/guides/metrics-catalog/catalog)
25+
</ChecklistItem>
1426

1527
## 02 — Work with dashboards
1628

17-
- [ ] **Open a dashboard and understand what they're looking at**`Viewer` Find dashboards from the home page and spaces; read chart titles, descriptions, and last-refreshed time. [Docs — exploring your content](/get-started/exploring-data/exploring-your-content)
18-
- [ ] **Navigate existing dashboards and charts**`Viewer` Browse spaces, search for content, and know where curated dashboards live. [Docs — exploring your content](/get-started/exploring-data/exploring-your-content)
19-
- [ ] **Use built-in filters, add their own, and cross-filter by clicking on charts**`Viewer` Apply dashboard filters, add a temporary filter, and click a chart value to filter the rest of the dashboard. [Docs — using dashboards (filters & cross-filtering)](/get-started/exploring-data/interactive-dashboards)
20-
- [ ] **Use Date Zoom to change date granularity on a dashboard**`Viewer` Switch charts between day, week, month, or year to zoom in on a moment or zoom out to see a trend — without editing the charts. [Docs — Date Zoom](/get-started/exploring-data/interactive-dashboards)
21-
- [ ] **Drill into the underlying data and export to CSV**`Interactive Viewer` View underlying records behind a chart, use Drill into to segment a metric, and download the results. [Docs — drill into & view underlying data](/get-started/exploring-data/interactive-dashboards)
22-
- [ ] **Subscribe to scheduled deliveries so the data comes to them**`Interactive Viewer` Set up email or Slack deliveries on a schedule. [Docs — scheduled deliveries](/guides/how-to-create-scheduled-deliveries)
29+
<ChecklistItem id="open-dashboard">
30+
**Open a dashboard and understand what they're looking at**`Viewer` Find dashboards from the home page and spaces; read chart titles, descriptions, and last-refreshed time. [Docs — exploring your content](/get-started/exploring-data/exploring-your-content)
31+
</ChecklistItem>
32+
<ChecklistItem id="navigate-dashboards">
33+
**Navigate existing dashboards and charts**`Viewer` Browse spaces, search for content, and know where curated dashboards live. [Docs — exploring your content](/get-started/exploring-data/exploring-your-content)
34+
</ChecklistItem>
35+
<ChecklistItem id="filters-and-cross-filter">
36+
**Use built-in filters, add their own, and cross-filter by clicking on charts**`Viewer` Apply dashboard filters, add a temporary filter, and click a chart value to filter the rest of the dashboard. [Docs — using dashboards (filters & cross-filtering)](/get-started/exploring-data/interactive-dashboards)
37+
</ChecklistItem>
38+
<ChecklistItem id="date-zoom">
39+
**Use Date Zoom to change date granularity on a dashboard**`Viewer` Switch charts between day, week, month, or year to zoom in on a moment or zoom out to see a trend — without editing the charts. [Docs — Date Zoom](/get-started/exploring-data/interactive-dashboards)
40+
</ChecklistItem>
41+
<ChecklistItem id="drill-and-export">
42+
**Drill into the underlying data and export to CSV**`Interactive Viewer` View underlying records behind a chart, use Drill into to segment a metric, and download the results. [Docs — drill into & view underlying data](/get-started/exploring-data/interactive-dashboards)
43+
</ChecklistItem>
44+
<ChecklistItem id="scheduled-deliveries">
45+
**Subscribe to scheduled deliveries so the data comes to them**`Interactive Viewer` Set up email or Slack deliveries on a schedule. [Docs — scheduled deliveries](/guides/how-to-create-scheduled-deliveries)
46+
</ChecklistItem>
2347

2448
## 03 — Explore the data
2549

26-
- [ ] **Build a simple table, sort it to answer a question, and turn it into a chart**`Interactive Viewer` Pick fields from a table, sort the results, and switch to a suitable chart type — no SQL required. [Docs — querying from tables](/get-started/exploring-data/using-explores)
27-
- [ ] **Break a metric down over time or by another dimension**`Interactive Viewer` Group a metric by week or month, or split it by a category to compare segments. [Docs — querying from tables](/get-started/exploring-data/using-explores)
50+
<ChecklistItem id="build-simple-table">
51+
**Build a simple table, sort it to answer a question, and turn it into a chart**`Interactive Viewer` Pick fields from a table, sort the results, and switch to a suitable chart type — no SQL required. [Docs — querying from tables](/get-started/exploring-data/using-explores)
52+
</ChecklistItem>
53+
<ChecklistItem id="break-down-metric">
54+
**Break a metric down over time or by another dimension**`Interactive Viewer` Group a metric by week or month, or split it by a category to compare segments. [Docs — querying from tables](/get-started/exploring-data/using-explores)
55+
</ChecklistItem>
2856

2957
## 04 — Run and share their own analysis
3058

31-
- [ ] **Create their own analysis from scratch in the Explorer**`Interactive Viewer` Start from a table, build an ad-hoc query, and answer a new question end to end. [Docs — exploring your data](/get-started/exploring-data/using-explores)
32-
- [ ] **Save charts into spaces**[`Editor`](/references/workspace/roles#project-roles) Save work to the right space so teammates can find it. [Docs — spaces & saved charts](/get-started/exploring-data/exploring-your-content)
33-
- [ ] **Build and organise charts into dashboards**`Editor` Create a new dashboard, arrange tiles, and add headings and context. [Docs — creating dashboards](/get-started/exploring-data/dashboards)
34-
- [ ] **Export as an image or PDF, or share a link in Slack**`Viewer` Get insights out of Lightdash and in front of the team. [Docs — exporting & sharing](/get-started/exploring-data/interactive-dashboards)
59+
<ChecklistItem id="analysis-from-scratch">
60+
**Create their own analysis from scratch in the Explorer**`Interactive Viewer` Start from a table, build an ad-hoc query, and answer a new question end to end. [Docs — exploring your data](/get-started/exploring-data/using-explores)
61+
</ChecklistItem>
62+
<ChecklistItem id="save-charts">
63+
**Save charts into spaces**[`Editor`](/references/workspace/roles#project-roles) Save work to the right space so teammates can find it. [Docs — spaces & saved charts](/get-started/exploring-data/exploring-your-content)
64+
</ChecklistItem>
65+
<ChecklistItem id="build-dashboards">
66+
**Build and organise charts into dashboards**`Editor` Create a new dashboard, arrange tiles, and add headings and context. [Docs — creating dashboards](/get-started/exploring-data/dashboards)
67+
</ChecklistItem>
68+
<ChecklistItem id="export-share">
69+
**Export as an image or PDF, or share a link in Slack**`Viewer` Get insights out of Lightdash and in front of the team. [Docs — exporting & sharing](/get-started/exploring-data/interactive-dashboards)
70+
</ChecklistItem>
3571

3672
## 05 — Ask AI
3773

38-
- [ ] **Ask business questions in plain English and get answers backed by curated metrics**`Interactive Viewer` The AI analyst answers using the same governed definitions as every dashboard. [Docs — using AI agents](/guides/ai-agents/using-ai-agents)
39-
- [ ] **Know where to access the AI analyst**`Interactive Viewer` Slack (if configured), Ask AI in the app, and from within dashboards — use Ask AI Agent from a chart or dashboard's menu. [Docs — using AI agents](/guides/ai-agents/using-ai-agents)
40-
- [ ] **Ask AI about a specific chart or dashboard**`Interactive Viewer` Launch a conversation with the chart or dashboard pre-loaded as context — click Ask AI Agent from its menu. [Docs — asking about a chart or dashboard](/guides/ai-agents/using-ai-agents#asking-about-a-chart-or-dashboard)
41-
- [ ] **Give feedback on AI answers with thumbs up / down**`Interactive Viewer` Any user can rate an agent response — thumbs down lets you optionally explain what went wrong, which helps the data team improve the agent. [Docs — using AI agents](/guides/ai-agents/using-ai-agents)
74+
<ChecklistItem id="ai-plain-english">
75+
**Ask business questions in plain English and get answers backed by curated metrics**`Interactive Viewer` The AI analyst answers using the same governed definitions as every dashboard. [Docs — using AI agents](/guides/ai-agents/using-ai-agents)
76+
</ChecklistItem>
77+
<ChecklistItem id="ai-where-to-access">
78+
**Know where to access the AI analyst**`Interactive Viewer` Slack (if configured), Ask AI in the app, and from within dashboards — use Ask AI Agent from a chart or dashboard's menu. [Docs — using AI agents](/guides/ai-agents/using-ai-agents)
79+
</ChecklistItem>
80+
<ChecklistItem id="ai-about-chart">
81+
**Ask AI about a specific chart or dashboard**`Interactive Viewer` Launch a conversation with the chart or dashboard pre-loaded as context — click Ask AI Agent from its menu. [Docs — asking about a chart or dashboard](/guides/ai-agents/using-ai-agents#asking-about-a-chart-or-dashboard)
82+
</ChecklistItem>
83+
<ChecklistItem id="ai-feedback">
84+
**Give feedback on AI answers with thumbs up / down**`Interactive Viewer` Any user can rate an agent response — thumbs down lets you optionally explain what went wrong, which helps the data team improve the agent. [Docs — using AI agents](/guides/ai-agents/using-ai-agents)
85+
</ChecklistItem>
86+
87+
</Checklist>
4288

4389
## Role reference
4490

snippets/checklist.jsx

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
// Interactive, persistent checklist components for Mintlify docs.
2+
//
3+
// Usage on a page:
4+
//
5+
// import { Checklist, ChecklistItem } from '/snippets/checklist.jsx';
6+
//
7+
// <Checklist storageKey="business-user-training">
8+
// <ChecklistItem id="semantic-layer">
9+
// **Understand the Lightdash semantic layer** — one governed source of truth.
10+
// </ChecklistItem>
11+
// <ChecklistItem id="dims-vs-metrics">
12+
// **Understand the difference between dimensions and metrics** — ...
13+
// </ChecklistItem>
14+
// </Checklist>
15+
//
16+
// Each item's checked state is persisted per-reader in localStorage under
17+
// `lightdash-checklist:<storageKey>`. The wrapper renders a progress bar and a
18+
// "Reset" button.
19+
20+
const ChecklistContext = React.createContext(null);
21+
22+
export const Checklist = ({ storageKey, children }) => {
23+
const key = `lightdash-checklist:${storageKey || 'default'}`;
24+
const [checked, setChecked] = React.useState({});
25+
const [hydrated, setHydrated] = React.useState(false);
26+
27+
// Hydrate from localStorage on mount (client-only).
28+
React.useEffect(() => {
29+
try {
30+
const raw = typeof window !== 'undefined' ? window.localStorage.getItem(key) : null;
31+
if (raw) setChecked(JSON.parse(raw));
32+
} catch (e) {
33+
// ignore malformed storage
34+
}
35+
setHydrated(true);
36+
}, [key]);
37+
38+
// Persist on change.
39+
React.useEffect(() => {
40+
if (!hydrated) return;
41+
try {
42+
window.localStorage.setItem(key, JSON.stringify(checked));
43+
} catch (e) {
44+
// storage full / blocked — ignore
45+
}
46+
}, [checked, hydrated, key]);
47+
48+
const toggle = React.useCallback((id) => {
49+
setChecked((prev) => ({ ...prev, [id]: !prev[id] }));
50+
}, []);
51+
52+
const reset = React.useCallback(() => {
53+
setChecked({});
54+
try {
55+
window.localStorage.removeItem(key);
56+
} catch (e) {
57+
// ignore
58+
}
59+
}, [key]);
60+
61+
// Count items by walking the children tree for ChecklistItem elements.
62+
const { total, done } = React.useMemo(() => {
63+
let t = 0;
64+
let d = 0;
65+
const walk = (nodes) => {
66+
React.Children.forEach(nodes, (child) => {
67+
if (!React.isValidElement(child)) return;
68+
if (child.type === ChecklistItem) {
69+
t += 1;
70+
if (checked[child.props.id]) d += 1;
71+
} else if (child.props && child.props.children) {
72+
walk(child.props.children);
73+
}
74+
});
75+
};
76+
walk(children);
77+
return { total: t, done: d };
78+
}, [children, checked]);
79+
80+
const percent = total === 0 ? 0 : Math.round((done / total) * 100);
81+
82+
return (
83+
<ChecklistContext.Provider value={{ checked, toggle }}>
84+
<div
85+
style={{
86+
position: 'sticky',
87+
top: '5rem',
88+
zIndex: 5,
89+
margin: '0 0 1.5rem',
90+
padding: '0.75rem 1rem',
91+
borderRadius: '0.5rem',
92+
background: 'var(--card-background, rgba(127,127,127,0.08))',
93+
border: '1px solid rgba(127,127,127,0.2)',
94+
display: 'flex',
95+
alignItems: 'center',
96+
gap: '1rem',
97+
flexWrap: 'wrap',
98+
}}
99+
>
100+
<div style={{ flex: '1 1 12rem', minWidth: '12rem' }}>
101+
<div
102+
style={{
103+
fontSize: '0.85rem',
104+
fontWeight: 600,
105+
marginBottom: '0.35rem',
106+
opacity: 0.85,
107+
}}
108+
>
109+
Progress: {done} / {total} ({percent}%)
110+
</div>
111+
<div
112+
style={{
113+
height: '0.5rem',
114+
width: '100%',
115+
background: 'rgba(127,127,127,0.2)',
116+
borderRadius: '999px',
117+
overflow: 'hidden',
118+
}}
119+
role="progressbar"
120+
aria-valuenow={percent}
121+
aria-valuemin={0}
122+
aria-valuemax={100}
123+
>
124+
<div
125+
style={{
126+
height: '100%',
127+
width: `${percent}%`,
128+
background: '#7857FE',
129+
transition: 'width 200ms ease',
130+
}}
131+
/>
132+
</div>
133+
</div>
134+
<button
135+
type="button"
136+
onClick={reset}
137+
disabled={done === 0}
138+
style={{
139+
fontSize: '0.8rem',
140+
fontWeight: 500,
141+
padding: '0.4rem 0.8rem',
142+
borderRadius: '0.4rem',
143+
border: '1px solid rgba(127,127,127,0.35)',
144+
background: 'transparent',
145+
cursor: done === 0 ? 'not-allowed' : 'pointer',
146+
opacity: done === 0 ? 0.5 : 1,
147+
color: 'inherit',
148+
}}
149+
>
150+
Reset
151+
</button>
152+
</div>
153+
<ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>{children}</ul>
154+
</ChecklistContext.Provider>
155+
);
156+
};
157+
158+
export const ChecklistItem = ({ id, children }) => {
159+
const ctx = React.useContext(ChecklistContext);
160+
const isChecked = !!(ctx && ctx.checked[id]);
161+
const onChange = () => ctx && ctx.toggle(id);
162+
const inputId = `checklist-${id}`;
163+
164+
return (
165+
<li
166+
style={{
167+
display: 'flex',
168+
alignItems: 'flex-start',
169+
gap: '0.65rem',
170+
padding: '0.5rem 0',
171+
borderBottom: '1px solid rgba(127,127,127,0.15)',
172+
}}
173+
>
174+
<input
175+
id={inputId}
176+
type="checkbox"
177+
checked={isChecked}
178+
onChange={onChange}
179+
style={{
180+
marginTop: '0.35rem',
181+
width: '1.05rem',
182+
height: '1.05rem',
183+
cursor: 'pointer',
184+
accentColor: '#7857FE',
185+
flexShrink: 0,
186+
}}
187+
/>
188+
<label
189+
htmlFor={inputId}
190+
style={{
191+
cursor: 'pointer',
192+
opacity: isChecked ? 0.55 : 1,
193+
textDecoration: isChecked ? 'line-through' : 'none',
194+
lineHeight: 1.5,
195+
}}
196+
>
197+
{children}
198+
</label>
199+
</li>
200+
);
201+
};

0 commit comments

Comments
 (0)