diff --git a/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.test.tsx b/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.test.tsx
index ca59051e704..b5c47e3a8ac 100644
--- a/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.test.tsx
+++ b/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.test.tsx
@@ -12,9 +12,14 @@ import { MatcherFilter } from './MatcherFilter';
jest.mock('@grafana/runtime');
describe('Analytics', () => {
- it('Sends log info when filtering alert instances by label', async () => {
- lodash.debounce = jest.fn().mockImplementation((fn) => fn);
+ beforeEach(() => {
+ lodash.debounce = jest.fn().mockImplementation((fn) => {
+ fn.cancel = () => {};
+ return fn;
+ });
+ });
+ it('Sends log info when filtering alert instances by label', async () => {
render();
const searchInput = screen.getByTestId('search-query-input');
@@ -22,4 +27,15 @@ describe('Analytics', () => {
expect(logInfo).toHaveBeenCalledWith(LogMessages.filterByLabel);
});
+
+ it('should call onChange handler', async () => {
+ const onFilterMock = jest.fn();
+
+ render();
+
+ const searchInput = screen.getByTestId('search-query-input');
+ await userEvent.type(searchInput, '=bar');
+
+ expect(onFilterMock).toHaveBeenLastCalledWith('foo=bar');
+ });
});
diff --git a/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx b/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx
index c4b02127be1..774f143cf9d 100644
--- a/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx
+++ b/public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx
@@ -1,6 +1,6 @@
import { css } from '@emotion/css';
import { debounce } from 'lodash';
-import React, { FormEvent } from 'react';
+import React, { FormEvent, useEffect, useMemo } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
@@ -11,20 +11,28 @@ import { LogMessages } from '../../Analytics';
interface Props {
className?: string;
- queryString?: string;
defaultQueryString?: string;
onFilterChange: (filterString: string) => void;
}
-export const MatcherFilter = ({ className, onFilterChange, defaultQueryString, queryString }: Props) => {
+export const MatcherFilter = ({ className, onFilterChange, defaultQueryString }: Props) => {
const styles = useStyles2(getStyles);
- const handleSearchChange = debounce((e: FormEvent) => {
- logInfo(LogMessages.filterByLabel);
- const target = e.target as HTMLInputElement;
- onFilterChange(target.value);
- }, 600);
+ const onSearchInputChanged = useMemo(
+ () =>
+ debounce((e: FormEvent) => {
+ logInfo(LogMessages.filterByLabel);
+
+ const target = e.target as HTMLInputElement;
+ onFilterChange(target.value);
+ }, 600),
+ [onFilterChange]
+ );
+
+ useEffect(() => onSearchInputChanged.cancel(), [onSearchInputChanged]);
+
const searchIcon = ;
+
return (