[Discover] Migrate deprecated filter types and functions usage to @kbn/es-query (#123052)

* Remove deprecated filter usage to use @kbn/es-query 

* Refactor initializing of kbn url tracking to its own function in a separate file for reducing the size of the plugin file
This commit is contained in:
Matthias Wilhelm 2022-02-24 12:08:48 +01:00 committed by GitHub
parent 6b5fb2863a
commit 6341cda194
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 164 additions and 87 deletions

View file

@ -12,7 +12,6 @@ import classNames from 'classnames';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiText, EuiPageContent, EuiPage, EuiSpacer } from '@elastic/eui';
import { cloneDeep } from 'lodash';
import { esFilters } from '../../../../data/public';
import { DOC_TABLE_LEGACY, SEARCH_FIELDS_FROM_SOURCE } from '../../../common';
import { ContextErrorMessage } from './components/context_error_message';
import { DataView, DataViewField } from '../../../../data/common';
@ -26,6 +25,7 @@ import { ContextAppContent } from './context_app_content';
import { SurrDocType } from './services/context';
import { DocViewFilterFn } from '../../services/doc_views/doc_views_types';
import { useDiscoverServices } from '../../utils/use_discover_services';
import { generateFilters } from '../../../../data/public';
const ContextAppContentMemoized = memo(ContextAppContent);
@ -111,13 +111,7 @@ export const ContextApp = ({ indexPattern, anchorId }: ContextAppProps) => {
const addFilter = useCallback(
async (field: DataViewField | string, values: unknown, operation: string) => {
const newFilters = esFilters.generateFilters(
filterManager,
field,
values,
operation,
indexPattern.id!
);
const newFilters = generateFilters(filterManager, field, values, operation, indexPattern.id!);
filterManager.addFilters(newFilters);
if (indexPatterns) {
const fieldName = typeof field === 'string' ? field : field.name;

View file

@ -5,7 +5,8 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { Filter, DataView, ISearchSource } from 'src/plugins/data/common';
import type { Filter } from '@kbn/es-query';
import { DataView, ISearchSource } from 'src/plugins/data/common';
import { DataPublicPluginStart } from 'src/plugins/data/public';
import { reverseSortDir, SortDirection } from '../utils/sorting';
import { convertIsoToMillis, extractNanos } from '../utils/date_conversion';

View file

@ -9,6 +9,7 @@
import { isEqual } from 'lodash';
import { History } from 'history';
import { NotificationsStart, IUiSettingsClient } from 'kibana/public';
import { Filter, compareFilters, COMPARE_ALL_OPTIONS } from '@kbn/es-query';
import {
createStateContainer,
createKbnUrlStateStorage,
@ -16,7 +17,8 @@ import {
withNotifyOnErrors,
ReduxLikeStateContainer,
} from '../../../../../kibana_utils/public';
import { esFilters, FilterManager, Filter } from '../../../../../data/public';
import { FilterManager } from '../../../../../data/public';
import { handleSourceColumnState } from '../../../utils/state_helpers';
export interface AppState {
@ -222,7 +224,7 @@ export function isEqualFilters(filtersA: Filter[], filtersB: Filter[]) {
} else if (!filtersA || !filtersB) {
return false;
}
return esFilters.compareFilters(filtersA, filtersB, esFilters.COMPARE_ALL_OPTIONS);
return compareFilters(filtersA, filtersB, COMPARE_ALL_OPTIONS);
}
/**
@ -239,7 +241,7 @@ function isEqualState(stateA: AppState | GlobalState, stateB: AppState | GlobalS
const { filters: stateBFilters = [], ...stateBPartial } = stateB;
return (
isEqual(stateAPartial, stateBPartial) &&
esFilters.compareFilters(stateAFilters, stateBFilters, esFilters.COMPARE_ALL_OPTIONS)
compareFilters(stateAFilters, stateBFilters, COMPARE_ALL_OPTIONS)
);
}

View file

@ -24,7 +24,7 @@ import classNames from 'classnames';
import { useDiscoverServices } from '../../../../utils/use_discover_services';
import { DiscoverNoResults } from '../no_results';
import { LoadingSpinner } from '../loading_spinner/loading_spinner';
import { esFilters } from '../../../../../../data/public';
import { generateFilters } from '../../../../../../data/public';
import { DataViewField } from '../../../../../../data/common';
import { DiscoverSidebarResponsive } from '../sidebar';
import { DiscoverLayoutProps } from './types';
@ -172,7 +172,7 @@ export function DiscoverLayout({
(field: DataViewField | string, values: string, operation: '+' | '-') => {
const fieldName = typeof field === 'string' ? field : field.name;
popularizeField(indexPattern, fieldName, indexPatterns, capabilities);
const newFilters = esFilters.generateFilters(
const newFilters = generateFilters(
filterManager,
field,
values,

View file

@ -10,6 +10,7 @@ import { isEqual, cloneDeep } from 'lodash';
import { i18n } from '@kbn/i18n';
import { History } from 'history';
import { NotificationsStart, IUiSettingsClient } from 'kibana/public';
import { Filter, FilterStateStore, compareFilters, COMPARE_ALL_OPTIONS } from '@kbn/es-query';
import {
createKbnUrlStateStorage,
createStateContainer,
@ -22,8 +23,6 @@ import {
import {
connectToQueryState,
DataPublicPluginStart,
esFilters,
Filter,
FilterManager,
Query,
SearchSessionInfoProvider,
@ -277,7 +276,7 @@ export function getState({
data.query,
appStateContainer,
{
filters: esFilters.FilterStateStore.APP_STATE,
filters: FilterStateStore.APP_STATE,
query: true,
}
);
@ -322,7 +321,7 @@ export function isEqualFilters(filtersA: Filter[], filtersB: Filter[]) {
} else if (!filtersA || !filtersB) {
return false;
}
return esFilters.compareFilters(filtersA, filtersB, esFilters.COMPARE_ALL_OPTIONS);
return compareFilters(filtersA, filtersB, COMPARE_ALL_OPTIONS);
}
/**

View file

@ -18,7 +18,12 @@ import { ISearchEmbeddable, SearchInput, SearchOutput } from './types';
import { SavedSearch } from '../services/saved_searches';
import { Adapters, RequestAdapter } from '../../../inspector/common';
import { SEARCH_EMBEDDABLE_TYPE } from './constants';
import { APPLY_FILTER_TRIGGER, esFilters, FilterManager } from '../../../data/public';
import {
APPLY_FILTER_TRIGGER,
esFilters,
FilterManager,
generateFilters,
} from '../../../data/public';
import { DiscoverServices } from '../build_services';
import {
Filter,
@ -27,6 +32,7 @@ import {
ISearchSource,
Query,
TimeRange,
FilterStateStore,
} from '../../../data/common';
import { SavedSearchEmbeddableComponent } from './saved_search_embeddable_component';
import { UiActionsStart } from '../../../ui_actions/public';
@ -281,7 +287,7 @@ export class SavedSearchEmbeddable
},
sampleSize: 500,
onFilter: async (field, value, operator) => {
let filters = esFilters.generateFilters(
let filters = generateFilters(
this.filterManager,
// @ts-expect-error
field,
@ -291,7 +297,7 @@ export class SavedSearchEmbeddable
);
filters = filters.map((filter) => ({
...filter,
$state: { store: esFilters.FilterStateStore.APP_STATE },
$state: { store: FilterStateStore.APP_STATE },
}));
await this.executeTriggerActions(APPLY_FILTER_TRIGGER, {

View file

@ -12,7 +12,8 @@ import {
EmbeddableOutput,
IEmbeddable,
} from 'src/plugins/embeddable/public';
import { Filter, DataView, TimeRange, Query } from '../../../data/common';
import type { Filter } from '@kbn/es-query';
import { DataView, TimeRange, Query } from '../../../data/common';
import { SavedSearch } from '../services/saved_searches';
import { SortOrder } from '../components/doc_table/components/table_header/helpers';

View file

@ -7,9 +7,9 @@
*/
import type { SerializableRecord } from '@kbn/utility-types';
import type { TimeRange, Filter, Query, QueryState, RefreshInterval } from '../../data/public';
import type { Filter } from '@kbn/es-query';
import type { TimeRange, Query, QueryState, RefreshInterval } from '../../data/public';
import type { LocatorDefinition, LocatorPublic } from '../../share/public';
import { esFilters } from '../../data/public';
import { setStateToKbnUrl } from '../../kibana_utils/public';
import type { VIEW_MODE } from './components/view_mode_toggle';
@ -127,10 +127,10 @@ export class DiscoverAppLocatorDefinition implements LocatorDefinition<DiscoverA
hideAggregatedPreview?: boolean;
} = {};
const queryState: QueryState = {};
const { isFilterPinned } = await import('@kbn/es-query');
if (query) appState.query = query;
if (filters && filters.length)
appState.filters = filters?.filter((f) => !esFilters.isFilterPinned(f));
if (filters && filters.length) appState.filters = filters?.filter((f) => !isFilterPinned(f));
if (indexPatternId) appState.index = indexPatternId;
if (columns) appState.columns = columns;
if (savedQuery) appState.savedQuery = savedQuery;
@ -138,8 +138,7 @@ export class DiscoverAppLocatorDefinition implements LocatorDefinition<DiscoverA
if (interval) appState.interval = interval;
if (timeRange) queryState.time = timeRange;
if (filters && filters.length)
queryState.filters = filters?.filter((f) => esFilters.isFilterPinned(f));
if (filters && filters.length) queryState.filters = filters?.filter((f) => isFilterPinned(f));
if (refreshInterval) queryState.refreshInterval = refreshInterval;
if (viewMode) appState.viewMode = viewMode;
if (hideAggregatedPreview) appState.hideAggregatedPreview = hideAggregatedPreview;

View file

@ -9,7 +9,6 @@
import { i18n } from '@kbn/i18n';
import React from 'react';
import { BehaviorSubject } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import {
AppMountParameters,
AppUpdater,
@ -18,8 +17,8 @@ import {
Plugin,
PluginInitializerContext,
} from 'kibana/public';
import { UiActionsStart, UiActionsSetup } from 'src/plugins/ui_actions/public';
import { EmbeddableStart, EmbeddableSetup } from 'src/plugins/embeddable/public';
import { UiActionsSetup, UiActionsStart } from 'src/plugins/ui_actions/public';
import { EmbeddableSetup, EmbeddableStart } from 'src/plugins/embeddable/public';
import { ChartsPluginStart } from 'src/plugins/charts/public';
import { NavigationPublicPluginStart as NavigationStart } from 'src/plugins/navigation/public';
import { SharePluginStart, SharePluginSetup } from 'src/plugins/share/public';
@ -27,27 +26,24 @@ import { UrlForwardingSetup, UrlForwardingStart } from 'src/plugins/url_forwardi
import { HomePublicPluginSetup } from 'src/plugins/home/public';
import { Start as InspectorPublicPluginStart } from 'src/plugins/inspector/public';
import { EuiLoadingContent } from '@elastic/eui';
import { DataPublicPluginStart, DataPublicPluginSetup, esFilters } from '../../data/public';
import { DataPublicPluginSetup, DataPublicPluginStart } from '../../data/public';
import { SavedObjectsStart } from '../../saved_objects/public';
import { createKbnUrlTracker } from '../../kibana_utils/public';
import { DEFAULT_APP_CATEGORIES } from '../../../core/public';
import { DocViewInput, DocViewInputFn } from './services/doc_views/doc_views_types';
import { DocViewsRegistry } from './services/doc_views/doc_views_registry';
import {
setDocViewsRegistry,
setUrlTracker,
setHeaderActionMenuMounter,
setUiActions,
setScopedHistory,
getScopedHistory,
setUiActions,
setUrlTracker,
syncHistoryLocations,
} from './kibana_services';
import { registerFeature } from './register_feature';
import { buildServices } from './build_services';
import { DiscoverAppLocatorDefinition, DiscoverAppLocator } from './locator';
import { DiscoverAppLocator, DiscoverAppLocatorDefinition } from './locator';
import { SearchEmbeddableFactory } from './embeddable';
import { UsageCollectionSetup } from '../../usage_collection/public';
import { replaceUrlHashQuery } from '../../kibana_utils/public/';
import { IndexPatternFieldEditorStart } from '../../../plugins/data_view_field_editor/public';
import { DeferredSpinner } from './components';
import { ViewSavedSearchAction } from './embeddable/view_saved_search_action';
@ -57,7 +53,7 @@ import { injectTruncateStyles } from './utils/truncate_styles';
import { DOC_TABLE_LEGACY, TRUNCATE_MAX_HEIGHT } from '../common';
import { DataViewEditorStart } from '../../../plugins/data_view_editor/public';
import { useDiscoverServices } from './utils/use_discover_services';
import { SEARCH_SESSION_ID_QUERY_PARAM } from './constants';
import { initializeKbnUrlTracking } from './utils/initialize_kbn_url_tracking';
const DocViewerLegacyTable = React.lazy(
() => import('./services/doc_views/components/doc_viewer_table/legacy')
@ -251,50 +247,8 @@ export class DiscoverPlugin
),
});
const {
appMounted,
appUnMounted,
stop: stopUrlTracker,
setActiveUrl: setTrackedUrl,
restorePreviousUrl,
} = createKbnUrlTracker({
// we pass getter here instead of plain `history`,
// so history is lazily created (when app is mounted)
// this prevents redundant `#` when not in discover app
getHistory: getScopedHistory,
baseUrl,
defaultSubUrl: '#/',
storageKey: `lastUrl:${core.http.basePath.get()}:discover`,
navLinkUpdater$: this.appStateUpdater,
toastNotifications: core.notifications.toasts,
stateParams: [
{
kbnUrlKey: '_g',
stateUpdate$: plugins.data.query.state$.pipe(
filter(
({ changes }) => !!(changes.globalFilters || changes.time || changes.refreshInterval)
),
map(({ state }) => ({
...state,
filters: state.filters?.filter(esFilters.isFilterPinned),
}))
),
},
],
onBeforeNavLinkSaved: (newNavLink: string) => {
// Do not save SEARCH_SESSION_ID into nav link, because of possible edge cases
// that could lead to session restoration failure.
// see: https://github.com/elastic/kibana/issues/87149
if (newNavLink.includes(SEARCH_SESSION_ID_QUERY_PARAM)) {
newNavLink = replaceUrlHashQuery(newNavLink, (query) => {
delete query[SEARCH_SESSION_ID_QUERY_PARAM];
return query;
});
}
return newNavLink;
},
});
const { setTrackedUrl, restorePreviousUrl, stopUrlTracker, appMounted, appUnMounted } =
initializeKbnUrlTracking(baseUrl, core, this.appStateUpdater, plugins);
setUrlTracker({ setTrackedUrl, restorePreviousUrl });
this.stopUrlTracking = () => {
stopUrlTracker();
@ -309,6 +263,7 @@ export class DiscoverPlugin
defaultPath: '#/',
category: DEFAULT_APP_CATEGORIES.kibana,
mount: async (params: AppMountParameters) => {
const [coreStart, discoverStartPlugins] = await core.getStartServices();
setScopedHistory(params.history);
setHeaderActionMenuMounter(params.setHeaderActionMenu);
syncHistoryLocations();
@ -319,7 +274,6 @@ export class DiscoverPlugin
window.dispatchEvent(new HashChangeEvent('hashchange'));
});
const [coreStart, discoverStartPlugins] = await core.getStartServices();
const services = buildServices(coreStart, discoverStartPlugins, this.initializerContext);
// make sure the index pattern list is up to date

View file

@ -9,7 +9,8 @@
import type { Capabilities } from 'kibana/public';
import type { IUiSettingsClient } from 'kibana/public';
import type { DataPublicPluginStart } from 'src/plugins/data/public';
import type { Filter, ISearchSource, SerializedSearchSourceFields } from 'src/plugins/data/common';
import type { Filter } from '@kbn/es-query';
import type { ISearchSource, SerializedSearchSourceFields } from 'src/plugins/data/common';
import {
DOC_HIDE_TIME_COLUMN_SETTING,
SEARCH_FIELDS_FROM_SOURCE,

View file

@ -0,0 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { AppUpdater } from 'kibana/public';
import { BehaviorSubject, Observable } from 'rxjs';
import { coreMock } from 'src/core/public/mocks';
import { DiscoverSetupPlugins } from '../plugin';
import { initializeKbnUrlTracking } from './initialize_kbn_url_tracking';
describe('initializeKbnUrlTracking', () => {
test('returns functions to start and stop url tracking', async () => {
const pluginsSetup = {
data: {
query: {
state$: new Observable(),
},
},
} as DiscoverSetupPlugins;
const result = initializeKbnUrlTracking(
'',
coreMock.createSetup(),
new BehaviorSubject<AppUpdater>(() => ({})),
pluginsSetup
);
expect(result).toMatchInlineSnapshot(`
Object {
"appMounted": [Function],
"appUnMounted": [Function],
"restorePreviousUrl": [Function],
"setTrackedUrl": [Function],
"stopUrlTracker": [Function],
}
`);
});
});

View file

@ -0,0 +1,80 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { AppUpdater, CoreSetup } from 'kibana/public';
import type { BehaviorSubject } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { createKbnUrlTracker, replaceUrlHashQuery } from '../../../kibana_utils/public';
import { getScopedHistory } from '../kibana_services';
import { SEARCH_SESSION_ID_QUERY_PARAM } from '../constants';
import type { DiscoverSetupPlugins } from '../plugin';
/**
* It creates the kbn url tracker for Discover to listens to history changes and optionally to global state
* changes and updates the nav link url of to point to the last visited page
*/
export function initializeKbnUrlTracking(
baseUrl: string,
core: CoreSetup,
navLinkUpdater$: BehaviorSubject<AppUpdater>,
plugins: DiscoverSetupPlugins
) {
const {
appMounted,
appUnMounted,
stop: stopUrlTracker,
setActiveUrl: setTrackedUrl,
restorePreviousUrl,
} = createKbnUrlTracker({
// we pass getter here instead of plain `history`,
// so history is lazily created (when app is mounted)
// this prevents redundant `#` when not in discover app
getHistory: getScopedHistory,
baseUrl,
defaultSubUrl: '#/',
storageKey: `lastUrl:${core.http.basePath.get()}:discover`,
navLinkUpdater$,
toastNotifications: core.notifications.toasts,
stateParams: [
{
kbnUrlKey: '_g',
stateUpdate$: plugins.data.query.state$.pipe(
filter(
({ changes }) => !!(changes.globalFilters || changes.time || changes.refreshInterval)
),
map(async ({ state }) => {
const { isFilterPinned } = await import('@kbn/es-query');
return {
...state,
filters: state.filters?.filter(isFilterPinned),
};
})
),
},
],
onBeforeNavLinkSaved: (newNavLink: string) => {
// Do not save SEARCH_SESSION_ID into nav link, because of possible edge cases
// that could lead to session restoration failure.
// see: https://github.com/elastic/kibana/issues/87149
if (newNavLink.includes(SEARCH_SESSION_ID_QUERY_PARAM)) {
newNavLink = replaceUrlHashQuery(newNavLink, (query) => {
delete query[SEARCH_SESSION_ID_QUERY_PARAM];
return query;
});
}
return newNavLink;
},
});
return {
appMounted,
appUnMounted,
stopUrlTracker,
setTrackedUrl,
restorePreviousUrl,
};
}

View file

@ -11,7 +11,8 @@ import { useHistory, matchPath } from 'react-router-dom';
import type { Location } from 'history';
import { stringify } from 'query-string';
import rison from 'rison-node';
import { esFilters, FilterManager } from '../../../data/public';
import { disableFilter } from '@kbn/es-query';
import { FilterManager } from '../../../data/public';
import { url } from '../../../kibana_utils/common';
import { useDiscoverServices } from './use_discover_services';
@ -39,7 +40,7 @@ export const getContextHash = (columns: string[], filterManager: FilterManager)
}),
_a: rison.encode({
columns,
filters: (appFilters || []).map(esFilters.disableFilter),
filters: (appFilters || []).map(disableFilter),
}),
}),
{ encode: false, sort: false }