From c203a030e8e6123b9abe5d580ea00a16aa81e0ba Mon Sep 17 00:00:00 2001 From: Konrad Lalik Date: Fri, 10 May 2024 15:42:23 +0200 Subject: [PATCH] Alerting: Fix MatcherFilter onChange handling (#87511) * Fix input onChange handler * Remove unused variables --- .../alert-groups/MatcherFilter.test.tsx | 12 ++------- .../components/alert-groups/MatcherFilter.tsx | 27 +++++++++---------- 2 files changed, 15 insertions(+), 24 deletions(-) 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 5138f5a8bfa..cc019e7c86c 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 @@ -1,6 +1,5 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import lodash from 'lodash'; // eslint-disable-line lodash/import-scope import React from 'react'; import * as analytics from '../../Analytics'; @@ -10,18 +9,11 @@ import { MatcherFilter } from './MatcherFilter'; const logInfoSpy = jest.spyOn(analytics, 'logInfo'); describe('Analytics', () => { - 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'); - await userEvent.type(searchInput, 'job='); + await userEvent.type(searchInput, 'job=', { delay: 600 }); // Delay waits for the MatcherFilter debounce expect(logInfoSpy).toHaveBeenCalledWith(analytics.LogMessages.filterByLabel); }); @@ -32,7 +24,7 @@ describe('Analytics', () => { render(); const searchInput = screen.getByTestId('search-query-input'); - await userEvent.type(searchInput, '=bar'); + await userEvent.type(searchInput, '=bar', { delay: 600 }); // Delay waits for the MatcherFilter debounce 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 4f8a2745173..dc87bb2fd58 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, useEffect, useMemo } from 'react'; +import React from 'react'; +import { useDebounce } from 'react-use'; import { GrafanaTheme2 } from '@grafana/data'; import { Field, Icon, Input, Label, Stack, Tooltip, useStyles2 } from '@grafana/ui'; @@ -16,17 +16,16 @@ interface Props { export const MatcherFilter = ({ onFilterChange, defaultQueryString }: Props) => { const styles = useStyles2(getStyles); - const onSearchInputChanged = useMemo( - () => - debounce((e: FormEvent) => { - logInfo(LogMessages.filterByLabel); - const target = e.currentTarget; - onFilterChange(target.value); - }, 600), - [onFilterChange] - ); + const [filterQuery, setFilterQuery] = React.useState(defaultQueryString ?? ''); - useEffect(() => onSearchInputChanged.cancel(), [onSearchInputChanged]); + useDebounce( + () => { + logInfo(LogMessages.filterByLabel); + onFilterChange(filterQuery); + }, + 600, + [filterQuery] + ); const searchIcon = ; const inputInvalid = defaultQueryString ? parseMatchers(defaultQueryString).length === 0 : false; @@ -63,8 +62,8 @@ export const MatcherFilter = ({ onFilterChange, defaultQueryString }: Props) => > setFilterQuery(e.currentTarget.value)} data-testid="search-query-input" prefix={searchIcon} className={styles.inputWidth}