fix(webapp): move Queues search and pagination above the table (#4834)
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
* - `Grid` — tiles; columns derived from tile count unless `columns` is set. `kind="charts"`
|
||||
* bakes the fixed chart-row height.
|
||||
* - `Content` — table / tabs below the tiles. Full-bleed by default; `inset` for a padded column.
|
||||
* `toolbar` adds a bar flush above the content for controls that scope only this region.
|
||||
*
|
||||
* Optional:
|
||||
* - `Sidebar` — a persistent right-hand panel; fixed `width` or `resizable`. Present ⇒ Root
|
||||
@@ -22,12 +23,14 @@
|
||||
* ```tsx
|
||||
* <MetricsLayout.Root>
|
||||
* <MetricsLayout.Filters>
|
||||
* <div className="flex items-center gap-2">…search + TimeFilter…</div>
|
||||
* <PaginationControls … />
|
||||
* <div className="flex items-center gap-2">…TimeFilter…</div>
|
||||
* <div className="flex items-center gap-2">…page-wide actions…</div>
|
||||
* </MetricsLayout.Filters>
|
||||
* <MetricsLayout.Grid>…stat tiles…</MetricsLayout.Grid>
|
||||
* <MetricsLayout.Grid kind="charts">…chart tiles…</MetricsLayout.Grid>
|
||||
* <MetricsLayout.Content>…table…</MetricsLayout.Content>
|
||||
* <MetricsLayout.Content toolbar={<>…search…<PaginationControls … /></>}>
|
||||
* …table…
|
||||
* </MetricsLayout.Content>
|
||||
* </MetricsLayout.Root>
|
||||
* ```
|
||||
*/
|
||||
@@ -341,16 +344,44 @@ function MetricsLayoutGrid({
|
||||
* spans edge to edge with its own top border; pass `inset` for a padded column (the detail page's
|
||||
* tabs + charts). Separation from the tiles above comes from the scroll column's gap alone (no
|
||||
* extra top margin), so the tile → content step matches the gap between tile rows.
|
||||
*
|
||||
* Pass `toolbar` for controls that scope this region only (search, pagination) — they sit flush on
|
||||
* top of the content instead of in the page-wide `Filters` bar, so their scope is visible.
|
||||
*/
|
||||
function MetricsLayoutContent({
|
||||
children,
|
||||
inset = false,
|
||||
toolbar,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
/** Pad the content into a column (page gutter) instead of letting it span edge to edge. */
|
||||
inset?: boolean;
|
||||
/**
|
||||
* Controls that act on this region alone. Rendered as a bar directly above the content with no
|
||||
* gap, so it reads as belonging to the table below rather than to the tiles above. Compose
|
||||
* left/right clusters as child divs — `justify-between` spreads them.
|
||||
*/
|
||||
toolbar?: ReactNode;
|
||||
}) {
|
||||
return <div className={cn("flex flex-col gap-2.5", inset && "px-2.5")}>{children}</div>;
|
||||
const content = <div className={cn("flex flex-col gap-2.5", inset && "px-2.5")}>{children}</div>;
|
||||
|
||||
if (!toolbar) {
|
||||
return content;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center justify-between gap-2 border-t border-grid-dimmed px-1.5 py-1.5",
|
||||
inset && "mx-2.5"
|
||||
)}
|
||||
>
|
||||
{toolbar}
|
||||
</div>
|
||||
{content}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export const MetricsLayout = {
|
||||
|
||||
+21
-12
@@ -493,12 +493,10 @@ function QueuesWithMetricsView() {
|
||||
</PageAccessories>
|
||||
</NavBar>
|
||||
<MetricsLayout.Root>
|
||||
{/* Filters — pinned bar directly under the NavBar. Left cluster = search + period; right
|
||||
cluster = pagination. */}
|
||||
{/* Filters — pinned bar directly under the NavBar. This row is page-wide only: Period is
|
||||
the one control that changes the tiles and charts below, so it leads the row. Search
|
||||
and pagination scope the table alone and live in that table's own bar instead. */}
|
||||
<MetricsLayout.Filters className="px-2">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<QueueFilters />
|
||||
</div>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<TimeFilter
|
||||
period={timeRange.period ?? undefined}
|
||||
@@ -507,16 +505,12 @@ function QueuesWithMetricsView() {
|
||||
maxPeriodDays={maxPeriodDays}
|
||||
shortcut={{ key: "d" }}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center gap-1.5">
|
||||
{environment.runsEnabled &&
|
||||
env.pauseSource !== ENVIRONMENT_PAUSE_SOURCE_BILLING_LIMIT ? (
|
||||
<EnvironmentPauseResumeButton env={env} />
|
||||
) : null}
|
||||
<PaginationControls
|
||||
currentPage={pagination.currentPage}
|
||||
totalPages={pagination.mode === "unfiltered" ? pagination.totalPages : 1}
|
||||
hasNextPage={pagination.mode === "filtered" ? pagination.hasMore : undefined}
|
||||
showPageNumbers={false}
|
||||
/>
|
||||
</div>
|
||||
</MetricsLayout.Filters>
|
||||
|
||||
@@ -688,7 +682,22 @@ function QueuesWithMetricsView() {
|
||||
</ChartSyncProvider>
|
||||
) : null}
|
||||
|
||||
<MetricsLayout.Content>
|
||||
<MetricsLayout.Content
|
||||
/* Search + pagination only ever affect the table, so they sit on the table rather than
|
||||
in the page-wide Filters bar, where their position implied they filtered the metrics
|
||||
above. Same left/right split as the classic view's bar. */
|
||||
toolbar={
|
||||
<>
|
||||
<QueueFilters />
|
||||
<PaginationControls
|
||||
currentPage={pagination.currentPage}
|
||||
totalPages={pagination.mode === "unfiltered" ? pagination.totalPages : 1}
|
||||
hasNextPage={pagination.mode === "filtered" ? pagination.hasMore : undefined}
|
||||
showPageNumbers={false}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{/* Default overflow-x-auto container so wide tables still scroll horizontally on
|
||||
narrow viewports; the page (not this region) owns vertical scrolling. */}
|
||||
<Table containerClassName="border-t">
|
||||
|
||||
Reference in New Issue
Block a user