UI Patterns
Common UI composition patterns in the Prometheus UI codebase.
Info Page Pattern
Used by: StatusPage, TSDBStatusPage, AgentPage, FlagsPage
The info page pattern combines InfoPageLayout + multiple InfoCard components, each containing a KeyValueTable or DataTable.
Structure
<InfoPageLayout>
<InfoCard title="Runtime Information" icon={IconServer}>
<KeyValueTable object={runtimeInfo} />
</InfoCard>
<InfoCard title="Build Information" icon={IconInfoCircle}>
<KeyValueTable object={buildInfo} />
</InfoCard>
<InfoCard title="Command-Line Flags" icon={IconFlag}>
<DataTable columns={flagColumns} data={flags} />
</InfoCard>
</InfoPageLayout>
Key Characteristics
- Max width of 1000px, centered
- Cards use shadow "xs" with borders
- Each card has an icon + title header
- Data wrapped in Suspense for async loading
Accordion List Pattern
Used by: AlertsPage, RulesPage, TargetsPage, ServiceDiscoveryPage
The accordion list pattern combines FilterToolbar + HealthPanel items inside an Accordion. Each page filters groups by state and search text, then renders expandable panels with health-colored borders.
Structure
// Filter bar at top
<FilterToolbar
searchValue={search}
onSearchChange={setSearch}
stateOptions={stateOptions}
selectedStates={states}
onStatesChange={setStates}
showCollapseAll={hasCollapseAll}
allCollapsed={collapsed}
onCollapseAllChange={setCollapsed}
/>
// Accordion with health panels
<Accordion multiple variant="separated">
{filteredGroups.map(group => (
<HealthPanel key={group.name} value={group.name} status={group.health}>
<Accordion.Control>
{group.name}
<StatusBadge status={group.health} />
</Accordion.Control>
<Accordion.Panel>...</Accordion.Panel>
</HealthPanel>
))}
</Accordion>
Variations
| Page | State Options | Collapse All | Pagination |
|---|---|---|---|
| AlertsPage | firing, pending, inactive | No | Yes |
| RulesPage | ok, err, unknown | No | Yes |
| TargetsPage | up, down, unknown | Yes | Pool limit (20) |
| ServiceDiscoveryPage | active, dropped | Yes | Pool limit (20) |
Query Panel Pattern
The query page is the most complex pattern, combining CodeMirror, time controls, graph rendering, and result tables.
Key Elements
- CodeMirror expression input embedded inside Mantine InputBase
- Enter executes query, Shift+Enter inserts newline, Escape blurs
- PromQL autocomplete with history overlay
- Time controls: range/end time, resolution, display mode
- Graph: uPlot for time series, with range selection
- Result table: SeriesName + DataTable combination
Data Flow
- User types PromQL expression
- Pressing Enter triggers
/query_rangeor/queryAPI call - Old data stays visible during query (no flash-to-empty)
- Results render in either graph or table view
- Range selection on graph updates time range and re-queries
Filter Bar Pattern
All filter bars in Prometheus UI follow the same composition:
[StateMultiSelect] + [TextInput with search icon] + [optional collapse button]
FilterToolbar encapsulates this entire pattern. The search input uses fuzzy matching via @nexucis/kvsearch on the page level. All filter values are persisted to URL query parameters.
URL Persistence
// Example URL with persisted filters:
/alerts?search=cpu&state=firing&state=pending&page=2
Suspense + ErrorBoundary Composition
Every async data page uses a consistent wrapping pattern:
<Suspense fallback={<Skeleton />}>
<ErrorBoundary
key={location.pathname}
FallbackComponent={ErrorFallback}
>
<PageContent />
</ErrorBoundary>
</Suspense>
Key Behaviors
useSuspenseAPIQuerythrows a promise during loading (Suspense catches it)- ErrorBoundary catches API errors and renders ErrorAlert
- ErrorBoundary resets on route change via
key={location.pathname} - Skeleton loading states are shown while data loads
URL-Persistent State
All major filter states are persisted in URL query parameters via use-query-params:
| State | URL Param | Type | Pages |
|---|---|---|---|
| Search text | search | StringParam | All list pages |
| State filter | state | ArrayParam | Alerts, Rules, Targets, SD |
| Page number | page | NumberParam | Alerts, Rules |
| Active tab | tab | StringParam | Query (graph/table) |
| Expression | expr | StringParam | Query |
| Time range | range, end | NumberParam | Query |
This enables:
- Bookmarkable filtered views
- Shareable links that reproduce exact dashboard state
- Browser back/forward navigation through filter history