Alerting: Fix MatcherFilter onChange handling (#87511)
* Fix input onChange handler * Remove unused variables
This commit is contained in:
+2
-10
@@ -1,6 +1,5 @@
|
|||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import lodash from 'lodash'; // eslint-disable-line lodash/import-scope
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import * as analytics from '../../Analytics';
|
import * as analytics from '../../Analytics';
|
||||||
@@ -10,18 +9,11 @@ import { MatcherFilter } from './MatcherFilter';
|
|||||||
const logInfoSpy = jest.spyOn(analytics, 'logInfo');
|
const logInfoSpy = jest.spyOn(analytics, 'logInfo');
|
||||||
|
|
||||||
describe('Analytics', () => {
|
describe('Analytics', () => {
|
||||||
beforeEach(() => {
|
|
||||||
lodash.debounce = jest.fn().mockImplementation((fn) => {
|
|
||||||
fn.cancel = () => {};
|
|
||||||
return fn;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Sends log info when filtering alert instances by label', async () => {
|
it('Sends log info when filtering alert instances by label', async () => {
|
||||||
render(<MatcherFilter onFilterChange={jest.fn()} />);
|
render(<MatcherFilter onFilterChange={jest.fn()} />);
|
||||||
|
|
||||||
const searchInput = screen.getByTestId('search-query-input');
|
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);
|
expect(logInfoSpy).toHaveBeenCalledWith(analytics.LogMessages.filterByLabel);
|
||||||
});
|
});
|
||||||
@@ -32,7 +24,7 @@ describe('Analytics', () => {
|
|||||||
render(<MatcherFilter defaultQueryString="foo" onFilterChange={onFilterMock} />);
|
render(<MatcherFilter defaultQueryString="foo" onFilterChange={onFilterMock} />);
|
||||||
|
|
||||||
const searchInput = screen.getByTestId('search-query-input');
|
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');
|
expect(onFilterMock).toHaveBeenLastCalledWith('foo=bar');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { debounce } from 'lodash';
|
import React from 'react';
|
||||||
import React, { FormEvent, useEffect, useMemo } from 'react';
|
import { useDebounce } from 'react-use';
|
||||||
|
|
||||||
import { GrafanaTheme2 } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { Field, Icon, Input, Label, Stack, Tooltip, useStyles2 } from '@grafana/ui';
|
import { Field, Icon, Input, Label, Stack, Tooltip, useStyles2 } from '@grafana/ui';
|
||||||
@@ -16,17 +16,16 @@ interface Props {
|
|||||||
export const MatcherFilter = ({ onFilterChange, defaultQueryString }: Props) => {
|
export const MatcherFilter = ({ onFilterChange, defaultQueryString }: Props) => {
|
||||||
const styles = useStyles2(getStyles);
|
const styles = useStyles2(getStyles);
|
||||||
|
|
||||||
const onSearchInputChanged = useMemo(
|
const [filterQuery, setFilterQuery] = React.useState<string>(defaultQueryString ?? '');
|
||||||
() =>
|
|
||||||
debounce((e: FormEvent<HTMLInputElement>) => {
|
|
||||||
logInfo(LogMessages.filterByLabel);
|
|
||||||
const target = e.currentTarget;
|
|
||||||
onFilterChange(target.value);
|
|
||||||
}, 600),
|
|
||||||
[onFilterChange]
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => onSearchInputChanged.cancel(), [onSearchInputChanged]);
|
useDebounce(
|
||||||
|
() => {
|
||||||
|
logInfo(LogMessages.filterByLabel);
|
||||||
|
onFilterChange(filterQuery);
|
||||||
|
},
|
||||||
|
600,
|
||||||
|
[filterQuery]
|
||||||
|
);
|
||||||
|
|
||||||
const searchIcon = <Icon name={'search'} />;
|
const searchIcon = <Icon name={'search'} />;
|
||||||
const inputInvalid = defaultQueryString ? parseMatchers(defaultQueryString).length === 0 : false;
|
const inputInvalid = defaultQueryString ? parseMatchers(defaultQueryString).length === 0 : false;
|
||||||
@@ -63,8 +62,8 @@ export const MatcherFilter = ({ onFilterChange, defaultQueryString }: Props) =>
|
|||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
defaultValue={defaultQueryString ?? ''}
|
value={filterQuery}
|
||||||
onChange={onSearchInputChanged}
|
onChange={(e) => setFilterQuery(e.currentTarget.value)}
|
||||||
data-testid="search-query-input"
|
data-testid="search-query-input"
|
||||||
prefix={searchIcon}
|
prefix={searchIcon}
|
||||||
className={styles.inputWidth}
|
className={styles.inputWidth}
|
||||||
|
|||||||
Reference in New Issue
Block a user