diff --git a/public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx b/public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx index 2dee977835d..7d9a8d184de 100644 --- a/public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx +++ b/public/app/features/alerting/unified/rule-list/GrafanaGroupLoader.tsx @@ -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 ; + } + return ( - <> - {promResponse.data.groups.at(0)?.rules.map((promRule) => { + + {pageItems.map((promRule) => { return ( ); })} - > + + {numberOfPages > 1 && ( + + )} + + ); } + +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), + }), +}); diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 2c009a575c4..42438db155f 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -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"