Alerting: Add pagination for rules in a group in the rule list view v2 (#108436)

* add pagination for rules in a group, in the rule list view v2

* update translations

* remove gap in stack
This commit is contained in:
Sonia Aguilar
2025-07-23 11:32:30 +02:00
committed by GitHub
parent 937cdc3682
commit 3fe21f1cca
2 changed files with 58 additions and 5 deletions
@@ -1,13 +1,20 @@
import { css } from '@emotion/css';
import { useMemo } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { t } from '@grafana/i18n';
import { Alert } from '@grafana/ui';
import { Alert, Pagination, Stack, useStyles2 } from '@grafana/ui';
import { GrafanaRuleGroupIdentifier } from 'app/types/unified-alerting';
import { prometheusApi } from '../api/prometheusApi';
import { usePagination } from '../hooks/usePagination';
import { RULE_LIST_POLL_INTERVAL_MS } from '../utils/constants';
import { GrafanaRuleListItem } from './GrafanaRuleListItem';
import { AlertRuleListItemSkeleton } from './components/AlertRuleListItemLoader';
const DEFAULT_PER_PAGE_PAGINATION_RULES_PER_GROUP_LIST_VIEW_V2 = 100;
const { useGetGrafanaGroupsQuery } = prometheusApi;
export interface GrafanaGroupLoaderProps {
@@ -31,6 +38,8 @@ export function GrafanaGroupLoader({
namespaceName,
expectedRulesCount = 3, // 3 is a random number. Usually we get the number of rules from Prometheus response
}: GrafanaGroupLoaderProps) {
const styles = useStyles2(getStyles);
const { data: promResponse, isLoading: isPromResponseLoading } = useGetGrafanaGroupsQuery(
{
folderUid: groupIdentifier.namespace.uid,
@@ -40,6 +49,16 @@ export function GrafanaGroupLoader({
{ pollingInterval: RULE_LIST_POLL_INTERVAL_MS }
);
const rules = useMemo(() => {
return promResponse?.data.groups.at(0)?.rules ?? [];
}, [promResponse]);
const { pageItems, page, numberOfPages, onPageChange } = usePagination(
rules,
1,
DEFAULT_PER_PAGE_PAGINATION_RULES_PER_GROUP_LIST_VIEW_V2
);
if (isPromResponseLoading) {
return (
<>
@@ -63,9 +82,14 @@ export function GrafanaGroupLoader({
);
}
// If no rules found, return early without pagination
if (rules.length === 0) {
return <Alert title={t('alerting.group-loader.no-rules', 'No rules found in this group')} severity="info" />;
}
return (
<>
{promResponse.data.groups.at(0)?.rules.map((promRule) => {
<Stack direction="column" gap={0}>
{pageItems.map((promRule) => {
return (
<GrafanaRuleListItem
key={promRule.uid}
@@ -77,6 +101,34 @@ export function GrafanaGroupLoader({
/>
);
})}
</>
<div className={styles.paginationWrapper}>
{numberOfPages > 1 && (
<Pagination
currentPage={page}
numberOfPages={numberOfPages}
onNavigate={onPageChange}
hideWhenSinglePage
className={styles.pagination}
/>
)}
</div>
</Stack>
);
}
const getStyles = (theme: GrafanaTheme2) => ({
pagination: css({
display: 'flex',
margin: 0,
paddingTop: theme.spacing(1),
paddingBottom: theme.spacing(0.25),
justifyContent: 'center',
float: 'none',
}),
paginationWrapper: css({
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'center',
marginLeft: theme.spacing(2.5),
}),
});
+2 -1
View File
@@ -1551,7 +1551,8 @@
"title": "Edit evaluation group"
},
"group-loader": {
"group-load-failed": "Failed to load rules from group {{ groupName }} in {{ namespaceName }}"
"group-load-failed": "Failed to load rules from group {{ groupName }} in {{ namespaceName }}",
"no-rules": "No rules found in this group"
},
"group-status": {
"content-the-group-is-being-deleted": "The group is being deleted"