Deployments
A deployment history like the ones on hosting platforms: status with build time, environment, branch and commit, and a filter bar for environment, status, branch, and date, with live counts on every option.
$ npx shadcn add https://www.shad-table.dev/r/deployments-table.json42 deployments
| Deployment | Status | Source | Created |
|---|---|---|---|
dpl_fb86738b4 Production | Building 42s | main 484f3e3Fix redirect loop after SSO login | 2m agoby ava |
dpl_c1e89af9e Production | Queued Waiting for a build slot | main 01c567fRefactor auth middleware | 12m agoby noah |
dpl_2e53a50ae ProductionCurrent | Ready 3m 18s | main 8aefd9fUpdate onboarding copy | 42m agoby sofia |
dpl_b8cf8d6ab Production | Ready 3m 52s | main fda099bUpdate onboarding copy | 59m agoby liam |
dpl_d2f89263d Preview | Error 2m 10s | fix/login-redirect bf739cdBump dependencies | 1h agoby sofia |
dpl_7720201ef Preview | Ready 1m 33s | feat/billing-v2 55cbc8cTighten CSP headers | 2h agoby sofia |
dpl_4ddc65e45 Preview | Error 2m 2s | feat/billing-v2 6584e9fFix flaky e2e test | 3h agoby sofia |
dpl_a2b69d641 Preview | Canceled 2m 22s | fix/login-redirect 1becdf3Update onboarding copy | 4h agoby liam |
dpl_9b994d72b Production | Ready 1m 30s | main 21486edHandle empty cart in checkout | 5h agoby mia |
dpl_c5efd02c1 Preview | Canceled 2m 53s | feat/billing-v2 cb07f11Tighten CSP headers | 6h agoby noah |
1–10 of 42
How it works
1.Every filter is a TanStack column filter
Environment, status, branch, and date each set a filter value on their own column, with a filterFn that knows its shape: a list of allowed values, or a number of days back. Clearing everything is one setColumnFilters([]) call, and the table never keeps a second copy of the filter state.
const inList: FilterFn<Deployment> = (row, id, value: string[] | undefined) =>!value?.length || value.includes(row.getValue<string>(id))const withinDays: FilterFn<Deployment> = (row, id, days: number | undefined) =>days === undefined || row.getValue<number>(id) >= NOW - days * 86_400_000
2.Option counts come from faceting, so they never lie
getFacetedUniqueValues() counts each status or branch after applying every other active filter, but not the column's own. With Production selected, the Status menu shows how many production deploys are Ready or Error, which is exactly what ticking that option would give you.
const counts = column?.getFacetedUniqueValues()<span className="ml-auto font-mono text-xs text-muted-foreground">{counts?.get(option) ?? 0}</span>
3.Search covers fields that are not visible columns
The commit SHA, message, and author are real columns hidden with columnVisibility, so the search box can match them without cluttering the table. A custom globalFilterFn decides exactly which fields are searched, instead of TanStack guessing from value types.
const searchDeployments: FilterFn<Deployment> = (row, _id, query: string) => {const q = query.trim().toLowerCase()if (!q) return trueconst d = row.originalreturn [d.id, d.branch, d.sha, d.message, d.author].some((field) =>field.toLowerCase().includes(q),)}
4.Filtering always starts from page 1
With autoResetPageIndex, any filter change sends the table back to the first page, so narrowing 42 deployments down to 3 never leaves you staring at an empty page 4. The footer and the count next to the filters both read from the filtered row model.
useReactTable({// ...autoResetPageIndex: true,getFilteredRowModel: getFilteredRowModel(),getFacetedRowModel: getFacetedRowModel(),getFacetedUniqueValues: getFacetedUniqueValues(),})