[Dashboard] Standardize table empty states with a shared component#9983
[Dashboard] Standardize table empty states with a shared component#9983stephenkevn wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a standardized empty-state UI across the dashboard by creating the EmptyState and EmptyTableState components, which are integrated into the clusters, jobs, pools, users, volumes, and workspaces views. It also adds a isForceEmpty utility function to allow developers and QA to force empty states via a URL query parameter. The review feedback suggests refactoring the inline styles in the new EmptyState component to Tailwind CSS classes to improve maintainability and consistency with the rest of the codebase.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| <div | ||
| className="flex items-center justify-center" | ||
| style={{ | ||
| width: 40, | ||
| height: 40, | ||
| marginBottom: 16, | ||
| borderRadius: 9999, | ||
| backgroundColor: '#f9fafb', | ||
| border: '1px solid #e5e7eb', | ||
| color: '#9ca3af', | ||
| }} | ||
| > | ||
| {icon || <Inbox size={20} strokeWidth={1.75} />} | ||
| </div> | ||
| <div style={{ fontSize: 16, fontWeight: 500, color: '#111827' }}> | ||
| {title} | ||
| </div> | ||
| {description ? ( | ||
| <div | ||
| style={{ | ||
| marginTop: 6, | ||
| fontSize: 14, | ||
| lineHeight: 1.55, | ||
| color: '#6b7280', | ||
| maxWidth: 360, | ||
| }} | ||
| > | ||
| {description} | ||
| </div> | ||
| ) : null} | ||
| {action ? <div style={{ marginTop: 20 }}>{action}</div> : null} |
There was a problem hiding this comment.
While the comment explains that colors are inline on purpose, many other styling properties like width, height, margin, borderRadius, fontSize, and fontWeight are also defined using inline styles. This makes the component harder to maintain and inconsistent with the rest of the codebase that uses Tailwind CSS.
To improve maintainability, consider refactoring these inline styles into Tailwind classes. You can use Tailwind's arbitrary value support to specify hex colors directly in the class names (e.g., bg-[#f9fafb]) to address the concern about theme variables. This keeps all styling within the className prop.
Here's a suggested refactoring:
<div
className="mb-4 flex h-10 w-10 items-center justify-center rounded-full border border-[#e5e7eb] bg-[#f9fafb] text-[#9ca3af]"
>
{icon || <Inbox size={20} strokeWidth={1.75} />}
</div>
<div className="text-base font-medium text-[#111827]">{title}</div>
{description ? (
<div className="mt-1.5 max-w-[360px] text-sm leading-[1.55] text-[#6b7280]">
{description}
</div>
) : null}
{action ? <div className="mt-5">{action}</div> : null}Add a reusable EmptyState block (neutral icon in a 40px circle, title, optional description and action) and an EmptyTableState helper that drops it into a table body via a colSpan row, keeping column headers and pagination visible. The block is vertically centered in a fixed 280px region so empty tables no longer collapse to a thin strip. Apply it to the clusters, jobs (managed + pools), users (+ service account tokens), volumes, and workspaces tables, with icons matching the nav and concise, action-first copy. A '?empty' URL flag forces the empty state on populated tables for review. Colors are inline hex because the theme CSS variables can resolve to white in some render contexts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6363e40 to
2ca1fbc
Compare
When a context has no nodes the Nodes section rendered nothing; show the shared EmptyState (icon + title) so it matches the other tables. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
EmptyStateblock (a neutral icon in a 40px circle, a title, and an optional description and action) undercomponents/elements/, plus anEmptyTableStatehelper incomponents/ui/table.jsxthat renders it inside a full-widthcolSpanrow so the column headers and pagination stay visible.?emptyURL flag forces the empty state on populated tables so the styling can be reviewed without clearing real data. Colors are inline hex because the theme CSS variables can resolve to white in some render contexts.Test plan
npm run lintandnpx prettier --checkon the touched files — both clean.npm run build— succeeds.npm run dev, then for each table visit?empty=1: the empty state renders (icon + title + description) centered in a 280px region with the column headers and pagination intact; removing the flag renders rows normally; no console errors. For Infrastructure, a context with no nodes shows the empty state instead of a blank section.