diff --git a/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.test.tsx b/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.test.tsx
index d3d5b197067..774f2ea7c79 100644
--- a/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.test.tsx
+++ b/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.test.tsx
@@ -1,5 +1,6 @@
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
+import { times } from 'lodash';
import React from 'react';
import { byLabelText, byRole, byTestId } from 'testing-library-selector';
@@ -25,6 +26,7 @@ const ui = {
pending: byLabelText(/^Pending/),
},
instanceRow: byTestId('row'),
+ showAllInstances: byTestId('show-all'),
};
describe('RuleDetailsMatchingInstances', () => {
@@ -116,6 +118,31 @@ describe('RuleDetailsMatchingInstances', () => {
expect(ui.instanceRow.get()).toHaveTextContent(alertStateToReadable(state));
}
);
+
+ it('should correctly filter instances', async () => {
+ const event = userEvent.setup();
+
+ const rule = mockCombinedRule({
+ promRule: mockPromAlertingRule({
+ alerts: times(100, () => mockPromAlert({ state: GrafanaAlertState.Normal })),
+ }),
+ instanceTotals: {
+ inactive: 100,
+ },
+ });
+
+ render();
+
+ // should show all instances by default
+ expect(ui.showAllInstances.query()).not.toBeInTheDocument();
+
+ // filter by "error" state, should have no instances in that state
+ await event.click(ui.grafanaStateButton.error.get());
+
+ // click "show all" instances
+ await event.click(ui.showAllInstances.get());
+ expect(ui.showAllInstances.query()).not.toBeInTheDocument();
+ });
});
});
diff --git a/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.tsx b/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.tsx
index c52170a4d6c..76add623041 100644
--- a/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.tsx
+++ b/public/app/features/alerting/unified/components/rules/RuleDetailsMatchingInstances.tsx
@@ -1,9 +1,10 @@
import { css, cx } from '@emotion/css';
import { countBy, sum } from 'lodash';
import React, { useMemo, useState } from 'react';
+import { useHistory } from 'react-router-dom';
import { GrafanaTheme2 } from '@grafana/data';
-import { LinkButton, useStyles2 } from '@grafana/ui';
+import { Button, useStyles2 } from '@grafana/ui';
import { MatcherFilter } from 'app/features/alerting/unified/components/alert-groups/MatcherFilter';
import {
AlertInstanceStateFilter,
@@ -34,25 +35,24 @@ interface ShowMoreStats {
visibleItemsCount: number;
}
-function ShowMoreInstances(props: { ruleViewPageLink: string; stats: ShowMoreStats }) {
+function ShowMoreInstances(props: { onClick: () => void; stats: ShowMoreStats }) {
const styles = useStyles2(getStyles);
- const { ruleViewPageLink, stats } = props;
+ const { onClick, stats } = props;
return (
Showing {stats.visibleItemsCount} out of {stats.totalItemsCount} instances
- {ruleViewPageLink && (
-
- Show all {stats.totalItemsCount} alert instances
-
- )}
+
);
}
export function RuleDetailsMatchingInstances(props: Props): JSX.Element | null {
+ const history = useHistory();
const {
rule: { promRule, namespace, instanceTotals },
itemsDisplayLimit = Number.POSITIVE_INFINITY,
@@ -98,8 +98,13 @@ export function RuleDetailsMatchingInstances(props: Props): JSX.Element | null {
const ruleViewPageLink = createViewLink(namespace.rulesSource, props.rule, location.pathname + location.search);
const statsComponents = getComponentsFromStats(instanceTotals);
+ const resetFilter = () => setAlertState(undefined);
+ const navigateToDetailView = () => history.push(ruleViewPageLink);
+
+ const onShowMoreInstances = enableFiltering ? resetFilter : navigateToDetailView;
+
const footerRow = hiddenInstancesCount ? (
-
+
) : undefined;
return (