diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.html b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.html index 2f7437faa8b2c..16e1aa758232e 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.html +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.html @@ -2,12 +2,12 @@ app-name="'context'" show-search-bar="true" show-filter-bar="true" + show-query-bar="false" show-save-query="false" show-date-picker="false" - - filters="contextApp.state.queryParameters.filters" - on-filters-updated="contextApp.actions.updateFilters" + index-patterns="[contextApp.indexPattern]" + use-default-behaviors="true" > diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.js index 5fa0958249d79..6549f13556373 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/context_app.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import { getServices, callAfterBindingsWorkaround, getAngularModule } from '../../kibana_services'; +import { callAfterBindingsWorkaround, getAngularModule } from '../../kibana_services'; import contextAppTemplate from './context_app.html'; import './context/components/action_bar'; import { getFirstSortableField } from './context/api/utils/sorting'; @@ -34,8 +34,6 @@ import { QueryActionsProvider, } from './context/query'; -const { timefilter } = getServices(); - const module = getAngularModule(); module.directive('contextApp', function ContextApp() { @@ -61,10 +59,6 @@ module.directive('contextApp', function ContextApp() { function ContextAppController($scope, config, Private) { const queryParameterActions = getQueryParameterActions(); const queryActions = Private(QueryActionsProvider); - - timefilter.disableAutoRefreshSelector(); - timefilter.disableTimeRangeSelector(); - this.state = createInitialState( parseInt(config.get('context:step'), 10), getFirstSortableField(this.indexPattern, config.get('context:tieBreakerFields')), diff --git a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx index d2f9cb6da716b..71d76f4db49e2 100644 --- a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx @@ -92,10 +92,10 @@ const defaultOnQuerySubmit = ( }; // Respond to user clearing a saved query -const defaultOnClearSavedQuery = (props: StatefulSearchBarProps, setSavedQuery: Function) => { +const defaultOnClearSavedQuery = (props: StatefulSearchBarProps, clearSavedQuery: Function) => { if (!props.useDefaultBehaviors) return props.onClearSavedQuery; return () => { - setSavedQuery(undefined); + clearSavedQuery(); if (props.onSavedQueryIdChange) props.onSavedQueryIdChange(); }; }; @@ -127,13 +127,16 @@ export function createSearchBar({ core, storage, data }: StatefulSearchBarDeps) // handle service state updates. // i.e. filters being added from a visualization directly to filterManager. - const { filters } = useFilterManager({ filterManager: data.query.filterManager }); + const { filters } = useFilterManager({ + filters: props.filters, + filterManager: data.query.filterManager, + }); const { timeRange, refreshInterval } = useTimefilter({ timefilter: data.query.timefilter.timefilter, }); // Fetch and update UI from saved query - const [savedQuery, setSavedQuery] = useSavedQuery({ + const { savedQuery, setSavedQuery, clearSavedQuery } = useSavedQuery({ queryService: data.query, setQuery, savedQueryId: props.savedQueryId, @@ -183,7 +186,7 @@ export function createSearchBar({ core, storage, data }: StatefulSearchBarDeps) onRefreshChange={defaultOnRefreshChange(data.query)} savedQuery={savedQuery} onQuerySubmit={defaultOnQuerySubmit(props, data.query, query, setQuery)} - onClearSavedQuery={defaultOnClearSavedQuery(props, setSavedQuery)} + onClearSavedQuery={defaultOnClearSavedQuery(props, clearSavedQuery)} onSavedQueryUpdated={defaultOnSavedQueryUpdated(props, setSavedQuery)} onSaved={defaultOnSavedQueryUpdated(props, setSavedQuery)} {...overrideDefaultBehaviors(props)} diff --git a/src/plugins/data/public/ui/search_bar/lib/clear_saved_query.test.ts b/src/plugins/data/public/ui/search_bar/lib/clear_saved_query.test.ts index b0f0c26a83dce..ccfe5464b9598 100644 --- a/src/plugins/data/public/ui/search_bar/lib/clear_saved_query.test.ts +++ b/src/plugins/data/public/ui/search_bar/lib/clear_saved_query.test.ts @@ -20,13 +20,12 @@ import { clearStateFromSavedQuery } from './clear_saved_query'; import { dataPluginMock } from '../../../mocks'; -import { coreMock } from '../../../../../../core/public/mocks'; import { DataPublicPluginStart } from '../../../types'; import { Query } from '../../..'; describe('clearStateFromSavedQuery', () => { + const DEFAULT_LANGUAGE = 'banana'; let dataMock: jest.Mocked; - const core = coreMock.createStart(); beforeEach(() => { dataMock = dataPluginMock.createStartContract(); @@ -35,21 +34,17 @@ describe('clearStateFromSavedQuery', () => { it('should clear filters and query', async () => { const setQueryState = jest.fn(); dataMock.query.filterManager.removeAll = jest.fn(); - clearStateFromSavedQuery(dataMock.query, setQueryState, core.uiSettings); + clearStateFromSavedQuery(dataMock.query, setQueryState, DEFAULT_LANGUAGE); expect(setQueryState).toHaveBeenCalled(); expect(dataMock.query.filterManager.removeAll).toHaveBeenCalled(); }); it('should use search:queryLanguage', async () => { - const LANGUAGE = 'banana'; const setQueryState = jest.fn(); dataMock.query.filterManager.removeAll = jest.fn(); - core.uiSettings.get.mockImplementation((key: string) => { - return key === 'search:queryLanguage' ? LANGUAGE : undefined; - }); - clearStateFromSavedQuery(dataMock.query, setQueryState, core.uiSettings); + clearStateFromSavedQuery(dataMock.query, setQueryState, DEFAULT_LANGUAGE); expect(setQueryState).toHaveBeenCalled(); - expect((setQueryState.mock.calls[0][0] as Query).language).toBe(LANGUAGE); + expect((setQueryState.mock.calls[0][0] as Query).language).toBe(DEFAULT_LANGUAGE); expect(dataMock.query.filterManager.removeAll).toHaveBeenCalled(); }); }); diff --git a/src/plugins/data/public/ui/search_bar/lib/clear_saved_query.ts b/src/plugins/data/public/ui/search_bar/lib/clear_saved_query.ts index a1443b753cd93..b2c777261c257 100644 --- a/src/plugins/data/public/ui/search_bar/lib/clear_saved_query.ts +++ b/src/plugins/data/public/ui/search_bar/lib/clear_saved_query.ts @@ -16,18 +16,16 @@ * specific language governing permissions and limitations * under the License. */ - -import { CoreStart } from 'kibana/public'; import { QueryStart } from '../../../query'; export const clearStateFromSavedQuery = ( queryService: QueryStart, setQueryStringState: Function, - uiSettings: CoreStart['uiSettings'] + defaultLanguage: string ) => { queryService.filterManager.removeAll(); setQueryStringState({ query: '', - language: uiSettings.get('search:queryLanguage'), + language: defaultLanguage, }); }; diff --git a/src/plugins/data/public/ui/search_bar/lib/populate_state_from_saved_query.test.ts b/src/plugins/data/public/ui/search_bar/lib/populate_state_from_saved_query.test.ts index e12bc734692c9..3242b37becd95 100644 --- a/src/plugins/data/public/ui/search_bar/lib/populate_state_from_saved_query.test.ts +++ b/src/plugins/data/public/ui/search_bar/lib/populate_state_from_saved_query.test.ts @@ -21,7 +21,7 @@ import { populateStateFromSavedQuery } from './populate_state_from_saved_query'; import { dataPluginMock } from '../../../mocks'; import { DataPublicPluginStart } from '../../../types'; -import { SavedQuery, Query, esFilters } from '../../..'; +import { SavedQuery, esFilters } from '../../..'; import { getFilter } from '../../../query/filter_manager/test_helpers/get_stub_filter'; describe('populateStateFromSavedQuery', () => { @@ -50,7 +50,7 @@ describe('populateStateFromSavedQuery', () => { const savedQuery: SavedQuery = { ...baseSavedQuery, }; - populateStateFromSavedQuery(dataMock.query, savedQuery, setQueryState); + populateStateFromSavedQuery(dataMock.query, setQueryState, savedQuery); expect(setQueryState).toHaveBeenCalled(); }); @@ -61,7 +61,7 @@ describe('populateStateFromSavedQuery', () => { }; const f1 = getFilter(esFilters.FilterStateStore.APP_STATE, false, false, 'age', 34); savedQuery.attributes.filters = [f1]; - populateStateFromSavedQuery(dataMock.query, savedQuery, setQueryState); + populateStateFromSavedQuery(dataMock.query, setQueryState, savedQuery); expect(setQueryState).toHaveBeenCalled(); expect(dataMock.query.filterManager.setFilters).toHaveBeenCalledWith([f1]); }); @@ -81,7 +81,7 @@ describe('populateStateFromSavedQuery', () => { }; const f1 = getFilter(esFilters.FilterStateStore.APP_STATE, false, false, 'age', 34); savedQuery.attributes.filters = [f1]; - populateStateFromSavedQuery(dataMock.query, savedQuery, setQueryState); + populateStateFromSavedQuery(dataMock.query, setQueryState, savedQuery); expect(setQueryState).toHaveBeenCalled(); expect(dataMock.query.filterManager.setFilters).toHaveBeenCalledWith([globalFilter, f1]); }); @@ -102,7 +102,7 @@ describe('populateStateFromSavedQuery', () => { dataMock.query.timefilter.timefilter.setTime = jest.fn(); dataMock.query.timefilter.timefilter.setRefreshInterval = jest.fn(); - populateStateFromSavedQuery(dataMock.query, savedQuery, jest.fn()); + populateStateFromSavedQuery(dataMock.query, jest.fn(), savedQuery); expect(dataMock.query.timefilter.timefilter.setTime).toHaveBeenCalledWith({ from: savedQuery.attributes.timefilter.from, diff --git a/src/plugins/data/public/ui/search_bar/lib/populate_state_from_saved_query.ts b/src/plugins/data/public/ui/search_bar/lib/populate_state_from_saved_query.ts index 7b2a73039e938..fd1517097753e 100644 --- a/src/plugins/data/public/ui/search_bar/lib/populate_state_from_saved_query.ts +++ b/src/plugins/data/public/ui/search_bar/lib/populate_state_from_saved_query.ts @@ -21,8 +21,8 @@ import { QueryStart, SavedQuery } from '../../..'; export const populateStateFromSavedQuery = ( queryService: QueryStart, - savedQuery: SavedQuery, - setQueryStringState: Function + setQueryStringState: Function, + savedQuery: SavedQuery ) => { const { timefilter: { timefilter }, diff --git a/src/plugins/data/public/ui/search_bar/lib/use_filter_manager.ts b/src/plugins/data/public/ui/search_bar/lib/use_filter_manager.ts index e6066b0c741dc..e889583aef609 100644 --- a/src/plugins/data/public/ui/search_bar/lib/use_filter_manager.ts +++ b/src/plugins/data/public/ui/search_bar/lib/use_filter_manager.ts @@ -19,14 +19,16 @@ import { useState, useEffect } from 'react'; import { Subscription } from 'rxjs'; -import { DataPublicPluginStart } from 'src/plugins/data/public'; +import { DataPublicPluginStart, esFilters } from '../../..'; interface UseFilterManagerProps { + filters?: esFilters.Filter[]; filterManager: DataPublicPluginStart['query']['filterManager']; } export const useFilterManager = (props: UseFilterManagerProps) => { - const [filters, setFilters] = useState(props.filterManager.getFilters()); + // Filters should be either what's passed in the initial state or the current state of the filter manager + const [filters, setFilters] = useState(props.filters || props.filterManager.getFilters()); useEffect(() => { const subscriptions = new Subscription(); diff --git a/src/plugins/data/public/ui/search_bar/lib/use_saved_query.ts b/src/plugins/data/public/ui/search_bar/lib/use_saved_query.ts index a2566f709bf5a..fdeeaab1dff06 100644 --- a/src/plugins/data/public/ui/search_bar/lib/use_saved_query.ts +++ b/src/plugins/data/public/ui/search_bar/lib/use_saved_query.ts @@ -17,7 +17,7 @@ * under the License. */ -import { useState, useEffect, SetStateAction, Dispatch } from 'react'; +import { useState, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { CoreStart } from 'kibana/public'; import { SavedQuery } from '../../../query'; @@ -33,55 +33,62 @@ interface UseSavedQueriesProps { savedQueryId?: string; } -type UseSavedQueriesRet = [ - SavedQuery | undefined, - Dispatch> -]; +interface UseSavedQueriesReturn { + savedQuery?: SavedQuery; + setSavedQuery: (savedQuery: SavedQuery) => void; + clearSavedQuery: () => void; +} -export const useSavedQuery = (props: UseSavedQueriesProps): UseSavedQueriesRet => { +export const useSavedQuery = (props: UseSavedQueriesProps): UseSavedQueriesReturn => { // Handle saved queries - const [savedQuery, setSavedQuery] = useState(); + const defaultLanguage = props.uiSettings.get('search:queryLanguage'); + const [savedQuery, setSavedQuery] = useState(); + // Effect is used to convert a saved query id into an object useEffect(() => { - const fetchSavedQuery = async () => { - if (props.savedQueryId) { - try { - // fetch saved query - const newSavedQuery = await props.queryService.savedQueries.getSavedQuery( - props.savedQueryId - ); - // Make sure we set the saved query to the most recent one - if (newSavedQuery && newSavedQuery.id === props.savedQueryId) { - setSavedQuery(newSavedQuery); - } - } catch (error) { - // Clear saved query - setSavedQuery(undefined); - // notify of saving error - props.notifications.toasts.addWarning({ - title: i18n.translate('data.search.unableToGetSavedQueryToastTitle', { - defaultMessage: 'Unable to load saved query {savedQueryId}', - values: { savedQueryId: props.savedQueryId }, - }), - text: `${error.message}`, - }); + const fetchSavedQuery = async (savedQueryId: string) => { + try { + // fetch saved query + const newSavedQuery = await props.queryService.savedQueries.getSavedQuery(savedQueryId); + // Make sure we set the saved query to the most recent one + if (newSavedQuery && newSavedQuery.id === savedQueryId) { + setSavedQuery(newSavedQuery); + populateStateFromSavedQuery(props.queryService, props.setQuery, newSavedQuery); } - } else { + } catch (error) { // Clear saved query setSavedQuery(undefined); + clearStateFromSavedQuery(props.queryService, props.setQuery, defaultLanguage); + // notify of saving error + props.notifications.toasts.addWarning({ + title: i18n.translate('data.search.unableToGetSavedQueryToastTitle', { + defaultMessage: 'Unable to load saved query {savedQueryId}', + values: { savedQueryId }, + }), + text: `${error.message}`, + }); } }; - fetchSavedQuery(); - }, [props.notifications.toasts, props.queryService.savedQueries, props.savedQueryId]); - - useEffect(() => { - if (savedQuery) { - populateStateFromSavedQuery(props.queryService, savedQuery, props.setQuery); - } else { - clearStateFromSavedQuery(props.queryService, props.setQuery, props.uiSettings); - } - }, [savedQuery, props.queryService, props.setQuery, props.uiSettings]); + if (props.savedQueryId) fetchSavedQuery(props.savedQueryId); + }, [ + defaultLanguage, + props.notifications.toasts, + props.queryService, + props.queryService.savedQueries, + props.savedQueryId, + props.setQuery, + ]); - return [savedQuery, setSavedQuery]; + return { + savedQuery, + setSavedQuery: (q: SavedQuery) => { + setSavedQuery(q); + populateStateFromSavedQuery(props.queryService, props.setQuery, q); + }, + clearSavedQuery: () => { + setSavedQuery(undefined); + clearStateFromSavedQuery(props.queryService, props.setQuery, defaultLanguage); + }, + }; }; diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx index b4e2f46b12a84..2f0cdb322912b 100644 --- a/src/plugins/data/public/ui/search_bar/search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx @@ -47,7 +47,6 @@ interface SearchBarInjectedDeps { timeHistory: TimeHistoryContract; // Filter bar onFiltersUpdated?: (filters: esFilters.Filter[]) => void; - filters?: esFilters.Filter[]; // Date picker dateRangeFrom?: string; dateRangeTo?: string; @@ -69,6 +68,7 @@ export interface SearchBarOwnProps { showFilterBar?: boolean; showDatePicker?: boolean; showAutoRefreshOnly?: boolean; + filters?: esFilters.Filter[]; // Query bar - should be in SearchBarInjectedDeps query?: Query; // Show when user has privileges to save