[Unified Search] Move autocomplete logic to unified search plugin (#129977)

* feat: move autocomplete logic from data plugin to unified search

* minor fix after comments

* updated Documentation: data.autocomplete -> unifiedSearch.autocomplete

* changed renameFromRoot order for autocomplete

* removed extra renameFromRoot in config deprecations, updated test

* added configPath for unified search plugin

* Update kibana.json

* updated path to autocomplete

* fix conflict

* fix conflict

* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'

* fix Linting

* fix functional_with_es_ssl test
This commit is contained in:
Nodir Latipov 2022-04-22 11:02:56 +05:00 committed by GitHub
parent fa7323769d
commit 7c01257055
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
163 changed files with 1253 additions and 392 deletions

View file

@ -159,8 +159,8 @@
# =================== Search Autocomplete ===================
# Time in milliseconds to wait for autocomplete suggestions from Elasticsearch.
# This value must be a whole number greater than zero. Defaults to 1000ms
#data.autocomplete.valueSuggestions.timeout: 1000
#unifiedSearch.autocomplete.valueSuggestions.timeout: 1000
# Maximum number of documents loaded by each shard to generate autocomplete suggestions.
# This value must be a whole number greater than zero. Defaults to 100_000
#data.autocomplete.valueSuggestions.terminateAfter: 100000
#unifiedSearch.autocomplete.valueSuggestions.terminateAfter: 100000

View file

@ -289,11 +289,11 @@ is an alternative to `elasticsearch.username` and `elasticsearch.password`.
| `interpreter.enableInVisualize`
| Enables use of interpreter in Visualize. *Default: `true`*
| `data.autocomplete.valueSuggestions.timeout:` {ess-icon}
| `unifiedSearch.autocomplete.valueSuggestions.timeout:` {ess-icon}
| Time in milliseconds to wait for autocomplete suggestions from {es}.
This value must be a whole number greater than zero. *Default: `"1000"`*
| `data.autocomplete.valueSuggestions.terminateAfter:` {ess-icon}
| `unifiedSearch.autocomplete.valueSuggestions.terminateAfter:` {ess-icon}
| Maximum number of documents loaded by each shard to generate autocomplete
suggestions. This value must be a whole number greater than zero.
*Default: `"100000"`*

View file

@ -122,7 +122,7 @@ pageLoadAssetSize:
sessionView: 77750
cloudSecurityPosture: 19109
visTypeGauge: 24113
unifiedSearch: 49195
unifiedSearch: 104869
data: 454087
expressionXY: 26500
eventAnnotation: 19334

View file

@ -21,7 +21,7 @@ import { uniq } from 'lodash';
import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715
// import { AutocompleteStart } from '../../../../../../../src/plugins/data/public';
// import { AutocompleteStart } from '../../../../../../../src/plugins/unified_search/public';
type AutocompleteStart = any;
import * as i18n from '../translations';

View file

@ -13,7 +13,7 @@ import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-
import { DataViewBase, DataViewFieldBase } from '@kbn/es-query';
// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715
// import { AutocompleteStart } from '../../../../../../../src/plugins/data/public';
// import { AutocompleteStart } from '../../../../../../../src/plugins/unified_search/public';
type AutocompleteStart = any;
import * as i18n from '../translations';

View file

@ -15,7 +15,7 @@ import { uniq } from 'lodash';
import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715
// import { AutocompleteStart } from '../../../../../../../src/plugins/data/public';
// import { AutocompleteStart } from '../../../../../../../src/plugins/unified_search/public';
type AutocompleteStart = any;
import * as i18n from '../translations';

View file

@ -12,7 +12,7 @@ import { ListOperatorTypeEnum as OperatorTypeEnum } from '@kbn/securitysolution-
import { DataViewBase, DataViewFieldBase, getDataViewFieldSubtypeNested } from '@kbn/es-query';
// TODO: I have to use any here for now, but once this is available below, we should use the correct types, https://github.com/elastic/kibana/issues/100715
// import { AutocompleteStart } from '../../../../../../../../src/plugins/data/public';
// import { AutocompleteStart } from '../../../../../../../../src/plugins/unified_search/public';
type AutocompleteStart = any;
interface FuncArgs {

View file

@ -40,6 +40,11 @@ kibana_vars=(
csp.report_to
data.autocomplete.valueSuggestions.terminateAfter
data.autocomplete.valueSuggestions.timeout
unifiedSearch.autocomplete.valueSuggestions.terminateAfter
unifiedSearch.autocomplete.valueSuggestions.timeout
unifiedSearch.autocomplete.querySuggestions.enabled
unifiedSearch.autocomplete.valueSuggestions.enabled
unifiedSearch.autocomplete.valueSuggestions.tiers
elasticsearch.customHeaders
elasticsearch.hosts
elasticsearch.logQueries

View file

@ -17,7 +17,8 @@
"expressions",
"embeddable",
"dataViews",
"data"
"data",
"unifiedSearch"
],
"optionalPlugins": []
}

View file

@ -31,7 +31,7 @@ import { decorators } from './decorators';
import { ControlsPanels } from '../control_group/types';
import { ControlGroupContainer } from '../control_group';
import { pluginServices, registry } from '../services/storybook';
import { replaceValueSuggestionMethod } from '../services/storybook/data';
import { replaceValueSuggestionMethod } from '../services/storybook/unified_search';
import { injectStorybookDataView } from '../services/storybook/data_views';
import { populateStorybookControlFactories } from './storybook_control_factories';
import { OptionsListRequest } from '../services/options_list';

View file

@ -24,7 +24,6 @@ export interface ControlsDataService {
) => Observable<{ min?: number; max?: number }>;
getDataView: DataPublicPluginStart['dataViews']['get'];
getDataView$: (id: string) => Observable<DataView>;
autocomplete: DataPublicPluginStart['autocomplete'];
query: DataPublicPluginStart['query'];
searchSource: DataPublicPluginStart['search']['searchSource'];
timefilter: DataPublicPluginStart['query']['timefilter']['timefilter'];

View file

@ -12,6 +12,7 @@ import { ControlsOverlaysService } from './overlays';
import { registry as stubRegistry } from './stub';
import { ControlsPluginStart } from '../types';
import { ControlsDataService } from './data';
import { ControlsUnifiedSearchService } from './unified_search';
import { ControlsService } from './controls';
import { ControlsHTTPService } from './http';
import { ControlsOptionsListService } from './options_list';
@ -22,6 +23,7 @@ export interface ControlsServices {
dataViews: ControlsDataViewsService;
overlays: ControlsOverlaysService;
data: ControlsDataService;
unifiedSearch: ControlsUnifiedSearchService;
http: ControlsHTTPService;
settings: ControlsSettingsService;

View file

@ -43,7 +43,7 @@ const minMaxAgg = (field?: DataViewField) => {
export const dataServiceFactory: DataServiceFactory = ({ startPlugins }) => {
const {
data: { query: queryPlugin, search, autocomplete },
data: { query: queryPlugin, search },
} = startPlugins;
const { data } = startPlugins;
@ -95,7 +95,6 @@ export const dataServiceFactory: DataServiceFactory = ({ startPlugins }) => {
from(fetchFieldRange(dataView, fieldName, input)),
getDataView: data.dataViews.get,
getDataView$: (id: string) => from(data.dataViews.get(id)),
autocomplete,
query: queryPlugin,
searchSource: search.searchSource,
timefilter: queryPlugin.timefilter.timefilter,

View file

@ -22,6 +22,7 @@ import { dataServiceFactory } from './data';
import { httpServiceFactory } from './http';
import { optionsListServiceFactory } from './options_list';
import { settingsServiceFactory } from './settings';
import { unifiedSearchServiceFactory } from './unified_search';
export const providers: PluginServiceProviders<
ControlsServices,
@ -29,6 +30,7 @@ export const providers: PluginServiceProviders<
> = {
http: new PluginServiceProvider(httpServiceFactory),
data: new PluginServiceProvider(dataServiceFactory),
unifiedSearch: new PluginServiceProvider(unifiedSearchServiceFactory),
overlays: new PluginServiceProvider(overlaysServiceFactory),
dataViews: new PluginServiceProvider(dataViewsServiceFactory),
settings: new PluginServiceProvider(settingsServiceFactory),

View file

@ -0,0 +1,26 @@
/*
* 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 { KibanaPluginServiceFactory } from '@kbn/presentation-util-plugin/public';
import { ControlsUnifiedSearchService } from '../unified_search';
import { ControlsPluginStartDeps } from '../../types';
export type UnifiedSearchServiceFactory = KibanaPluginServiceFactory<
ControlsUnifiedSearchService,
ControlsPluginStartDeps
>;
export const unifiedSearchServiceFactory: UnifiedSearchServiceFactory = ({ startPlugins }) => {
const {
unifiedSearch: { autocomplete },
} = startPlugins;
return {
autocomplete,
};
};

View file

@ -9,20 +9,11 @@
import { of, Observable } from 'rxjs';
import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public';
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { DataViewField, DataView } from '@kbn/data-views-plugin/common';
import { DataView } from '@kbn/data-views-plugin/common';
import { ControlsDataService } from '../data';
let valueSuggestionMethod = ({ field, query }: { field: DataViewField; query: string }) =>
Promise.resolve(['storybook', 'default', 'values']);
export const replaceValueSuggestionMethod = (
newMethod: ({ field, query }: { field: DataViewField; query: string }) => Promise<string[]>
) => (valueSuggestionMethod = newMethod);
export type DataServiceFactory = PluginServiceFactory<ControlsDataService>;
export const dataServiceFactory: DataServiceFactory = () => ({
autocomplete: {
getValueSuggestions: valueSuggestionMethod,
} as unknown as DataPublicPluginStart['autocomplete'],
query: {} as unknown as DataPublicPluginStart['query'],
searchSource: {
create: () => ({

View file

@ -14,6 +14,7 @@ import {
} from '@kbn/presentation-util-plugin/public';
import { ControlsServices } from '..';
import { dataServiceFactory } from './data';
import { unifiedSearchServiceFactory } from './unified_search';
import { overlaysServiceFactory } from './overlays';
import { dataViewsServiceFactory } from './data_views';
import { httpServiceFactory } from '../stub/http';
@ -28,6 +29,7 @@ export const providers: PluginServiceProviders<ControlsServices> = {
dataViews: new PluginServiceProvider(dataViewsServiceFactory),
http: new PluginServiceProvider(httpServiceFactory),
data: new PluginServiceProvider(dataServiceFactory),
unifiedSearch: new PluginServiceProvider(unifiedSearchServiceFactory),
overlays: new PluginServiceProvider(overlaysServiceFactory),
settings: new PluginServiceProvider(settingsServiceFactory),

View file

@ -0,0 +1,25 @@
/*
* 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 { PluginServiceFactory } from '@kbn/presentation-util-plugin/public';
import { DataViewField } from '@kbn/data-views-plugin/common';
import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import { ControlsUnifiedSearchService } from '../unified_search';
let valueSuggestionMethod = ({ field, query }: { field: DataViewField; query: string }) =>
Promise.resolve(['storybook', 'default', 'values']);
export const replaceValueSuggestionMethod = (
newMethod: ({ field, query }: { field: DataViewField; query: string }) => Promise<string[]>
) => (valueSuggestionMethod = newMethod);
export type UnifiedSearchServiceFactory = PluginServiceFactory<ControlsUnifiedSearchService>;
export const unifiedSearchServiceFactory: UnifiedSearchServiceFactory = () => ({
autocomplete: {
getValueSuggestions: valueSuggestionMethod,
} as unknown as UnifiedSearchPublicPluginStart['autocomplete'],
});

View file

@ -20,6 +20,7 @@ import { dataServiceFactory } from '../storybook/data';
import { dataViewsServiceFactory } from '../storybook/data_views';
import { optionsListServiceFactory } from '../storybook/options_list';
import { settingsServiceFactory } from '../storybook/settings';
import { unifiedSearchServiceFactory } from '../storybook/unified_search';
export const providers: PluginServiceProviders<ControlsServices> = {
http: new PluginServiceProvider(httpServiceFactory),
@ -27,7 +28,7 @@ export const providers: PluginServiceProviders<ControlsServices> = {
overlays: new PluginServiceProvider(overlaysServiceFactory),
dataViews: new PluginServiceProvider(dataViewsServiceFactory),
settings: new PluginServiceProvider(settingsServiceFactory),
unifiedSearch: new PluginServiceProvider(unifiedSearchServiceFactory),
controls: new PluginServiceProvider(controlsServiceFactory),
optionsList: new PluginServiceProvider(optionsListServiceFactory),
};

View file

@ -0,0 +1,13 @@
/*
* 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 { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
export interface ControlsUnifiedSearchService {
autocomplete: UnifiedSearchPublicPluginStart['autocomplete'];
}

View file

@ -17,6 +17,7 @@ import {
} from '@kbn/embeddable-plugin/public';
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { DataView, DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import { ControlInput } from '../common/types';
import { ControlsService } from './services/controls';
@ -70,6 +71,7 @@ export interface ControlsPluginSetupDeps {
}
export interface ControlsPluginStartDeps {
data: DataPublicPluginStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
embeddable: EmbeddableStart;
dataViews: DataViewsPublicPluginStart;
}

View file

@ -14,8 +14,8 @@ import { Observable } from 'rxjs';
import { CoreSetup, ElasticsearchClient } from '@kbn/core/server';
import { getKbnServerError, reportServerError } from '@kbn/kibana-utils-plugin/server';
import { PluginSetup as DataPluginSetup } from '@kbn/data-plugin/server';
import { FieldSpec, getFieldSubtypeNested } from '@kbn/data-views-plugin/common';
import { PluginSetup as UnifiedSearchPluginSetup } from '@kbn/unified-search-plugin/server';
import {
OptionsListRequestBody,
OptionsListResponse,
@ -23,7 +23,7 @@ import {
export const setupOptionsListSuggestionsRoute = (
{ http }: CoreSetup,
getAutocompleteSettings: DataPluginSetup['autocomplete']['getAutocompleteSettings']
getAutocompleteSettings: UnifiedSearchPluginSetup['autocomplete']['getAutocompleteSettings']
) => {
const router = http.createRouter();

View file

@ -10,6 +10,7 @@ import { CoreSetup, Plugin } from '@kbn/core/server';
import { EmbeddableSetup } from '@kbn/embeddable-plugin/server';
import { PluginSetup as DataSetup } from '@kbn/data-plugin/server';
import { PluginSetup as UnifiedSearchSetup } from '@kbn/unified-search-plugin/server';
import { setupOptionsListSuggestionsRoute } from './control_types/options_list/options_list_suggestions_route';
import { controlGroupContainerPersistableStateServiceFactory } from './control_group/control_group_container_factory';
import { optionsListPersistableStateServiceFactory } from './control_types/options_list/options_list_embeddable_factory';
@ -18,10 +19,11 @@ import { timeSliderPersistableStateServiceFactory } from './control_types/time_s
interface SetupDeps {
embeddable: EmbeddableSetup;
data: DataSetup;
unifiedSearch: UnifiedSearchSetup;
}
export class ControlsPlugin implements Plugin<object, object, SetupDeps> {
public setup(core: CoreSetup, { embeddable, data }: SetupDeps) {
public setup(core: CoreSetup, { embeddable, unifiedSearch }: SetupDeps) {
embeddable.registerEmbeddableFactory(optionsListPersistableStateServiceFactory());
embeddable.registerEmbeddableFactory(timeSliderPersistableStateServiceFactory());
@ -29,7 +31,7 @@ export class ControlsPlugin implements Plugin<object, object, SetupDeps> {
controlGroupContainerPersistableStateServiceFactory(embeddable)
);
setupOptionsListSuggestionsRoute(core, data.autocomplete.getAutocompleteSettings);
setupOptionsListSuggestionsRoute(core, unifiedSearch.autocomplete.getAutocompleteSettings);
return {};
}

View file

@ -23,6 +23,7 @@
{ "path": "../embeddable/tsconfig.json" },
{ "path": "../presentation_util/tsconfig.json" },
{ "path": "../kibana_react/tsconfig.json" },
{ "path": "../data/tsconfig.json" }
{ "path": "../data/tsconfig.json" },
{ "path": "../unified_search/tsconfig.json" }
]
}

View file

@ -9,28 +9,6 @@
import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
autocomplete: schema.object({
querySuggestions: schema.object({
enabled: schema.boolean({ defaultValue: true }),
}),
valueSuggestions: schema.object({
enabled: schema.boolean({ defaultValue: true }),
tiers: schema.arrayOf(
schema.oneOf([
schema.literal('data_content'),
schema.literal('data_hot'),
schema.literal('data_warm'),
schema.literal('data_cold'),
schema.literal('data_frozen'),
]),
{
defaultValue: ['data_hot', 'data_warm', 'data_content', 'data_cold'],
}
),
terminateAfter: schema.duration({ defaultValue: 100000 }),
timeout: schema.duration({ defaultValue: 1000 }),
}),
}),
search: schema.object({
aggs: schema.object({
shardDelay: schema.object({

View file

@ -4,7 +4,7 @@
"server": true,
"ui": true,
"requiredPlugins": ["bfetch", "expressions", "uiActions", "share", "inspector", "fieldFormats", "dataViews"],
"serviceFolders": ["search", "query", "autocomplete", "ui"],
"serviceFolders": ["search", "query", "ui"],
"optionalPlugins": ["usageCollection", "taskManager", "security"],
"extraPublicDirs": ["common"],
"requiredBundles": ["kibanaUtils", "kibanaReact", "inspector"],

View file

@ -95,20 +95,6 @@ export {
DuplicateDataViewError,
} from '../common';
/*
* Autocomplete query suggestions:
*/
export type {
QuerySuggestion,
QuerySuggestionGetFn,
QuerySuggestionGetFnArgs,
QuerySuggestionBasic,
QuerySuggestionField,
AutocompleteStart,
} from './autocomplete';
export { QuerySuggestionTypes } from './autocomplete';
/*
* Search:
*/
@ -273,8 +259,12 @@ export {
TimeHistory,
getQueryLog,
mapAndFlattenFilters,
QueryService,
} from './query';
export { NowProvider } from './now_provider';
export type { NowProviderInternalContract } from './now_provider';
export type {
QueryState,
SavedQuery,
@ -288,6 +278,7 @@ export type {
PersistedLog,
QueryStringContract,
QuerySetup,
TimefilterSetup,
} from './query';
export type { AggsStart } from './search/aggs';

View file

@ -11,27 +11,14 @@ import { createDatatableUtilitiesMock } from '../common/mocks';
import { DataPlugin, DataViewsContract } from '.';
import { searchServiceMock } from './search/mocks';
import { queryServiceMock } from './query/mocks';
import { AutocompleteStart, AutocompleteSetup } from './autocomplete';
import { createNowProviderMock } from './now_provider/mocks';
export type Setup = jest.Mocked<ReturnType<DataPlugin['setup']>>;
export type Start = jest.Mocked<ReturnType<DataPlugin['start']>>;
const autocompleteSetupMock: jest.Mocked<AutocompleteSetup> = {
getQuerySuggestions: jest.fn(),
getAutocompleteSettings: jest.fn(),
};
const autocompleteStartMock: jest.Mocked<AutocompleteStart> = {
getValueSuggestions: jest.fn(),
getQuerySuggestions: jest.fn(),
hasQuerySuggestions: jest.fn(),
};
const createSetupContract = (): Setup => {
const querySetupMock = queryServiceMock.createSetupContract();
return {
autocomplete: autocompleteSetupMock,
search: searchServiceMock.createSetupContract(),
query: querySetupMock,
};
@ -58,7 +45,6 @@ const createStartContract = (): Start => {
createFiltersFromValueClickAction: jest.fn().mockResolvedValue(['yes']),
createFiltersFromRangeSelectAction: jest.fn(),
},
autocomplete: autocompleteStartMock,
datatableUtilities: createDatatableUtilitiesMock(),
search: searchServiceMock.createStartContract(),
fieldFormats: fieldFormatsServiceMock.createStartContract(),

View file

@ -21,7 +21,6 @@ import type {
DataSetupDependencies,
DataStartDependencies,
} from './types';
import { AutocompleteService } from './autocomplete';
import { SearchService } from './search/search_service';
import { QueryService } from './query';
import {
@ -52,7 +51,6 @@ export class DataPublicPlugin
DataStartDependencies
>
{
private readonly autocomplete: AutocompleteService;
private readonly searchService: SearchService;
private readonly queryService: QueryService;
private readonly storage: IStorageWrapper;
@ -62,7 +60,6 @@ export class DataPublicPlugin
this.searchService = new SearchService(initializerContext);
this.queryService = new QueryService();
this.autocomplete = new AutocompleteService(initializerContext);
this.storage = new Storage(window.localStorage);
this.nowProvider = new NowProvider();
}
@ -113,10 +110,6 @@ export class DataPublicPlugin
);
return {
autocomplete: this.autocomplete.setup(core, {
timefilter: queryService.timefilter,
usageCollection,
}),
search: searchService,
query: queryService,
};
@ -161,7 +154,6 @@ export class DataPublicPlugin
createFiltersFromValueClickAction,
createFiltersFromRangeSelectAction,
},
autocomplete: this.autocomplete.start(),
datatableUtilities,
fieldFormats,
indexPatterns: dataViews,
@ -175,7 +167,6 @@ export class DataPublicPlugin
}
public stop() {
this.autocomplete.clearProviders();
this.queryService.stop();
this.searchService.stop();
}

View file

@ -16,7 +16,6 @@ import { FieldFormatsSetup, FieldFormatsStart } from '@kbn/field-formats-plugin/
import { UsageCollectionSetup, UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
import { Setup as InspectorSetup } from '@kbn/inspector-plugin/public';
import { DatatableUtilitiesService } from '../common';
import { AutocompleteSetup, AutocompleteStart } from './autocomplete';
import { createFiltersFromRangeSelectAction, createFiltersFromValueClickAction } from './actions';
import type { ISearchSetup, ISearchStart } from './search';
import { QuerySetup, QueryStart } from './query';
@ -42,7 +41,6 @@ export interface DataStartDependencies {
* Data plugin public Setup contract
*/
export interface DataPublicPluginSetup {
autocomplete: AutocompleteSetup;
search: ISearchSetup;
query: QuerySetup;
}
@ -64,11 +62,6 @@ export interface DataPublicPluginStart {
* {@link DataPublicPluginStartActions}
*/
actions: DataPublicPluginStartActions;
/**
* autocomplete service
* {@link AutocompleteStart}
*/
autocomplete: AutocompleteStart;
/**
* data views service
* {@link DataViewsContract}

View file

@ -16,6 +16,8 @@ import { DataServerPlugin, DataPluginSetup, DataPluginStart } from './plugin';
export * from './deprecated';
export { getEsQueryConfig, DEFAULT_QUERY_LANGUAGE } from '../common';
export { getRequestAbortedSignal } from './lib';
/**
* Exporters (CSV)
*/
@ -68,7 +70,6 @@ import {
// tabify
calcAutoIntervalLessThan,
} from '../common';
import { autocompleteConfigDeprecationProvider } from './config_deprecations';
export type {
ParsedInterval,
@ -121,9 +122,7 @@ export type { DataPluginSetup as PluginSetup, DataPluginStart as PluginStart };
export { DataServerPlugin as Plugin };
export const config: PluginConfigDescriptor<ConfigSchema> = {
deprecations: autocompleteConfigDeprecationProvider,
exposeToBrowser: {
autocomplete: true,
search: true,
},
schema: configSchema,

View file

@ -18,16 +18,10 @@ import {
import { createIndexPatternsStartMock } from './data_views/mocks';
import { createDatatableUtilitiesMock } from './datatable_utilities/mock';
import { DataRequestHandlerContext } from './search';
import { AutocompleteSetup } from './autocomplete';
const autocompleteSetupMock: jest.Mocked<AutocompleteSetup> = {
getAutocompleteSettings: jest.fn(),
};
function createSetupContract() {
return {
search: createSearchSetupMock(),
autocomplete: autocompleteSetupMock,
/**
* @deprecated - use directly from "fieldFormats" plugin instead
*/

View file

@ -19,17 +19,14 @@ import { SearchService } from './search/search_service';
import { QueryService } from './query/query_service';
import { ScriptsService } from './scripts';
import { KqlTelemetryService } from './kql_telemetry';
import { AutocompleteService } from './autocomplete';
import { getUiSettings } from './ui_settings';
import { QuerySetup } from './query';
import { AutocompleteSetup } from './autocomplete/autocomplete_service';
interface DataEnhancements {
search: SearchEnhancements;
}
export interface DataPluginSetup {
autocomplete: AutocompleteSetup;
search: ISearchSetup;
query: QuerySetup;
/**
@ -81,7 +78,6 @@ export class DataServerPlugin
private readonly searchService: SearchService;
private readonly scriptsService: ScriptsService;
private readonly kqlTelemetryService: KqlTelemetryService;
private readonly autocompleteService: AutocompleteService;
private readonly queryService = new QueryService();
private readonly logger: Logger;
@ -90,7 +86,6 @@ export class DataServerPlugin
this.searchService = new SearchService(initializerContext, this.logger);
this.scriptsService = new ScriptsService();
this.kqlTelemetryService = new KqlTelemetryService(initializerContext);
this.autocompleteService = new AutocompleteService(initializerContext);
}
public setup(
@ -110,7 +105,6 @@ export class DataServerPlugin
});
return {
autocomplete: this.autocompleteService.setup(core),
__enhance: (enhancements: DataEnhancements) => {
searchSetup.__enhance(enhancements.search);
},

View file

@ -9,7 +9,10 @@
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
import { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public';
import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import {
UnifiedSearchPublicPluginStart,
UnifiedSearchPluginSetup,
} from '@kbn/unified-search-plugin/public';
import { Plugin as ExpressionsPublicPlugin } from '@kbn/expressions-plugin/public';
import { VisualizationsSetup, VisualizationsStart } from '@kbn/visualizations-plugin/public';
import { createInputControlVisFn } from './input_control_fn';
@ -26,6 +29,7 @@ export interface InputControlSettings {
export interface InputControlVisDependencies {
core: InputControlVisCoreSetup;
data: DataPublicPluginSetup;
unifiedSearch: UnifiedSearchPluginSetup;
getSettings: () => Promise<InputControlSettings>;
}
@ -34,6 +38,7 @@ export interface InputControlVisPluginSetupDependencies {
expressions: ReturnType<ExpressionsPublicPlugin['setup']>;
visualizations: VisualizationsSetup;
data: DataPublicPluginSetup;
unifiedSearch: UnifiedSearchPluginSetup;
}
/** @internal */
@ -50,15 +55,16 @@ export class InputControlVisPlugin implements Plugin<void, void> {
public setup(
core: InputControlVisCoreSetup,
{ expressions, visualizations, data }: InputControlVisPluginSetupDependencies
{ expressions, visualizations, unifiedSearch, data }: InputControlVisPluginSetupDependencies
) {
const visualizationDependencies: Readonly<InputControlVisDependencies> = {
core,
data,
unifiedSearch,
getSettings: async () => {
const { timeout, terminateAfter } = data.autocomplete.getAutocompleteSettings();
const { timeout, terminateAfter } = unifiedSearch.autocomplete.getAutocompleteSettings();
return { autocompleteTimeout: timeout, autocompleteTerminateAfter: terminateAfter };
},
data,
};
expressions.registerFunction(createInputControlVisFn);

View file

@ -8,6 +8,29 @@
import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({});
export const configSchema = schema.object({
autocomplete: schema.object({
querySuggestions: schema.object({
enabled: schema.boolean({ defaultValue: true }),
}),
valueSuggestions: schema.object({
enabled: schema.boolean({ defaultValue: true }),
tiers: schema.arrayOf(
schema.oneOf([
schema.literal('data_content'),
schema.literal('data_hot'),
schema.literal('data_warm'),
schema.literal('data_cold'),
schema.literal('data_frozen'),
]),
{
defaultValue: ['data_hot', 'data_warm', 'data_content', 'data_cold'],
}
),
terminateAfter: schema.duration({ defaultValue: 100000 }),
timeout: schema.duration({ defaultValue: 1000 }),
}),
}),
});
export type ConfigSchema = TypeOf<typeof configSchema>;

View file

@ -7,8 +7,10 @@
"name": "Unified Search",
"githubTeam": "kibana-app-services"
},
"server": false,
"server": true,
"ui": true,
"requiredPlugins": ["dataViews", "data", "uiActions"],
"requiredBundles": ["kibanaUtils", "kibanaReact", "data"]
"requiredBundles": ["kibanaUtils", "kibanaReact", "data"],
"serviceFolders": ["autocomplete"],
"configPath": ["unifiedSearch"]
}

View file

@ -8,8 +8,8 @@
import { CoreSetup, PluginInitializerContext } from '@kbn/core/public';
import moment from 'moment';
import type { TimefilterSetup } from '@kbn/data-plugin/public';
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
import type { TimefilterSetup } from '../query';
import { QuerySuggestionGetFn } from './providers/query_suggestion_provider';
import {
getEmptyValueSuggestions,
@ -23,7 +23,7 @@ import {
KUERY_LANGUAGE_NAME,
setupKqlQuerySuggestionProvider,
} from './providers/kql_query_suggestion';
import { DataPublicPluginStart, DataStartDependencies } from '../types';
import { UnifiedSearchPublicPluginStart, UnifiedSearchStartDependencies } from '../types';
export class AutocompleteService {
autocompleteConfig: ConfigSchema['autocomplete'];
@ -50,7 +50,7 @@ export class AutocompleteService {
/** @public **/
public setup(
core: CoreSetup<DataStartDependencies, DataPublicPluginStart>,
core: CoreSetup<UnifiedSearchStartDependencies, UnifiedSearchPublicPluginStart>,
{
timefilter,
usageCollection,

View file

@ -6,9 +6,10 @@
* Side Public License, v 1.
*/
import { setupGetConjunctionSuggestions } from './conjunction';
import { QuerySuggestionGetFnArgs, KueryNode } from '../../..';
import { coreMock } from '@kbn/core/public/mocks';
import { KueryNode } from '@kbn/data-plugin/public';
import { setupGetConjunctionSuggestions } from './conjunction';
import { QuerySuggestionGetFnArgs } from '../query_suggestion_provider';
const mockKueryNode = (kueryNode: Partial<KueryNode>) => kueryNode as unknown as KueryNode;

View file

@ -10,21 +10,21 @@ import React from 'react';
import { $Keys } from 'utility-types';
import { FormattedMessage } from '@kbn/i18n-react';
import { KqlQuerySuggestionProvider } from './types';
import { QuerySuggestion, QuerySuggestionTypes } from '../../..';
import { QuerySuggestion, QuerySuggestionTypes } from '../query_suggestion_provider';
const bothArgumentsText = (
<FormattedMessage
id="data.kueryAutocomplete.andOperatorDescription.bothArgumentsText"
id="unifiedSearch.kueryAutocomplete.andOperatorDescription.bothArgumentsText"
defaultMessage="both arguments"
description="Part of data.kueryAutocomplete.andOperatorDescription. Full text: 'Requires both arguments to be true'"
description="Part of unifiedSearch.kueryAutocomplete.andOperatorDescription. Full text: 'Requires both arguments to be true'"
/>
);
const oneOrMoreArgumentsText = (
<FormattedMessage
id="data.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText"
id="unifiedSearch.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText"
defaultMessage="one or more arguments"
description="Part of data.kueryAutocomplete.orOperatorDescription. Full text: 'Requires one or more arguments to be true'"
description="Part of unifiedSearch.kueryAutocomplete.orOperatorDescription. Full text: 'Requires one or more arguments to be true'"
/>
);
@ -32,20 +32,20 @@ const conjunctions: Record<string, JSX.Element> = {
and: (
<p>
<FormattedMessage
id="data.kueryAutocomplete.andOperatorDescription"
id="unifiedSearch.kueryAutocomplete.andOperatorDescription"
defaultMessage="Requires {bothArguments} to be true"
values={{
bothArguments: <span className="kbnSuggestionItem__callout">{bothArgumentsText}</span>,
}}
description="Full text: ' Requires both arguments to be true'. See
'data.kueryAutocomplete.andOperatorDescription.bothArgumentsText' for 'both arguments' part."
'unifiedSearch.kueryAutocomplete.andOperatorDescription.bothArgumentsText' for 'both arguments' part."
/>
</p>
),
or: (
<p>
<FormattedMessage
id="data.kueryAutocomplete.orOperatorDescription"
id="unifiedSearch.kueryAutocomplete.orOperatorDescription"
defaultMessage="Requires {oneOrMoreArguments} to be true"
values={{
oneOrMoreArguments: (
@ -53,7 +53,7 @@ const conjunctions: Record<string, JSX.Element> = {
),
}}
description="Full text: 'Requires one or more arguments to be true'. See
'data.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText' for 'one or more arguments' part."
'unifiedSearch.kueryAutocomplete.orOperatorDescription.oneOrMoreArgumentsText' for 'one or more arguments' part."
/>
</p>
),

View file

@ -8,8 +8,9 @@
import indexPatternResponse from './__fixtures__/index_pattern_response.json';
import { indexPatterns as indexPatternsUtils, KueryNode } from '@kbn/data-plugin/public';
import { setupGetFieldSuggestions } from './field';
import { indexPatterns as indexPatternsUtils, QuerySuggestionGetFnArgs, KueryNode } from '../../..';
import { QuerySuggestionGetFnArgs } from '../query_suggestion_provider';
import { coreMock } from '@kbn/core/public/mocks';
const mockKueryNode = (kueryNode: Partial<KueryNode>) => kueryNode as unknown as KueryNode;

View file

@ -6,15 +6,11 @@
* Side Public License, v 1.
*/
import { IFieldType, indexPatterns as indexPatternsUtils } from '@kbn/data-plugin/public';
import { flatten } from 'lodash';
import { escapeKuery } from './lib/escape_kuery';
import { sortPrefixFirst } from './sort_prefix_first';
import {
IFieldType,
indexPatterns as indexPatternsUtils,
QuerySuggestionField,
QuerySuggestionTypes,
} from '../../..';
import { QuerySuggestionField, QuerySuggestionTypes } from '../query_suggestion_provider';
import { KqlQuerySuggestionProvider } from './types';
const keywordComparator = (first: IFieldType, second: IFieldType) => {

View file

@ -14,12 +14,12 @@ import { setupGetFieldSuggestions } from './field';
import { setupGetValueSuggestions } from './value';
import { setupGetOperatorSuggestions } from './operator';
import { setupGetConjunctionSuggestions } from './conjunction';
import { UnifiedSearchPublicPluginStart } from '../../../types';
import {
QuerySuggestion,
QuerySuggestionGetFnArgs,
QuerySuggestionGetFn,
DataPublicPluginStart,
} from '../../..';
} from '../query_suggestion_provider';
const cursorSymbol = '@kuery-cursor@';
@ -29,7 +29,7 @@ const dedup = (suggestions: QuerySuggestion[]): QuerySuggestion[] =>
export const KUERY_LANGUAGE_NAME = 'kuery';
export const setupKqlQuerySuggestionProvider = (
core: CoreSetup<object, DataPublicPluginStart>
core: CoreSetup<object, UnifiedSearchPublicPluginStart>
): QuerySuggestionGetFn => {
const providers = {
field: setupGetFieldSuggestions(core),

View file

@ -9,7 +9,8 @@
import indexPatternResponse from './__fixtures__/index_pattern_response.json';
import { setupGetOperatorSuggestions } from './operator';
import { QuerySuggestionGetFnArgs, KueryNode } from '../../..';
import { KueryNode } from '@kbn/data-plugin/public';
import { QuerySuggestionGetFnArgs } from '../query_suggestion_provider';
import { coreMock } from '@kbn/core/public/mocks';
const mockKueryNode = (kueryNode: Partial<KueryNode>) => kueryNode as unknown as KueryNode;

View file

@ -12,48 +12,48 @@ import { $Keys } from 'utility-types';
import { flatten } from 'lodash';
import { KqlQuerySuggestionProvider } from './types';
import { QuerySuggestionTypes } from '../../..';
import { QuerySuggestionTypes } from '../query_suggestion_provider';
const equalsText = (
<FormattedMessage
id="data.kueryAutocomplete.equalOperatorDescription.equalsText"
id="unifiedSearch.kueryAutocomplete.equalOperatorDescription.equalsText"
defaultMessage="equals"
description="Part of data.kueryAutocomplete.equalOperatorDescription. Full text: 'equals some value'"
description="Part of unifiedSearch.kueryAutocomplete.equalOperatorDescription. Full text: 'equals some value'"
/>
);
const lessThanOrEqualToText = (
<FormattedMessage
id="data.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText"
id="unifiedSearch.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText"
defaultMessage="less than or equal to"
description="Part of data.kueryAutocomplete.lessThanOrEqualOperatorDescription. Full text: 'is less than or equal to some value'"
description="Part of unifiedSearch.kueryAutocomplete.lessThanOrEqualOperatorDescription. Full text: 'is less than or equal to some value'"
/>
);
const greaterThanOrEqualToText = (
<FormattedMessage
id="data.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText"
id="unifiedSearch.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText"
defaultMessage="greater than or equal to"
description="Part of data.kueryAutocomplete.greaterThanOrEqualOperatorDescription. Full text: 'is greater than or equal to some value'"
description="Part of unifiedSearch.kueryAutocomplete.greaterThanOrEqualOperatorDescription. Full text: 'is greater than or equal to some value'"
/>
);
const lessThanText = (
<FormattedMessage
id="data.kueryAutocomplete.lessThanOperatorDescription.lessThanText"
id="unifiedSearch.kueryAutocomplete.lessThanOperatorDescription.lessThanText"
defaultMessage="less than"
description="Part of data.kueryAutocomplete.lessThanOperatorDescription. Full text: 'is less than some value'"
description="Part of unifiedSearch.kueryAutocomplete.lessThanOperatorDescription. Full text: 'is less than some value'"
/>
);
const greaterThanText = (
<FormattedMessage
id="data.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText"
id="unifiedSearch.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText"
defaultMessage="greater than"
description="Part of data.kueryAutocomplete.greaterThanOperatorDescription. Full text: 'is greater than some value'"
description="Part of unifiedSearch.kueryAutocomplete.greaterThanOperatorDescription. Full text: 'is greater than some value'"
/>
);
const existsText = (
<FormattedMessage
id="data.kueryAutocomplete.existOperatorDescription.existsText"
id="unifiedSearch.kueryAutocomplete.existOperatorDescription.existsText"
defaultMessage="exists"
description="Part of data.kueryAutocomplete.existOperatorDescription. Full text: 'exists in any form'"
description="Part of unifiedSearch.kueryAutocomplete.existOperatorDescription. Full text: 'exists in any form'"
/>
);
@ -61,11 +61,11 @@ const operators = {
':': {
description: (
<FormattedMessage
id="data.kueryAutocomplete.equalOperatorDescription"
id="unifiedSearch.kueryAutocomplete.equalOperatorDescription"
defaultMessage="{equals} some value"
values={{ equals: <span className="kbnSuggestionItem__callout">{equalsText}</span> }}
description="Full text: 'equals some value'. See
'data.kueryAutocomplete.equalOperatorDescription.equalsText' for 'equals' part."
'unifiedSearch.kueryAutocomplete.equalOperatorDescription.equalsText' for 'equals' part."
/>
),
fieldTypes: [
@ -84,7 +84,7 @@ const operators = {
'<=': {
description: (
<FormattedMessage
id="data.kueryAutocomplete.lessThanOrEqualOperatorDescription"
id="unifiedSearch.kueryAutocomplete.lessThanOrEqualOperatorDescription"
defaultMessage="is {lessThanOrEqualTo} some value"
values={{
lessThanOrEqualTo: (
@ -92,7 +92,7 @@ const operators = {
),
}}
description="Full text: 'is less than or equal to some value'. See
'data.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText' for 'less than or equal to' part."
'unifiedSearch.kueryAutocomplete.lessThanOrEqualOperatorDescription.lessThanOrEqualToText' for 'less than or equal to' part."
/>
),
fieldTypes: ['number', 'number_range', 'date', 'date_range', 'ip', 'ip_range'],
@ -100,7 +100,7 @@ const operators = {
'>=': {
description: (
<FormattedMessage
id="data.kueryAutocomplete.greaterThanOrEqualOperatorDescription"
id="unifiedSearch.kueryAutocomplete.greaterThanOrEqualOperatorDescription"
defaultMessage="is {greaterThanOrEqualTo} some value"
values={{
greaterThanOrEqualTo: (
@ -108,7 +108,7 @@ const operators = {
),
}}
description="Full text: 'is greater than or equal to some value'. See
'data.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText' for 'greater than or equal to' part."
'unifiedSearch.kueryAutocomplete.greaterThanOrEqualOperatorDescription.greaterThanOrEqualToText' for 'greater than or equal to' part."
/>
),
fieldTypes: ['number', 'number_range', 'date', 'date_range', 'ip', 'ip_range'],
@ -116,11 +116,11 @@ const operators = {
'<': {
description: (
<FormattedMessage
id="data.kueryAutocomplete.lessThanOperatorDescription"
id="unifiedSearch.kueryAutocomplete.lessThanOperatorDescription"
defaultMessage="is {lessThan} some value"
values={{ lessThan: <span className="kbnSuggestionItem__callout">{lessThanText}</span> }}
description="Full text: 'is less than some value'. See
'data.kueryAutocomplete.lessThanOperatorDescription.lessThanText' for 'less than' part."
'unifiedSearch.kueryAutocomplete.lessThanOperatorDescription.lessThanText' for 'less than' part."
/>
),
fieldTypes: ['number', 'number_range', 'date', 'date_range', 'ip', 'ip_range'],
@ -128,13 +128,13 @@ const operators = {
'>': {
description: (
<FormattedMessage
id="data.kueryAutocomplete.greaterThanOperatorDescription"
id="unifiedSearch.kueryAutocomplete.greaterThanOperatorDescription"
defaultMessage="is {greaterThan} some value"
values={{
greaterThan: <span className="kbnSuggestionItem__callout">{greaterThanText}</span>,
}}
description="Full text: 'is greater than some value'. See
'data.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText' for 'greater than' part."
'unifiedSearch.kueryAutocomplete.greaterThanOperatorDescription.greaterThanText' for 'greater than' part."
/>
),
fieldTypes: ['number', 'number_range', 'date', 'date_range', 'ip', 'ip_range'],
@ -142,11 +142,11 @@ const operators = {
': *': {
description: (
<FormattedMessage
id="data.kueryAutocomplete.existOperatorDescription"
id="unifiedSearch.kueryAutocomplete.existOperatorDescription"
defaultMessage="{exists} in any form"
values={{ exists: <span className="kbnSuggestionItem__callout">{existsText}</span> }}
description="Full text: 'exists in any form'. See
'data.kueryAutocomplete.existOperatorDescription.existsText' for 'exists' part."
'unifiedSearch.kueryAutocomplete.existOperatorDescription.existsText' for 'exists' part."
/>
),
fieldTypes: undefined,

View file

@ -6,10 +6,11 @@
* Side Public License, v 1.
*/
import { KueryNode } from '@kbn/es-query';
import { CoreSetup } from '@kbn/core/public';
import { DataPublicPluginStart, QuerySuggestionBasic, QuerySuggestionGetFnArgs } from '../../..';
import { KueryNode } from '@kbn/es-query';
import type { UnifiedSearchPublicPluginStart } from '../../../types';
import { QuerySuggestionBasic, QuerySuggestionGetFnArgs } from '../query_suggestion_provider';
export type KqlQuerySuggestionProvider<T = QuerySuggestionBasic> = (
core: CoreSetup<object, DataPublicPluginStart>
core: CoreSetup<object, UnifiedSearchPublicPluginStart>
) => (querySuggestionsGetFnArgs: QuerySuggestionGetFnArgs, kueryNode: KueryNode) => Promise<T[]>;

View file

@ -8,8 +8,10 @@
import { setupGetValueSuggestions } from './value';
import indexPatternResponse from './__fixtures__/index_pattern_response.json';
import { coreMock } from '@kbn/core/public/mocks';
import { QuerySuggestionGetFnArgs, KueryNode } from '../../..';
import { KueryNode } from '@kbn/data-plugin/public';
import { QuerySuggestionGetFnArgs } from '../query_suggestion_provider';
const mockKueryNode = (kueryNode: Partial<KueryNode>) => kueryNode as unknown as KueryNode;

View file

@ -8,15 +8,11 @@
import { flatten } from 'lodash';
import { CoreSetup } from '@kbn/core/public';
import { IFieldType, IIndexPattern } from '@kbn/data-plugin/public';
import { escapeQuotes } from './lib/escape_kuery';
import { KqlQuerySuggestionProvider } from './types';
import {
DataPublicPluginStart,
IFieldType,
IIndexPattern,
QuerySuggestion,
QuerySuggestionTypes,
} from '../../..';
import type { UnifiedSearchPublicPluginStart } from '../../../types';
import { QuerySuggestion, QuerySuggestionTypes } from '../query_suggestion_provider';
const wrapAsSuggestions = (start: number, end: number, query: string, values: string[]) =>
values
@ -29,7 +25,7 @@ const wrapAsSuggestions = (start: number, end: number, query: string, values: st
}));
export const setupGetValueSuggestions: KqlQuerySuggestionProvider = (
core: CoreSetup<object, DataPublicPluginStart>
core: CoreSetup<object, UnifiedSearchPublicPluginStart>
) => {
const autoCompleteServicePromise = core
.getStartServices()

View file

@ -6,8 +6,8 @@
* Side Public License, v 1.
*/
import { ValueSuggestionsMethod } from '../../../common';
import { IFieldType, IIndexPattern } from '../../../common';
import { ValueSuggestionsMethod } from '@kbn/data-plugin/common';
import { IFieldType, IIndexPattern } from '@kbn/data-plugin/common';
export enum QuerySuggestionTypes {
Field = 'field',

View file

@ -6,12 +6,12 @@
* Side Public License, v 1.
*/
import { stubIndexPattern, stubFields } from '../../stubs';
import type { TimefilterSetup } from '../../query';
import { IUiSettingsClient, CoreSetup } from '@kbn/core/public';
import { stubIndexPattern, stubFields } from '@kbn/data-plugin/public/stubs';
import type { TimefilterSetup } from '@kbn/data-plugin/public';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
import { setupValueSuggestionProvider } from './value_suggestion_provider';
import type { ValueSuggestionsGetFn } from './value_suggestion_provider';
import { IUiSettingsClient, CoreSetup } from '@kbn/core/public';
import { UI_SETTINGS } from '../../../common';
describe('FieldSuggestions', () => {
let getValueSuggestions: ValueSuggestionsGetFn;

View file

@ -6,12 +6,17 @@
* Side Public License, v 1.
*/
import { CoreSetup } from '@kbn/core/public';
import dateMath from '@kbn/datemath';
import { buildQueryFromFilters } from '@kbn/es-query';
import { memoize } from 'lodash';
import { CoreSetup } from '@kbn/core/public';
import { IIndexPattern, IFieldType, UI_SETTINGS, ValueSuggestionsMethod } from '../../../common';
import type { TimefilterSetup } from '../../query';
import {
IIndexPattern,
IFieldType,
UI_SETTINGS,
ValueSuggestionsMethod,
} from '@kbn/data-plugin/common';
import type { TimefilterSetup } from '@kbn/data-plugin/public';
import { AutocompleteUsageCollector } from '../collectors';
export type ValueSuggestionsGetFn = (args: ValueSuggestionsGetFnArgs) => Promise<any[]>;

View file

@ -7,12 +7,13 @@
*/
import React from 'react';
import { debounce } from 'lodash';
import { withKibana, KibanaReactContextValue } from '@kbn/kibana-react-plugin/public';
import { IFieldType, UI_SETTINGS } from '@kbn/data-plugin/common';
import { DataView } from '@kbn/data-views-plugin/common';
import { IDataPluginServices } from '@kbn/data-plugin/public';
import { debounce } from 'lodash';
import { getAutocomplete } from '../../services';
export interface PhraseSuggestorProps {
kibana: KibanaReactContextValue<IDataPluginServices>;
@ -79,8 +80,7 @@ export class PhraseSuggestorUI<T extends PhraseSuggestorProps> extends React.Com
return;
}
this.setState({ isLoading: true });
const suggestions = await this.services.data.autocomplete.getValueSuggestions({
const suggestions = await getAutocomplete().getValueSuggestions({
indexPattern,
field,
query,

View file

@ -7,19 +7,31 @@
*/
import { PluginInitializerContext } from '@kbn/core/public';
import { ConfigSchema } from '../config';
import { UnifiedSearchPublicPlugin } from './plugin';
export type { IndexPatternSelectProps } from './index_pattern_select';
export type { QueryStringInputProps } from './query_string_input';
export { QueryStringInput } from './query_string_input';
export type { StatefulSearchBarProps, SearchBarProps } from './search_bar';
export type { UnifiedSearchPublicPluginStart } from './types';
export type { UnifiedSearchPublicPluginStart, UnifiedSearchPluginSetup } from './types';
export { SearchBar } from './search_bar';
export { FilterLabel, FilterItem } from './filter_bar';
export type { ApplyGlobalFilterActionContext } from './actions';
export { ACTION_GLOBAL_APPLY_FILTER } from './actions';
/*
* Autocomplete query suggestions:
*/
export type {
QuerySuggestion,
QuerySuggestionGetFn,
QuerySuggestionGetFnArgs,
AutocompleteStart,
} from './autocomplete';
export { QuerySuggestionTypes } from './autocomplete';
import { UnifiedSearchPublicPlugin } from './plugin';
// This exports static code and TypeScript types,
// as well as, Kibana Platform `plugin()` initializer.
export function plugin(initializerContext: PluginInitializerContext<ConfigSchema>) {

View file

@ -7,12 +7,31 @@
*/
import { UnifiedSearchPublicPlugin } from './plugin';
import { AutocompleteStart, AutocompleteSetup } from './autocomplete';
export type Setup = jest.Mocked<ReturnType<UnifiedSearchPublicPlugin['setup']>>;
export type Start = jest.Mocked<ReturnType<UnifiedSearchPublicPlugin['start']>>;
const autocompleteSetupMock: jest.Mocked<AutocompleteSetup> = {
getQuerySuggestions: jest.fn(),
getAutocompleteSettings: jest.fn(),
};
const autocompleteStartMock: jest.Mocked<AutocompleteStart> = {
getValueSuggestions: jest.fn(),
getQuerySuggestions: jest.fn(),
hasQuerySuggestions: jest.fn(),
};
const createSetupContract = (): Setup => {
return {
autocomplete: autocompleteSetupMock,
};
};
const createStartContract = (): Start => {
return {
autocomplete: autocompleteStartMock,
ui: {
IndexPatternSelect: jest.fn(),
SearchBar: jest.fn().mockReturnValue(null),
@ -22,4 +41,5 @@ const createStartContract = (): Start => {
export const unifiedSearchPluginMock = {
createStartContract,
createSetupContract,
};

View file

@ -13,11 +13,16 @@ import { Storage, IStorageWrapper } from '@kbn/kibana-utils-plugin/public';
import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
import { APPLY_FILTER_TRIGGER } from '@kbn/data-plugin/public';
import { ConfigSchema } from '../config';
import { setIndexPatterns, setTheme, setOverlays } from './services';
import { setIndexPatterns, setTheme, setOverlays, setAutocomplete } from './services';
import { AutocompleteService } from './autocomplete';
import { createSearchBar } from './search_bar';
import { createIndexPatternSelect } from './index_pattern_select';
import { UnifiedSearchPluginSetup, UnifiedSearchPublicPluginStart } from './types';
import type { UnifiedSearchStartDependencies, UnifiedSearchSetupDependencies } from './types';
import type {
UnifiedSearchStartDependencies,
UnifiedSearchSetupDependencies,
UnifiedSearchPluginSetup,
UnifiedSearchPublicPluginStart,
} from './types';
import { createFilterAction } from './actions/apply_filter_action';
import { ACTION_GLOBAL_APPLY_FILTER } from './actions';
@ -25,22 +30,30 @@ export class UnifiedSearchPublicPlugin
implements Plugin<UnifiedSearchPluginSetup, UnifiedSearchPublicPluginStart>
{
private readonly storage: IStorageWrapper;
private readonly autocomplete: AutocompleteService;
private usageCollection: UsageCollectionSetup | undefined;
constructor(initializerContext: PluginInitializerContext<ConfigSchema>) {
this.storage = new Storage(window.localStorage);
this.autocomplete = new AutocompleteService(initializerContext);
}
public setup(
core: CoreSetup,
{ uiActions, data }: UnifiedSearchSetupDependencies
core: CoreSetup<UnifiedSearchStartDependencies, UnifiedSearchPublicPluginStart>,
{ uiActions, data, usageCollection }: UnifiedSearchSetupDependencies
): UnifiedSearchPluginSetup {
const { query } = data;
uiActions.registerAction(
createFilterAction(query.filterManager, query.timefilter.timefilter, core.theme)
);
return {};
return {
autocomplete: this.autocomplete.setup(core, {
timefilter: query.timefilter,
usageCollection,
}),
};
}
public start(
@ -50,6 +63,8 @@ export class UnifiedSearchPublicPlugin
setTheme(core.theme);
setOverlays(core.overlays);
setIndexPatterns(dataViews);
const autocompleteStart = this.autocomplete.start();
setAutocomplete(autocompleteStart);
const SearchBar = createSearchBar({
core,
@ -68,8 +83,11 @@ export class UnifiedSearchPublicPlugin
IndexPatternSelect: createIndexPatternSelect(dataViews),
SearchBar,
},
autocomplete: autocompleteStart,
};
}
public stop() {}
public stop() {
this.autocomplete.clearProviders();
}
}

View file

@ -20,6 +20,9 @@ import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { I18nProvider } from '@kbn/i18n-react';
import { stubIndexPattern } from '@kbn/data-plugin/public/stubs';
import { UI_SETTINGS } from '@kbn/data-plugin/common';
import { setAutocomplete } from '../services';
import { unifiedSearchPluginMock } from '../mocks';
const startMock = coreMock.createStart();
const mockTimeHistory = {
@ -112,6 +115,11 @@ describe('QueryBarTopRowTopRow', () => {
jest.clearAllMocks();
});
beforeEach(() => {
const autocompleteStart = unifiedSearchPluginMock.createStartContract();
setAutocomplete(autocompleteStart.autocomplete);
});
it('Should render query and time picker', () => {
const { getByText, getByTestId } = render(
wrapQueryBarTopRowInContext({

View file

@ -28,6 +28,9 @@ import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
import { stubIndexPattern } from '@kbn/data-plugin/public/stubs';
import { KibanaContextProvider, withKibana } from '@kbn/kibana-react-plugin/public';
import { setAutocomplete } from '../services';
import { unifiedSearchPluginMock } from '../mocks';
jest.useFakeTimers();
const startMock = coreMock.createStart();
@ -92,6 +95,11 @@ describe('QueryStringInput', () => {
jest.clearAllMocks();
});
beforeEach(() => {
const autocompleteStart = unifiedSearchPluginMock.createStartContract();
setAutocomplete(autocompleteStart.autocomplete);
});
it('Should render the given query', async () => {
const { getByText } = render(
wrapQueryStringInputInContext({

View file

@ -28,13 +28,7 @@ import {
import { FormattedMessage } from '@kbn/i18n-react';
import { compact, debounce, isEqual, isFunction } from 'lodash';
import { Toast } from '@kbn/core/public';
import {
IDataPluginServices,
Query,
QuerySuggestion,
QuerySuggestionTypes,
getQueryLog,
} from '@kbn/data-plugin/public';
import { IDataPluginServices, Query, getQueryLog } from '@kbn/data-plugin/public';
import { DataView } from '@kbn/data-views-plugin/public';
import type { PersistedLog } from '@kbn/data-plugin/public';
import { getFieldSubtypeNested, KIBANA_USER_QUERY_LANGUAGE_KEY } from '@kbn/data-plugin/common';
@ -47,7 +41,8 @@ import { QueryLanguageSwitcher } from './language_switcher';
import type { SuggestionsListSize } from '../typeahead/suggestions_component';
import { SuggestionsComponent } from '../typeahead';
import { onRaf } from '../utils';
import { getTheme } from '../services';
import { QuerySuggestion, QuerySuggestionTypes } from '../autocomplete';
import { getTheme, getAutocomplete } from '../services';
export interface QueryStringInputProps {
indexPatterns: Array<DataView | string>;
@ -201,7 +196,7 @@ export default class QueryStringInputUI extends PureComponent<Props, State> {
const queryString = this.getQueryString();
const recentSearchSuggestions = this.getRecentSearchSuggestions(queryString);
const hasQuerySuggestions = this.services.data.autocomplete.hasQuerySuggestions(language);
const hasQuerySuggestions = getAutocomplete().hasQuerySuggestions(language);
if (
!hasQuerySuggestions ||
@ -222,7 +217,7 @@ export default class QueryStringInputUI extends PureComponent<Props, State> {
if (this.abortController) this.abortController.abort();
this.abortController = new AbortController();
const suggestions =
(await this.services.data.autocomplete.getQuerySuggestions({
(await getAutocomplete().getQuerySuggestions({
language,
indexPatterns,
query: queryString,

View file

@ -9,6 +9,7 @@
import { ThemeServiceStart, OverlayStart } from '@kbn/core/public';
import { createGetterSetter } from '@kbn/kibana-utils-plugin/public';
import { DataViewsContract } from '@kbn/data-views-plugin/public';
import { AutocompleteStart } from '.';
export const [getIndexPatterns, setIndexPatterns] =
createGetterSetter<DataViewsContract>('IndexPatterns');
@ -16,3 +17,6 @@ export const [getIndexPatterns, setIndexPatterns] =
export const [getTheme, setTheme] = createGetterSetter<ThemeServiceStart>('Theme');
export const [getOverlays, setOverlays] = createGetterSetter<OverlayStart>('Overlays');
export const [getAutocomplete, setAutocomplete] =
createGetterSetter<AutocompleteStart>('Autocomplete');

View file

@ -8,7 +8,7 @@
import { mount, shallow } from 'enzyme';
import React from 'react';
import { QuerySuggestion, QuerySuggestionTypes } from '@kbn/data-plugin/public';
import { QuerySuggestion, QuerySuggestionTypes } from '../autocomplete';
import { SuggestionComponent } from './suggestion_component';
const noop = () => {

View file

@ -9,7 +9,7 @@
import { EuiIcon } from '@elastic/eui';
import classNames from 'classnames';
import React, { useCallback } from 'react';
import { QuerySuggestion } from '@kbn/data-plugin/public';
import { QuerySuggestion } from '../autocomplete';
import { SuggestionOnClick, SuggestionOnMouseEnter } from './types';
function getEuiIconType(type: string) {

View file

@ -8,7 +8,7 @@
import { mount, shallow } from 'enzyme';
import React from 'react';
import { QuerySuggestion, QuerySuggestionTypes } from '@kbn/data-plugin/public';
import { QuerySuggestion, QuerySuggestionTypes } from '../autocomplete';
import { SuggestionComponent } from './suggestion_component';
import SuggestionsComponent from './suggestions_component';

View file

@ -13,7 +13,7 @@ import classNames from 'classnames';
import styled from 'styled-components';
import useRafState from 'react-use/lib/useRafState';
import { QuerySuggestion } from '@kbn/data-plugin/public';
import { QuerySuggestion } from '../autocomplete';
import { SuggestionComponent } from './suggestion_component';
import {
SUGGESTIONS_LIST_REQUIRED_BOTTOM_SPACE,

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import { QuerySuggestion } from '@kbn/data-plugin/public';
import { QuerySuggestion } from '../autocomplete';
export type SuggestionOnClick = (suggestion: QuerySuggestion, index: number) => void;

View file

@ -5,19 +5,24 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { UiActionsSetup, UiActionsStart } from '@kbn/ui-actions-plugin/public';
import { IndexPatternSelectProps, StatefulSearchBarProps } from '.';
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
import { AutocompleteSetup, AutocompleteStart } from './autocomplete';
import type { IndexPatternSelectProps, StatefulSearchBarProps } from '.';
export interface UnifiedSearchSetupDependencies {
uiActions: UiActionsSetup;
data: DataPublicPluginStart;
usageCollection?: UsageCollectionSetup;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface UnifiedSearchPluginSetup {}
export interface UnifiedSearchPluginSetup {
autocomplete: AutocompleteSetup;
}
export interface UnifiedSearchStartDependencies {
dataViews: DataViewsPublicPluginStart;
@ -38,6 +43,11 @@ export interface UnifiedSearchPublicPluginStartUi {
* Unified search plugin public Start contract
*/
export interface UnifiedSearchPublicPluginStart {
/**
* autocomplete service
* {@link AutocompleteStart}
*/
autocomplete: AutocompleteStart;
/**
* prewired UI components
* {@link DataPublicPluginStartUi}

View file

@ -9,8 +9,8 @@
import { get, map } from 'lodash';
import { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { IFieldType, getFieldSubtypeNested } from '@kbn/data-plugin/common';
import { ConfigSchema } from '../../config';
import { IFieldType, getFieldSubtypeNested } from '../../common';
import { findIndexPatternById, getFieldByName } from '../data_views';
export async function termsAggSuggestions(

View file

@ -8,7 +8,7 @@
import { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { FieldSpec } from '../../common';
import { IFieldType } from '@kbn/data-plugin/common';
import { findIndexPatternById, getFieldByName } from '../data_views';
import { ConfigSchema } from '../../config';
@ -20,7 +20,7 @@ export async function termsEnumSuggestions(
fieldName: string,
query: string,
filters?: estypes.QueryDslQueryContainer[],
field?: FieldSpec,
field?: IFieldType,
abortSignal?: AbortSignal
) {
const { tiers } = config.autocomplete.valueSuggestions;

View file

@ -9,8 +9,8 @@
import { schema } from '@kbn/config-schema';
import { IRouter } from '@kbn/core/server';
import { firstValueFrom, Observable } from 'rxjs';
import { getRequestAbortedSignal } from '@kbn/data-plugin/server';
import { getKbnServerError, reportServerError } from '@kbn/kibana-utils-plugin/server';
import { getRequestAbortedSignal } from '../lib';
import type { ConfigSchema } from '../../config';
import { termsEnumSuggestions } from './terms_enum';
import { termsAggSuggestions } from './terms_agg';

View file

@ -0,0 +1,137 @@
/*
* 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 { cloneDeep } from 'lodash';
import { applyDeprecations, configDeprecationFactory } from '@kbn/config';
import { configDeprecationsMock } from '@kbn/core/server/mocks';
import { autocompleteConfigDeprecationProvider } from './config_deprecations';
const deprecationContext = configDeprecationsMock.createContext();
const applyConfigDeprecations = (settings: Record<string, any> = {}) => {
const deprecations = autocompleteConfigDeprecationProvider(configDeprecationFactory);
const deprecationMessages: string[] = [];
const migrated = applyDeprecations(
settings,
deprecations.map((deprecation) => ({
deprecation,
path: '',
context: deprecationContext,
})),
() =>
({ message }) =>
deprecationMessages.push(message)
);
return {
messages: deprecationMessages,
migrated: migrated.config,
};
};
describe('Config Deprecations', () => {
it('does not report deprecations for default configurationc', () => {
const configFirstStep = { data: { autocomplete: { valueSuggestions: {} } } };
const { messages, migrated } = applyConfigDeprecations(cloneDeep(configFirstStep));
expect(migrated).toEqual(configFirstStep);
expect(messages).toHaveLength(0);
});
it('renames kibana.autocompleteTerminateAfter to unifiedSearch.autocomplete.valueSuggestions.terminateAfter', () => {
const config = {
kibana: {
autocompleteTerminateAfter: 123,
},
};
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
expect(migrated.kibana?.autocompleteTerminateAfter).not.toBeDefined();
expect(migrated.unifiedSearch.autocomplete.valueSuggestions.terminateAfter).toEqual(123);
expect(messages).toMatchInlineSnapshot(`
Array [
"Setting \\"kibana.autocompleteTerminateAfter\\" has been replaced by \\"unifiedSearch.autocomplete.valueSuggestions.terminateAfter\\"",
]
`);
});
it('renames kibana.autocompleteTimeout to unifiedSearch.autocomplete.valueSuggestions.timeout', () => {
const config = {
kibana: {
autocompleteTimeout: 123,
},
};
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
expect(migrated.kibana?.autocompleteTimeout).not.toBeDefined();
expect(migrated.unifiedSearch.autocomplete.valueSuggestions.timeout).toEqual(123);
expect(messages).toMatchInlineSnapshot(`
Array [
"Setting \\"kibana.autocompleteTimeout\\" has been replaced by \\"unifiedSearch.autocomplete.valueSuggestions.timeout\\"",
]
`);
});
it('renames data.autocomplete.querySuggestions.enabled to unifiedSearch.autocomplete.querySuggestions.enabled', () => {
const config = {
data: {
autocomplete: {
querySuggestions: {
enabled: false,
},
},
},
};
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
expect(migrated.data?.autocomplete.querySuggestions.enabled).not.toBeDefined();
expect(migrated.unifiedSearch.autocomplete.querySuggestions.enabled).toEqual(false);
expect(messages).toMatchInlineSnapshot(`
Array [
"Setting \\"data.autocomplete.querySuggestions.enabled\\" has been replaced by \\"unifiedSearch.autocomplete.querySuggestions.enabled\\"",
]
`);
});
it('renames data.autocomplete.valueSuggestions.enabled to unifiedSearch.autocomplete.valueSuggestions.enabled', () => {
const config = {
data: {
autocomplete: {
valueSuggestions: {
enabled: false,
},
},
},
};
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
expect(migrated.data?.autocomplete.valueSuggestions.enabled).not.toBeDefined();
expect(migrated.unifiedSearch.autocomplete.valueSuggestions.enabled).toEqual(false);
expect(messages).toMatchInlineSnapshot(`
Array [
"Setting \\"data.autocomplete.valueSuggestions.enabled\\" has been replaced by \\"unifiedSearch.autocomplete.valueSuggestions.enabled\\"",
]
`);
});
it('renames data.autocomplete.valueSuggestions.tiers to unifiedSearch.autocomplete.valueSuggestions.tiers', () => {
const config = {
data: {
autocomplete: {
valueSuggestions: {
tiers: [],
},
},
},
};
const { messages, migrated } = applyConfigDeprecations(cloneDeep(config));
expect(migrated.data?.autocomplete.valueSuggestions.tiers).not.toBeDefined();
expect(migrated.unifiedSearch.autocomplete.valueSuggestions.tiers).toEqual([]);
expect(messages).toMatchInlineSnapshot(`
Array [
"Setting \\"data.autocomplete.valueSuggestions.tiers\\" has been replaced by \\"unifiedSearch.autocomplete.valueSuggestions.tiers\\"",
]
`);
});
});

View file

@ -0,0 +1,59 @@
/*
* 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 type { ConfigDeprecationProvider } from '@kbn/core/server';
export const autocompleteConfigDeprecationProvider: ConfigDeprecationProvider = ({
renameFromRoot,
}) => [
renameFromRoot(
'data.autocomplete.valueSuggestions.terminateAfter',
'unifiedSearch.autocomplete.valueSuggestions.terminateAfter',
{ level: 'warning' }
),
renameFromRoot(
'kibana.autocompleteTerminateAfter',
'unifiedSearch.autocomplete.valueSuggestions.terminateAfter',
{ level: 'warning' }
),
renameFromRoot(
'data.autocomplete.valueSuggestions.timeout',
'unifiedSearch.autocomplete.valueSuggestions.timeout',
{
level: 'warning',
}
),
renameFromRoot(
'kibana.autocompleteTimeout',
'unifiedSearch.autocomplete.valueSuggestions.timeout',
{
level: 'warning',
}
),
renameFromRoot(
'data.autocomplete.querySuggestions.enabled',
'unifiedSearch.autocomplete.querySuggestions.enabled',
{
level: 'warning',
}
),
renameFromRoot(
'data.autocomplete.valueSuggestions.enabled',
'unifiedSearch.autocomplete.valueSuggestions.enabled',
{
level: 'warning',
}
),
renameFromRoot(
'data.autocomplete.valueSuggestions.tiers',
'unifiedSearch.autocomplete.valueSuggestions.tiers',
{
level: 'warning',
}
),
];

View file

@ -0,0 +1,9 @@
/*
* 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.
*/
export * from '@kbn/data-views-plugin/server';

View file

@ -0,0 +1,40 @@
/*
* 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 { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
import { ConfigSchema, configSchema } from '../config';
import {
UnifiedSearchServerPlugin,
UnifiedSearchServerPluginSetup,
UnifiedSearchServerPluginStart,
} from './plugin';
import { autocompleteConfigDeprecationProvider } from './config_deprecations';
/**
* Static code to be shared externally
* @public
*/
export function plugin(initializerContext: PluginInitializerContext<ConfigSchema>) {
return new UnifiedSearchServerPlugin(initializerContext);
}
export type {
UnifiedSearchServerPluginSetup as PluginSetup,
UnifiedSearchServerPluginStart as PluginStart,
};
export { UnifiedSearchServerPlugin as Plugin };
export const config: PluginConfigDescriptor<ConfigSchema> = {
deprecations: autocompleteConfigDeprecationProvider,
exposeToBrowser: {
autocomplete: true,
},
schema: configSchema,
};

View file

@ -0,0 +1,23 @@
/*
* 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 { AutocompleteSetup } from './autocomplete';
const autocompleteSetupMock: jest.Mocked<AutocompleteSetup> = {
getAutocompleteSettings: jest.fn(),
};
function createSetupContract() {
return {
autocomplete: autocompleteSetupMock,
};
}
export const dataPluginMock = {
createSetupContract,
};

View file

@ -0,0 +1,50 @@
/*
* 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 { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/server';
import { ConfigSchema } from '../config';
import { AutocompleteService } from './autocomplete';
import { AutocompleteSetup } from './autocomplete/autocomplete_service';
export interface UnifiedSearchServerPluginSetup {
autocomplete: AutocompleteSetup;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface UnifiedSearchServerPluginStart {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface UnifiedSearchServerPluginSetupDependencies {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface UnifiedSearchServerPluginStartDependencies {}
export class UnifiedSearchServerPlugin implements Plugin<UnifiedSearchServerPluginSetup> {
private readonly autocompleteService: AutocompleteService;
constructor(initializerContext: PluginInitializerContext<ConfigSchema>) {
this.autocompleteService = new AutocompleteService(initializerContext);
}
public setup(
core: CoreSetup<UnifiedSearchServerPluginStartDependencies, UnifiedSearchServerPluginStart>,
{}: UnifiedSearchServerPluginSetupDependencies
) {
return {
autocomplete: this.autocompleteService.setup(core),
};
}
public start(core: CoreStart, {}: UnifiedSearchServerPluginStartDependencies) {
return {};
}
public stop() {}
}
export { UnifiedSearchServerPlugin as Plugin };

View file

@ -9,7 +9,9 @@
"include": [
"public/**/*",
"config.ts",
"public/**/*.json"
"public/**/*.json",
"server/**/*",
"config.ts",
],
"references": [
{ "path": "../../core/tsconfig.json" },

View file

@ -85,11 +85,11 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
// Ensure that your change does not unintentionally expose any sensitive values!
'console.ui.enabled (boolean)',
'dashboard.allowByValueEmbeddables (boolean)',
'data.autocomplete.querySuggestions.enabled (boolean)',
'data.autocomplete.valueSuggestions.enabled (boolean)',
'data.autocomplete.valueSuggestions.terminateAfter (duration)',
'data.autocomplete.valueSuggestions.tiers (array)',
'data.autocomplete.valueSuggestions.timeout (duration)',
'unifiedSearch.autocomplete.querySuggestions.enabled (boolean)',
'unifiedSearch.autocomplete.valueSuggestions.enabled (boolean)',
'unifiedSearch.autocomplete.valueSuggestions.terminateAfter (duration)',
'unifiedSearch.autocomplete.valueSuggestions.tiers (array)',
'unifiedSearch.autocomplete.valueSuggestions.timeout (duration)',
'data.search.aggs.shardDelay.enabled (boolean)',
'enterpriseSearch.host (string)',
'home.disableWelcomeScreen (boolean)',

View file

@ -16,7 +16,8 @@
"licensing",
"observability",
"ruleRegistry",
"triggersActionsUi"
"triggersActionsUi",
"unifiedSearch"
],
"optionalPlugins": [
"actions",

View file

@ -10,8 +10,9 @@ import { i18n } from '@kbn/i18n';
import { uniqueId } from 'lodash';
import React, { useState } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { QuerySuggestion } from '@kbn/unified-search-plugin/public';
import { DataView } from '@kbn/data-plugin/common';
import { esKuery, QuerySuggestion } from '@kbn/data-plugin/public';
import { esKuery } from '@kbn/data-plugin/public';
import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context';
import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params';
import { useApmParams } from '../../../hooks/use_apm_params';
@ -55,7 +56,7 @@ export function KueryBar(props: {
});
const { urlParams } = useLegacyUrlParams();
const location = useLocation();
const { data } = useApmPluginContext().plugins;
const { unifiedSearch } = useApmPluginContext().plugins;
let currentRequestCheck;
@ -103,7 +104,7 @@ export function KueryBar(props: {
try {
const suggestions = (
(await data.autocomplete.getQuerySuggestions({
(await unifiedSearch.autocomplete.getQuerySuggestions({
language: 'kuery',
indexPatterns: [dataView],
boolFilter:

View file

@ -4,6 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { i18n } from '@kbn/i18n';
import { from } from 'rxjs';
import { map } from 'rxjs/operators';
@ -17,9 +18,10 @@ import {
PluginInitializerContext,
} from '@kbn/core/public';
import type {
DataPublicPluginSetup,
DataPublicPluginStart,
DataPublicPluginSetup,
} from '@kbn/data-plugin/public';
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import type { EmbeddableStart } from '@kbn/embeddable-plugin/public';
import type { HomePublicPluginSetup } from '@kbn/home-plugin/public';
import { Start as InspectorPluginStart } from '@kbn/inspector-plugin/public';
@ -63,6 +65,7 @@ export type ApmPluginStart = void;
export interface ApmPluginSetupDeps {
alerting?: AlertingPluginPublicSetup;
data: DataPublicPluginSetup;
unifiedSearch: UnifiedSearchPublicPluginStart;
features: FeaturesPluginSetup;
home?: HomePublicPluginSetup;
licensing: LicensingPluginSetup;

View file

@ -11,6 +11,7 @@ type Stubs =
| 'licensing'
| 'storage'
| 'data'
| 'unifiedSearch'
| 'deprecations'
| 'fatalErrors'
| 'navigation'
@ -23,6 +24,7 @@ export const stubbedStartServices: StubbedStartServices = {
licensing: {} as FleetStartServices['licensing'],
storage: {} as FleetStartServices['storage'],
data: {} as FleetStartServices['data'],
unifiedSearch: {} as FleetStartServices['unifiedSearch'],
deprecations: {} as FleetStartServices['deprecations'],
fatalErrors: {} as FleetStartServices['fatalErrors'],
navigation: {} as FleetStartServices['navigation'],

View file

@ -8,7 +8,7 @@
"server": true,
"ui": true,
"configPath": ["xpack", "fleet"],
"requiredPlugins": ["licensing", "data", "encryptedSavedObjects", "navigation", "customIntegrations", "share", "spaces", "security"],
"requiredPlugins": ["licensing", "data", "encryptedSavedObjects", "navigation", "customIntegrations", "share", "spaces", "security", "unifiedSearch"],
"optionalPlugins": ["features", "cloud", "usageCollection", "home", "globalSearch", "telemetry"],
"extraPublicDirs": ["common"],
"requiredBundles": ["kibanaReact", "cloud", "esUiShared", "infra", "kibanaUtils", "usageCollection", "unifiedSearch"]

View file

@ -17,7 +17,7 @@ export const DatasetFilter: React.FunctionComponent<{
selectedDatasets: string[];
onToggleDataset: (dataset: string) => void;
}> = memo(({ selectedDatasets, onToggleDataset }) => {
const { data } = useStartServices();
const { unifiedSearch } = useStartServices();
const [isOpen, setIsOpen] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [datasetValues, setDatasetValues] = useState<string[]>([AGENT_DATASET]);
@ -29,7 +29,7 @@ export const DatasetFilter: React.FunctionComponent<{
const fetchValues = async () => {
setIsLoading(true);
try {
const values = await data.autocomplete.getValueSuggestions({
const values = await unifiedSearch.autocomplete.getValueSuggestions({
indexPattern: {
title: AGENT_LOG_INDEX_PATTERN,
fields: [DATASET_FIELD],
@ -44,7 +44,7 @@ export const DatasetFilter: React.FunctionComponent<{
setIsLoading(false);
};
fetchValues();
}, [data.autocomplete]);
}, [unifiedSearch.autocomplete]);
return (
<EuiPopover

View file

@ -28,7 +28,7 @@ export const LogLevelFilter: React.FunctionComponent<{
selectedLevels: string[];
onToggleLevel: (level: string) => void;
}> = memo(({ selectedLevels, onToggleLevel }) => {
const { data } = useStartServices();
const { unifiedSearch } = useStartServices();
const [isOpen, setIsOpen] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [levelValues, setLevelValues] = useState<string[]>([]);
@ -40,7 +40,7 @@ export const LogLevelFilter: React.FunctionComponent<{
const fetchValues = async () => {
setIsLoading(true);
try {
const values: string[] = await data.autocomplete.getValueSuggestions({
const values: string[] = await unifiedSearch.autocomplete.getValueSuggestions({
indexPattern: {
title: AGENT_LOG_INDEX_PATTERN,
fields: [LOG_LEVEL_FIELD],
@ -55,7 +55,7 @@ export const LogLevelFilter: React.FunctionComponent<{
setIsLoading(false);
};
fetchValues();
}, [data.autocomplete]);
}, [unifiedSearch.autocomplete]);
const noLogsFound = (
<div className="euiFilterSelect__note">

View file

@ -5,6 +5,7 @@
* 2.0.
*/
import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks';
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
import { licensingMock } from '@kbn/licensing-plugin/public/mocks';
import { cloudMock } from '@kbn/cloud-plugin/public/mocks';
@ -27,6 +28,7 @@ export const createStartDepsMock = () => {
return {
licensing: licensingMock.createStart(),
data: dataPluginMock.createStartContract(),
unifiedSearch: unifiedSearchPluginMock.createStartContract(),
navigation: navigationPluginMock.createStartContract(),
customIntegrations: customIntegrationsMock.createStart(),
share: sharePluginMock.createStartContract(),

View file

@ -41,6 +41,8 @@ import type { LicensingPluginStart } from '@kbn/licensing-plugin/public';
import type { CloudSetup } from '@kbn/cloud-plugin/public';
import type { GlobalSearchPluginSetup } from '@kbn/global-search-plugin/public';
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import {
PLUGIN_ID,
INTEGRATIONS_PLUGIN_ID,
@ -92,6 +94,7 @@ export interface FleetSetupDeps {
export interface FleetStartDeps {
licensing: LicensingPluginStart;
data: DataPublicPluginStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
navigation: NavigationPublicPluginStart;
customIntegrations: CustomIntegrationsStart;
share: SharePluginStart;

View file

@ -59,6 +59,8 @@ function getServiceMocks() {
query: {
savedQueries: {},
},
},
unifiedSearch: {
autocomplete: {
hasQuerySuggestions: () => false,
},

Some files were not shown because too many files have changed in this diff Show more