diff --git a/packages/dashboard-ui-components/src/components/data-grid/data-grid.tsx b/packages/dashboard-ui-components/src/components/data-grid/data-grid.tsx index 7bacf4d94..c8763af3d 100644 --- a/packages/dashboard-ui-components/src/components/data-grid/data-grid.tsx +++ b/packages/dashboard-ui-components/src/components/data-grid/data-grid.tsx @@ -376,6 +376,15 @@ function hashStringToInt(value: string): number { return Math.abs(hash); } +/** + * Column flex fractions used when the grid is loading before any schema is + * known (e.g. QueryDataGrid discovers columns from the first result page). + * Without these, `SkeletonRow` would render zero cells and the body looks + * like an empty black void instead of a shimmer. + */ +const SCHEMA_PENDING_COL_FRACTIONS = [0.18, 0.16, 0.34, 0.2, 0.12] as const; +const SCHEMA_PENDING_SKELETON_ROWS = 10; + function SkeletonRow({ columns, height, @@ -405,6 +414,72 @@ function SkeletonRow({ ); } +/** Sticky header shimmer when columns haven't been discovered yet. */ +function SchemaPendingHeaderCells({ showCheckbox }: { showCheckbox?: boolean }) { + return ( + <> + {showCheckbox && ( +
+ )} + {SCHEMA_PENDING_COL_FRACTIONS.map((frac, colIdx) => ( +
+ +
+ ))} + + ); +} + +/** Full-width body shimmer when columns haven't been discovered yet. */ +function SchemaPendingSkeleton({ + rowHeight, + showCheckbox, +}: { + rowHeight: number, + showCheckbox?: boolean, +}) { + return ( +
+ {Array.from({ length: SCHEMA_PENDING_SKELETON_ROWS }).map((_, rowIdx) => ( +
+ {showCheckbox && ( +
+ +
+ )} + {SCHEMA_PENDING_COL_FRACTIONS.map((frac, colIdx) => ( +
+ +
+ ))} +
+ ))} +
+ ); +} + // ─── Selection checkbox ────────────────────────────────────────────── function SelectionCheckbox({ @@ -1138,30 +1213,36 @@ export function DataGrid(props: DataGridProps) { >
- {selectionMode !== "none" && ( -
- {selectionMode === "multiple" && ( - + {isLoading && visibleColumns.length === 0 ? ( + + ) : ( + <> + {selectionMode !== "none" && ( +
+ {selectionMode === "multiple" && ( + + )} +
)} -
+ {visibleColumns.map((col) => { + const header = headerByColId.get(col.id); + if (!header) return null; + return ; + })} + )} - {visibleColumns.map((col) => { - const header = headerByColId.get(col.id); - if (!header) return null; - return ; - })}
@@ -1190,15 +1271,27 @@ export function DataGrid(props: DataGridProps) { }} > {isLoading && ( -
- {loadingState ?? Array.from({ length: 8 }).map((_, i) => ( - - ))} +
+ {loadingState ?? ( + visibleColumns.length === 0 ? ( + // Schema not known yet (common for query grids that discover + // columns from the first page) — fall back to a full-width + // shimmer so loading never looks like an empty black pane. + + ) : ( + Array.from({ length: 8 }).map((_, i) => ( + + )) + ) + )}
)}