Commit 65d87a4
Dashboard: DataGrid refactor + layout (stacked on overview-revamp) (#1338)
## Summary
Stacked on `overview-revamp` (now rebased against `dev`). Introduces a
first-class `DataGrid` component in
`@stackframe/dashboard-ui-components`, migrates every dashboard table
off the legacy `DesignDataTable` / hand-rolled `<Table>` pattern to it,
and ships a matching dashboard design guide.
Since the last writeup the `DataGrid` runtime has been substantially
rewritten: the virtualizer now supports `rowHeight="auto"` with
`estimatedRowHeight`, every column can opt into `cellOverflow: "wrap"`,
the toolbar + header stick under a configurable `stickyTop`, and the
seeded dummy data has been fleshed out so the migrated surfaces render
with realistic density. The AI-analytics prompt was also extended with
full schema docs for the auth / team / email / payments tables so
natural-language queries produce better SQL.
**Base:** `dev` → **Head:** `ui-fixes-minor`
**Scope:** 39 files, ~+6.5k / -2.4k
## Screenshots
Captured against the seeded Demo Project on the local dashboard
(`admin@example.com` via mock GitHub OAuth). Viewport: **1920×1200**
(standard) and **2560×1440** (widescreen). Assets hosted in [this
gist](https://gist.github.com/mantrakp04/2fe05ddbb2d2d7cd2d237027c909c1b9).
### Overview — revamped metrics + line chart
| Light | Dark |
| --- | --- |
|

|

|
Widescreen:
| Light | Dark |
| --- | --- |
|

|

|
### Users — DataGrid with seeded rows
| Light | Dark |
| --- | --- |
|

|

|
Widescreen:
| Light | Dark |
| --- | --- |
|

|

|
### Transactions — new DataGridToolbar + sticky chrome
| Light | Dark |
| --- | --- |
|

|

|
Widescreen:
| Light | Dark |
| --- | --- |
|

|

|
### Teams
| Light | Dark |
| --- | --- |
|

|

|
Widescreen:
| Light | Dark |
| --- | --- |
|

|

|
### Email Outbox
| Light | Dark |
| --- | --- |
|

|

|
Widescreen:
| Light | Dark |
| --- | --- |
|

|

|
### Payments — Customers
| Light | Dark |
| --- | --- |
|

|

|
Widescreen:
| Light | Dark |
| --- | --- |
|

|

|
### Sticky behaviour — scrolled views
Grids scrolled down ~600px. The page header is still pinned, and the
`DataGrid` toolbar + column header row stay put under it (backdrop-blur
+ `stickyTop` offset) while the virtualized body rows scroll past.
Compare the scrolled view against the top-of-page view above.
| Page | Light | Dark |
| --- | --- | --- |
| Users |

|

|
| Teams |

|

|
| Transactions |

|

|
| Payments Customers |

|

|
| Email Outbox |

|

|
| Analytics Tables |

|

|
### Other migrated surfaces
| Page | Light | Dark |
| --- | --- | --- |
| Analytics Tables |

|

|
| Emails |

|

|
| Email Sent |

|

|
| Domains |

|

|
| Webhooks |

|

|
| External DB Sync |

|

|
## What's new
### `DataGrid` in `@stackframe/dashboard-ui-components`
A new, fully-typed, fully-controlled grid component under
`packages/dashboard-ui-components/src/components/data-grid/`. Single
source of truth for tabular UI across the dashboard.
Package files:
- `data-grid.tsx` — main grid renderer (virtualized rows, sticky toolbar
+ header)
- `data-grid-toolbar.tsx` — built-in toolbar (search, columns, density,
export)
- `data-grid-sizing.ts` — column width / flex / min-width resolution
- `state.ts` — state helpers (`createDefaultDataGridState`, sort /
select / paginate utilities, `exportToCsv`, date formatters)
- `strings.ts` — i18n string table + `resolveDataGridStrings`
- `types.ts` — public types (`DataGridColumnDef`, `DataGridProps`,
`DataGridState`, `DataGridDataSource`, etc.)
- `use-data-source.ts` — `useDataSource` hook with `client` / `server` /
`infinite` modes
- `index.ts` — package entrypoint
Features:
- Controlled state (`state` + `onChange`) covering sorting, pagination,
column visibility, column widths, column pinning, selection,
date-display mode, and quick search.
- Column definitions with `string` / `number` / `date` / `dateTime` /
`boolean` / `singleSelect` / `custom` types, custom `renderCell`, custom
sort comparators, per-column `parseValue` / `dateFormat`, pinning,
align, flex / min / max width.
- **Cell overflow control** — new `cellOverflow: "truncate" | "wrap"`
per column. `"wrap"` + `rowHeight="auto"` lets rows grow to fit
multi-line content.
- **Dynamic row heights** — `rowHeight` now accepts `"auto"` with an
`estimatedRowHeight` hint for the virtualizer, eliminating
scroll-position jank while rows are still being measured.
- **Sticky chrome with `stickyTop`** — the toolbar and header stick
under a caller-provided offset (matching the page header height) with a
proper blur backdrop. See the _Sticky behaviour — scrolled views_
section above for the visual.
- Client-side sort + quick-search + pagination via `useDataSource` —
consumer never pre-sorts / paginates.
- Server-side and async-generator data sources for streaming / cursor
pagination.
- Paginated and infinite-scroll UI modes.
- CSV export + clipboard copy.
- Row single / multi selection with shift-range anchor.
- Row + cell click / double-click callbacks.
- Pluggable toolbar / footer / empty / loading states and i18n strings.
### Dashboard design guide
New `apps/dashboard/DESIGN-GUIDE.md`: prescriptive, AI-readable source
of truth for dashboard UI. Documents when to use each
`design-components` primitive, the `DataGrid` canonical pattern, color /
typography / spacing / motion rules, route-specific guidance, and the
migration priority. Now also documents the new `cellOverflow` and
dynamic-`rowHeight` patterns, and marks `DesignDataTable` as deprecated
in favor of `DataGrid` + `useDataSource` + `createDefaultDataGridState`.
### Overview page revamp
`apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/(overview)/line-chart.tsx`
— line chart rewritten on top of the shared `AnalyticsChart` /
`DonutChartDisplay` primitives, feeding the revamped Overview.
### Data-table migrations
Every shared table under `apps/dashboard/src/components/data-table/` has
been rewritten on top of `DataGrid`:
- `api-key-table.tsx`
- `payment-product-table.tsx`
- `permission-table.tsx`
- `team-member-search-table.tsx`
- `team-member-table.tsx`
- `team-search-table.tsx`
- `team-table.tsx`
- `transaction-table.tsx` — now also wires in `DataGridToolbar` with
search / column visibility
- `user-search-picker.tsx`
- `user-table.tsx` — extracted `USER_TABLE_COLUMNS` for readability /
reuse
### Page adoption
Page-level tables migrated to `DataGrid` (or the new `useDataSource` +
`createDefaultDataGridState` pattern):
- `(overview)/line-chart.tsx`
- `analytics/tables/query-data-grid.tsx` (now with sticky header)
- `domains/page-client.tsx`
- `email-drafts/[draftId]/page-client.tsx`
- `email-outbox/page-client.tsx` (with `DataGridToolbar`)
- `email-sent/page-client.tsx`, `grouped-email-table.tsx`,
`sent-emails-view.tsx`
- `emails/page-client.tsx`
- `external-db-sync/page-client.tsx`
- `payments/layout.tsx`, `payments/customers/page-client.tsx`,
`payments/products/[productId]/page-client.tsx`
- `users/[userId]/page-client.tsx`
- `webhooks/page-client.tsx`, `webhooks/[endpointId]/page-client.tsx`
- `design-language/page-client.tsx`,
`design-language/realistic-demo/page-client.tsx`
- `playground/page-client.tsx`
### Backend & supporting changes
- `apps/backend/src/lib/ai/prompts.ts` — extends the AI-analytics prompt
with detailed schema docs for `contact_channels`, `teams`,
`team_member_profiles`, `team_permissions`, `team_invitations`,
`email_outboxes`, `project_permissions`, `notification_preferences`,
`refresh_tokens`, and `connected_accounts`, so natural-language queries
have richer context to compile against.
- `apps/backend/src/lib/seed-dummy-data.ts` — additional OAuth providers
on seed users, improving dummy-data coverage for the migrated tables
(visible on the Users grid).
- `apps/dashboard/src/app/globals.css` — adds `--data-grid-sticky-top`
token used to derive the grid's sticky offset under the page header.
- `packages/template/src/dev-tool/dev-tool-core.ts` — persist the
"closed" state when the user closes the dev-tool panel so it doesn't
reopen on next load.
## Notes for reviewers
- Rebased onto latest `dev`; conflict in `api-key-table.tsx` resolved by
keeping the `DataGrid` implementation (consistent with the other
migrated tables).
- `DesignDataTable` is still in the codebase but marked deprecated in
the design guide — new code must use `DataGrid`.
- `DataGrid` is fully controlled: consumers must pass state + onChange,
must feed `rows` from `useDataSource` (never raw arrays), and must
define columns outside the component or via `useMemo`. The guide's §4.12
spells this out.
- `rowHeight="auto"` is opt-in; the default fixed-height virtualization
path is unchanged and remains the fast path for dense, single-line grids
(users, transactions, etc.).
- Screenshots are JPEG this round — the local capture tooling's PNG path
was producing blank frames, so the new set is `.jpg` end-to-end. Same
viewports, same seeded project.
## Test plan
- [ ] `pnpm lint` passes
- [ ] `pnpm typecheck` passes
- [ ] Load the dashboard and verify every migrated surface renders,
sorts, searches, paginates, and handles row-click navigation:
- [ ] Overview (line chart + donut metrics)
- [ ] Users list + user detail (teams, sessions, permissions, API keys)
- [ ] Teams list + team detail (members, permissions)
- [ ] Domains
- [ ] Emails, email-sent, email-outbox, email-drafts
- [ ] Webhooks list + endpoint detail
- [ ] Payments customers, product detail, transactions (new toolbar)
- [ ] External DB sync
- [ ] Analytics query table (sticky header)
- [ ] Verify infinite-scroll surfaces (domains, etc.) load additional
rows on scroll
- [ ] Verify sticky header stays below the page header in light and dark
themes
- [ ] Verify CSV export produces correct output on a representative
table
- [ ] Verify column resize, visibility toggle, and sort work across
themes
- [ ] Verify `cellOverflow: "wrap"` rows grow to fit when
`rowHeight="auto"` and clip when `rowHeight` is numeric
- [ ] Spot-check AI analytics queries against the new schema context
(contact_channels, teams, email_outboxes, …)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Unified table components across dashboard with improved infinite
pagination and quick search.
* **Improvements**
* Enhanced table performance with sticky headers and better row height
handling.
* Improved sorting, filtering, and data loading with consistent state
management.
* Better visual consistency across all data grids and table layouts.
* **UI/Styling**
* Refined table styling for better text truncation and content wrapping.
* Optimized layout spacing and alignment across dashboard tables.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Developing-Gamer <maxcodes11110@gmail.com>
Co-authored-by: Armaan Jain <84474476+Developing-Gamer@users.noreply.github.com>
Co-authored-by: Konstantin Wohlwend <n2d4xc@gmail.com>1 parent 5423d77 commit 65d87a4
73 files changed
Lines changed: 6610 additions & 3409 deletions
File tree
- .claude
- apps
- backend/src
- app/api/latest
- ai/query/[mode]
- internal
- metrics
- user-counts
- projects-dau
- lib
- ai
- tools
- dashboard
- src
- app
- (main)/(protected)
- (outside-dashboard)
- playground
- projects
- projects/[projectId]
- (overview)
- analytics/tables
- design-language
- realistic-demo
- domains
- email-drafts
- [draftId]
- email-outbox
- email-sent
- emails
- external-db-sync
- payments
- customers
- products/[productId]
- users
- [userId]
- webhooks
- [endpointId]
- components
- data-table
- lib
- prefetch
- e2e/tests
- backend/endpoints/api/v1
- __snapshots__
- internal-tool/scripts
- claude
- packages
- dashboard-ui-components/src/components
- analytics-chart
- data-grid
- template/src
- dev-tool
- lib/stack-app/apps/implementations
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
355 | 355 | | |
356 | 356 | | |
357 | 357 | | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
Lines changed: 26 additions & 42 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
17 | | - | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
| |||
29 | 30 | | |
30 | 31 | | |
31 | 32 | | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | 33 | | |
38 | 34 | | |
39 | 35 | | |
| |||
79 | 75 | | |
80 | 76 | | |
81 | 77 | | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
82 | 84 | | |
83 | 85 | | |
84 | 86 | | |
85 | 87 | | |
86 | | - | |
| 88 | + | |
87 | 89 | | |
88 | 90 | | |
89 | 91 | | |
| |||
99 | 101 | | |
100 | 102 | | |
101 | 103 | | |
102 | | - | |
| 104 | + | |
103 | 105 | | |
104 | 106 | | |
105 | 107 | | |
106 | 108 | | |
107 | 109 | | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
| 110 | + | |
| 111 | + | |
121 | 112 | | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
| 113 | + | |
126 | 114 | | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
135 | 118 | | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
141 | 124 | | |
142 | | - | |
| 125 | + | |
| 126 | + | |
143 | 127 | | |
144 | 128 | | |
145 | 129 | | |
| |||
152 | 136 | | |
153 | 137 | | |
154 | 138 | | |
155 | | - | |
| 139 | + | |
156 | 140 | | |
157 | 141 | | |
158 | 142 | | |
| |||
183 | 167 | | |
184 | 168 | | |
185 | 169 | | |
186 | | - | |
| 170 | + | |
187 | 171 | | |
188 | 172 | | |
189 | 173 | | |
| |||
0 commit comments