Skip to content

Commit

Permalink
[Security Solution] Fix setting the initial Kibana filters (elastic#7…
Browse files Browse the repository at this point in the history
…5215) (elastic#75751)

* [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>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
patrykkopycinski and elasticmachine authored Aug 24, 2020
1 parent 8c2b0ef commit 0743648
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/plugins/data/public/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {}),
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import {
filterQuerySelector,
fromStrSelector,
isLoadingSelector,
kindSelector,
queriesSelector,
savedQuerySelector,
startSelector,
Expand All @@ -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;
Expand All @@ -57,7 +58,7 @@ const SearchBarContainer = styled.div`
}
`;

const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
export const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
({
end,
filterQuery,
Expand All @@ -74,20 +75,27 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
updateSearch,
dataTestSubj,
}) => {
const { data } = useKibana().services;
const {
timefilter: { timefilter },
filterManager,
} = data.query;

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(),
});
}
data: {
query: {
timefilter: { timefilter },
filterManager,
},
ui: { SearchBar },
},
storage,
} = useKibana().services;

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 }) => {
Expand Down Expand Up @@ -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(
Expand All @@ -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(
Expand Down Expand Up @@ -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(() => {
Expand All @@ -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;
Expand All @@ -234,6 +246,7 @@ const SearchBarComponent = memo<SiemSearchBarProps & PropsFromRedux>(
filterManager.getUpdates$().subscribe({
next: () => {
if (isSubscribed) {
saveAppStateToStorage(filterManager.getAppFilters());
setSearchBarFilter({
id,
filters: filterManager.getFilters(),
Expand All @@ -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}
Expand All @@ -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();
Expand All @@ -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),
Expand Down

0 comments on commit 0743648

Please sign in to comment.