[Security Solution] Fix setting the initial Kibana filters (#75215)

* [Security Solution] Fix setting the initial Kibana filters

* add unit test

* keep appState in kibana storage

* fix logic

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Patryk Kopyciński 2020-08-24 15:25:51 +02:00 committed by GitHub
parent 3768aab743
commit 65c724808f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 92 additions and 28 deletions

View file

@ -61,7 +61,7 @@ const createStartContract = (): Start => {
query: queryStartMock,
ui: {
IndexPatternSelect: jest.fn(),
SearchBar: jest.fn(),
SearchBar: jest.fn().mockReturnValue(null),
},
indexPatterns: ({
createField: jest.fn(() => {}),

View file

@ -0,0 +1,44 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import { mount } from 'enzyme';
import { InputsModelId } from '../../store/inputs/constants';
import { SearchBarComponent } from '.';
import { TestProviders } from '../../mock';
jest.mock('../../lib/kibana');
describe('SearchBarComponent', () => {
const props = {
id: 'global' as InputsModelId,
indexPattern: {
fields: [],
title: '',
},
updateSearch: jest.fn(),
setSavedQuery: jest.fn(),
setSearchBarFilter: jest.fn(),
end: '',
start: '',
toStr: '',
fromStr: '',
isLoading: false,
filterQuery: {
query: '',
language: '',
},
queries: [],
savedQuery: undefined,
};
it('calls setSearchBarFilter on mount', () => {
mount(<SearchBarComponent {...props} />, { wrappingComponent: TestProviders });
expect(props.setSearchBarFilter).toHaveBeenCalled();
});
});

View file

@ -33,7 +33,6 @@ import {
filterQuerySelector,
fromStrSelector,
isLoadingSelector,
kindSelector,
queriesSelector,
savedQuerySelector,
startSelector,
@ -44,6 +43,8 @@ import { networkActions } from '../../../network/store';
import { timelineActions } from '../../../timelines/store/timeline';
import { useKibana } from '../../lib/kibana';
const APP_STATE_STORAGE_KEY = 'securitySolution.searchBar.appState';
interface SiemSearchBarProps {
id: InputsModelId;
indexPattern: IIndexPattern;
@ -57,7 +58,7 @@ const SearchBarContainer = styled.div`
}
`;
const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
export const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
({
end,
filterQuery,
@ -74,20 +75,27 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
updateSearch,
dataTestSubj,
}) => {
const { data } = useKibana().services;
const {
timefilter: { timefilter },
filterManager,
} = data.query;
data: {
query: {
timefilter: { timefilter },
filterManager,
},
ui: { SearchBar },
},
storage,
} = useKibana().services;
if (fromStr != null && toStr != null) {
timefilter.setTime({ from: fromStr, to: toStr });
} else if (start != null && end != null) {
timefilter.setTime({
from: new Date(start).toISOString(),
to: new Date(end).toISOString(),
});
}
useEffect(() => {
if (fromStr != null && toStr != null) {
timefilter.setTime({ from: fromStr, to: toStr });
} else if (start != null && end != null) {
timefilter.setTime({
from: new Date(start).toISOString(),
to: new Date(end).toISOString(),
});
}
}, [end, fromStr, start, timefilter, toStr]);
const onQuerySubmit = useCallback(
(payload: { dateRange: TimeRange; query?: Query }) => {
@ -135,8 +143,7 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
window.setTimeout(() => updateSearch(updateSearchBar), 0);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[id, end, filterQuery, fromStr, queries, start, toStr]
[id, toStr, end, fromStr, start, filterManager, filterQuery, queries, updateSearch]
);
const onRefresh = useCallback(
@ -155,16 +162,14 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
queries.forEach((q) => q.refetch && (q.refetch as inputsModel.Refetch)());
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[id, queries, filterManager]
[updateSearch, id, filterManager, queries]
);
const onSaved = useCallback(
(newSavedQuery: SavedQuery) => {
setSavedQuery({ id, savedQuery: newSavedQuery });
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[id]
[id, setSavedQuery]
);
const onSavedQueryUpdated = useCallback(
@ -200,8 +205,7 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
updateSearch(updateSearchBar);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[id, end, fromStr, start, toStr]
[id, toStr, end, fromStr, start, filterManager, updateSearch]
);
const onClearSavedQuery = useCallback(() => {
@ -223,8 +227,16 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
filterManager,
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [id, end, filterManager, fromStr, start, toStr, savedQuery]);
}, [savedQuery, updateSearch, id, toStr, end, fromStr, start, filterManager]);
const saveAppStateToStorage = useCallback(
(filters: Filter[]) => storage.set(APP_STATE_STORAGE_KEY, filters),
[storage]
);
const getAppStateFromStorage = useCallback(() => storage.get(APP_STATE_STORAGE_KEY) ?? [], [
storage,
]);
useEffect(() => {
let isSubscribed = true;
@ -234,6 +246,7 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
filterManager.getUpdates$().subscribe({
next: () => {
if (isSubscribed) {
saveAppStateToStorage(filterManager.getAppFilters());
setSearchBarFilter({
id,
filters: filterManager.getFilters(),
@ -243,16 +256,25 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
})
);
// for the initial state
filterManager.setAppFilters(getAppStateFromStorage());
setSearchBarFilter({
id,
filters: filterManager.getFilters(),
});
return () => {
isSubscribed = false;
subscriptions.unsubscribe();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const indexPatterns = useMemo(() => [indexPattern], [indexPattern]);
return (
<SearchBarContainer data-test-subj={`${id}DatePicker`}>
<data.ui.SearchBar
<SearchBar
appName="siem"
isLoading={isLoading}
indexPatterns={indexPatterns}
@ -279,7 +301,6 @@ const makeMapStateToProps = () => {
const getEndSelector = endSelector();
const getFromStrSelector = fromStrSelector();
const getIsLoadingSelector = isLoadingSelector();
const getKindSelector = kindSelector();
const getQueriesSelector = queriesSelector();
const getStartSelector = startSelector();
const getToStrSelector = toStrSelector();
@ -292,7 +313,6 @@ const makeMapStateToProps = () => {
fromStr: getFromStrSelector(inputsRange),
filterQuery: getFilterQuerySelector(inputsRange),
isLoading: getIsLoadingSelector(inputsRange),
kind: getKindSelector(inputsRange),
queries: getQueriesSelector(inputsRange),
savedQuery: getSavedQuerySelector(inputsRange),
start: getStartSelector(inputsRange),