diff --git a/docs/developer/visualize/development-create-visualization.asciidoc b/docs/developer/visualize/development-create-visualization.asciidoc index bddcebcde3aa5..b782428b83135 100644 --- a/docs/developer/visualize/development-create-visualization.asciidoc +++ b/docs/developer/visualize/development-create-visualization.asciidoc @@ -64,7 +64,7 @@ The list of common parameters: - *responseHandler*: one of the available response handlers or a for a custom response handler - *editor*: one of the available editors or Editor class for custom one - *editorConfig*: object holding editor parameters -- *options.showTimePicker*: show or hide time picker (defaults to true) +- *options.showTimePicker*: show or hide time filter (defaults to true) - *options.showQueryBar*: show or hide query bar (defaults to true) - *options.showFilterBar*: show or hide filter bar (defaults to true) - *options.showIndexSelection*: show or hide index selection (defaults to true) @@ -275,7 +275,7 @@ VisTypesRegistryProvider.register(MyNewVisType); [[development-visualization-request-handlers]] === Visualization Request Handlers Request handler gets called when one of the following keys on AppState change: -`vis`, `query`, `filters` or `uiState` and when timepicker is updated. On top +`vis`, `query`, `filters` or `uiState` and when the time filter is updated. On top of that it will also get called on force refresh. By default visualizations will use the `courier` request handler. They can also choose to use any of the other provided @@ -417,7 +417,7 @@ The `vis` object holds the visualization state and is the window into kibana: - *vis.getUiState()*: gets UI state of visualization - *vis.uiStateVal(name, val)*: updates a property in UI state - *vis.isEditorMode()*: returns true if in editor mode -- *vis.API.timeFilter*: allows you to access time picker +- *vis.API.timeFilter*: allows you to access time filter - *vis.API.queryFilter*: gives you access to queryFilter - *vis.API.events.click*: default click handler - *vis.API.events.brush*: default brush handler @@ -430,12 +430,12 @@ visualization's render method. For the parameters that should not be saved with the visualization you should use the UI state. These hold viewer-specific state, such as popup open/closed, custom colors applied to the series etc. -You can access filter bar and time picker through the objects defined on `vis.API` +You can access the filter bar and time filter through the objects defined on `vis.API` [[development-vis-timefilter]] ==== timeFilter -Update the timefilter time values and call update() method on it to update time picker +Update the timefilter time values and call update() method on it to update the time filter ["source","js"] ----------- diff --git a/docs/development/core/server/kibana-plugin-server.apicaller.md b/docs/development/core/server/kibana-plugin-server.apicaller.md index 10065a4089ce5..9fd50ea5c4b66 100644 --- a/docs/development/core/server/kibana-plugin-server.apicaller.md +++ b/docs/development/core/server/kibana-plugin-server.apicaller.md @@ -2,11 +2,11 @@ [Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [APICaller](./kibana-plugin-server.apicaller.md) -## APICaller type +## APICaller interface Signature: ```typescript -export declare type APICaller = (endpoint: string, clientParams: Record, options?: CallAPIOptions) => Promise; +export interface APICaller ``` diff --git a/docs/development/core/server/kibana-plugin-server.assistanceapiresponse.indices.md b/docs/development/core/server/kibana-plugin-server.assistanceapiresponse.indices.md new file mode 100644 index 0000000000000..307cd3bb5ae21 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.assistanceapiresponse.indices.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [AssistanceAPIResponse](./kibana-plugin-server.assistanceapiresponse.md) > [indices](./kibana-plugin-server.assistanceapiresponse.indices.md) + +## AssistanceAPIResponse.indices property + +Signature: + +```typescript +indices: { + [indexName: string]: { + action_required: MIGRATION_ASSISTANCE_INDEX_ACTION; + }; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-server.assistanceapiresponse.md b/docs/development/core/server/kibana-plugin-server.assistanceapiresponse.md new file mode 100644 index 0000000000000..8e8dfb07ca08a --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.assistanceapiresponse.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [AssistanceAPIResponse](./kibana-plugin-server.assistanceapiresponse.md) + +## AssistanceAPIResponse interface + +Signature: + +```typescript +export interface AssistanceAPIResponse +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [indices](./kibana-plugin-server.assistanceapiresponse.indices.md) | {
[indexName: string]: {
action_required: MIGRATION_ASSISTANCE_INDEX_ACTION;
};
} | | + diff --git a/docs/development/core/server/kibana-plugin-server.assistantapiclientparams.md b/docs/development/core/server/kibana-plugin-server.assistantapiclientparams.md new file mode 100644 index 0000000000000..eb03b943a30ef --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.assistantapiclientparams.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [AssistantAPIClientParams](./kibana-plugin-server.assistantapiclientparams.md) + +## AssistantAPIClientParams interface + +Signature: + +```typescript +export interface AssistantAPIClientParams extends GenericParams +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [method](./kibana-plugin-server.assistantapiclientparams.method.md) | 'GET' | | +| [path](./kibana-plugin-server.assistantapiclientparams.path.md) | '/_migration/assistance' | | + diff --git a/docs/development/core/server/kibana-plugin-server.assistantapiclientparams.method.md b/docs/development/core/server/kibana-plugin-server.assistantapiclientparams.method.md new file mode 100644 index 0000000000000..feeb4403ca0a3 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.assistantapiclientparams.method.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [AssistantAPIClientParams](./kibana-plugin-server.assistantapiclientparams.md) > [method](./kibana-plugin-server.assistantapiclientparams.method.md) + +## AssistantAPIClientParams.method property + +Signature: + +```typescript +method: 'GET'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.assistantapiclientparams.path.md b/docs/development/core/server/kibana-plugin-server.assistantapiclientparams.path.md new file mode 100644 index 0000000000000..3b82c477993e0 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.assistantapiclientparams.path.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [AssistantAPIClientParams](./kibana-plugin-server.assistantapiclientparams.md) > [path](./kibana-plugin-server.assistantapiclientparams.path.md) + +## AssistantAPIClientParams.path property + +Signature: + +```typescript +path: '/_migration/assistance'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.clusterclient.asscoped.md b/docs/development/core/server/kibana-plugin-server.clusterclient.asscoped.md index d649eab42f086..f87fc34bdc45f 100644 --- a/docs/development/core/server/kibana-plugin-server.clusterclient.asscoped.md +++ b/docs/development/core/server/kibana-plugin-server.clusterclient.asscoped.md @@ -9,7 +9,7 @@ Creates an instance of `ScopedClusterClient` based on the configuration the curr Signature: ```typescript -asScoped(request?: KibanaRequest | LegacyRequest | FakeRequest): ScopedClusterClient; +asScoped(request?: KibanaRequest | LegacyRequest | FakeRequest): IScopedClusterClient; ``` ## Parameters @@ -20,5 +20,5 @@ asScoped(request?: KibanaRequest | LegacyRequest | FakeRequest): ScopedClusterCl Returns: -`ScopedClusterClient` +`IScopedClusterClient` diff --git a/docs/development/core/server/kibana-plugin-server.clusterclient.callasinternaluser.md b/docs/development/core/server/kibana-plugin-server.clusterclient.callasinternaluser.md index 0b314c5670365..74003189c765d 100644 --- a/docs/development/core/server/kibana-plugin-server.clusterclient.callasinternaluser.md +++ b/docs/development/core/server/kibana-plugin-server.clusterclient.callasinternaluser.md @@ -9,5 +9,5 @@ Calls specified endpoint with provided clientParams on behalf of the Kibana inte Signature: ```typescript -callAsInternalUser: (endpoint: string, clientParams?: Record, options?: CallAPIOptions | undefined) => Promise; +callAsInternalUser: APICaller; ``` diff --git a/docs/development/core/server/kibana-plugin-server.clusterclient.md b/docs/development/core/server/kibana-plugin-server.clusterclient.md index a23b30fd184c6..6288bc0a07c11 100644 --- a/docs/development/core/server/kibana-plugin-server.clusterclient.md +++ b/docs/development/core/server/kibana-plugin-server.clusterclient.md @@ -6,10 +6,12 @@ Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`). +See [ClusterClient](./kibana-plugin-server.clusterclient.md). + Signature: ```typescript -export declare class ClusterClient +export declare class ClusterClient implements IClusterClient ``` ## Constructors @@ -22,7 +24,7 @@ export declare class ClusterClient | Property | Modifiers | Type | Description | | --- | --- | --- | --- | -| [callAsInternalUser](./kibana-plugin-server.clusterclient.callasinternaluser.md) | | (endpoint: string, clientParams?: Record<string, any>, options?: CallAPIOptions | undefined) => Promise<any> | Calls specified endpoint with provided clientParams on behalf of the Kibana internal user. | +| [callAsInternalUser](./kibana-plugin-server.clusterclient.callasinternaluser.md) | | APICaller | Calls specified endpoint with provided clientParams on behalf of the Kibana internal user. | ## Methods diff --git a/docs/development/core/server/kibana-plugin-server.coresetup.elasticsearch.md b/docs/development/core/server/kibana-plugin-server.coresetup.elasticsearch.md index cd99eabe1e1e5..dfe1839babdad 100644 --- a/docs/development/core/server/kibana-plugin-server.coresetup.elasticsearch.md +++ b/docs/development/core/server/kibana-plugin-server.coresetup.elasticsearch.md @@ -8,8 +8,8 @@ ```typescript elasticsearch: { - adminClient$: Observable; - dataClient$: Observable; - createClient: (type: string, clientConfig?: Partial) => ClusterClient; + adminClient$: Observable; + dataClient$: Observable; + createClient: (type: string, clientConfig?: Partial) => IClusterClient; }; ``` diff --git a/docs/development/core/server/kibana-plugin-server.coresetup.md b/docs/development/core/server/kibana-plugin-server.coresetup.md index 528557e91bd17..a53f807d001bd 100644 --- a/docs/development/core/server/kibana-plugin-server.coresetup.md +++ b/docs/development/core/server/kibana-plugin-server.coresetup.md @@ -17,6 +17,6 @@ export interface CoreSetup | Property | Type | Description | | --- | --- | --- | | [context](./kibana-plugin-server.coresetup.context.md) | {
createContextContainer: ContextSetup['createContextContainer'];
} | | -| [elasticsearch](./kibana-plugin-server.coresetup.elasticsearch.md) | {
adminClient$: Observable<ClusterClient>;
dataClient$: Observable<ClusterClient>;
createClient: (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ClusterClient;
} | | +| [elasticsearch](./kibana-plugin-server.coresetup.elasticsearch.md) | {
adminClient$: Observable<IClusterClient>;
dataClient$: Observable<IClusterClient>;
createClient: (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => IClusterClient;
} | | | [http](./kibana-plugin-server.coresetup.http.md) | {
createCookieSessionStorageFactory: HttpServiceSetup['createCookieSessionStorageFactory'];
registerOnPreAuth: HttpServiceSetup['registerOnPreAuth'];
registerAuth: HttpServiceSetup['registerAuth'];
registerOnPostAuth: HttpServiceSetup['registerOnPostAuth'];
basePath: HttpServiceSetup['basePath'];
isTlsEnabled: HttpServiceSetup['isTlsEnabled'];
registerRouteHandlerContext: <T extends keyof RequestHandlerContext>(name: T, provider: RequestHandlerContextProvider<T>) => RequestHandlerContextContainer;
createRouter: () => IRouter;
} | | diff --git a/docs/development/core/server/kibana-plugin-server.deprecationapiclientparams.md b/docs/development/core/server/kibana-plugin-server.deprecationapiclientparams.md new file mode 100644 index 0000000000000..3dfe6b181a3d3 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationapiclientparams.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationAPIClientParams](./kibana-plugin-server.deprecationapiclientparams.md) + +## DeprecationAPIClientParams interface + +Signature: + +```typescript +export interface DeprecationAPIClientParams extends GenericParams +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [method](./kibana-plugin-server.deprecationapiclientparams.method.md) | 'GET' | | +| [path](./kibana-plugin-server.deprecationapiclientparams.path.md) | '/_migration/deprecations' | | + diff --git a/docs/development/core/server/kibana-plugin-server.deprecationapiclientparams.method.md b/docs/development/core/server/kibana-plugin-server.deprecationapiclientparams.method.md new file mode 100644 index 0000000000000..7b9364009923b --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationapiclientparams.method.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationAPIClientParams](./kibana-plugin-server.deprecationapiclientparams.md) > [method](./kibana-plugin-server.deprecationapiclientparams.method.md) + +## DeprecationAPIClientParams.method property + +Signature: + +```typescript +method: 'GET'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.deprecationapiclientparams.path.md b/docs/development/core/server/kibana-plugin-server.deprecationapiclientparams.path.md new file mode 100644 index 0000000000000..dbddedf75171d --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationapiclientparams.path.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationAPIClientParams](./kibana-plugin-server.deprecationapiclientparams.md) > [path](./kibana-plugin-server.deprecationapiclientparams.path.md) + +## DeprecationAPIClientParams.path property + +Signature: + +```typescript +path: '/_migration/deprecations'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.cluster_settings.md b/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.cluster_settings.md new file mode 100644 index 0000000000000..5af134100407c --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.cluster_settings.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationAPIResponse](./kibana-plugin-server.deprecationapiresponse.md) > [cluster\_settings](./kibana-plugin-server.deprecationapiresponse.cluster_settings.md) + +## DeprecationAPIResponse.cluster\_settings property + +Signature: + +```typescript +cluster_settings: DeprecationInfo[]; +``` diff --git a/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.index_settings.md b/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.index_settings.md new file mode 100644 index 0000000000000..c8d20c9696f63 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.index_settings.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationAPIResponse](./kibana-plugin-server.deprecationapiresponse.md) > [index\_settings](./kibana-plugin-server.deprecationapiresponse.index_settings.md) + +## DeprecationAPIResponse.index\_settings property + +Signature: + +```typescript +index_settings: IndexSettingsDeprecationInfo; +``` diff --git a/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.md b/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.md new file mode 100644 index 0000000000000..8ebe61f4efaa5 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationAPIResponse](./kibana-plugin-server.deprecationapiresponse.md) + +## DeprecationAPIResponse interface + +Signature: + +```typescript +export interface DeprecationAPIResponse +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [cluster\_settings](./kibana-plugin-server.deprecationapiresponse.cluster_settings.md) | DeprecationInfo[] | | +| [index\_settings](./kibana-plugin-server.deprecationapiresponse.index_settings.md) | IndexSettingsDeprecationInfo | | +| [ml\_settings](./kibana-plugin-server.deprecationapiresponse.ml_settings.md) | DeprecationInfo[] | | +| [node\_settings](./kibana-plugin-server.deprecationapiresponse.node_settings.md) | DeprecationInfo[] | | + diff --git a/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.ml_settings.md b/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.ml_settings.md new file mode 100644 index 0000000000000..5a4e273df69a6 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.ml_settings.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationAPIResponse](./kibana-plugin-server.deprecationapiresponse.md) > [ml\_settings](./kibana-plugin-server.deprecationapiresponse.ml_settings.md) + +## DeprecationAPIResponse.ml\_settings property + +Signature: + +```typescript +ml_settings: DeprecationInfo[]; +``` diff --git a/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.node_settings.md b/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.node_settings.md new file mode 100644 index 0000000000000..5901c49d0edf1 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationapiresponse.node_settings.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationAPIResponse](./kibana-plugin-server.deprecationapiresponse.md) > [node\_settings](./kibana-plugin-server.deprecationapiresponse.node_settings.md) + +## DeprecationAPIResponse.node\_settings property + +Signature: + +```typescript +node_settings: DeprecationInfo[]; +``` diff --git a/docs/development/core/server/kibana-plugin-server.deprecationinfo.details.md b/docs/development/core/server/kibana-plugin-server.deprecationinfo.details.md new file mode 100644 index 0000000000000..17dbeff942255 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationinfo.details.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationInfo](./kibana-plugin-server.deprecationinfo.md) > [details](./kibana-plugin-server.deprecationinfo.details.md) + +## DeprecationInfo.details property + +Signature: + +```typescript +details?: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.deprecationinfo.level.md b/docs/development/core/server/kibana-plugin-server.deprecationinfo.level.md new file mode 100644 index 0000000000000..99b629bbbb8cc --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationinfo.level.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationInfo](./kibana-plugin-server.deprecationinfo.md) > [level](./kibana-plugin-server.deprecationinfo.level.md) + +## DeprecationInfo.level property + +Signature: + +```typescript +level: MIGRATION_DEPRECATION_LEVEL; +``` diff --git a/docs/development/core/server/kibana-plugin-server.deprecationinfo.md b/docs/development/core/server/kibana-plugin-server.deprecationinfo.md new file mode 100644 index 0000000000000..21c10bde26378 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationinfo.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationInfo](./kibana-plugin-server.deprecationinfo.md) + +## DeprecationInfo interface + +Signature: + +```typescript +export interface DeprecationInfo +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [details](./kibana-plugin-server.deprecationinfo.details.md) | string | | +| [level](./kibana-plugin-server.deprecationinfo.level.md) | MIGRATION_DEPRECATION_LEVEL | | +| [message](./kibana-plugin-server.deprecationinfo.message.md) | string | | +| [url](./kibana-plugin-server.deprecationinfo.url.md) | string | | + diff --git a/docs/development/core/server/kibana-plugin-server.deprecationinfo.message.md b/docs/development/core/server/kibana-plugin-server.deprecationinfo.message.md new file mode 100644 index 0000000000000..f027ac83f3b6e --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationinfo.message.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationInfo](./kibana-plugin-server.deprecationinfo.md) > [message](./kibana-plugin-server.deprecationinfo.message.md) + +## DeprecationInfo.message property + +Signature: + +```typescript +message: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.deprecationinfo.url.md b/docs/development/core/server/kibana-plugin-server.deprecationinfo.url.md new file mode 100644 index 0000000000000..4fdc9d544b7ff --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.deprecationinfo.url.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [DeprecationInfo](./kibana-plugin-server.deprecationinfo.md) > [url](./kibana-plugin-server.deprecationinfo.url.md) + +## DeprecationInfo.url property + +Signature: + +```typescript +url: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.adminclient_.md b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.adminclient_.md index f118941cad602..31cf07ac66a46 100644 --- a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.adminclient_.md +++ b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.adminclient_.md @@ -7,5 +7,5 @@ Signature: ```typescript -readonly adminClient$: Observable; +readonly adminClient$: Observable; ``` diff --git a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.createclient.md b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.createclient.md index c29d3fbbf69ab..34d04d26e9654 100644 --- a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.createclient.md +++ b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.createclient.md @@ -9,7 +9,7 @@ Create application specific Elasticsearch cluster API client with customized con Signature: ```typescript -readonly createClient: (type: string, clientConfig?: Partial) => ClusterClient; +readonly createClient: (type: string, clientConfig?: Partial) => IClusterClient; ``` ## Example diff --git a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.dataclient_.md b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.dataclient_.md index 599e7af0f7757..240dff2e53635 100644 --- a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.dataclient_.md +++ b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.dataclient_.md @@ -7,5 +7,5 @@ Signature: ```typescript -readonly dataClient$: Observable; +readonly dataClient$: Observable; ``` diff --git a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.md b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.md index 53fb66ade0517..9c3b92a88fe07 100644 --- a/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.md +++ b/docs/development/core/server/kibana-plugin-server.elasticsearchservicesetup.md @@ -15,8 +15,8 @@ export interface ElasticsearchServiceSetup | Property | Type | Description | | --- | --- | --- | -| [adminClient$](./kibana-plugin-server.elasticsearchservicesetup.adminclient_.md) | Observable<ClusterClient> | | -| [createClient](./kibana-plugin-server.elasticsearchservicesetup.createclient.md) | (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ClusterClient | Create application specific Elasticsearch cluster API client with customized config. | -| [dataClient$](./kibana-plugin-server.elasticsearchservicesetup.dataclient_.md) | Observable<ClusterClient> | | +| [adminClient$](./kibana-plugin-server.elasticsearchservicesetup.adminclient_.md) | Observable<IClusterClient> | | +| [createClient](./kibana-plugin-server.elasticsearchservicesetup.createclient.md) | (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => IClusterClient | Create application specific Elasticsearch cluster API client with customized config. | +| [dataClient$](./kibana-plugin-server.elasticsearchservicesetup.dataclient_.md) | Observable<IClusterClient> | | | [legacy](./kibana-plugin-server.elasticsearchservicesetup.legacy.md) | {
readonly config$: Observable<ElasticsearchConfig>;
} | | diff --git a/docs/development/core/server/kibana-plugin-server.iclusterclient.md b/docs/development/core/server/kibana-plugin-server.iclusterclient.md new file mode 100644 index 0000000000000..834afa6db5157 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.iclusterclient.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [IClusterClient](./kibana-plugin-server.iclusterclient.md) + +## IClusterClient type + +Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via `asScoped(...)`). + +See [ClusterClient](./kibana-plugin-server.clusterclient.md). + +Signature: + +```typescript +export declare type IClusterClient = Pick; +``` diff --git a/docs/development/core/server/kibana-plugin-server.indexsettingsdeprecationinfo.md b/docs/development/core/server/kibana-plugin-server.indexsettingsdeprecationinfo.md new file mode 100644 index 0000000000000..8fd0c6bb9f997 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.indexsettingsdeprecationinfo.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [IndexSettingsDeprecationInfo](./kibana-plugin-server.indexsettingsdeprecationinfo.md) + +## IndexSettingsDeprecationInfo interface + +Signature: + +```typescript +export interface IndexSettingsDeprecationInfo +``` diff --git a/docs/development/core/server/kibana-plugin-server.iscopedclusterclient.md b/docs/development/core/server/kibana-plugin-server.iscopedclusterclient.md new file mode 100644 index 0000000000000..becd1d26d2473 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.iscopedclusterclient.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [IScopedClusterClient](./kibana-plugin-server.iscopedclusterclient.md) + +## IScopedClusterClient type + +Serves the same purpose as "normal" `ClusterClient` but exposes additional `callAsCurrentUser` method that doesn't use credentials of the Kibana internal user (as `callAsInternalUser` does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API. + +See [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md). + +Signature: + +```typescript +export declare type IScopedClusterClient = Pick; +``` diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md index 3c01e7aeef325..1247c52a5704b 100644 --- a/docs/development/core/server/kibana-plugin-server.md +++ b/docs/development/core/server/kibana-plugin-server.md @@ -17,11 +17,11 @@ The plugin integrates with the core system via lifecycle events: `setup` | Class | Description | | --- | --- | | [BasePath](./kibana-plugin-server.basepath.md) | Access or manipulate the Kibana base path | -| [ClusterClient](./kibana-plugin-server.clusterclient.md) | Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)). | +| [ClusterClient](./kibana-plugin-server.clusterclient.md) | Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)).See [ClusterClient](./kibana-plugin-server.clusterclient.md). | | [ElasticsearchErrorHelpers](./kibana-plugin-server.elasticsearcherrorhelpers.md) | Helpers for working with errors returned from the Elasticsearch service.Since the internal data of errors are subject to change, consumers of the Elasticsearch service should always use these helpers to classify errors instead of checking error internals such as body.error.header[WWW-Authenticate] | | [KibanaRequest](./kibana-plugin-server.kibanarequest.md) | Kibana specific abstraction for an incoming request. | | [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md) | | -| [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md) | Serves the same purpose as "normal" ClusterClient but exposes additional callAsCurrentUser method that doesn't use credentials of the Kibana internal user (as callAsInternalUser does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API | +| [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md) | Serves the same purpose as "normal" ClusterClient but exposes additional callAsCurrentUser method that doesn't use credentials of the Kibana internal user (as callAsInternalUser does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API.See [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md). | ## Enumerations @@ -33,6 +33,9 @@ The plugin integrates with the core system via lifecycle events: `setup` | Interface | Description | | --- | --- | +| [APICaller](./kibana-plugin-server.apicaller.md) | | +| [AssistanceAPIResponse](./kibana-plugin-server.assistanceapiresponse.md) | | +| [AssistantAPIClientParams](./kibana-plugin-server.assistantapiclientparams.md) | | | [AuthResultParams](./kibana-plugin-server.authresultparams.md) | Result of an incoming request authentication. | | [AuthToolkit](./kibana-plugin-server.authtoolkit.md) | A tool set defining an outcome of Auth interceptor for incoming request. | | [CallAPIOptions](./kibana-plugin-server.callapioptions.md) | The set of options that defines how API call should be made and result be processed. | @@ -40,6 +43,9 @@ The plugin integrates with the core system via lifecycle events: `setup` | [CoreSetup](./kibana-plugin-server.coresetup.md) | Context passed to the plugins setup method. | | [CoreStart](./kibana-plugin-server.corestart.md) | Context passed to the plugins start method. | | [CustomHttpResponseOptions](./kibana-plugin-server.customhttpresponseoptions.md) | HTTP response parameters for a response with adjustable status code. | +| [DeprecationAPIClientParams](./kibana-plugin-server.deprecationapiclientparams.md) | | +| [DeprecationAPIResponse](./kibana-plugin-server.deprecationapiresponse.md) | | +| [DeprecationInfo](./kibana-plugin-server.deprecationinfo.md) | | | [DiscoveredPlugin](./kibana-plugin-server.discoveredplugin.md) | Small container object used to expose information about discovered plugins that may or may not have been started. | | [ElasticsearchError](./kibana-plugin-server.elasticsearcherror.md) | | | [ElasticsearchServiceSetup](./kibana-plugin-server.elasticsearchservicesetup.md) | | @@ -50,6 +56,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [HttpServiceStart](./kibana-plugin-server.httpservicestart.md) | | | [IContextContainer](./kibana-plugin-server.icontextcontainer.md) | An object that handles registration of context providers and configuring handlers with context. | | [IKibanaSocket](./kibana-plugin-server.ikibanasocket.md) | A tiny abstraction for TCP socket. | +| [IndexSettingsDeprecationInfo](./kibana-plugin-server.indexsettingsdeprecationinfo.md) | | | [IRouter](./kibana-plugin-server.irouter.md) | Registers route handlers for specified resource path and method. | | [KibanaRequestRoute](./kibana-plugin-server.kibanarequestroute.md) | Request specific route information exposed to a handler. | | [LegacyRequest](./kibana-plugin-server.legacyrequest.md) | | @@ -109,7 +116,6 @@ The plugin integrates with the core system via lifecycle events: `setup` | Type Alias | Description | | --- | --- | -| [APICaller](./kibana-plugin-server.apicaller.md) | | | [AuthenticationHandler](./kibana-plugin-server.authenticationhandler.md) | | | [AuthHeaders](./kibana-plugin-server.authheaders.md) | Auth Headers map | | [ConfigPath](./kibana-plugin-server.configpath.md) | | @@ -123,11 +129,15 @@ The plugin integrates with the core system via lifecycle events: `setup` | [HttpResponsePayload](./kibana-plugin-server.httpresponsepayload.md) | Data send to the client as a response payload. | | [HttpServiceSetup](./kibana-plugin-server.httpservicesetup.md) | | | [IBasePath](./kibana-plugin-server.ibasepath.md) | Access or manipulate the Kibana base path[BasePath](./kibana-plugin-server.basepath.md) | +| [IClusterClient](./kibana-plugin-server.iclusterclient.md) | Represents an Elasticsearch cluster API client and allows to call API on behalf of the internal Kibana user and the actual user that is derived from the request headers (via asScoped(...)).See [ClusterClient](./kibana-plugin-server.clusterclient.md). | | [IContextProvider](./kibana-plugin-server.icontextprovider.md) | A function that returns a context value for a specific key of given context type. | | [IsAuthenticated](./kibana-plugin-server.isauthenticated.md) | Return authentication status for a request. | +| [IScopedClusterClient](./kibana-plugin-server.iscopedclusterclient.md) | Serves the same purpose as "normal" ClusterClient but exposes additional callAsCurrentUser method that doesn't use credentials of the Kibana internal user (as callAsInternalUser does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API.See [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md). | | [KibanaResponseFactory](./kibana-plugin-server.kibanaresponsefactory.md) | Creates an object containing request response payload, HTTP headers, error details, and other data transmitted to the client. | | [KnownHeaders](./kibana-plugin-server.knownheaders.md) | Set of well-known HTTP headers. | | [LifecycleResponseFactory](./kibana-plugin-server.lifecycleresponsefactory.md) | Creates an object containing redirection or error response with error details, HTTP headers, and other data transmitted to the client. | +| [MIGRATION\_ASSISTANCE\_INDEX\_ACTION](./kibana-plugin-server.migration_assistance_index_action.md) | | +| [MIGRATION\_DEPRECATION\_LEVEL](./kibana-plugin-server.migration_deprecation_level.md) | | | [OnPostAuthHandler](./kibana-plugin-server.onpostauthhandler.md) | | | [OnPreAuthHandler](./kibana-plugin-server.onpreauthhandler.md) | | | [PluginInitializer](./kibana-plugin-server.plugininitializer.md) | The plugin export at the root of a plugin's server directory should conform to this interface. | diff --git a/docs/development/core/server/kibana-plugin-server.migration_assistance_index_action.md b/docs/development/core/server/kibana-plugin-server.migration_assistance_index_action.md new file mode 100644 index 0000000000000..4753bd0db71f6 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.migration_assistance_index_action.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [MIGRATION\_ASSISTANCE\_INDEX\_ACTION](./kibana-plugin-server.migration_assistance_index_action.md) + +## MIGRATION\_ASSISTANCE\_INDEX\_ACTION type + +Signature: + +```typescript +export declare type MIGRATION_ASSISTANCE_INDEX_ACTION = 'upgrade' | 'reindex'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.migration_deprecation_level.md b/docs/development/core/server/kibana-plugin-server.migration_deprecation_level.md new file mode 100644 index 0000000000000..2751faf6a1cd9 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.migration_deprecation_level.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [MIGRATION\_DEPRECATION\_LEVEL](./kibana-plugin-server.migration_deprecation_level.md) + +## MIGRATION\_DEPRECATION\_LEVEL type + +Signature: + +```typescript +export declare type MIGRATION_DEPRECATION_LEVEL = 'none' | 'info' | 'warning' | 'critical'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.requesthandlercontext.core.md b/docs/development/core/server/kibana-plugin-server.requesthandlercontext.core.md index 3274db0cf508d..d06b3b9ea637c 100644 --- a/docs/development/core/server/kibana-plugin-server.requesthandlercontext.core.md +++ b/docs/development/core/server/kibana-plugin-server.requesthandlercontext.core.md @@ -9,8 +9,8 @@ ```typescript core: { elasticsearch: { - dataClient: ScopedClusterClient; - adminClient: ScopedClusterClient; + dataClient: IScopedClusterClient; + adminClient: IScopedClusterClient; }; }; ``` diff --git a/docs/development/core/server/kibana-plugin-server.requesthandlercontext.md b/docs/development/core/server/kibana-plugin-server.requesthandlercontext.md index d7498f04733dd..85c7989c6e863 100644 --- a/docs/development/core/server/kibana-plugin-server.requesthandlercontext.md +++ b/docs/development/core/server/kibana-plugin-server.requesthandlercontext.md @@ -16,5 +16,5 @@ export interface RequestHandlerContext | Property | Type | Description | | --- | --- | --- | -| [core](./kibana-plugin-server.requesthandlercontext.core.md) | {
elasticsearch: {
dataClient: ScopedClusterClient;
adminClient: ScopedClusterClient;
};
} | | +| [core](./kibana-plugin-server.requesthandlercontext.core.md) | {
elasticsearch: {
dataClient: IScopedClusterClient;
adminClient: IScopedClusterClient;
};
} | | diff --git a/docs/development/core/server/kibana-plugin-server.scopedclusterclient.callascurrentuser.md b/docs/development/core/server/kibana-plugin-server.scopedclusterclient.callascurrentuser.md index f96554296e653..ce0c51be08698 100644 --- a/docs/development/core/server/kibana-plugin-server.scopedclusterclient.callascurrentuser.md +++ b/docs/development/core/server/kibana-plugin-server.scopedclusterclient.callascurrentuser.md @@ -9,7 +9,7 @@ Calls specified `endpoint` with provided `clientParams` on behalf of the user in Signature: ```typescript -callAsCurrentUser(endpoint: string, clientParams?: Record, options?: CallAPIOptions): Promise; +callAsCurrentUser(endpoint: string, clientParams?: Record, options?: CallAPIOptions): Promise; ``` ## Parameters @@ -22,5 +22,5 @@ callAsCurrentUser(endpoint: string, clientParams?: Record, options? Returns: -`Promise` +`Promise` diff --git a/docs/development/core/server/kibana-plugin-server.scopedclusterclient.callasinternaluser.md b/docs/development/core/server/kibana-plugin-server.scopedclusterclient.callasinternaluser.md index 395d65197e2cc..59811de18d926 100644 --- a/docs/development/core/server/kibana-plugin-server.scopedclusterclient.callasinternaluser.md +++ b/docs/development/core/server/kibana-plugin-server.scopedclusterclient.callasinternaluser.md @@ -9,7 +9,7 @@ Calls specified `endpoint` with provided `clientParams` on behalf of the Kibana Signature: ```typescript -callAsInternalUser(endpoint: string, clientParams?: Record, options?: CallAPIOptions): Promise; +callAsInternalUser(endpoint: string, clientParams?: Record, options?: CallAPIOptions): Promise; ``` ## Parameters @@ -22,5 +22,5 @@ callAsInternalUser(endpoint: string, clientParams?: Record, options Returns: -`Promise` +`Promise` diff --git a/docs/development/core/server/kibana-plugin-server.scopedclusterclient.md b/docs/development/core/server/kibana-plugin-server.scopedclusterclient.md index 817beced3346d..7833f698d486d 100644 --- a/docs/development/core/server/kibana-plugin-server.scopedclusterclient.md +++ b/docs/development/core/server/kibana-plugin-server.scopedclusterclient.md @@ -4,12 +4,14 @@ ## ScopedClusterClient class -Serves the same purpose as "normal" `ClusterClient` but exposes additional `callAsCurrentUser` method that doesn't use credentials of the Kibana internal user (as `callAsInternalUser` does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API +Serves the same purpose as "normal" `ClusterClient` but exposes additional `callAsCurrentUser` method that doesn't use credentials of the Kibana internal user (as `callAsInternalUser` does) to request Elasticsearch API, but rather passes HTTP headers extracted from the current user request to the API. + +See [ScopedClusterClient](./kibana-plugin-server.scopedclusterclient.md). Signature: ```typescript -export declare class ScopedClusterClient +export declare class ScopedClusterClient implements IScopedClusterClient ``` ## Constructors diff --git a/docs/discover/autorefresh.asciidoc b/docs/discover/autorefresh.asciidoc deleted file mode 100644 index 1929f7a24dcc1..0000000000000 --- a/docs/discover/autorefresh.asciidoc +++ /dev/null @@ -1,19 +0,0 @@ -=== Refreshing the Search Results -You can configure a refresh interval to automatically refresh the page with the latest index data. This periodically -resubmits the search query. - -When a refresh interval is set, it is displayed to the left of the Time Filter in the menu bar. - -To set the refresh interval: - -. Click the *Time Filter* image:images/TimeFilter.jpg[Time Filter]. -. Click the *Refresh Interval* tab. -. Choose a refresh interval from the list. - -To automatically refresh the data, click the image:images/autorefresh.png[] *Auto-refresh* button when the time picker -is open and select an autorefresh interval: - -image::images/autorefresh-intervals.png[] - -When auto-refresh is enabled, Kibana's top bar displays a pause button and the auto-refresh interval: -image:images/autorefresh-pause.png[]. Click the *Pause* button to pause auto-refresh. diff --git a/docs/discover/search.asciidoc b/docs/discover/search.asciidoc index 790cc669927c1..cfca4f2fc092b 100644 --- a/docs/discover/search.asciidoc +++ b/docs/discover/search.asciidoc @@ -1,5 +1,5 @@ [[search]] -== Searching Your Data +== Searching your data You can search the indices that match the current index pattern by entering your search criteria in the Query bar. By default you can use Kibana's standard query language which features autocomplete and a simple, easy to use syntax. Kibana's legacy query @@ -24,7 +24,7 @@ the request to Elasticsearch. include::kuery.asciidoc[] [[lucene-query]] -=== Lucene Query Syntax +=== Lucene query syntax Kibana's legacy query language was based on the Lucene query syntax. For the time being this syntax is still available under the options menu in the Query Bar and in Advanced Settings. The following are some tips that can help get you started. @@ -70,7 +70,7 @@ Kibana see <>. [role="screenshot"] image::discover/images/read-only-badge.png[Example of Discover's read only access indicator in Kibana's header] -==== Saving a Search +==== Save a search To save the current search: . Click *Save* in the Kibana toolbar. @@ -78,7 +78,7 @@ To save the current search: You can import, export and delete saved searches from *Management/Kibana/Saved Objects*. -==== Opening a Saved Search +==== Open a saved search To load a saved search into Discover: . Click *Open* in the Kibana toolbar. @@ -102,7 +102,7 @@ Saved queries don't include information specific to Discover, such as the curren ==== Read only access If you have insufficient privileges to save queries, the *Save current query* button isn't visible in the saved query management popover. For more information, see <> -==== Saving a query +==== Save a query To save the current query text, filters, and time filter: . Click *#* in the search bar, next to the query text input. @@ -117,13 +117,13 @@ image::discover/images/saved-query-management-component-all-privileges.png["Exam image::discover/images/saved-query-save-form-default-filters.png["Example of the saved query management save form with the filters option included and the time filter option excluded",width="80%"] . Click *Save*. -==== Loading a query +==== Load a query To load a saved query into Discover, Dashboard, or Visualize: . Click *#* in the search bar, next to the query text input. . Select the query you want to load. You might need to scroll down to find the query you are looking for. -==== Saving changes to a query +==== Save changes to a query If you load a query and then make changes to the query text, the filters, or the time filter, you can save the changes as a new query or update the existing query. To save the changes as a new query: @@ -143,13 +143,13 @@ To save the changes to the current query: . Enter a description, and then select the filter options that you want to include. . Click *Save*. -==== Clearing a query +==== Clear a query To clear a query that is currently loaded in an application: . Click *#* in the search bar. . Click *Clear* in the popover. -==== Deleting a query +==== Delete a query To completely delete a query: . Click *#* in the search bar, next to the query text input. @@ -162,7 +162,7 @@ image::discover/images/saved-query-management-component-delete-query-button.png[ You can import, export, and delete saved queries from <>. [[select-pattern]] -=== Changing Which Indices You're Searching +=== Change the indices you're searching When you submit a search request, the indices that match the currently-selected index pattern are searched. The current index pattern is shown below the toolbar. To change which indices you are searching, click the index pattern and select a @@ -172,24 +172,22 @@ For more information about index patterns, see <>. [[autorefresh]] -=== Refreshing the Search Results +=== Refresh the search results As more documents are added to the indices you're searching, the search results shown in Discover and used to display visualizations get stale. You can configure a refresh interval to periodically resubmit your searches to retrieve the latest results. -To enable auto refresh: +. Click image:images/time-filter-calendar.png[]. -. Click the *Time Picker* image:images/time-picker.jpg[Time Picker] in the -Kibana toolbar. -. Click *Auto refresh*. -. Choose a refresh interval from the list. +. In the *Refresh every* field, enter the refresh rate, then select the interval + from the dropdown. + +. Click *Start*. + image::images/autorefresh-intervals.png[] -When auto refresh is enabled, the refresh interval is displayed next to the -Time Picker, along with a Pause button. To temporarily disable auto refresh, -click *Pause*. +To disable auto refresh, click *Stop*. -NOTE: If auto refresh is not enabled, you can manually refresh visualizations -by clicking *Refresh*. +If auto refresh is not enabled, click *Refresh* to manually refresh the search +results. diff --git a/docs/discover/set-time-filter.asciidoc b/docs/discover/set-time-filter.asciidoc index 6587d4febe4d2..c2d366cdcbbb6 100644 --- a/docs/discover/set-time-filter.asciidoc +++ b/docs/discover/set-time-filter.asciidoc @@ -1,46 +1,56 @@ [[set-time-filter]] == Setting the time filter -You can -set a time filter if your index contains time-based events and a time-field is -configured for the selected index pattern. -By default, the time filter is set to the last 15 minutes. You can use the time -picker to change the time filter, or select a specific time -range in the histogram. +If your index contains time-based events, and a time-field is configured for the +selected index pattern, set a time filter that displays only the data within the +specified time range. +You can use the time filter to change the time range, or select a specific time +range in the histogram. [float] -=== Filter with the time picker - -To quickly select from popular time range options, click the calendar -dropdown image:infrastructure/images/time-filter-calendar.png[]. - +[[use-time-filter]] +=== Use the time filter + +Use the time filter to change the time range. By default, the time filter is set +to the last 15 minutes. + +. Click image:images/time-filter-calendar.png[]. + +. Choose one of the following: + +* *Quick select* to use a recent time range, then use the back and forward + arrows to move through the time ranges. + +* *Commonly used* to use a time range from options such as *Last 15 minutes*, + *Today*, and *Week to date*. + +* *Recently used date ranges* to use a previously selected data range that + you recently used. + +* *Refresh every* to specify an automatic refresh rate. ++ [role="screenshot"] -image::images/Timepicker-View.png[Time picker menu] - -With the time picker, you can choose from: - -* *Quick select* to choose a recent time range, and use the back and forward arrows to move through the time ranges. -* *Commonly used* to choose a time range from options such as *Last 15 minutes*, *Today*, and *Week to date*. -* *Refresh every* to specify an auto-refresh rate. - -For control over the start and end times, -click the start time or end time in -the bar next to the calendar dropdown. In this popup, -you can select *Absolute*, *Relative* or *Now*, -and then specify the required options. +image::images/Timepicker-View.png[Time filter menu] +. To set the start and end times, click the bar next to the time filter. +In the popup, select *Absolute*, *Relative* or *Now*, then specify the required +options. ++ +[role="screenshot"] +image::images/time-filter-bar.png[Time filter bar] [float] -=== Filter from the histogram +=== Select a time range from the histogram + +To select a specific time range in the histogram, choose one of the following: -You can set a time filter from the histogram in two ways: +* Click the bar that represents the time range you want to zoom in on. -* Click the bar that represents the time interval you want to zoom in on. -* Click and drag to view a specific timespan. You must start the selection with +* Click and drag to view a specific time range. You must start the selection with the cursor over the background of the chart--the cursor changes to a plus sign when you hover over a valid start point. -To use a different interval, click the dropdown and select an interval. +* Click the dropdown, then select an interval. [role="screenshot"] image::images/Histogram-Time.png[Time range selector in Histogram] diff --git a/docs/images/autorefresh-intervals.png b/docs/images/autorefresh-intervals.png index b8c8edaf71592..a79ae2f1f6c46 100644 Binary files a/docs/images/autorefresh-intervals.png and b/docs/images/autorefresh-intervals.png differ diff --git a/docs/images/autorefresh.png b/docs/images/autorefresh.png index cf24bac5af08f..9a6225b9007bd 100644 Binary files a/docs/images/autorefresh.png and b/docs/images/autorefresh.png differ diff --git a/docs/images/time-filter-bar.png b/docs/images/time-filter-bar.png new file mode 100644 index 0000000000000..9ad7801c5bddc Binary files /dev/null and b/docs/images/time-filter-bar.png differ diff --git a/docs/images/time-filter-calendar.png b/docs/images/time-filter-calendar.png new file mode 100644 index 0000000000000..7487401ca2e4b Binary files /dev/null and b/docs/images/time-filter-calendar.png differ diff --git a/docs/infrastructure/infra-ui.asciidoc b/docs/infrastructure/infra-ui.asciidoc index be8fc29b98ab2..b976714587b7f 100644 --- a/docs/infrastructure/infra-ui.asciidoc +++ b/docs/infrastructure/infra-ui.asciidoc @@ -49,7 +49,7 @@ For example, enter `host.hostname : "host1"` to see only the information for `ho [[infra-date]] === Specify the time and date -Click the time selector image:infrastructure/images/infra-time-selector.png[time selector icon] to choose the timeframe for the metrics. +Click the time filter image:infrastructure/images/infra-time-selector.png[time filter icon] to choose the timeframe for the metrics. The values shown are the values for the last minute at the specified time and date. [float] diff --git a/docs/logs/using.asciidoc b/docs/logs/using.asciidoc index cdc990ff1caa0..bebc225feb0e6 100644 --- a/docs/logs/using.asciidoc +++ b/docs/logs/using.asciidoc @@ -30,8 +30,9 @@ If so, <> to change the [[logs-time]] === Specify the time and date -Click the time selector image:logs/images/logs-time-selector.png[time selector icon] to choose the timeframe for the logs. -Log entries for the time you specify appear in the middle of the page, with the earlier entries above and the later entries below. +Click image:images/time-filter-calendar.png[time filter calendar], then choose the time range for the logs. + +Log entries for the specified time appear in the middle of the page, with the earlier entries above and the later entries below. To quickly jump to a nearby point in time, click the minimap timeline to the right. // ++ what's this thing called? It's minimap in the UI. Would timeline be better? diff --git a/docs/plugins/known-plugins.asciidoc b/docs/plugins/known-plugins.asciidoc index d5344a796c7ce..58885ae04605d 100644 --- a/docs/plugins/known-plugins.asciidoc +++ b/docs/plugins/known-plugins.asciidoc @@ -60,7 +60,7 @@ This list of plugins is not guaranteed to work on your version of Kibana. Instea [float] === Other -* https://github.com/nreese/kibana-time-plugin[Time picker as a dashboard panel] Widget to view and edit the time range from within dashboards. +* https://github.com/nreese/kibana-time-plugin[Time filter as a dashboard panel] Widget to view and edit the time range from within dashboards. * https://github.com/Webiks/kibana-API.git[Kibana-API] (webiks) Exposes an API with Kibana functionality. Use it to create, edit and embed visualizations, and also to search inside an embedded dashboard. diff --git a/docs/user/monitoring/beats-details.asciidoc b/docs/user/monitoring/beats-details.asciidoc index bb4b998da9966..672ed6226e427 100644 --- a/docs/user/monitoring/beats-details.asciidoc +++ b/docs/user/monitoring/beats-details.asciidoc @@ -14,7 +14,7 @@ image::user/monitoring/images/monitoring-beats.jpg["Monitoring Beats",link="imag To view an overview of the Beats data in the cluster, click *Overview*. The overview page has a section for activity in the last day, which is a real-time sample of data. Below that, a summary bar and charts follow the typical paradigm -of data in the Monitoring UI, which is bound to the span of the time picker in +of data in the Monitoring UI, which is bound to the span of the time filter in the top right corner of the page. This overview page can therefore show up-to-date or historical information. diff --git a/docs/user/plugins.asciidoc b/docs/user/plugins.asciidoc index e80a81993c4f9..83c1ab1a842bb 100644 --- a/docs/user/plugins.asciidoc +++ b/docs/user/plugins.asciidoc @@ -1,22 +1,22 @@ [[kibana-plugins]] -= Kibana Plugins += Kibana plugins [partintro] -- -Add-on functionality for Kibana is implemented with plug-in modules. You use the `bin/kibana-plugin` +Add-on functionality for {kib} is implemented with plug-in modules. You use the `bin/kibana-plugin` command to manage these modules. [IMPORTANT] .Plugin compatibility ============================================== -The Kibana plugin interfaces are in a state of constant development. We cannot provide backwards compatibility for plugins due to the high rate of change. Kibana enforces that the installed plugins match the version of Kibana itself. Plugin developers will have to release a new version of their plugin for each new Kibana release as a result. +The {kib} plugin interfaces are in a state of constant development. We cannot provide backwards compatibility for plugins due to the high rate of change. {kib} enforces that the installed plugins match the version of {kib} itself. Plugin developers will have to release a new version of their plugin for each new {kib} release as a result. ============================================== -- [[install-plugin]] -== Installing Plugins +== Install plugins Use the following command to install a plugin: @@ -28,9 +28,9 @@ When you specify a plugin name without a URL, the plugin tool attempts to downlo ["source","shell",subs="attributes"] $ bin/kibana-plugin install x-pack - [float] -=== Installing Plugins from an Arbitrary URL +[[install-plugin-url]] +=== Install plugins from an arbitrary URL You can download official Elastic plugins simply by specifying their name. You can alternatively specify a URL to a specific plugin, as in the following @@ -42,22 +42,10 @@ $ bin/kibana-plugin install https://artifacts.elastic.co/downloads/packs/x-pack/ You can specify URLs that use the HTTP, HTTPS, or `file` protocols. [float] -=== Installing Plugins to an Arbitrary Directory - -Use the `-d` or `--plugin-dir` option after the `install` command to specify a directory for plugins, as in the following -example: - -[source,shell] -$ bin/kibana-plugin install file:///some/local/path/my-plugin.zip -d path/to/directory - -NOTE: This command creates the specified directory if it does not already exist. - -WARNING: This option is deprecated and will be removed in Kibana 7. It is known to not work with some plugins, including {xpack}. - -[float] +[[install-plugin-proxy-support]] === Proxy support for plugin installation -Kibana supports plugin installation via a proxy. It uses the `http_proxy` and `https_proxy` +{kib} supports plugin installation via a proxy. It uses the `http_proxy` and `https_proxy` environment variables to detect a proxy for HTTP and HTTPS URLs. It also respects the `no_proxy` environment variable to exclude specific URLs from proxying. @@ -67,9 +55,8 @@ You can specify the environment variable directly when installing plugins: [source,shell] $ http_proxy="http://proxy.local:4242" bin/kibana-plugin install - [[update-remove-plugin]] -== Updating & Removing Plugins +== Update and remove plugins To update a plugin, remove the current version and reinstall the plugin. @@ -80,10 +67,10 @@ $ bin/kibana-plugin remove x-pack You can also remove a plugin manually by deleting the plugin's subdirectory under the `plugins/` directory. -NOTE: Removing a plugin will result in an "optimize" run which will delay the next start of Kibana. +NOTE: Removing a plugin will result in an "optimize" run which will delay the next start of {kib}. [[disable-plugin]] -== Disabling Plugins +== Disable plugins Use the following command to disable a plugin: @@ -92,12 +79,12 @@ Use the following command to disable a plugin: ./bin/kibana --.enabled=false <1> ----------- -NOTE: Disabling or enabling a plugin will result in an "optimize" run which will delay the start of Kibana. +NOTE: Disabling or enabling a plugin will result in an "optimize" run which will delay the start of {kib}. <1> You can find a plugin's plugin ID as the value of the `name` property in the plugin's `package.json` file. [[configure-plugin-manager]] -== Configuring the Plugin Manager +== Configure the plugin manager By default, the plugin manager provides you with feedback on the status of the activity you've asked the plugin manager to perform. You can control the level of feedback for the `install` and `remove` commands with the `--quiet` and @@ -116,15 +103,17 @@ bin/kibana-plugin install --timeout 30s sample-plugin bin/kibana-plugin install --timeout 1m sample-plugin [float] -=== Plugins and Custom Kibana Configurations +[[plugin-custom-configuration]] +=== Plugins and custom {kib} configurations Use the `-c` or `--config` options with the `install` and `remove` commands to specify the path to the configuration file -used to start Kibana. By default, Kibana uses the configuration file `config/kibana.yml`. When you change your installed -plugins, the `bin/kibana-plugin` command restarts the Kibana server. When you are using a customized configuration file, +used to start {kib}. By default, {kib} uses the configuration file `config/kibana.yml`. When you change your installed +plugins, the `bin/kibana-plugin` command restarts the {kib} server. When you are using a customized configuration file, you must specify the path to that configuration file each time you use the `bin/kibana-plugin` command. [float] -=== Plugin Manager Exit Codes +[[plugin-manager-exit-codes]] +=== Plugin manager exit codes [horizontal] 0:: Success diff --git a/docs/visualize/vega.asciidoc b/docs/visualize/vega.asciidoc index a35d234a3586d..d5b7ccb12f48c 100644 --- a/docs/visualize/vega.asciidoc +++ b/docs/visualize/vega.asciidoc @@ -75,7 +75,7 @@ Here is an example of an Elasticsearch query that counts the number of documents // An object instead of a string for the url value // is treated as a context-aware Elasticsearch query. url: { - // Filter the time picker (upper right corner) with this field + // Specify the time filter (upper right corner) with this field %timefield%: @timestamp // Apply dashboard context filters when set %context%: true diff --git a/src/core/server/elasticsearch/api_types.ts b/src/core/server/elasticsearch/api_types.ts new file mode 100644 index 0000000000000..02834739942b5 --- /dev/null +++ b/src/core/server/elasticsearch/api_types.ts @@ -0,0 +1,357 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { + Client, + GenericParams, + // root params + BulkIndexDocumentsParams, + ClearScrollParams, + CountParams, + CreateDocumentParams, + DeleteDocumentParams, + DeleteDocumentByQueryParams, + DeleteScriptParams, + DeleteTemplateParams, + ExistsParams, + ExplainParams, + FieldStatsParams, + GetParams, + GetResponse, + GetScriptParams, + GetSourceParams, + GetTemplateParams, + IndexDocumentParams, + InfoParams, + MGetParams, + MSearchParams, + MSearchTemplateParams, + MTermVectorsParams, + PingParams, + PutScriptParams, + PutTemplateParams, + ReindexParams, + ReindexRethrottleParams, + RenderSearchTemplateParams, + ScrollParams, + SearchParams, + SearchShardsParams, + SearchTemplateParams, + SuggestParams, + TermvectorsParams, + UpdateDocumentParams, + UpdateDocumentByQueryParams, + MGetResponse, + MSearchResponse, + SearchResponse, + // cat + CatAliasesParams, + CatAllocationParams, + CatFielddataParams, + CatHealthParams, + CatHelpParams, + CatIndicesParams, + CatCommonParams, + CatRecoveryParams, + CatSegmentsParams, + CatShardsParams, + CatSnapshotsParams, + CatTasksParams, + CatThreadPoolParams, + // cluster + ClusterAllocationExplainParams, + ClusterGetSettingsParams, + ClusterHealthParams, + ClusterPendingTasksParams, + ClusterPutSettingsParams, + ClusterRerouteParams, + ClusterStateParams, + ClusterStatsParams, + // indices + IndicesAnalyzeParams, + IndicesClearCacheParams, + IndicesCloseParams, + IndicesCreateParams, + IndicesDeleteParams, + IndicesDeleteAliasParams, + IndicesDeleteTemplateParams, + IndicesExistsParams, + IndicesExistsAliasParams, + IndicesExistsTemplateParams, + IndicesExistsTypeParams, + IndicesFlushParams, + IndicesFlushSyncedParams, + IndicesForcemergeParams, + IndicesGetParams, + IndicesGetAliasParams, + IndicesGetFieldMappingParams, + IndicesGetMappingParams, + IndicesGetSettingsParams, + IndicesGetTemplateParams, + IndicesGetUpgradeParams, + IndicesOpenParams, + IndicesPutAliasParams, + IndicesPutMappingParams, + IndicesPutSettingsParams, + IndicesPutTemplateParams, + IndicesRecoveryParams, + IndicesRefreshParams, + IndicesRolloverParams, + IndicesSegmentsParams, + IndicesShardStoresParams, + IndicesShrinkParams, + IndicesStatsParams, + IndicesUpdateAliasesParams, + IndicesUpgradeParams, + IndicesValidateQueryParams, + // ingest + IngestDeletePipelineParams, + IngestGetPipelineParams, + IngestPutPipelineParams, + IngestSimulateParams, + // nodes + NodesHotThreadsParams, + NodesInfoParams, + NodesStatsParams, + // snapshot + SnapshotCreateParams, + SnapshotCreateRepositoryParams, + SnapshotDeleteParams, + SnapshotDeleteRepositoryParams, + SnapshotGetParams, + SnapshotGetRepositoryParams, + SnapshotRestoreParams, + SnapshotStatusParams, + SnapshotVerifyRepositoryParams, + // tasks + TasksCancelParams, + TasksGetParams, + TasksListParams, +} from 'elasticsearch'; + +/** + * The set of options that defines how API call should be made and result be + * processed. + * + * @public + */ +export interface CallAPIOptions { + /** + * Indicates whether `401 Unauthorized` errors returned from the Elasticsearch API + * should be wrapped into `Boom` error instances with properly set `WWW-Authenticate` + * header that could have been returned by the API itself. If API didn't specify that + * then `Basic realm="Authorization Required"` is used as `WWW-Authenticate`. + */ + wrap401Errors: boolean; + /** + * A signal object that allows you to abort the request via an AbortController object. + */ + signal?: AbortSignal; +} + +/** @public */ +export interface APICaller { + /* eslint-disable */ + (endpoint: 'bulk', params: BulkIndexDocumentsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'clearScroll', params: ClearScrollParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'count', params: CountParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'create', params: CreateDocumentParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'delete', params: DeleteDocumentParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'deleteByQuery', params: DeleteDocumentByQueryParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'deleteScript', params: DeleteScriptParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'deleteTemplate', params: DeleteTemplateParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'exists', params: ExistsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'explain', params: ExplainParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'fieldStats', params: FieldStatsParams, options?: CallAPIOptions): ReturnType; + // Generic types cannot be properly looked up with ReturnType. Hard code these explicitly. + (endpoint: 'get', params: GetParams, options?: CallAPIOptions): Promise>; + (endpoint: 'getScript', params: GetScriptParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'getSource', params: GetSourceParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'getTemplate', params: GetTemplateParams, options?: CallAPIOptions): ReturnType; + // Generic types cannot be properly looked up with ReturnType. Hard code these explicitly. + (endpoint: 'index', params: IndexDocumentParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'info', params: InfoParams, options?: CallAPIOptions): ReturnType; + // Generic types cannot be properly looked up with ReturnType. Hard code these explicitly. + (endpoint: 'mget', params: MGetParams, options?: CallAPIOptions): Promise>; + (endpoint: 'msearch', params: MSearchParams, options?: CallAPIOptions): Promise>; + (endpoint: 'msearchTemplate', params: MSearchTemplateParams, options?: CallAPIOptions): Promise>; + (endpoint: 'mtermvectors', params: MTermVectorsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'ping', params: PingParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'putScript', params: PutScriptParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'putTemplate', params: PutTemplateParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'reindex', params: ReindexParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'reindexRethrottle', params: ReindexRethrottleParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'renderSearchTemplate', params: RenderSearchTemplateParams, options?: CallAPIOptions): ReturnType; + // Generic types cannot be properly looked up with ReturnType. Hard code these explicitly. + (endpoint: 'scroll', params: ScrollParams, options?: CallAPIOptions): Promise>; + (endpoint: 'search', params: SearchParams, options?: CallAPIOptions): Promise>; + (endpoint: 'searchShards', params: SearchShardsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'searchTemplate', params: SearchTemplateParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'suggest', params: SuggestParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'termvectors', params: TermvectorsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'update', params: UpdateDocumentParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'updateByQuery', params: UpdateDocumentByQueryParams, options?: CallAPIOptions): ReturnType; + + // cat namespace + (endpoint: 'cat.aliases', params: CatAliasesParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.allocation', params: CatAllocationParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.count', params: CatAllocationParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.fielddata', params: CatFielddataParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.health', params: CatHealthParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.help', params: CatHelpParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.indices', params: CatIndicesParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.master', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.nodeattrs', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.nodes', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.pendingTasks', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.plugins', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.recovery', params: CatRecoveryParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.repositories', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.segments', params: CatSegmentsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.shards', params: CatShardsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.snapshots', params: CatSnapshotsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.tasks', params: CatTasksParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cat.threadPool', params: CatThreadPoolParams, options?: CallAPIOptions): ReturnType; + + // cluster namespace + (endpoint: 'cluster.allocationExplain', params: ClusterAllocationExplainParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cluster.getSettings', params: ClusterGetSettingsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cluster.health', params: ClusterHealthParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cluster.pendingTasks', params: ClusterPendingTasksParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cluster.putSettings', params: ClusterPutSettingsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cluster.reroute', params: ClusterRerouteParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cluster.state', params: ClusterStateParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'cluster.stats', params: ClusterStatsParams, options?: CallAPIOptions): ReturnType; + + // indices namespace + (endpoint: 'indices.analyze', params: IndicesAnalyzeParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.clearCache', params: IndicesClearCacheParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.close', params: IndicesCloseParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.create', params: IndicesCreateParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.delete', params: IndicesDeleteParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.deleteAlias', params: IndicesDeleteAliasParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.deleteTemplate', params: IndicesDeleteTemplateParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.exists', params: IndicesExistsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.existsAlias', params: IndicesExistsAliasParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.existsTemplate', params: IndicesExistsTemplateParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.existsType', params: IndicesExistsTypeParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.flush', params: IndicesFlushParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.flushSynced', params: IndicesFlushSyncedParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.forcemerge', params: IndicesForcemergeParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.get', params: IndicesGetParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.getAlias', params: IndicesGetAliasParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.getFieldMapping', params: IndicesGetFieldMappingParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.getMapping', params: IndicesGetMappingParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.getSettings', params: IndicesGetSettingsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.getTemplate', params: IndicesGetTemplateParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.getUpgrade', params: IndicesGetUpgradeParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.open', params: IndicesOpenParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.putAlias', params: IndicesPutAliasParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.putMapping', params: IndicesPutMappingParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.putSettings', params: IndicesPutSettingsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.putTemplate', params: IndicesPutTemplateParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.recovery', params: IndicesRecoveryParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.refresh', params: IndicesRefreshParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.rollover', params: IndicesRolloverParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.segments', params: IndicesSegmentsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.shardStores', params: IndicesShardStoresParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.shrink', params: IndicesShrinkParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.stats', params: IndicesStatsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.updateAliases', params: IndicesUpdateAliasesParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.upgrade', params: IndicesUpgradeParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'indices.validateQuery', params: IndicesValidateQueryParams, options?: CallAPIOptions): ReturnType; + + // ingest namepsace + (endpoint: 'ingest.deletePipeline', params: IngestDeletePipelineParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'ingest.getPipeline', params: IngestGetPipelineParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'ingest.putPipeline', params: IngestPutPipelineParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'ingest.simulate', params: IngestSimulateParams, options?: CallAPIOptions): ReturnType; + + // nodes namespace + (endpoint: 'nodes.hotThreads', params: NodesHotThreadsParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'nodes.info', params: NodesInfoParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'nodes.stats', params: NodesStatsParams, options?: CallAPIOptions): ReturnType; + + // snapshot namespace + (endpoint: 'snapshot.create', params: SnapshotCreateParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'snapshot.createRepository', params: SnapshotCreateRepositoryParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'snapshot.delete', params: SnapshotDeleteParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'snapshot.deleteRepository', params: SnapshotDeleteRepositoryParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'snapshot.get', params: SnapshotGetParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'snapshot.getRepository', params: SnapshotGetRepositoryParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'snapshot.restore', params: SnapshotRestoreParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'snapshot.status', params: SnapshotStatusParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'snapshot.verifyRepository', params: SnapshotVerifyRepositoryParams, options?: CallAPIOptions): ReturnType; + + // tasks namespace + (endpoint: 'tasks.cancel', params: TasksCancelParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'tasks.get', params: TasksGetParams, options?: CallAPIOptions): ReturnType; + (endpoint: 'tasks.list', params: TasksListParams, options?: CallAPIOptions): ReturnType; + + // other APIs accessed via transport.request + (endpoint: 'transport.request', clientParams: AssistantAPIClientParams, options?: CallAPIOptions): Promise< + AssistanceAPIResponse + >; + (endpoint: 'transport.request', clientParams: DeprecationAPIClientParams, options?: CallAPIOptions): Promise< + DeprecationAPIResponse + >; + + // Catch-all definition + (endpoint: string, clientParams?: Record, options?: CallAPIOptions): Promise; + /* eslint-enable */ +} + +export interface AssistantAPIClientParams extends GenericParams { + path: '/_migration/assistance'; + method: 'GET'; +} + +export type MIGRATION_ASSISTANCE_INDEX_ACTION = 'upgrade' | 'reindex'; +export type MIGRATION_DEPRECATION_LEVEL = 'none' | 'info' | 'warning' | 'critical'; + +export interface AssistanceAPIResponse { + indices: { + [indexName: string]: { + action_required: MIGRATION_ASSISTANCE_INDEX_ACTION; + }; + }; +} + +export interface DeprecationAPIClientParams extends GenericParams { + path: '/_migration/deprecations'; + method: 'GET'; +} + +export interface DeprecationInfo { + level: MIGRATION_DEPRECATION_LEVEL; + message: string; + url: string; + details?: string; +} + +export interface IndexSettingsDeprecationInfo { + [indexName: string]: DeprecationInfo[]; +} + +export interface DeprecationAPIResponse { + cluster_settings: DeprecationInfo[]; + ml_settings: DeprecationInfo[]; + node_settings: DeprecationInfo[]; + index_settings: IndexSettingsDeprecationInfo; +} diff --git a/src/core/server/elasticsearch/cluster_client.ts b/src/core/server/elasticsearch/cluster_client.ts index aa40010bf3b1a..cd581013e7957 100644 --- a/src/core/server/elasticsearch/cluster_client.ts +++ b/src/core/server/elasticsearch/cluster_client.ts @@ -27,7 +27,8 @@ import { ElasticsearchClientConfig, parseElasticsearchClientConfig, } from './elasticsearch_client_config'; -import { ScopedClusterClient } from './scoped_cluster_client'; +import { ScopedClusterClient, IScopedClusterClient } from './scoped_cluster_client'; +import { CallAPIOptions, APICaller } from './api_types'; /** * Support Legacy platform request for the period of migration. @@ -36,25 +37,6 @@ import { ScopedClusterClient } from './scoped_cluster_client'; */ const noop = () => undefined; -/** - * The set of options that defines how API call should be made and result be - * processed. - * - * @public - */ -export interface CallAPIOptions { - /** - * Indicates whether `401 Unauthorized` errors returned from the Elasticsearch API - * should be wrapped into `Boom` error instances with properly set `WWW-Authenticate` - * header that could have been returned by the API itself. If API didn't specify that - * then `Basic realm="Authorization Required"` is used as `WWW-Authenticate`. - */ - wrap401Errors: boolean; - /** - * A signal object that allows you to abort the request via an AbortController object. - */ - signal?: AbortSignal; -} /** * Calls the Elasticsearch API endpoint with the specified parameters. @@ -64,12 +46,12 @@ export interface CallAPIOptions { * Elasticsearch JS client. * @param options Options that affect the way we call the API and process the result. */ -async function callAPI( +const callAPI = async ( client: Client, endpoint: string, clientParams: Record = {}, options: CallAPIOptions = { wrap401Errors: true } -): Promise { +) => { const clientPath = endpoint.split('.'); const api: any = get(client, clientPath); if (!api) { @@ -95,7 +77,7 @@ async function callAPI( throw ElasticsearchErrorHelpers.decorateNotAuthorizedError(err); } -} +}; /** * Fake request object created manually by Kibana plugins. @@ -111,9 +93,17 @@ export interface FakeRequest { * of the internal Kibana user and the actual user that is derived from the request * headers (via `asScoped(...)`). * + * See {@link ClusterClient}. + * + * @public + */ +export type IClusterClient = Pick; + +/** + * {@inheritDoc IClusterClient} * @public */ -export class ClusterClient { +export class ClusterClient implements IClusterClient { /** * Raw Elasticsearch JS client that acts on behalf of the Kibana internal user. */ @@ -145,14 +135,14 @@ export class ClusterClient { * @param clientParams - A dictionary of parameters that will be passed directly to the Elasticsearch JS client. * @param options - Options that affect the way we call the API and process the result. */ - public callAsInternalUser = async ( + public callAsInternalUser: APICaller = async ( endpoint: string, clientParams: Record = {}, options?: CallAPIOptions ) => { this.assertIsNotClosed(); - return await callAPI(this.client, endpoint, clientParams, options); + return await (callAPI.bind(null, this.client) as APICaller)(endpoint, clientParams, options); }; /** @@ -181,7 +171,7 @@ export class ClusterClient { * @param request - Request the `ScopedClusterClient` instance will be scoped to. * Supports request optionality, Legacy.Request & FakeRequest for BWC with LegacyPlatform */ - public asScoped(request?: KibanaRequest | LegacyRequest | FakeRequest) { + public asScoped(request?: KibanaRequest | LegacyRequest | FakeRequest): IScopedClusterClient { // It'd have been quite expensive to create and configure client for every incoming // request since it involves parsing of the config, reading of the SSL certificate and // key files etc. Moreover scoped client needs two Elasticsearch JS clients at the same @@ -211,14 +201,18 @@ export class ClusterClient { * @param clientParams - A dictionary of parameters that will be passed directly to the Elasticsearch JS client. * @param options - Options that affect the way we call the API and process the result. */ - private callAsCurrentUser = async ( + private callAsCurrentUser: APICaller = async ( endpoint: string, clientParams: Record = {}, options?: CallAPIOptions ) => { this.assertIsNotClosed(); - return await callAPI(this.scopedClient!, endpoint, clientParams, options); + return await (callAPI.bind(null, this.scopedClient!) as APICaller)( + endpoint, + clientParams, + options + ); }; private assertIsNotClosed() { diff --git a/src/core/server/elasticsearch/elasticsearch_service.mock.ts b/src/core/server/elasticsearch/elasticsearch_service.mock.ts index dd35a4c3f5489..6cf759b73c656 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.mock.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.mock.ts @@ -18,17 +18,17 @@ */ import { BehaviorSubject } from 'rxjs'; -import { ClusterClient } from './cluster_client'; -import { ScopedClusterClient } from './scoped_cluster_client'; +import { IClusterClient } from './cluster_client'; +import { IScopedClusterClient } from './scoped_cluster_client'; import { ElasticsearchConfig } from './elasticsearch_config'; import { ElasticsearchService, ElasticsearchServiceSetup } from './elasticsearch_service'; -const createScopedClusterClientMock = (): jest.Mocked> => ({ +const createScopedClusterClientMock = (): jest.Mocked => ({ callAsInternalUser: jest.fn(), callAsCurrentUser: jest.fn(), }); -const createClusterClientMock = (): jest.Mocked> => ({ +const createClusterClientMock = (): jest.Mocked => ({ callAsInternalUser: jest.fn(), asScoped: jest.fn().mockImplementation(createScopedClusterClientMock), close: jest.fn(), @@ -41,8 +41,8 @@ const createSetupContractMock = () => { }, createClient: jest.fn().mockImplementation(createClusterClientMock), - adminClient$: new BehaviorSubject((createClusterClientMock() as unknown) as ClusterClient), - dataClient$: new BehaviorSubject((createClusterClientMock() as unknown) as ClusterClient), + adminClient$: new BehaviorSubject((createClusterClientMock() as unknown) as IClusterClient), + dataClient$: new BehaviorSubject((createClusterClientMock() as unknown) as IClusterClient), }; return setupContract; }; diff --git a/src/core/server/elasticsearch/elasticsearch_service.ts b/src/core/server/elasticsearch/elasticsearch_service.ts index 38a0d19b1ae3f..9bec697825346 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.ts @@ -23,7 +23,7 @@ import { merge } from 'lodash'; import { CoreService } from '../../types'; import { CoreContext } from '../core_context'; import { Logger } from '../logging'; -import { ClusterClient } from './cluster_client'; +import { ClusterClient, IClusterClient } from './cluster_client'; import { ElasticsearchClientConfig } from './elasticsearch_client_config'; import { ElasticsearchConfig, ElasticsearchConfigType } from './elasticsearch_config'; import { HttpServiceSetup, GetAuthHeaders } from '../http/'; @@ -65,9 +65,9 @@ export interface ElasticsearchServiceSetup { readonly createClient: ( type: string, clientConfig?: Partial - ) => ClusterClient; - readonly adminClient$: Observable; - readonly dataClient$: Observable; + ) => IClusterClient; + readonly adminClient$: Observable; + readonly dataClient$: Observable; } /** @internal */ diff --git a/src/core/server/elasticsearch/index.ts b/src/core/server/elasticsearch/index.ts index f732f9e39b9e3..7b496b738182b 100644 --- a/src/core/server/elasticsearch/index.ts +++ b/src/core/server/elasticsearch/index.ts @@ -18,8 +18,9 @@ */ export { ElasticsearchServiceSetup, ElasticsearchService } from './elasticsearch_service'; -export { CallAPIOptions, ClusterClient, FakeRequest } from './cluster_client'; -export { ScopedClusterClient, Headers, APICaller } from './scoped_cluster_client'; +export { IClusterClient, ClusterClient, FakeRequest } from './cluster_client'; +export { IScopedClusterClient, ScopedClusterClient, Headers } from './scoped_cluster_client'; export { ElasticsearchClientConfig } from './elasticsearch_client_config'; export { config } from './elasticsearch_config'; export { ElasticsearchError, ElasticsearchErrorHelpers } from './errors'; +export * from './api_types'; diff --git a/src/core/server/elasticsearch/scoped_cluster_client.ts b/src/core/server/elasticsearch/scoped_cluster_client.ts index d89a15e336b33..02a37e1e3567f 100644 --- a/src/core/server/elasticsearch/scoped_cluster_client.ts +++ b/src/core/server/elasticsearch/scoped_cluster_client.ts @@ -19,27 +19,31 @@ import { intersection, isObject } from 'lodash'; import { Headers } from '../http/router'; -import { CallAPIOptions } from './cluster_client'; +import { APICaller, CallAPIOptions } from './api_types'; /** @public */ export { Headers }; -/** @public */ -export type APICaller = ( - endpoint: string, - clientParams: Record, - options?: CallAPIOptions -) => Promise; - /** * Serves the same purpose as "normal" `ClusterClient` but exposes additional * `callAsCurrentUser` method that doesn't use credentials of the Kibana internal * user (as `callAsInternalUser` does) to request Elasticsearch API, but rather - * passes HTTP headers extracted from the current user request to the API + * passes HTTP headers extracted from the current user request to the API. * + * See {@link ScopedClusterClient}. + * + * @public + */ +export type IScopedClusterClient = Pick< + ScopedClusterClient, + 'callAsCurrentUser' | 'callAsInternalUser' +>; + +/** + * {@inheritDoc IScopedClusterClient} * @public */ -export class ScopedClusterClient { +export class ScopedClusterClient implements IScopedClusterClient { constructor( private readonly internalAPICaller: APICaller, private readonly scopedAPICaller: APICaller, diff --git a/src/core/server/index.ts b/src/core/server/index.ts index ca497e0f2d32d..3cc420b766439 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -41,10 +41,10 @@ import { Observable } from 'rxjs'; import { - ClusterClient, + IClusterClient, ElasticsearchClientConfig, ElasticsearchServiceSetup, - ScopedClusterClient, + IScopedClusterClient, } from './elasticsearch'; import { HttpServiceSetup, @@ -68,16 +68,17 @@ export { } from './context'; export { CoreId } from './core_context'; export { - CallAPIOptions, ClusterClient, + IClusterClient, Headers, ScopedClusterClient, + IScopedClusterClient, ElasticsearchClientConfig, ElasticsearchError, ElasticsearchErrorHelpers, - APICaller, FakeRequest, } from './elasticsearch'; +export * from './elasticsearch/api_types'; export { AuthenticationHandler, AuthHeaders, @@ -184,8 +185,8 @@ export { LegacyServiceSetupDeps, LegacyServiceStartDeps } from './legacy'; export interface RequestHandlerContext { core: { elasticsearch: { - dataClient: ScopedClusterClient; - adminClient: ScopedClusterClient; + dataClient: IScopedClusterClient; + adminClient: IScopedClusterClient; }; }; } @@ -200,12 +201,12 @@ export interface CoreSetup { createContextContainer: ContextSetup['createContextContainer']; }; elasticsearch: { - adminClient$: Observable; - dataClient$: Observable; + adminClient$: Observable; + dataClient$: Observable; createClient: ( type: string, clientConfig?: Partial - ) => ClusterClient; + ) => IClusterClient; }; http: { createCookieSessionStorageFactory: HttpServiceSetup['createCookieSessionStorageFactory']; diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 79728ecc8fb98..8c028fee95d93 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -5,30 +5,410 @@ ```ts import Boom from 'boom'; +import { BulkIndexDocumentsParams } from 'elasticsearch'; import { CallCluster } from 'src/legacy/core_plugins/elasticsearch'; +import { CatAliasesParams } from 'elasticsearch'; +import { CatAllocationParams } from 'elasticsearch'; +import { CatCommonParams } from 'elasticsearch'; +import { CatFielddataParams } from 'elasticsearch'; +import { CatHealthParams } from 'elasticsearch'; +import { CatHelpParams } from 'elasticsearch'; +import { CatIndicesParams } from 'elasticsearch'; +import { CatRecoveryParams } from 'elasticsearch'; +import { CatSegmentsParams } from 'elasticsearch'; +import { CatShardsParams } from 'elasticsearch'; +import { CatSnapshotsParams } from 'elasticsearch'; +import { CatTasksParams } from 'elasticsearch'; +import { CatThreadPoolParams } from 'elasticsearch'; +import { ClearScrollParams } from 'elasticsearch'; +import { Client } from 'elasticsearch'; +import { ClusterAllocationExplainParams } from 'elasticsearch'; +import { ClusterGetSettingsParams } from 'elasticsearch'; +import { ClusterHealthParams } from 'elasticsearch'; +import { ClusterPendingTasksParams } from 'elasticsearch'; +import { ClusterPutSettingsParams } from 'elasticsearch'; +import { ClusterRerouteParams } from 'elasticsearch'; +import { ClusterStateParams } from 'elasticsearch'; +import { ClusterStatsParams } from 'elasticsearch'; import { ConfigOptions } from 'elasticsearch'; +import { CountParams } from 'elasticsearch'; +import { CreateDocumentParams } from 'elasticsearch'; +import { DeleteDocumentByQueryParams } from 'elasticsearch'; +import { DeleteDocumentParams } from 'elasticsearch'; +import { DeleteScriptParams } from 'elasticsearch'; +import { DeleteTemplateParams } from 'elasticsearch'; import { DetailedPeerCertificate } from 'tls'; import { Duration } from 'moment'; +import { ExistsParams } from 'elasticsearch'; +import { ExplainParams } from 'elasticsearch'; +import { FieldStatsParams } from 'elasticsearch'; +import { GenericParams } from 'elasticsearch'; +import { GetParams } from 'elasticsearch'; +import { GetResponse } from 'elasticsearch'; +import { GetScriptParams } from 'elasticsearch'; +import { GetSourceParams } from 'elasticsearch'; +import { GetTemplateParams } from 'elasticsearch'; import { IncomingHttpHeaders } from 'http'; +import { IndexDocumentParams } from 'elasticsearch'; import { IndexPatternsService } from 'src/legacy/server/index_patterns'; +import { IndicesAnalyzeParams } from 'elasticsearch'; +import { IndicesClearCacheParams } from 'elasticsearch'; +import { IndicesCloseParams } from 'elasticsearch'; +import { IndicesCreateParams } from 'elasticsearch'; +import { IndicesDeleteAliasParams } from 'elasticsearch'; +import { IndicesDeleteParams } from 'elasticsearch'; +import { IndicesDeleteTemplateParams } from 'elasticsearch'; +import { IndicesExistsAliasParams } from 'elasticsearch'; +import { IndicesExistsParams } from 'elasticsearch'; +import { IndicesExistsTemplateParams } from 'elasticsearch'; +import { IndicesExistsTypeParams } from 'elasticsearch'; +import { IndicesFlushParams } from 'elasticsearch'; +import { IndicesFlushSyncedParams } from 'elasticsearch'; +import { IndicesForcemergeParams } from 'elasticsearch'; +import { IndicesGetAliasParams } from 'elasticsearch'; +import { IndicesGetFieldMappingParams } from 'elasticsearch'; +import { IndicesGetMappingParams } from 'elasticsearch'; +import { IndicesGetParams } from 'elasticsearch'; +import { IndicesGetSettingsParams } from 'elasticsearch'; +import { IndicesGetTemplateParams } from 'elasticsearch'; +import { IndicesGetUpgradeParams } from 'elasticsearch'; +import { IndicesOpenParams } from 'elasticsearch'; +import { IndicesPutAliasParams } from 'elasticsearch'; +import { IndicesPutMappingParams } from 'elasticsearch'; +import { IndicesPutSettingsParams } from 'elasticsearch'; +import { IndicesPutTemplateParams } from 'elasticsearch'; +import { IndicesRecoveryParams } from 'elasticsearch'; +import { IndicesRefreshParams } from 'elasticsearch'; +import { IndicesRolloverParams } from 'elasticsearch'; +import { IndicesSegmentsParams } from 'elasticsearch'; +import { IndicesShardStoresParams } from 'elasticsearch'; +import { IndicesShrinkParams } from 'elasticsearch'; +import { IndicesStatsParams } from 'elasticsearch'; +import { IndicesUpdateAliasesParams } from 'elasticsearch'; +import { IndicesUpgradeParams } from 'elasticsearch'; +import { IndicesValidateQueryParams } from 'elasticsearch'; +import { InfoParams } from 'elasticsearch'; +import { IngestDeletePipelineParams } from 'elasticsearch'; +import { IngestGetPipelineParams } from 'elasticsearch'; +import { IngestPutPipelineParams } from 'elasticsearch'; +import { IngestSimulateParams } from 'elasticsearch'; import { KibanaConfigType } from 'src/core/server/kibana_config'; import { Logger as Logger_2 } from 'src/core/server/logging'; +import { MGetParams } from 'elasticsearch'; +import { MGetResponse } from 'elasticsearch'; +import { MSearchParams } from 'elasticsearch'; +import { MSearchResponse } from 'elasticsearch'; +import { MSearchTemplateParams } from 'elasticsearch'; +import { MTermVectorsParams } from 'elasticsearch'; +import { NodesHotThreadsParams } from 'elasticsearch'; +import { NodesInfoParams } from 'elasticsearch'; +import { NodesStatsParams } from 'elasticsearch'; import { ObjectType } from '@kbn/config-schema'; import { Observable } from 'rxjs'; import { PeerCertificate } from 'tls'; +import { PingParams } from 'elasticsearch'; +import { PutScriptParams } from 'elasticsearch'; +import { PutTemplateParams } from 'elasticsearch'; import { Readable } from 'stream'; +import { ReindexParams } from 'elasticsearch'; +import { ReindexRethrottleParams } from 'elasticsearch'; +import { RenderSearchTemplateParams } from 'elasticsearch'; import { Request } from 'hapi'; import { ResponseObject } from 'hapi'; import { ResponseToolkit } from 'hapi'; +import { ScrollParams } from 'elasticsearch'; +import { SearchParams } from 'elasticsearch'; +import { SearchResponse } from 'elasticsearch'; +import { SearchShardsParams } from 'elasticsearch'; +import { SearchTemplateParams } from 'elasticsearch'; import { Server } from 'hapi'; import { ShallowPromise } from '@kbn/utility-types'; +import { SnapshotCreateParams } from 'elasticsearch'; +import { SnapshotCreateRepositoryParams } from 'elasticsearch'; +import { SnapshotDeleteParams } from 'elasticsearch'; +import { SnapshotDeleteRepositoryParams } from 'elasticsearch'; +import { SnapshotGetParams } from 'elasticsearch'; +import { SnapshotGetRepositoryParams } from 'elasticsearch'; +import { SnapshotRestoreParams } from 'elasticsearch'; +import { SnapshotStatusParams } from 'elasticsearch'; +import { SnapshotVerifyRepositoryParams } from 'elasticsearch'; import { Stream } from 'stream'; +import { SuggestParams } from 'elasticsearch'; +import { TasksCancelParams } from 'elasticsearch'; +import { TasksGetParams } from 'elasticsearch'; +import { TasksListParams } from 'elasticsearch'; +import { TermvectorsParams } from 'elasticsearch'; import { Type } from '@kbn/config-schema'; import { TypeOf } from '@kbn/config-schema'; +import { UpdateDocumentByQueryParams } from 'elasticsearch'; +import { UpdateDocumentParams } from 'elasticsearch'; import { Url } from 'url'; // @public (undocumented) -export type APICaller = (endpoint: string, clientParams: Record, options?: CallAPIOptions) => Promise; +export interface APICaller { + // (undocumented) + (endpoint: 'cluster.state', params: ClusterStateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'bulk', params: BulkIndexDocumentsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'count', params: CountParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'create', params: CreateDocumentParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'delete', params: DeleteDocumentParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'deleteByQuery', params: DeleteDocumentByQueryParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'deleteScript', params: DeleteScriptParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'deleteTemplate', params: DeleteTemplateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'exists', params: ExistsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'explain', params: ExplainParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'fieldStats', params: FieldStatsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'get', params: GetParams, options?: CallAPIOptions): Promise>; + // (undocumented) + (endpoint: 'getScript', params: GetScriptParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'getSource', params: GetSourceParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'getTemplate', params: GetTemplateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'index', params: IndexDocumentParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'info', params: InfoParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'mget', params: MGetParams, options?: CallAPIOptions): Promise>; + // (undocumented) + (endpoint: 'msearch', params: MSearchParams, options?: CallAPIOptions): Promise>; + // (undocumented) + (endpoint: 'msearchTemplate', params: MSearchTemplateParams, options?: CallAPIOptions): Promise>; + // (undocumented) + (endpoint: 'mtermvectors', params: MTermVectorsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'ping', params: PingParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'putScript', params: PutScriptParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'putTemplate', params: PutTemplateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'reindex', params: ReindexParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'reindexRethrottle', params: ReindexRethrottleParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'renderSearchTemplate', params: RenderSearchTemplateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'scroll', params: ScrollParams, options?: CallAPIOptions): Promise>; + // (undocumented) + (endpoint: 'search', params: SearchParams, options?: CallAPIOptions): Promise>; + // (undocumented) + (endpoint: 'searchShards', params: SearchShardsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'searchTemplate', params: SearchTemplateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'suggest', params: SuggestParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'termvectors', params: TermvectorsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'update', params: UpdateDocumentParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'updateByQuery', params: UpdateDocumentByQueryParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.aliases', params: CatAliasesParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.allocation', params: CatAllocationParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.count', params: CatAllocationParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.fielddata', params: CatFielddataParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.health', params: CatHealthParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.help', params: CatHelpParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.indices', params: CatIndicesParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.master', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.nodeattrs', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.nodes', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.pendingTasks', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.plugins', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.recovery', params: CatRecoveryParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.repositories', params: CatCommonParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.segments', params: CatSegmentsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.shards', params: CatShardsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.snapshots', params: CatSnapshotsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.tasks', params: CatTasksParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cat.threadPool', params: CatThreadPoolParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cluster.allocationExplain', params: ClusterAllocationExplainParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cluster.getSettings', params: ClusterGetSettingsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cluster.health', params: ClusterHealthParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cluster.pendingTasks', params: ClusterPendingTasksParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cluster.putSettings', params: ClusterPutSettingsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cluster.reroute', params: ClusterRerouteParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'clearScroll', params: ClearScrollParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'cluster.stats', params: ClusterStatsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.analyze', params: IndicesAnalyzeParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.clearCache', params: IndicesClearCacheParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.close', params: IndicesCloseParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.create', params: IndicesCreateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.delete', params: IndicesDeleteParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.deleteAlias', params: IndicesDeleteAliasParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.deleteTemplate', params: IndicesDeleteTemplateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.exists', params: IndicesExistsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.existsAlias', params: IndicesExistsAliasParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.existsTemplate', params: IndicesExistsTemplateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.existsType', params: IndicesExistsTypeParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.flush', params: IndicesFlushParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.flushSynced', params: IndicesFlushSyncedParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.forcemerge', params: IndicesForcemergeParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.get', params: IndicesGetParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.getAlias', params: IndicesGetAliasParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.getFieldMapping', params: IndicesGetFieldMappingParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.getMapping', params: IndicesGetMappingParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.getSettings', params: IndicesGetSettingsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.getTemplate', params: IndicesGetTemplateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.getUpgrade', params: IndicesGetUpgradeParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.open', params: IndicesOpenParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.putAlias', params: IndicesPutAliasParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.putMapping', params: IndicesPutMappingParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.putSettings', params: IndicesPutSettingsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.putTemplate', params: IndicesPutTemplateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.recovery', params: IndicesRecoveryParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.refresh', params: IndicesRefreshParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.rollover', params: IndicesRolloverParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.segments', params: IndicesSegmentsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.shardStores', params: IndicesShardStoresParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.shrink', params: IndicesShrinkParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.stats', params: IndicesStatsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.updateAliases', params: IndicesUpdateAliasesParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.upgrade', params: IndicesUpgradeParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'indices.validateQuery', params: IndicesValidateQueryParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'ingest.deletePipeline', params: IngestDeletePipelineParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'ingest.getPipeline', params: IngestGetPipelineParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'ingest.putPipeline', params: IngestPutPipelineParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'ingest.simulate', params: IngestSimulateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'nodes.hotThreads', params: NodesHotThreadsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'nodes.info', params: NodesInfoParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'nodes.stats', params: NodesStatsParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'snapshot.create', params: SnapshotCreateParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'snapshot.createRepository', params: SnapshotCreateRepositoryParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'snapshot.delete', params: SnapshotDeleteParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'snapshot.deleteRepository', params: SnapshotDeleteRepositoryParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'snapshot.get', params: SnapshotGetParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'snapshot.getRepository', params: SnapshotGetRepositoryParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'snapshot.restore', params: SnapshotRestoreParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'snapshot.status', params: SnapshotStatusParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'snapshot.verifyRepository', params: SnapshotVerifyRepositoryParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'tasks.cancel', params: TasksCancelParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'tasks.get', params: TasksGetParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'tasks.list', params: TasksListParams, options?: CallAPIOptions): ReturnType; + // (undocumented) + (endpoint: 'transport.request', clientParams: AssistantAPIClientParams, options?: CallAPIOptions): Promise; + // (undocumented) + (endpoint: 'transport.request', clientParams: DeprecationAPIClientParams, options?: CallAPIOptions): Promise; + // (undocumented) + (endpoint: string, clientParams?: Record, options?: CallAPIOptions): Promise; +} + +// Warning: (ae-missing-release-tag) "AssistanceAPIResponse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface AssistanceAPIResponse { + // (undocumented) + indices: { + [indexName: string]: { + action_required: MIGRATION_ASSISTANCE_INDEX_ACTION; + }; + }; +} + +// Warning: (ae-missing-release-tag) "AssistantAPIClientParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface AssistantAPIClientParams extends GenericParams { + // (undocumented) + method: 'GET'; + // (undocumented) + path: '/_migration/assistance'; +} // Warning: (ae-forgotten-export) The symbol "AuthResult" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts @@ -81,10 +461,10 @@ export interface CallAPIOptions { } // @public -export class ClusterClient { +export class ClusterClient implements IClusterClient { constructor(config: ElasticsearchClientConfig, log: Logger, getAuthHeaders?: GetAuthHeaders); - asScoped(request?: KibanaRequest | LegacyRequest | FakeRequest): ScopedClusterClient; - callAsInternalUser: (endpoint: string, clientParams?: Record, options?: CallAPIOptions | undefined) => Promise; + asScoped(request?: KibanaRequest | LegacyRequest | FakeRequest): IScopedClusterClient; + callAsInternalUser: APICaller; close(): void; } @@ -124,9 +504,9 @@ export interface CoreSetup { }; // (undocumented) elasticsearch: { - adminClient$: Observable; - dataClient$: Observable; - createClient: (type: string, clientConfig?: Partial) => ClusterClient; + adminClient$: Observable; + dataClient$: Observable; + createClient: (type: string, clientConfig?: Partial) => IClusterClient; }; // (undocumented) http: { @@ -153,6 +533,44 @@ export interface CustomHttpResponseOptions; - readonly createClient: (type: string, clientConfig?: Partial) => ClusterClient; + readonly adminClient$: Observable; + readonly createClient: (type: string, clientConfig?: Partial) => IClusterClient; // (undocumented) - readonly dataClient$: Observable; + readonly dataClient$: Observable; // (undocumented) readonly legacy: { readonly config$: Observable; @@ -279,6 +697,9 @@ export interface HttpServiceStart { // @public export type IBasePath = Pick; +// @public +export type IClusterClient = Pick; + // @public export interface IContextContainer> { createHandler(pluginOpaqueId: PluginOpaqueId, handler: THandler): (...rest: HandlerParameters) => ShallowPromise>; @@ -299,6 +720,14 @@ export interface IKibanaSocket { getPeerCertificate(detailed?: boolean): PeerCertificate | DetailedPeerCertificate | null; } +// Warning: (ae-missing-release-tag) "IndexSettingsDeprecationInfo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface IndexSettingsDeprecationInfo { + // (undocumented) + [indexName: string]: DeprecationInfo[]; +} + // @internal (undocumented) export interface InternalCoreSetup { // (undocumented) @@ -333,6 +762,9 @@ export interface IRouter { // @public export type IsAuthenticated = (request: KibanaRequest | LegacyRequest) => boolean; +// @public +export type IScopedClusterClient = Pick; + // @public export class KibanaRequest { // @internal (undocumented) @@ -494,6 +926,16 @@ export interface LogRecord { timestamp: Date; } +// Warning: (ae-missing-release-tag) "MIGRATION_ASSISTANCE_INDEX_ACTION" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type MIGRATION_ASSISTANCE_INDEX_ACTION = 'upgrade' | 'reindex'; + +// Warning: (ae-missing-release-tag) "MIGRATION_DEPRECATION_LEVEL" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type MIGRATION_DEPRECATION_LEVEL = 'none' | 'info' | 'warning' | 'critical'; + // Warning: (ae-forgotten-export) The symbol "OnPostAuthResult" needs to be exported by the entry point index.d.ts // // @public (undocumented) @@ -602,8 +1044,8 @@ export interface RequestHandlerContext { // (undocumented) core: { elasticsearch: { - dataClient: ScopedClusterClient; - adminClient: ScopedClusterClient; + dataClient: IScopedClusterClient; + adminClient: IScopedClusterClient; }; }; } @@ -1075,10 +1517,10 @@ export interface SavedObjectsUpdateResponse, options?: CallAPIOptions): Promise; - callAsInternalUser(endpoint: string, clientParams?: Record, options?: CallAPIOptions): Promise; + callAsCurrentUser(endpoint: string, clientParams?: Record, options?: CallAPIOptions): Promise; + callAsInternalUser(endpoint: string, clientParams?: Record, options?: CallAPIOptions): Promise; } // @public diff --git a/src/legacy/core_plugins/expressions/public/expressions/lib/loader.ts b/src/legacy/core_plugins/expressions/public/expressions/lib/loader.ts index d56756b6ba987..144013521f1aa 100644 --- a/src/legacy/core_plugins/expressions/public/expressions/lib/loader.ts +++ b/src/legacy/core_plugins/expressions/public/expressions/lib/loader.ts @@ -27,11 +27,11 @@ import { getInspector } from '../services'; export class ExpressionLoader { data$: Observable; - update$: Observable; - render$: Observable; - events$: Observable; + update$: ExpressionRenderHandler['update$']; + render$: ExpressionRenderHandler['render$']; + events$: ExpressionRenderHandler['events$']; - private dataHandler: ExpressionDataHandler; + private dataHandler!: ExpressionDataHandler; private renderHandler: ExpressionRenderHandler; private dataSubject: Subject; private data: Data; diff --git a/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/kibana.test.ts.snap b/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/kibana.test.ts.snap index fa90c5262a5ba..5a3810d8ddd93 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/kibana.test.ts.snap +++ b/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/kibana.test.ts.snap @@ -5,7 +5,9 @@ Object { "filters": Array [ Object { "meta": Object { + "alias": null, "disabled": false, + "negate": false, }, "query": Object { "match": Object {}, diff --git a/src/legacy/core_plugins/interpreter/public/functions/clog.ts b/src/legacy/core_plugins/interpreter/public/functions/clog.ts index 4867726a42d72..586584b498ac7 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/clog.ts +++ b/src/legacy/core_plugins/interpreter/public/functions/clog.ts @@ -17,10 +17,18 @@ * under the License. */ -export const clog = () => ({ - name: 'clog', +import { ExpressionFunction } from '../../types'; + +const name = 'clog'; + +type Context = any; +type ClogExpressionFunction = ExpressionFunction; + +export const clog = (): ClogExpressionFunction => ({ + name, + args: {}, help: 'Outputs the context to the console', - fn: (context: any) => { + fn: context => { console.log(context); // eslint-disable-line no-console return context; }, diff --git a/src/legacy/core_plugins/interpreter/public/functions/font.ts b/src/legacy/core_plugins/interpreter/public/functions/font.ts index 6f4097f22c3c0..5cd5add318e26 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/font.ts +++ b/src/legacy/core_plugins/interpreter/public/functions/font.ts @@ -33,14 +33,14 @@ import { } from '../types'; interface Arguments { - align: TextAlignment; - color: string; - family: FontFamily; - italic: boolean; - lHeight: number | null; - size: number; - underline: boolean; - weight: FontWeight; + align?: TextAlignment; + color?: string; + family?: FontFamily; + italic?: boolean; + lHeight?: number | null; + size?: number; + underline?: boolean; + weight?: FontWeight; } export function font(): ExpressionFunction<'font', null, Arguments, Style> { @@ -88,6 +88,7 @@ export function font(): ExpressionFunction<'font', null, Arguments, Style> { types: ['boolean'], }, lHeight: { + default: null, aliases: ['lineHeight'], help: i18n.translate('interpreter.functions.font.args.lHeightHelpText', { defaultMessage: 'The line height in pixels', @@ -126,7 +127,7 @@ export function font(): ExpressionFunction<'font', null, Arguments, Style> { }, }, fn: (_context, args) => { - if (!Object.values(FontWeight).includes(args.weight)) { + if (!Object.values(FontWeight).includes(args.weight!)) { throw new Error( i18n.translate('interpreter.functions.font.invalidFontWeightErrorMessage', { defaultMessage: "Invalid font weight: '{weight}'", @@ -136,7 +137,7 @@ export function font(): ExpressionFunction<'font', null, Arguments, Style> { }) ); } - if (!Object.values(TextAlignment).includes(args.align)) { + if (!Object.values(TextAlignment).includes(args.align!)) { throw new Error( i18n.translate('interpreter.functions.font.invalidTextAlignmentErrorMessage', { defaultMessage: "Invalid text alignment: '{align}'", diff --git a/src/legacy/core_plugins/interpreter/public/functions/kibana.test.ts b/src/legacy/core_plugins/interpreter/public/functions/kibana.test.ts index 9f80449ac36be..cd67825b534cd 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/kibana.test.ts +++ b/src/legacy/core_plugins/interpreter/public/functions/kibana.test.ts @@ -19,18 +19,29 @@ import { functionWrapper } from '../../test_helpers'; import { kibana } from './kibana'; +import { KibanaContext, FunctionHandlers } from '../../types'; describe('interpreter/functions#kibana', () => { const fn = functionWrapper(kibana); - let context: any; - let initialContext: any; - let handlers: any; + let context: Partial; + let initialContext: KibanaContext; + let handlers: FunctionHandlers; beforeEach(() => { context = { timeRange: { from: '0', to: '1' } }; initialContext = { + type: 'kibana_context', query: { language: 'lucene', query: 'geo.src:US' }, - filters: [{ meta: { disabled: false }, query: { match: {} } }], + filters: [ + { + meta: { + disabled: false, + negate: false, + alias: null, + }, + query: { match: {} }, + }, + ], timeRange: { from: '2', to: '3' }, }; handlers = { @@ -57,11 +68,34 @@ describe('interpreter/functions#kibana', () => { }); it('combines filters from context with initialContext', () => { - context.filters = [{ meta: { disabled: true }, query: { match: {} } }]; + context.filters = [ + { + meta: { + disabled: true, + negate: false, + alias: null, + }, + query: { match: {} }, + }, + ]; const actual = fn(context, {}, handlers); expect(actual.filters).toEqual([ - { meta: { disabled: false }, query: { match: {} } }, - { meta: { disabled: true }, query: { match: {} } }, + { + meta: { + disabled: false, + negate: false, + alias: null, + }, + query: { match: {} }, + }, + { + meta: { + disabled: true, + negate: false, + alias: null, + }, + query: { match: {} }, + }, ]); }); }); diff --git a/src/legacy/core_plugins/interpreter/public/functions/kibana.ts b/src/legacy/core_plugins/interpreter/public/functions/kibana.ts index 37ff337f58b8d..c027b220ad0d0 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/kibana.ts +++ b/src/legacy/core_plugins/interpreter/public/functions/kibana.ts @@ -18,27 +18,39 @@ */ import { i18n } from '@kbn/i18n'; +import { ExpressionFunction, KibanaContext } from '../../types'; -export const kibana = () => ({ +export type ExpressionFunctionKibana = ExpressionFunction< + 'kibana', + KibanaContext | null, + object, + KibanaContext +>; + +export const kibana = (): ExpressionFunctionKibana => ({ name: 'kibana', type: 'kibana_context', - context: {}, + + context: { + types: ['kibana_context', 'null'], + }, + help: i18n.translate('interpreter.functions.kibana.help', { defaultMessage: 'Gets kibana global context', }), args: {}, - fn(context: any, args: any, handlers: any) { + fn(context, args, handlers) { const initialContext = handlers.getInitialContext ? handlers.getInitialContext() : {}; - if (context.query) { + if (context && context.query) { initialContext.query = initialContext.query.concat(context.query); } - if (context.filters) { + if (context && context.filters) { initialContext.filters = initialContext.filters.concat(context.filters); } - const timeRange = initialContext.timeRange || context.timeRange; + const timeRange = initialContext.timeRange || (context ? context.timeRange : undefined); return { ...context, diff --git a/src/legacy/core_plugins/interpreter/public/functions/kibana_context.ts b/src/legacy/core_plugins/interpreter/public/functions/kibana_context.ts index 2f2241a367094..1ba7b450c5409 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/kibana_context.ts +++ b/src/legacy/core_plugins/interpreter/public/functions/kibana_context.ts @@ -19,8 +19,23 @@ import chrome from 'ui/chrome'; import { i18n } from '@kbn/i18n'; +import { ExpressionFunction, KibanaContext } from '../../types'; -export const kibanaContext = () => ({ +interface Arguments { + q?: string | null; + filters?: string | null; + timeRange?: string | null; + savedSearchId?: string | null; +} + +export type ExpressionFunctionKibanaContext = ExpressionFunction< + 'kibana_context', + KibanaContext | null, + Arguments, + Promise +>; + +export const kibanaContext = (): ExpressionFunctionKibanaContext => ({ name: 'kibana_context', type: 'kibana_context', context: { @@ -34,21 +49,33 @@ export const kibanaContext = () => ({ types: ['string', 'null'], aliases: ['query', '_'], default: null, + help: i18n.translate('interpreter.functions.kibana_context.q.help', { + defaultMessage: 'Specify Kibana free form text query', + }), }, filters: { types: ['string', 'null'], default: '"[]"', + help: i18n.translate('interpreter.functions.kibana_context.filters.help', { + defaultMessage: 'Specify Kibana generic filters', + }), }, timeRange: { types: ['string', 'null'], default: null, + help: i18n.translate('interpreter.functions.kibana_context.timeRange.help', { + defaultMessage: 'Specify Kibana time range filter', + }), }, savedSearchId: { types: ['string', 'null'], default: null, + help: i18n.translate('interpreter.functions.kibana_context.savedSearchId.help', { + defaultMessage: 'Specify saved search ID to be used for queries and filters', + }), }, }, - async fn(context: any, args: any) { + async fn(context, args, handlers) { const $injector = await chrome.dangerouslyGetActiveInjector(); const savedSearches = $injector.get('savedSearches') as any; const queryArg = args.q ? JSON.parse(args.q) : []; @@ -63,15 +90,19 @@ export const kibanaContext = () => ({ filters = filters.concat(searchFilters); } - if (context.query) { + if (context && context.query) { queries = queries.concat(context.query); } - if (context.filters) { + if (context && context.filters) { filters = filters.concat(context.filters).filter((f: any) => !f.meta.disabled); } - const timeRange = args.timeRange ? JSON.parse(args.timeRange) : context.timeRange; + const timeRange = args.timeRange + ? JSON.parse(args.timeRange) + : context + ? context.timeRange + : undefined; return { type: 'kibana_context', diff --git a/src/legacy/core_plugins/interpreter/public/functions/vis_dimension.ts b/src/legacy/core_plugins/interpreter/public/functions/vis_dimension.ts index 19503dbe03ae9..4190a597b0120 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/vis_dimension.ts +++ b/src/legacy/core_plugins/interpreter/public/functions/vis_dimension.ts @@ -18,8 +18,21 @@ */ import { i18n } from '@kbn/i18n'; +import { ExpressionFunction, KibanaDatatable } from '../../types'; -export const visDimension = () => ({ +const name = 'visdimension'; + +type Context = KibanaDatatable | null; + +interface Arguments { + accessor: string | number; + format?: string; + formatParams?: string; +} + +type Return = any; + +export const visDimension = (): ExpressionFunction => ({ name: 'visdimension', help: i18n.translate('interpreter.function.visDimension.help', { defaultMessage: 'Generates visConfig dimension object', @@ -39,16 +52,23 @@ export const visDimension = () => ({ format: { types: ['string'], default: 'string', + help: i18n.translate('interpreter.function.visDimension.format.help', { + defaultMessage: 'Format', + }), }, formatParams: { types: ['string'], default: '"{}"', + help: i18n.translate('interpreter.function.visDimension.formatParams.help', { + defaultMessage: 'Format params', + }), }, }, - fn: (context: any, args: any) => { - const accessor = Number.isInteger(args.accessor) - ? args.accessor - : context.columns.find((c: any) => c.id === args.accessor); + fn: (context, args) => { + const accessor = + typeof args.accessor === 'number' + ? args.accessor + : context!.columns.find(c => c.id === args.accessor); if (accessor === undefined) { throw new Error( i18n.translate('interpreter.function.visDimension.error.accessor', { @@ -62,7 +82,7 @@ export const visDimension = () => ({ accessor, format: { id: args.format, - params: JSON.parse(args.formatParams), + params: JSON.parse(args.formatParams!), }, }; }, diff --git a/src/legacy/core_plugins/interpreter/public/functions/visualization.ts b/src/legacy/core_plugins/interpreter/public/functions/visualization.ts index 94be78befd3d0..159395e7654f4 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/visualization.ts +++ b/src/legacy/core_plugins/interpreter/public/functions/visualization.ts @@ -22,57 +22,85 @@ import { i18n } from '@kbn/i18n'; import chrome from 'ui/chrome'; import { FilterBarQueryFilterProvider } from 'ui/filter_manager/query_filter'; import { PersistedState } from 'ui/persisted_state'; +import { VisResponseValue } from 'src/plugins/visualizations/public'; import { setup as data } from '../../../data/public/legacy'; import { start as visualizations } from '../../../visualizations/public/legacy'; +import { ExpressionFunction, Render } from '../../types'; -export const visualization = () => ({ +interface Arguments { + index?: string | null; + metricsAtAllLevels?: boolean; + partialRows?: boolean; + type?: string; + schemas?: string; + visConfig?: string; + uiState?: string; +} + +export type ExpressionFunctionVisualization = ExpressionFunction< + 'visualization', + any, + Arguments, + Promise> +>; + +export const visualization = (): ExpressionFunctionVisualization => ({ name: 'visualization', type: 'render', help: i18n.translate('interpreter.functions.visualization.help', { defaultMessage: 'A simple visualization', }), args: { + // TODO: Below `help` keys should be internationalized once this function + // TODO: is moved to visualizations plugin. index: { types: ['string', 'null'], default: null, + help: 'Index', }, metricsAtAllLevels: { types: ['boolean'], default: false, + help: 'Metrics levels', }, partialRows: { types: ['boolean'], default: false, + help: 'Partial rows', }, type: { types: ['string'], default: '', + help: 'Type', }, schemas: { types: ['string'], default: '"{}"', + help: 'Schemas', }, visConfig: { types: ['string'], default: '"{}"', + help: 'Visualization configuration', }, uiState: { types: ['string'], default: '"{}"', + help: 'User interface state', }, }, - async fn(context: any, args: any, handlers: any) { + async fn(context, args, handlers) { const $injector = await chrome.dangerouslyGetActiveInjector(); const Private = $injector.get('Private') as any; const { indexPatterns } = data.indexPatterns; const queryFilter = Private(FilterBarQueryFilterProvider); - const visConfigParams = JSON.parse(args.visConfig); - const schemas = JSON.parse(args.schemas); + const visConfigParams = args.visConfig ? JSON.parse(args.visConfig) : {}; + const schemas = args.schemas ? JSON.parse(args.schemas) : {}; const visType = visualizations.types.get(args.type || 'histogram') as any; const indexPattern = args.index ? await indexPatterns.get(args.index) : null; - const uiStateParams = JSON.parse(args.uiState); + const uiStateParams = args.uiState ? JSON.parse(args.uiState) : {}; const uiState = new PersistedState(uiStateParams); if (typeof visType.requestHandler === 'function') { @@ -117,7 +145,7 @@ export const visualization = () => ({ as: 'visualization', value: { visData: context, - visType: args.type, + visType: args.type || '', visConfig: visConfigParams, }, }; diff --git a/src/legacy/core_plugins/interpreter/public/interpreter.test.ts b/src/legacy/core_plugins/interpreter/public/interpreter.test.ts index 1de1e8c0cc059..429a943c3ff36 100644 --- a/src/legacy/core_plugins/interpreter/public/interpreter.test.ts +++ b/src/legacy/core_plugins/interpreter/public/interpreter.test.ts @@ -35,13 +35,13 @@ jest.mock('@kbn/interpreter/common', () => ({ registryFactory: jest.fn(), })); -const mockInterpreter = { +const mockExecutor = { interpreter: { interpretAst: jest.fn(), }, }; jest.mock('./lib/interpreter', () => ({ - initializeInterpreter: jest.fn().mockReturnValue(Promise.resolve(mockInterpreter)), + initializeExecutor: jest.fn().mockReturnValue(Promise.resolve(mockExecutor)), })); jest.mock('./registries', () => ({ @@ -59,26 +59,26 @@ jest.mock('./renderers/visualization', () => ({ visualization: {} })); describe('interpreter/interpreter', () => { let getInterpreter: any; let interpretAst: any; - let initializeInterpreter: any; + let initializeExecutor: any; beforeEach(() => { jest.clearAllMocks(); jest.resetModules(); getInterpreter = require('./interpreter').getInterpreter; interpretAst = require('./interpreter').interpretAst; - initializeInterpreter = require('./lib/interpreter').initializeInterpreter; + initializeExecutor = require('./lib/interpreter').initializeExecutor; }); describe('getInterpreter', () => { it('initializes interpreter', async () => { await getInterpreter(); - expect(initializeInterpreter).toHaveBeenCalledTimes(1); + expect(initializeExecutor).toHaveBeenCalledTimes(1); }); it('only initializes interpreter once', async () => { await getInterpreter(); await getInterpreter(); - expect(initializeInterpreter).toHaveBeenCalledTimes(1); + expect(initializeExecutor).toHaveBeenCalledTimes(1); }); it('resolves', async () => { @@ -100,21 +100,21 @@ describe('interpreter/interpreter', () => { it('initializes interpreter if needed', async () => { const params = [{}]; await interpretAst(...params); - expect(initializeInterpreter).toHaveBeenCalledTimes(1); + expect(initializeExecutor).toHaveBeenCalledTimes(1); }); it('calls interpreter.interpretAst with the provided params', async () => { const params = [{}]; await interpretAst(...params); - expect(mockInterpreter.interpreter.interpretAst).toHaveBeenCalledTimes(1); - expect(mockInterpreter.interpreter.interpretAst).toHaveBeenCalledWith(...params); + expect(mockExecutor.interpreter.interpretAst).toHaveBeenCalledTimes(1); + expect(mockExecutor.interpreter.interpretAst).toHaveBeenCalledWith({}, undefined, undefined); }); it('calls interpreter.interpretAst each time', async () => { const params = [{}]; await interpretAst(...params); await interpretAst(...params); - expect(mockInterpreter.interpreter.interpretAst).toHaveBeenCalledTimes(2); + expect(mockExecutor.interpreter.interpretAst).toHaveBeenCalledTimes(2); }); }); }); diff --git a/src/legacy/core_plugins/interpreter/public/interpreter.ts b/src/legacy/core_plugins/interpreter/public/interpreter.ts index 8ba82d5daf759..1f0f8141345d2 100644 --- a/src/legacy/core_plugins/interpreter/public/interpreter.ts +++ b/src/legacy/core_plugins/interpreter/public/interpreter.ts @@ -20,7 +20,11 @@ import 'uiExports/interpreter'; // @ts-ignore import { register, registryFactory } from '@kbn/interpreter/common'; -import { initializeInterpreter } from './lib/interpreter'; +import { + initializeExecutor, + ExpressionExecutor, + ExpressionInterpretWithHandlers, +} from './lib/interpreter'; import { registries } from './registries'; import { functions } from './functions'; import { visualization } from './renderers/visualization'; @@ -39,16 +43,16 @@ register(registries, { renderers: [visualization], }); -let interpreterPromise: Promise | undefined; +let executorPromise: Promise | undefined; export const getInterpreter = async () => { - if (!interpreterPromise) { - interpreterPromise = initializeInterpreter(); + if (!executorPromise) { + executorPromise = initializeExecutor(); } - return await interpreterPromise; + return await executorPromise; }; -export const interpretAst = async (...params: any) => { +export const interpretAst: ExpressionInterpretWithHandlers = async (ast, context, handlers) => { const { interpreter } = await getInterpreter(); - return await interpreter.interpretAst(...params); + return await interpreter.interpretAst(ast, context, handlers); }; diff --git a/src/legacy/core_plugins/interpreter/public/lib/interpreter.ts b/src/legacy/core_plugins/interpreter/public/lib/interpreter.ts index e8b946dab7163..399ecc5950268 100644 --- a/src/legacy/core_plugins/interpreter/public/lib/interpreter.ts +++ b/src/legacy/core_plugins/interpreter/public/lib/interpreter.ts @@ -17,18 +17,34 @@ * under the License. */ +import { ExpressionInterpret } from 'src/plugins/expressions/common/expressions/interpreter_provider'; import { interpreterProvider } from '../../common'; import { createHandlers } from './create_handlers'; import { registries } from '../registries'; +import { FunctionHandlers } from '../../types'; -export async function initializeInterpreter() { - const interpretAst = async (ast: any, context: any, handlers: any) => { - const interpretFn = await interpreterProvider({ +export type ExpressionInterpretWithHandlers = ( + ast: Parameters[0], + context: Parameters[1], + handlers: FunctionHandlers +) => ReturnType; + +export interface ExpressionInterpreter { + interpretAst: ExpressionInterpretWithHandlers; +} + +export interface ExpressionExecutor { + interpreter: ExpressionInterpreter; +} + +export async function initializeExecutor(): Promise { + const interpretAst: ExpressionInterpretWithHandlers = async (ast, context, handlers) => { + const interpret = await interpreterProvider({ types: registries.types.toJS(), handlers: { ...handlers, ...createHandlers() }, functions: registries.browserFunctions.toJS(), }); - return interpretFn(ast, context); + return interpret(ast, context); }; return { interpreter: { interpretAst } }; diff --git a/src/legacy/core_plugins/interpreter/test_helpers.ts b/src/legacy/core_plugins/interpreter/test_helpers.ts index 741cd83bb47fe..1f39a8271367c 100644 --- a/src/legacy/core_plugins/interpreter/test_helpers.ts +++ b/src/legacy/core_plugins/interpreter/test_helpers.ts @@ -18,12 +18,16 @@ */ import { mapValues } from 'lodash'; +import { AnyExpressionFunction, FunctionHandlers } from './types'; // Takes a function spec and passes in default args, // overriding with any provided args. -export const functionWrapper = (fnSpec: any) => { +export const functionWrapper = (fnSpec: () => T) => { const spec = fnSpec(); const defaultArgs = mapValues(spec.args, argSpec => argSpec.default); - return (context: any, args: any, handlers: any) => - spec.fn(context, { ...defaultArgs, ...args }, handlers); + return ( + context: object | null, + args: Record = {}, + handlers: FunctionHandlers = {} + ) => spec.fn(context, { ...defaultArgs, ...args }, handlers); }; diff --git a/src/legacy/core_plugins/vis_type_markdown/public/markdown_fn.test.ts b/src/legacy/core_plugins/vis_type_markdown/public/markdown_fn.test.ts index 009797905701c..81316076274b8 100644 --- a/src/legacy/core_plugins/vis_type_markdown/public/markdown_fn.test.ts +++ b/src/legacy/core_plugins/vis_type_markdown/public/markdown_fn.test.ts @@ -30,7 +30,7 @@ describe('interpreter/functions#markdown', () => { }; it('returns an object with the correct structure', async () => { - const actual = await fn(undefined, args, undefined); + const actual = await fn(null, args, undefined); expect(actual).toMatchSnapshot(); }); }); diff --git a/src/legacy/server/index_patterns/mixin.ts b/src/legacy/server/index_patterns/mixin.ts index 914bdc01063b9..a7180d6a2d70e 100644 --- a/src/legacy/server/index_patterns/mixin.ts +++ b/src/legacy/server/index_patterns/mixin.ts @@ -19,7 +19,7 @@ import { IndexPatternsService } from './service'; import KbnServer from '../kbn_server'; -import { APICaller } from '../../../core/server'; +import { APICaller, CallAPIOptions } from '../../../core/server'; import { Legacy } from '../../../../kibana'; import { registerRoutes } from './routes'; @@ -43,8 +43,11 @@ export function indexPatternsMixin(kbnServer: KbnServer, server: Legacy.Server) */ server.addMemoizedFactoryToRequest('getIndexPatternsService', (request: Legacy.Request) => { const { callWithRequest } = request.server.plugins.elasticsearch.getCluster('data'); - const callCluster: APICaller = (endpoint, params, options) => - callWithRequest(request, endpoint, params, options); + const callCluster: APICaller = ( + endpoint: string, + params?: Record, + options?: CallAPIOptions + ) => callWithRequest(request, endpoint, params, options); return server.indexPatternsServiceFactory({ callCluster }); }); diff --git a/src/legacy/server/index_patterns/routes.ts b/src/legacy/server/index_patterns/routes.ts index 60b2ea28afab5..fb78b94e0f77f 100644 --- a/src/legacy/server/index_patterns/routes.ts +++ b/src/legacy/server/index_patterns/routes.ts @@ -19,14 +19,23 @@ import { first } from 'rxjs/operators'; import { schema } from '@kbn/config-schema'; -import { CoreSetup, KibanaRequest, RequestHandlerContext, APICaller } from '../../../core/server'; +import { + CoreSetup, + KibanaRequest, + RequestHandlerContext, + APICaller, + CallAPIOptions, +} from '../../../core/server'; import { IndexPatternsService } from './service'; export function registerRoutes(core: CoreSetup) { const getIndexPatternsService = async (request: KibanaRequest): Promise => { const client = await core.elasticsearch.dataClient$.pipe(first()).toPromise(); - const callCluster: APICaller = (endpoint, params, options) => - client.asScoped(request).callAsCurrentUser(endpoint, params, options); + const callCluster: APICaller = ( + endpoint: string, + params?: Record, + options?: CallAPIOptions + ) => client.asScoped(request).callAsCurrentUser(endpoint, params, options); return new Promise(resolve => resolve(new IndexPatternsService(callCluster))); }; diff --git a/src/legacy/ui/public/visualize/loader/pipeline_data_loader.ts b/src/legacy/ui/public/visualize/loader/pipeline_data_loader.ts index 14a2e74a0ec34..c1aa6903abe88 100644 --- a/src/legacy/ui/public/visualize/loader/pipeline_data_loader.ts +++ b/src/legacy/ui/public/visualize/loader/pipeline_data_loader.ts @@ -29,7 +29,7 @@ export class PipelineDataLoader { return runPipeline( this.vis.pipelineExpression, - {}, + { type: 'null' }, { getInitialContext: () => ({ type: 'kibana_context', diff --git a/src/legacy/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts b/src/legacy/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts index 43dbb06f8c973..78a959b2b0f71 100644 --- a/src/legacy/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts +++ b/src/legacy/ui/public/visualize/loader/pipeline_helpers/run_pipeline.ts @@ -19,10 +19,8 @@ // @ts-ignore import { fromExpression } from '@kbn/interpreter/common'; -// @ts-ignore -import { getInterpreter } from 'plugins/interpreter/interpreter'; - import { Adapters } from 'ui/inspector'; +import { getInterpreter } from '../../../../../core_plugins/interpreter/public/interpreter'; import { KibanaContext } from '../../../../../core_plugins/interpreter/public'; type getInitialContextFunction = () => KibanaContext; @@ -35,11 +33,11 @@ export interface RunPipelineHandlers { export const runPipeline = async ( expression: string, - context: object, + context: any, handlers: RunPipelineHandlers ) => { const ast = fromExpression(expression); const { interpreter } = await getInterpreter(); - const pipelineResponse = await interpreter.interpretAst(ast, context, handlers); + const pipelineResponse = await interpreter.interpretAst(ast, context, handlers as any); return pipelineResponse; }; diff --git a/src/legacy/ui/public/visualize/loader/types.ts b/src/legacy/ui/public/visualize/loader/types.ts index bb1113d212261..87183d839e637 100644 --- a/src/legacy/ui/public/visualize/loader/types.ts +++ b/src/legacy/ui/public/visualize/loader/types.ts @@ -21,7 +21,7 @@ import { Filter } from '@kbn/es-query'; import { TimeRange } from 'src/plugins/data/public'; import { Query } from 'src/legacy/core_plugins/data/public'; import { SavedObject } from 'ui/saved_objects/saved_object'; - +import { VisResponseValue } from 'src/plugins/visualizations/public'; import { SearchSource } from '../../courier'; import { PersistedState } from '../../persisted_state'; import { AppState } from '../../state_management/app_state'; @@ -36,13 +36,6 @@ export interface VisSavedObject extends SavedObject { destroy: () => void; } -interface VisResponseValue { - visType: string; - visData: object; - visConfig: object; - params?: object; -} - export interface VisResponseData { as: string; value: VisResponseValue; diff --git a/src/plugins/expressions/common/expressions/create_error.ts b/src/plugins/expressions/common/expressions/create_error.ts index cee288e5e1b35..8236ff8709a82 100644 --- a/src/plugins/expressions/common/expressions/create_error.ts +++ b/src/plugins/expressions/common/expressions/create_error.ts @@ -17,11 +17,18 @@ * under the License. */ -export const createError = (err: any) => ({ +type ErrorLike = Partial>; + +export const createError = (err: string | ErrorLike) => ({ type: 'error', error: { - stack: process.env.NODE_ENV === 'production' ? undefined : err.stack, + stack: + process.env.NODE_ENV === 'production' + ? undefined + : typeof err === 'object' + ? err.stack + : undefined, message: typeof err === 'string' ? err : err.message, - name: (err && err.name) || 'Error', + name: typeof err === 'object' ? err.name || 'Error' : 'Error', }, }); diff --git a/src/plugins/expressions/common/expressions/expression_types/boolean.ts b/src/plugins/expressions/common/expressions/expression_types/boolean.ts index 84beaf1cc66e5..0ad2c14f87756 100644 --- a/src/plugins/expressions/common/expressions/expression_types/boolean.ts +++ b/src/plugins/expressions/common/expressions/expression_types/boolean.ts @@ -23,7 +23,7 @@ import { Render } from './render'; const name = 'boolean'; -export const boolean = (): ExpressionType => ({ +export const boolean = (): ExpressionType<'boolean', boolean> => ({ name, from: { null: () => false, diff --git a/src/plugins/expressions/common/expressions/expression_types/datatable.ts b/src/plugins/expressions/common/expressions/expression_types/datatable.ts index ef5e24278f497..3c0b5ca9bba58 100644 --- a/src/plugins/expressions/common/expressions/expression_types/datatable.ts +++ b/src/plugins/expressions/common/expressions/expression_types/datatable.ts @@ -29,8 +29,8 @@ const name = 'datatable'; * A Utility function that Typescript can use to determine if an object is a Datatable. * @param datatable */ -export const isDatatable = (datatable: any): datatable is Datatable => - !!datatable && datatable.type === 'datatable'; +export const isDatatable = (datatable: unknown): datatable is Datatable => + !!datatable && typeof datatable === 'object' && (datatable as any).type === 'datatable'; /** * This type represents the `type` of any `DatatableColumn` in a `Datatable`. @@ -38,7 +38,7 @@ export const isDatatable = (datatable: any): datatable is Datatable => export type DatatableColumnType = 'string' | 'number' | 'boolean' | 'date' | 'null'; /** - * This type represents a `DatatableRow` in a `Datatable`. + * This type represents a row in a `Datatable`. */ export type DatatableRow = Record; @@ -95,64 +95,48 @@ export const datatable = (): ExpressionType { + rows: rows.map(row => { return zipObject(map(columns, 'name'), row); }), }; }, from: { - null: () => { - return { - type: name, - rows: [], - columns: [], - }; - }, - pointseries: (context: PointSeries) => { - return { - type: name, - rows: context.rows, - columns: map(context.columns, (val, colName) => { - return { name: colName!, type: val.type }; - }), - }; - }, + null: () => ({ + type: name, + rows: [], + columns: [], + }), + pointseries: (value: PointSeries) => ({ + type: name, + rows: value.rows, + columns: map(value.columns, (val, colName) => { + return { name: colName!, type: val.type }; + }), + }), }, to: { - render: (table): Render => { - return { - type: 'render', - as: 'table', - value: { - datatable: table, - paginate: true, - perPage: 10, - showHeader: true, - }, - }; - }, - pointseries: (table): PointSeries => { - // datatable columns are an array that looks like [{ name: "one", type: "string" }, { name: "two", type: "string" }] - // rows look like [{ one: 1, two: 2}, { one: 3, two: 4}, ...] + render: (table): Render => ({ + type: 'render', + as: 'table', + value: { + datatable: table, + paginate: true, + perPage: 10, + showHeader: true, + }, + }), + pointseries: (table: Datatable): PointSeries => { const validFields = ['x', 'y', 'color', 'size', 'text']; const columns = table.columns.filter(column => validFields.includes(column.name)); const rows = table.rows.map(row => pick(row, validFields)); - return { type: 'pointseries', - columns: columns.reduce((acc: Record, column) => { - /* pointseries columns are an object that looks like this - * { - * x: { type: "string", expression: "x", role: "dimension" }, - * y: { type: "string", expression: "y", role: "dimension" } - * } - */ + columns: columns.reduce>((acc, column) => { acc[column.name] = { type: column.type, expression: column.name, role: 'dimension', }; - return acc; }, {}), rows, diff --git a/src/plugins/expressions/common/expressions/expression_types/error.ts b/src/plugins/expressions/common/expressions/expression_types/error.ts index ffafc1ecd9184..f70ddf90c3de5 100644 --- a/src/plugins/expressions/common/expressions/expression_types/error.ts +++ b/src/plugins/expressions/common/expressions/expression_types/error.ts @@ -19,17 +19,26 @@ import { ExpressionType } from '../types'; import { Render } from './render'; +import { ExpressionValueBoxed } from '../types/types'; const name = 'error'; -// TODO: Improve typings on this interface [#38553] -export interface InterpreterErrorType { - type: typeof name; - error: unknown; - info: unknown; -} +export type ExpressionValueError = ExpressionValueBoxed< + 'error', + { + error: unknown; + info: unknown; + } +>; -export const error = (): ExpressionType => ({ +/** + * @deprecated + * + * Exported for backwards compatibility. + */ +export type InterpreterErrorType = ExpressionValueError; + +export const error = (): ExpressionType<'error', ExpressionValueError> => ({ name, to: { render: (input): Render> => { diff --git a/src/plugins/expressions/common/expressions/expression_types/kibana_context.ts b/src/plugins/expressions/common/expressions/expression_types/kibana_context.ts index 0c76e5e83a5ee..174517abc2c05 100644 --- a/src/plugins/expressions/common/expressions/expression_types/kibana_context.ts +++ b/src/plugins/expressions/common/expressions/expression_types/kibana_context.ts @@ -25,7 +25,7 @@ export type KIBANA_CONTEXT_NAME = 'kibana_context'; export interface KibanaContext { type: typeof name; - query?: Query; + query?: Query | Query[]; filters?: Filter[]; timeRange?: TimeRange; } diff --git a/src/plugins/expressions/common/expressions/expression_types/kibana_datatable.ts b/src/plugins/expressions/common/expressions/expression_types/kibana_datatable.ts index c145ed2b48445..7f77e226ff1d9 100644 --- a/src/plugins/expressions/common/expressions/expression_types/kibana_datatable.ts +++ b/src/plugins/expressions/common/expressions/expression_types/kibana_datatable.ts @@ -19,6 +19,7 @@ import { map } from 'lodash'; import { SerializedFieldFormat } from '../types/common'; +import { Datatable, PointSeries } from '../types'; const name = 'kibana_datatable'; @@ -41,12 +42,11 @@ export interface KibanaDatatable { export const kibanaDatatable = () => ({ name, from: { - // TODO: import datatable types here instead of using any - datatable: (context: any) => { + datatable: (context: Datatable) => { return { type: name, rows: context.rows, - columns: context.columns.map((column: any) => { + columns: context.columns.map(column => { return { id: column.name, name: column.name, @@ -54,8 +54,7 @@ export const kibanaDatatable = () => ({ }), }; }, - // TODO: import pointseries types here instead of using any - pointseries: (context: any) => { + pointseries: (context: PointSeries) => { const columns = map(context.columns, (column, n) => { return { id: n, name: n, ...column }; }); diff --git a/src/plugins/expressions/common/expressions/expression_types/pointseries.ts b/src/plugins/expressions/common/expressions/expression_types/pointseries.ts index dfad139dd20c5..adf2bfc67f160 100644 --- a/src/plugins/expressions/common/expressions/expression_types/pointseries.ts +++ b/src/plugins/expressions/common/expressions/expression_types/pointseries.ts @@ -20,6 +20,7 @@ import { ExpressionType } from '../types'; import { Datatable } from './datatable'; import { Render } from './render'; +import { ExpressionValueBoxed } from '../types/types'; const name = 'pointseries'; @@ -42,16 +43,20 @@ export interface PointSeriesColumn { */ export type PointSeriesColumns = Record | {}; +export type PointSeriesRow = Record; + /** * A `PointSeries` is a unique structure that represents dots on a chart. */ -export interface PointSeries { - type: typeof name; - columns: PointSeriesColumns; - rows: Array>; -} +export type PointSeries = ExpressionValueBoxed< + 'pointseries', + { + columns: PointSeriesColumns; + rows: PointSeriesRow[]; + } +>; -export const pointseries = (): ExpressionType => ({ +export const pointseries = (): ExpressionType<'pointseries', PointSeries> => ({ name, from: { null: () => { diff --git a/src/plugins/expressions/common/expressions/expression_types/render.ts b/src/plugins/expressions/common/expressions/expression_types/render.ts index 22c6e469eb771..3d6852b897508 100644 --- a/src/plugins/expressions/common/expressions/expression_types/render.ts +++ b/src/plugins/expressions/common/expressions/expression_types/render.ts @@ -18,17 +18,20 @@ */ import { ExpressionType } from '../types'; +import { ExpressionValueBoxed } from '../types/types'; const name = 'render'; /** * Represents an object that is intended to be rendered. */ -export interface Render { - type: typeof name; - as: string; - value: T; -} +export type Render = ExpressionValueBoxed< + typeof name, + { + as: string; + value: T; + } +>; export const render = (): ExpressionType> => ({ name, diff --git a/src/plugins/expressions/common/expressions/expression_types/shape.ts b/src/plugins/expressions/common/expressions/expression_types/shape.ts index 434bab97e4037..e8f6fbdc8062e 100644 --- a/src/plugins/expressions/common/expressions/expression_types/shape.ts +++ b/src/plugins/expressions/common/expressions/expression_types/shape.ts @@ -20,12 +20,10 @@ import { ExpressionType } from '../types'; import { Render } from './render'; -const name = 'shape'; - -export const shape = (): ExpressionType => ({ - name, +export const shape = (): ExpressionType<'shape', Render> => ({ + name: 'shape', to: { - render: (input: T): Render => { + render: input => { return { type: 'render', as: name, diff --git a/src/plugins/expressions/common/expressions/interpreter_provider.ts b/src/plugins/expressions/common/expressions/interpreter_provider.ts index 7a9309a2a42f2..59ba1085a9d7d 100644 --- a/src/plugins/expressions/common/expressions/interpreter_provider.ts +++ b/src/plugins/expressions/common/expressions/interpreter_provider.ts @@ -21,37 +21,29 @@ import { clone, each, keys, last, mapValues, reduce, zipObject } from 'lodash'; // @ts-ignore -import { fromExpression, getType, getByAlias, castProvider } from '@kbn/interpreter/common'; +import { fromExpression, getByAlias, castProvider } from '@kbn/interpreter/common'; import { createError } from './create_error'; -import { ExpressionAST } from './types'; +import { ExpressionAST, ExpressionFunctionAST, AnyExpressionFunction, ArgumentType } from './types'; +import { getType } from '../../common'; export { createError }; -export function interpreterProvider(config: any) { +export interface InterpreterConfig { + functions: any; + types: any; + handlers: any; +} + +export type ExpressionInterpret = (ast: ExpressionAST, context?: any) => any; + +export function interpreterProvider(config: InterpreterConfig): ExpressionInterpret { const { functions, types } = config; const handlers = { ...config.handlers, types }; const cast = castProvider(types); - return interpret; - - async function interpret(node: ExpressionAST, context = null) { - switch (getType(node)) { - case 'expression': - return invokeChain(node.chain, context); - case 'string': - case 'number': - case 'null': - case 'boolean': - return node; - default: - throw new Error(`Unknown AST object: ${JSON.stringify(node)}`); - } - } - - async function invokeChain(chainArr: any, context: any): Promise { - if (!chainArr.length) return Promise.resolve(context); - + async function invokeChain(chainArr: ExpressionFunctionAST[], context: any): Promise { + if (!chainArr.length) return context; // if execution was aborted return error if (handlers.abortSignal && handlers.abortSignal.aborted) { return createError({ @@ -59,9 +51,9 @@ export function interpreterProvider(config: any) { name: 'AbortError', }); } - const chain = clone(chainArr); const link = chain.shift(); // Every thing in the chain will always be a function right? + if (!link) throw Error('Function chain is empty.'); const { function: fnName, arguments: fnArgs } = link; const fnDef = getByAlias(functions, fnName); @@ -89,9 +81,13 @@ export function interpreterProvider(config: any) { } } - async function invokeFunction(fnDef: any, context: any, args: any): Promise { + async function invokeFunction( + fnDef: AnyExpressionFunction, + context: any, + args: Record + ): Promise { // Check function input. - const acceptableContext = cast(context, fnDef.context.types); + const acceptableContext = cast(context, fnDef.context ? fnDef.context.types : undefined); const fnOutput = await fnDef.fn(acceptableContext, args, handlers); // Validate that the function returned the type it said it would. @@ -119,7 +115,11 @@ export function interpreterProvider(config: any) { } // Processes the multi-valued AST argument values into arguments that can be passed to the function - async function resolveArgs(fnDef: any, context: any, argAsts: any): Promise { + async function resolveArgs( + fnDef: AnyExpressionFunction, + context: any, + argAsts: any + ): Promise { const argDefs = fnDef.args; // Use the non-alias name from the argument definition @@ -140,13 +140,15 @@ export function interpreterProvider(config: any) { // Check for missing required arguments each(argDefs, argDef => { - const { aliases, default: argDefault, name: argName, required } = argDef; + const { aliases, default: argDefault, name: argName, required } = argDef as (ArgumentType< + any + > & { name: string }); if ( typeof argDefault === 'undefined' && required && typeof dealiasedArgAsts[argName] === 'undefined' ) { - if (aliases.length === 0) { + if (!aliases || aliases.length === 0) { throw new Error(`${fnDef.name} requires an argument`); } else { const errorArg = argName === '_' ? aliases[0] : argName; // use an alias if _ is the missing arg @@ -204,4 +206,21 @@ export function interpreterProvider(config: any) { // function which would be treated as a promise return { resolvedArgs }; } + + const interpret: ExpressionInterpret = async function interpret(ast, context = null) { + const type = getType(ast); + switch (type) { + case 'expression': + return invokeChain(ast.chain, context); + case 'string': + case 'number': + case 'null': + case 'boolean': + return ast; + default: + throw new Error(`Unknown AST object: ${JSON.stringify(ast)}`); + } + }; + + return interpret; } diff --git a/src/plugins/expressions/common/expressions/serialize_provider.ts b/src/plugins/expressions/common/expressions/serialize_provider.ts index 1bd06a38a2560..067c59c4689e3 100644 --- a/src/plugins/expressions/common/expressions/serialize_provider.ts +++ b/src/plugins/expressions/common/expressions/serialize_provider.ts @@ -20,7 +20,7 @@ import { get, identity } from 'lodash'; export function getType(node: any) { - if (node == null) return 'null'; + if (!node) return 'null'; if (typeof node === 'object') { if (!node.type) throw new Error('Objects must have a type property'); return node.type; diff --git a/src/plugins/expressions/common/expressions/types/functions.ts b/src/plugins/expressions/common/expressions/types/functions.ts index d640e351c5640..5ead129398e42 100644 --- a/src/plugins/expressions/common/expressions/types/functions.ts +++ b/src/plugins/expressions/common/expressions/types/functions.ts @@ -42,6 +42,8 @@ export interface ExpressionFunction any; } + +export type AnyExpressionFunction = ExpressionFunction; diff --git a/src/plugins/expressions/common/expressions/types/index.ts b/src/plugins/expressions/common/expressions/types/index.ts index 06f19023320a2..baa0850cfd76c 100644 --- a/src/plugins/expressions/common/expressions/types/index.ts +++ b/src/plugins/expressions/common/expressions/types/index.ts @@ -25,8 +25,8 @@ export { UnmappedTypeStrings, UnwrapPromise, } from './common'; -export { ExpressionFunction } from './functions'; -export { ExpressionType } from './types'; +export { ExpressionFunction, AnyExpressionFunction, FunctionHandlers } from './functions'; +export { ExpressionType, AnyExpressionType } from './types'; export * from '../expression_types'; export type ExpressionArgAST = string | boolean | number | ExpressionAST; diff --git a/src/plugins/expressions/common/expressions/types/types.ts b/src/plugins/expressions/common/expressions/types/types.ts index a6c8a564a4484..59297e922d313 100644 --- a/src/plugins/expressions/common/expressions/types/types.ts +++ b/src/plugins/expressions/common/expressions/types/types.ts @@ -17,17 +17,40 @@ * under the License. */ +export type ExpressionValueUnboxed = any; + +export type ExpressionValueBoxed = { + type: Type; +} & Value; + +export type ExpressionValue = ExpressionValueUnboxed | ExpressionValueBoxed; + +export type ExpressionValueConverter = ( + input: I, + availableTypes: Record +) => O; + /** * A generic type which represents a custom Expression Type Definition that's * registered to the Interpreter. */ -export interface ExpressionType { +export interface ExpressionType< + Name extends string, + Value extends ExpressionValueUnboxed | ExpressionValueBoxed, + SerializedType = undefined +> { name: Name; validate?: (type: any) => void | Error; - serialize?: (type: Type) => SerializedType; - deserialize?: (type: SerializedType) => Type; + serialize?: (type: Value) => SerializedType; + deserialize?: (type: SerializedType) => Value; // TODO: Update typings for the `availableTypes` parameter once interfaces for this // have been added elsewhere in the interpreter. - from?: Record) => Type>; - to?: Record) => unknown>; + from?: { + [type: string]: ExpressionValueConverter; + }; + to?: { + [type: string]: ExpressionValueConverter; + }; } + +export type AnyExpressionType = ExpressionType; diff --git a/src/plugins/expressions/public/expressions/expressions_service.ts b/src/plugins/expressions/public/expressions/expressions_service.ts index 77c3d43f61900..4b6820143b794 100644 --- a/src/plugins/expressions/public/expressions/expressions_service.ts +++ b/src/plugins/expressions/public/expressions/expressions_service.ts @@ -18,12 +18,12 @@ */ import { FunctionsRegistry, RenderFunctionsRegistry, TypesRegistry } from './interpreter'; -import { ExpressionType } from '../../common/expressions/types'; +import { AnyExpressionType, AnyExpressionFunction } from '../../common/expressions/types'; export interface ExpressionsSetupContract { - registerFunction: (fn: any) => void; + registerFunction: (fn: () => AnyExpressionFunction) => void; registerRenderer: (renderer: any) => void; - registerType: (type: () => ExpressionType) => void; + registerType: (type: () => AnyExpressionType) => void; __LEGACY: { functions: FunctionsRegistry; renderers: RenderFunctionsRegistry; @@ -44,13 +44,13 @@ export class ExpressionsService { const { functions, renderers, types } = this; this.setupApi = { - registerFunction: (fn: any) => { + registerFunction: fn => { this.functions.register(fn); }, registerRenderer: (renderer: any) => { this.renderers.register(renderer); }, - registerType: (type: () => ExpressionType) => { + registerType: type => { this.types.register(type); }, __LEGACY: { diff --git a/src/plugins/expressions/public/expressions/interpreter.ts b/src/plugins/expressions/public/expressions/interpreter.ts index 336d672f0a621..f27ef57c7980a 100644 --- a/src/plugins/expressions/public/expressions/interpreter.ts +++ b/src/plugins/expressions/public/expressions/interpreter.ts @@ -26,7 +26,7 @@ /* eslint-disable max-classes-per-file */ import { clone, mapValues, includes } from 'lodash'; import { Type } from '../../common/expressions/interpreter'; -import { ExpressionType } from '../../common/expressions/types'; +import { ExpressionType, AnyExpressionFunction } from '../../common/expressions/types'; export class Registry { _prop: string; @@ -160,7 +160,7 @@ export class RenderFunctionsRegistry extends Registry { } } -export class FunctionsRegistry extends Registry { +export class FunctionsRegistry extends Registry { wrapper(obj: any) { return new (Fn as any)(obj); } diff --git a/src/legacy/core_plugins/interpreter/public/lib/render_function.ts b/src/plugins/visualizations/public/index.ts similarity index 50% rename from src/legacy/core_plugins/interpreter/public/lib/render_function.ts rename to src/plugins/visualizations/public/index.ts index 76d1f58b66195..d8f7b5091eb8f 100644 --- a/src/legacy/core_plugins/interpreter/public/lib/render_function.ts +++ b/src/plugins/visualizations/public/index.ts @@ -17,26 +17,4 @@ * under the License. */ -export function RenderFunction(this: any, config: any) { - // This must match the name of the function that is used to create the `type: render` object - this.name = config.name; - - // Use this to set a more friendly name - this.displayName = config.displayName || this.name; - - // A sentence or few about what this element does - this.help = config.help; - - // used to validate the data before calling the render function - this.validate = config.validate || function validate() {}; - - // tell the renderer if the dom node should be reused, it's recreated each time by default - this.reuseDomNode = Boolean(config.reuseDomNode); - - // the function called to render the data - this.render = - config.render || - function render(domNode: any, data: any, done: any) { - done(); - }; -} +export * from './types'; diff --git a/src/legacy/core_plugins/interpreter/public/lib/render_functions_registry.ts b/src/plugins/visualizations/public/types.ts similarity index 74% rename from src/legacy/core_plugins/interpreter/public/lib/render_functions_registry.ts rename to src/plugins/visualizations/public/types.ts index 427e7f7454c24..6487266956119 100644 --- a/src/legacy/core_plugins/interpreter/public/lib/render_functions_registry.ts +++ b/src/plugins/visualizations/public/types.ts @@ -17,13 +17,9 @@ * under the License. */ -import { Registry } from '@kbn/interpreter/common'; -import { RenderFunction } from './render_function'; - -class RenderFunctionsRegistry extends Registry { - wrapper(obj: any) { - return new (RenderFunction as any)(obj); - } +export interface VisResponseValue { + visType: string; + visData: object; + visConfig: object; + params?: object; } - -export { RenderFunctionsRegistry }; diff --git a/test/interpreter_functional/test_suites/run_pipeline/helpers.js b/test/interpreter_functional/test_suites/run_pipeline/helpers.js index aacdf1f615bd7..6186720b617af 100644 --- a/test/interpreter_functional/test_suites/run_pipeline/helpers.js +++ b/test/interpreter_functional/test_suites/run_pipeline/helpers.js @@ -66,6 +66,8 @@ export const expectExpressionProvider = ({ getService, updateBaselines }) => { runExpression: async (step, stepContext) => { log.debug(`running expression ${step || expression}`); const promise = browser.executeAsync((expression, context, initialContext, done) => { + if (!context) context = {}; + if (!context.type) context.type = 'null'; window.runPipeline(expression, context, initialContext).then(result => { done(result); }); diff --git a/x-pack/legacy/plugins/code/index.ts b/x-pack/legacy/plugins/code/index.ts index c4cd23fa872ba..c66718024bba6 100644 --- a/x-pack/legacy/plugins/code/index.ts +++ b/x-pack/legacy/plugins/code/index.ts @@ -39,6 +39,7 @@ export const code = (kibana: any) => const config = server.config(); return { codeUiEnabled: config.get('xpack.code.ui.enabled'), + codeIntegrationsEnabled: config.get('xpack.code.integrations.enabled'), }; }, hacks: ['plugins/code/hacks/toggle_app_link_in_nav'], @@ -50,6 +51,9 @@ export const code = (kibana: any) => ui: Joi.object({ enabled: Joi.boolean().default(true), }).default(), + integrations: Joi.object({ + enabled: Joi.boolean().default(false), + }).default(), enabled: Joi.boolean().default(true), }).default(); }, diff --git a/x-pack/legacy/plugins/code/public/components/app.tsx b/x-pack/legacy/plugins/code/public/components/app.tsx index 54363213bcad5..e87e9dd88e6a4 100644 --- a/x-pack/legacy/plugins/code/public/components/app.tsx +++ b/x-pack/legacy/plugins/code/public/components/app.tsx @@ -7,6 +7,7 @@ import React from 'react'; import { HashRouter as Router, Redirect, Switch } from 'react-router-dom'; +import chrome from 'ui/chrome'; import { connect } from 'react-redux'; import { RootState } from '../reducers'; import { Admin } from './admin_page/admin'; @@ -17,6 +18,7 @@ import { NotFound } from './main/not_found'; import { Route } from './route'; import * as ROUTES from './routes'; import { Search } from './search_page/search'; +import { Integrations } from './integrations'; const RooComponent = (props: { setupOk?: boolean }) => { if (props.setupOk) { @@ -33,6 +35,8 @@ const Root = connect(mapStateToProps)(RooComponent); const Empty = () => null; +const integrationsEnabled = chrome.getInjected('codeIntegrationsEnabled'); + export const App = () => { return ( @@ -45,6 +49,9 @@ export const App = () => { + {integrationsEnabled && ( + + )} diff --git a/x-pack/legacy/plugins/code/public/components/codeblock/codeblock.tsx b/x-pack/legacy/plugins/code/public/components/codeblock/codeblock.tsx index 910129eb1a3c1..89c9e9137158f 100644 --- a/x-pack/legacy/plugins/code/public/components/codeblock/codeblock.tsx +++ b/x-pack/legacy/plugins/code/public/components/codeblock/codeblock.tsx @@ -5,50 +5,72 @@ */ import { EuiPanel } from '@elastic/eui'; -import { editor, IPosition, IRange } from 'monaco-editor'; +import { editor, IRange } from 'monaco-editor'; import React from 'react'; import { ResizeChecker } from '../shared/resize_checker'; import { monaco } from '../../monaco/monaco'; import { registerEditor } from '../../monaco/single_selection_helper'; -interface Props { - code: string; - fileComponent?: React.ReactNode; - startLine?: number; - language?: string; - highlightRanges?: IRange[]; - onClick?: (event: IPosition) => void; +export interface Position { + lineNumber: string; + column: number; +} + +export interface Props { + content: string; + header: React.ReactNode; + language: string; + highlightRanges: IRange[]; + onClick: (event: Position) => void; folding: boolean; - lineNumbersFunc: (line: number) => string; + /** + * Returns the line number to display for a given line. + * @param lineIndex The index of the given line (0-indexed) + */ + lineNumber: (lineIndex: number) => string; + className?: string; } export class CodeBlock extends React.PureComponent { + static defaultProps = { + header: undefined, + folding: false, + highlightRanges: [], + language: 'text', + lineNumber: String, + onClick: () => {}, + }; + private el: HTMLDivElement | null = null; private ed?: editor.IStandaloneCodeEditor; private resizeChecker?: ResizeChecker; private currentHighlightDecorations: string[] = []; public async componentDidMount() { + const { content, highlightRanges, language, onClick } = this.props; + if (this.el) { - await this.tryLoadFile(this.props.code, this.props.language || 'text'); + await this.tryLoadFile(content, language); this.ed!.onMouseDown((e: editor.IEditorMouseEvent) => { if ( - this.props.onClick && + onClick && (e.target.type === monaco.editor.MouseTargetType.GUTTER_LINE_NUMBERS || e.target.type === monaco.editor.MouseTargetType.CONTENT_TEXT) ) { const position = e.target.position || { lineNumber: 0, column: 0 }; - const lineNumber = (this.props.startLine || 0) + position.lineNumber; - this.props.onClick({ + const lineNumber = this.lineNumber(position.lineNumber); + + onClick({ lineNumber, column: position.column, }); } }); registerEditor(this.ed!); - if (this.props.highlightRanges) { - const decorations = this.props.highlightRanges.map((range: IRange) => { + + if (highlightRanges.length) { + const decorations = highlightRanges.map((range: IRange) => { return { range, options: { @@ -66,6 +88,7 @@ export class CodeBlock extends React.PureComponent { }); } } + private async tryLoadFile(code: string, language: string) { try { await monaco.editor.colorize(code, language, {}); @@ -79,7 +102,7 @@ export class CodeBlock extends React.PureComponent { this.ed = monaco.editor.create(this.el!, { value: code, language, - lineNumbers: this.lineNumbersFunc.bind(this), + lineNumbers: this.lineNumber, readOnly: true, folding: this.props.folding, minimap: { @@ -103,17 +126,16 @@ export class CodeBlock extends React.PureComponent { } public componentDidUpdate(prevProps: Readonly) { - if ( - prevProps.code !== this.props.code || - prevProps.highlightRanges !== this.props.highlightRanges - ) { + const { content, highlightRanges } = this.props; + + if (prevProps.content !== content || prevProps.highlightRanges !== highlightRanges) { if (this.ed) { const model = this.ed.getModel(); if (model) { - model.setValue(this.props.code); + model.setValue(content); - if (this.props.highlightRanges) { - const decorations = this.props.highlightRanges!.map((range: IRange) => { + if (highlightRanges.length) { + const decorations = highlightRanges!.map((range: IRange) => { return { range, options: { @@ -138,19 +160,20 @@ export class CodeBlock extends React.PureComponent { } public render() { - const linesCount = this.props.code.split('\n').length; + const { className, header } = this.props; + const height = this.lines.length * 18; + return ( - - {this.props.fileComponent} -
(this.el = r)} style={{ height: linesCount * 18 }} /> + + {header} +
(this.el = r)} style={{ height }} /> ); } - private lineNumbersFunc = (line: number) => { - if (this.props.lineNumbersFunc) { - return this.props.lineNumbersFunc(line); - } - return `${(this.props.startLine || 0) + line}`; - }; + private lineNumber = (lineIndex: number) => this.props.lineNumber(lineIndex - 1); + + private get lines(): string[] { + return this.props.content.split('\n'); + } } diff --git a/x-pack/legacy/plugins/code/public/components/editor/references_panel.tsx b/x-pack/legacy/plugins/code/public/components/editor/references_panel.tsx index 219c5e837155c..785238eb5fab7 100644 --- a/x-pack/legacy/plugins/code/public/components/editor/references_panel.tsx +++ b/x-pack/legacy/plugins/code/public/components/editor/references_panel.tsx @@ -14,13 +14,12 @@ import { EuiTitle, } from '@elastic/eui'; import classname from 'classnames'; -import { IPosition } from 'monaco-editor'; import queryString from 'querystring'; import React from 'react'; import { parseSchema } from '../../../common/uri_util'; import { GroupedFileResults, GroupedRepoResults } from '../../actions'; import { history } from '../../utils/url'; -import { CodeBlock } from '../codeblock/codeblock'; +import { CodeBlock, Position } from '../codeblock/codeblock'; interface Props { isLoading: boolean; @@ -114,12 +113,9 @@ export class ReferencesPanel extends React.Component { private renderReference(file: GroupedFileResults) { const key = `${file.uri}`; - const lineNumberFn = (l: number) => { - return file.lineNumbers[l - 1]; - }; - const fileComponent = ( + const header = ( - + {file.file} @@ -128,23 +124,22 @@ export class ReferencesPanel extends React.Component { return ( file.lineNumbers[i]} highlightRanges={file.highlights} - fileComponent={fileComponent} - onClick={this.onCodeClick.bind(this, file.lineNumbers, file.uri)} + onClick={this.onCodeClick(file.uri)} /> ); } - private onCodeClick(lineNumbers: string[], url: string, pos: IPosition) { - const line = parseInt(lineNumbers[pos.lineNumber - 1], 10); - history.push(this.computeUrl(url, line)); - } + private onCodeClick = (url: string) => (position: Position) => { + const lineNum = parseInt(position.lineNumber, 10); + history.push(this.computeUrl(url, lineNum)); + }; private computeUrl(url: string, line?: number) { const { uri } = parseSchema(url)!; @@ -158,6 +153,7 @@ export class ReferencesPanel extends React.Component { tab: 'references', refUrl: this.props.refUrl, }); + return line !== undefined ? `${uri}!L${line}:0?${query}` : `${uri}?${query}`; } } diff --git a/x-pack/legacy/plugins/code/public/components/integrations/data.ts b/x-pack/legacy/plugins/code/public/components/integrations/data.ts new file mode 100644 index 0000000000000..83137dff158ee --- /dev/null +++ b/x-pack/legacy/plugins/code/public/components/integrations/data.ts @@ -0,0 +1,159 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export interface Snippet { + uri: string; + filePath: string; + language?: string; + compositeContent: { + content: string; + lineMapping: string[]; + }; +} + +export type Results = Record; + +export const results: Results = { + 'ringside.ts#L18': { + uri: 'github.com/rylnd/ringside', + filePath: 'src/ringside.ts', + language: 'typescript', + compositeContent: { + content: + "\nimport { fitsInside, fitsOutside } from './fitting';\n\nexport interface RingsideInterface {\n positions(): FittedPosition[];\n}\n\nclass Ringside implements RingsideInterface {\n readonly innerBounds: FullRect;\n readonly outerBounds: FullRect;\n\n}\n\nexport default Ringside;\n", + lineMapping: [ + '..', + '13', + '14', + '15', + '16', + '17', + '18', + '19', + '20', + '21', + '..', + '67', + '68', + '69', + '70', + ], + }, + }, + 'ringside.story.tsx#L12': { + uri: 'github.com/rylnd/ringside', + filePath: 'stories/ringside.story.tsx', + language: 'typescript', + compositeContent: { + content: + "\nimport { interpolateRainbow } from 'd3-scale-chromatic';\n\nimport { Ringside } from '../src';\nimport { XAlignment, YAlignment, XBasis, YBasis } from '../src/types';\n\nlet ringside: Ringside;\n\nconst enumKeys: (e: any) => string[] = e =>\n\n\nconst color = position => {\n const combos = ringside.positions().map(p => JSON.stringify(p));\n const hash = combos.indexOf(JSON.stringify(position)) / combos.length;\n\n\n};\n\nconst Stories = storiesOf('Ringside', module).addDecorator(withKnobs);\n\nStories.add('Ringside', () => {\n", + lineMapping: [ + '..', + '5', + '6', + '7', + '8', + '9', + '10', + '11', + '12', + '..', + '14', + '15', + '16', + '17', + '18', + '..', + '20', + '21', + '22', + '23', + '24', + '..', + ], + }, + }, + + 'ringside.story.tsx#L8': { + uri: 'github.com/rylnd/ringside', + filePath: 'stories/ringside.story.tsx', + language: 'typescript', + compositeContent: { + content: + "import { Ringside } from '../src';\n\ndescribe('Ringside', () => {\n let inner;\n let outer;\n let height;\n let width;\n let ringside: Ringside;\n\n beforeEach(() => {\n\n width = 50;\n\n ringside = new Ringside(inner, outer, height, width);\n });\n\n", + lineMapping: [ + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '..', + '14', + '15', + '16', + '17', + '18', + '..', + ], + }, + }, + + 'ringside.story.tsx#L14': { + uri: 'github.com/rylnd/ringside', + filePath: 'stories/ringside.story.tsx', + language: 'typescript', + compositeContent: { + content: + "import { Ringside } from '../src';\n\ndescribe('Ringside', () => {\n let inner;\n let outer;\n let height;\n let width;\n let ringside: Ringside;\n\n beforeEach(() => {\n\n width = 50;\n\n ringside = new Ringside(inner, outer, height, width);\n });\n\n", + lineMapping: [ + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + '10', + '..', + '14', + '15', + '16', + '17', + '18', + '..', + ], + }, + }, +}; + +export interface Frame { + fileName: string; + lineNumber: number; + functionName?: string; +} + +export const frames: Frame[] = [ + { fileName: 'ringside.ts', lineNumber: 18 }, + { fileName: 'node_modules/library_code.js', lineNumber: 100 }, + { fileName: 'ringside.story.tsx', lineNumber: 8 }, + { fileName: 'node_modules/other_stuff.js', lineNumber: 58 }, + { fileName: 'node_modules/other/other.js', lineNumber: 3 }, + { fileName: 'ringside.story.tsx', lineNumber: 12 }, + { fileName: 'ringside.story.tsx', lineNumber: 14 }, +]; + +export const repos = [ + 'https://github.com/a/repo', + 'https://github.com/another/repo', + 'https://github.com/also/a_repo', +]; diff --git a/x-pack/legacy/plugins/code/public/components/integrations/frame_header.tsx b/x-pack/legacy/plugins/code/public/components/integrations/frame_header.tsx new file mode 100644 index 0000000000000..0fa482f8bce36 --- /dev/null +++ b/x-pack/legacy/plugins/code/public/components/integrations/frame_header.tsx @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import { EuiButtonIcon, EuiFlexGroup, EuiLink, EuiText, EuiTextColor } from '@elastic/eui'; + +export const FrameHeader = ({ + fileName, + lineNumber, + onClick, +}: { + fileName: string; + lineNumber: number | string; + onClick: () => void; +}) => ( + + + {fileName} + at + line {lineNumber} + + + Last updated: 14 mins ago + + + +); diff --git a/x-pack/legacy/plugins/code/public/components/integrations/helpers.ts b/x-pack/legacy/plugins/code/public/components/integrations/helpers.ts new file mode 100644 index 0000000000000..6b55a5e2a0f45 --- /dev/null +++ b/x-pack/legacy/plugins/code/public/components/integrations/helpers.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +// TODO(rylnd): make this an actual external link +export const externalFileURI: (repoUri: string, filePath: string) => string = (uri, path) => + `/${uri}/blob/HEAD/${path}`; diff --git a/x-pack/legacy/plugins/code/public/components/integrations/index.tsx b/x-pack/legacy/plugins/code/public/components/integrations/index.tsx new file mode 100644 index 0000000000000..5052b3502748d --- /dev/null +++ b/x-pack/legacy/plugins/code/public/components/integrations/index.tsx @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { EuiFlexGroup, EuiText } from '@elastic/eui'; + +import { CodeBlock } from '../codeblock/codeblock'; +import { history } from '../../utils/url'; +import { FrameHeader } from './frame_header'; +import { RepoTitle } from './repo_title'; +import { externalFileURI } from './helpers'; +import { frames, results } from './data'; + +export const Integrations = () => ( +
+ {frames.map(frame => { + const { fileName, lineNumber } = frame; + const key = `${fileName}#L${lineNumber}`; + const snippet = results[key]; + + if (snippet) { + const { compositeContent, filePath, language, uri } = snippet; + const { content, lineMapping } = compositeContent; + const fileUrl = externalFileURI(uri, filePath); + + return ( +
+ + history.push(fileUrl)} + /> + } + language={language} + lineNumber={i => lineMapping[i]} + /> +
+ ); + } + + return ( +
+ + + {fileName} + at + line {lineNumber} + + +
+ ); + })} +
+); diff --git a/x-pack/legacy/plugins/code/public/components/integrations/integrations.scss b/x-pack/legacy/plugins/code/public/components/integrations/integrations.scss new file mode 100644 index 0000000000000..24fe406cd0960 --- /dev/null +++ b/x-pack/legacy/plugins/code/public/components/integrations/integrations.scss @@ -0,0 +1,43 @@ +.integrations__container { + padding: $euiSize; +} + +.integrations__frame { + margin: $euiSizeS 0; +} + +.integrations__code { + @include euiCodeFont; +} + +.integrations__link--external { + margin-left: $euiSizeS; +} + +.integrations__preposition { + margin: 0 $euiSizeS; + color: $euiColorMediumShade; +} + +.integrations__button-icon { + padding: $euiSizeXS; + background-color: $euiColorLightestShade; + border: 1px solid $euiColorLightShade; +} + +.integrations__snippet-info { + margin-bottom: $euiSizeS; +} + +.integrations__snippet-title { + margin-bottom: $euiSizeS; +} + +.integrations__text--bold { + font-weight: $euiFontWeightBold; +} + +.integrations__popover { + margin-bottom: 1rem; + width: 300px; +} diff --git a/x-pack/legacy/plugins/code/public/components/integrations/repo_title.tsx b/x-pack/legacy/plugins/code/public/components/integrations/repo_title.tsx new file mode 100644 index 0000000000000..2ed3d529b699b --- /dev/null +++ b/x-pack/legacy/plugins/code/public/components/integrations/repo_title.tsx @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; + +import { EuiText } from '@elastic/eui'; +import { RepositoryUtils } from '../../../common/repository_utils'; + +export const RepoTitle = ({ uri }: { uri: string }) => { + const org = RepositoryUtils.orgNameFromUri(uri); + const name = RepositoryUtils.repoNameFromUri(uri); + + return ( + + {org}/ + {name} + + ); +}; diff --git a/x-pack/legacy/plugins/code/public/components/routes.ts b/x-pack/legacy/plugins/code/public/components/routes.ts index 0d4ccf4e5e826..d741ca1896850 100644 --- a/x-pack/legacy/plugins/code/public/components/routes.ts +++ b/x-pack/legacy/plugins/code/public/components/routes.ts @@ -15,3 +15,4 @@ export const REPO = `/:resource/:org/:repo`; export const MAIN_ROOT = `/:resource/:org/:repo/${pathTypes}/:revision`; export const ADMIN = '/admin'; export const SEARCH = '/search'; +export const INTEGRATIONS = '/integrations'; diff --git a/x-pack/legacy/plugins/code/public/components/search_page/code_result.tsx b/x-pack/legacy/plugins/code/public/components/search_page/code_result.tsx index 632c221f0680b..72aacce978671 100644 --- a/x-pack/legacy/plugins/code/public/components/search_page/code_result.tsx +++ b/x-pack/legacy/plugins/code/public/components/search_page/code_result.tsx @@ -6,13 +6,12 @@ import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { IPosition } from 'monaco-editor'; import React from 'react'; import { Link } from 'react-router-dom'; import { RepositoryUtils } from '../../../common/repository_utils'; import { history } from '../../utils/url'; -import { CodeBlock } from '../codeblock/codeblock'; +import { CodeBlock, Position } from '../codeblock/codeblock'; interface Props { query: string; @@ -22,15 +21,14 @@ interface Props { export class CodeResult extends React.PureComponent { public render() { const { results, query } = this.props; + return results.map(item => { - const { uri, filePath, hits, compositeContent } = item; + const { compositeContent, filePath, hits, language, uri } = item; const { content, lineMapping, ranges } = compositeContent; - const repoLinkUrl = `/${uri}/tree/HEAD/`; - const fileLinkUrl = `/${uri}/blob/HEAD/${filePath}`; const key = `${uri}-${filePath}-${query}`; - const lineMappingFunc = (l: number) => { - return lineMapping[l - 1]; - }; + const repoLinkUrl = `/${uri}/tree/HEAD/`; + const fileLinkUrl = `/${uri}/blob/HEAD/${filePath}`; // TODO(rylnd) move these to link helpers + return (
@@ -75,23 +73,23 @@ export class CodeResult extends React.PureComponent { lineMapping[i]} + onClick={this.onCodeClick(fileLinkUrl)} />
); }); } - private onCodeClick(lineNumbers: string[], fileUrl: string, pos: IPosition) { - const line = parseInt(lineNumbers[pos.lineNumber - 1], 10); - if (!isNaN(line)) { - history.push(`${fileUrl}!L${line}:0`); + private onCodeClick = (url: string) => (position: Position) => { + const lineNumber = parseInt(position.lineNumber, 10); + + if (!isNaN(lineNumber)) { + history.push(`${url}!L${lineNumber}:0`); } - } + }; } diff --git a/x-pack/legacy/plugins/code/public/index.scss b/x-pack/legacy/plugins/code/public/index.scss index aecaa46272ded..6d996a80f283f 100644 --- a/x-pack/legacy/plugins/code/public/index.scss +++ b/x-pack/legacy/plugins/code/public/index.scss @@ -4,6 +4,7 @@ @import "./monaco/override_monaco_styles.scss"; @import "./components/diff_page/diff.scss"; @import "./components/main/main.scss"; +@import "./components/integrations/integrations.scss"; // TODO: Cleanup everything above this line diff --git a/x-pack/legacy/plugins/code/public/monaco/override_monaco_styles.scss b/x-pack/legacy/plugins/code/public/monaco/override_monaco_styles.scss index 3e03c5693d434..b6f39a34e8653 100644 --- a/x-pack/legacy/plugins/code/public/monaco/override_monaco_styles.scss +++ b/x-pack/legacy/plugins/code/public/monaco/override_monaco_styles.scss @@ -9,6 +9,7 @@ .monaco-editor.mac .margin-view-overlays .line-numbers { cursor: pointer; + color: $euiColorMediumShade; background-color: $euiColorLightestShade; } diff --git a/x-pack/legacy/plugins/file_upload/public/components/json_upload_and_parse.js b/x-pack/legacy/plugins/file_upload/public/components/json_upload_and_parse.js index d5f9a21d6454d..f761899719d64 100644 --- a/x-pack/legacy/plugins/file_upload/public/components/json_upload_and_parse.js +++ b/x-pack/legacy/plugins/file_upload/public/components/json_upload_and_parse.js @@ -65,6 +65,14 @@ export class JsonUploadAndParse extends Component { indexPatternResp: '', }; + componentDidMount() { + this._isMounted = true; + } + + componentWillUnmount() { + this._isMounted = false; + } + _resetFileAndIndexSettings = () => { if (this.props.onFileRemove && this.state.fileRef) { this.props.onFileRemove(this.state.fileRef); @@ -86,7 +94,11 @@ export class JsonUploadAndParse extends Component { this._setSelectedType(this.state); this._setIndexReady({ ...this.state, ...this.props }); this._indexData({ ...this.state, ...this.props }); - if (this.props.isIndexingTriggered && !this.state.showImportProgress) { + if ( + this.props.isIndexingTriggered && + !this.state.showImportProgress && + this._isMounted + ) { this.setState({ showImportProgress: true }); } } @@ -131,6 +143,10 @@ export class JsonUploadAndParse extends Component { parsedFile, transformDetails, indexName, selectedIndexType, appName ); + if (!this._isMounted) { + return; + } + // Index error if (!indexDataResp.success) { this.setState({ @@ -158,6 +174,9 @@ export class JsonUploadAndParse extends Component { } // Indexing complete, update state & callback (if any) + if (!this._isMounted || !indexPatternResp) { + return; + } this.setState({ currentIndexingStage: INDEXING_STAGE.INDEX_PATTERN_COMPLETE }); @@ -170,12 +189,18 @@ export class JsonUploadAndParse extends Component { } _createIndexPattern = async ({ indexName }) => { + if (!this._isMounted) { + return; + } this.setState({ indexPatternRequestInFlight: true, currentIndexingStage: INDEXING_STAGE.CREATING_INDEX_PATTERN }); const indexPatternResp = await createIndexPattern(indexName); + if (!this._isMounted) { + return; + } this.setState({ indexPatternResp, indexPatternRequestInFlight: false, diff --git a/x-pack/legacy/plugins/lens/public/assets/chart_area.svg b/x-pack/legacy/plugins/lens/public/assets/chart_area.svg new file mode 100644 index 0000000000000..78f27300f90d3 --- /dev/null +++ b/x-pack/legacy/plugins/lens/public/assets/chart_area.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/x-pack/legacy/plugins/lens/public/assets/chart_area_stacked.svg b/x-pack/legacy/plugins/lens/public/assets/chart_area_stacked.svg new file mode 100644 index 0000000000000..2da6f38eaebfd --- /dev/null +++ b/x-pack/legacy/plugins/lens/public/assets/chart_area_stacked.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/x-pack/legacy/plugins/lens/public/assets/chart_bar.svg b/x-pack/legacy/plugins/lens/public/assets/chart_bar.svg new file mode 100644 index 0000000000000..a0dbc9dca9b57 --- /dev/null +++ b/x-pack/legacy/plugins/lens/public/assets/chart_bar.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/x-pack/legacy/plugins/lens/public/assets/chart_bar_horizontal.svg b/x-pack/legacy/plugins/lens/public/assets/chart_bar_horizontal.svg new file mode 100644 index 0000000000000..4b934c99740d7 --- /dev/null +++ b/x-pack/legacy/plugins/lens/public/assets/chart_bar_horizontal.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/x-pack/legacy/plugins/lens/public/assets/chart_bar_horizontal_stacked.svg b/x-pack/legacy/plugins/lens/public/assets/chart_bar_horizontal_stacked.svg new file mode 100644 index 0000000000000..3b60d22868bbc --- /dev/null +++ b/x-pack/legacy/plugins/lens/public/assets/chart_bar_horizontal_stacked.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/x-pack/legacy/plugins/lens/public/assets/chart_bar_stacked.svg b/x-pack/legacy/plugins/lens/public/assets/chart_bar_stacked.svg new file mode 100644 index 0000000000000..8b875af8a12d3 --- /dev/null +++ b/x-pack/legacy/plugins/lens/public/assets/chart_bar_stacked.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/x-pack/legacy/plugins/lens/public/assets/chart_datatable.svg b/x-pack/legacy/plugins/lens/public/assets/chart_datatable.svg new file mode 100644 index 0000000000000..eb479dfbd0ea7 --- /dev/null +++ b/x-pack/legacy/plugins/lens/public/assets/chart_datatable.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/x-pack/legacy/plugins/lens/public/assets/chart_line.svg b/x-pack/legacy/plugins/lens/public/assets/chart_line.svg new file mode 100644 index 0000000000000..177e999496210 --- /dev/null +++ b/x-pack/legacy/plugins/lens/public/assets/chart_line.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/x-pack/legacy/plugins/lens/public/assets/chart_metric.svg b/x-pack/legacy/plugins/lens/public/assets/chart_metric.svg new file mode 100644 index 0000000000000..d48264868f734 --- /dev/null +++ b/x-pack/legacy/plugins/lens/public/assets/chart_metric.svg @@ -0,0 +1,4 @@ + + + + diff --git a/x-pack/legacy/plugins/lens/public/assets/chart_mixed_xy.svg b/x-pack/legacy/plugins/lens/public/assets/chart_mixed_xy.svg new file mode 100644 index 0000000000000..f7c78f3eb2ba8 --- /dev/null +++ b/x-pack/legacy/plugins/lens/public/assets/chart_mixed_xy.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/x-pack/legacy/plugins/lens/public/datatable_visualization_plugin/visualization.tsx b/x-pack/legacy/plugins/lens/public/datatable_visualization_plugin/visualization.tsx index 27f59de2908be..18a6d112e14d6 100644 --- a/x-pack/legacy/plugins/lens/public/datatable_visualization_plugin/visualization.tsx +++ b/x-pack/legacy/plugins/lens/public/datatable_visualization_plugin/visualization.tsx @@ -19,6 +19,7 @@ import { } from '../types'; import { generateId } from '../id_generator'; import { NativeRenderer } from '../native_renderer'; +import chartTableSVG from '../assets/chart_datatable.svg'; export interface LayerState { layerId: string; @@ -97,17 +98,18 @@ export const datatableVisualization: Visualization< { id: 'lnsDatatable', icon: 'visTable', + largeIcon: chartTableSVG, label: i18n.translate('xpack.lens.datatable.label', { - defaultMessage: 'Datatable', + defaultMessage: 'Data table', }), }, ], getDescription(state) { return { - icon: 'visTable', + icon: chartTableSVG, label: i18n.translate('xpack.lens.datatable.label', { - defaultMessage: 'Datatable', + defaultMessage: 'Data table', }), }; }, @@ -168,7 +170,7 @@ export const datatableVisualization: Visualization< }, ], }, - previewIcon: 'visTable', + previewIcon: chartTableSVG, // dont show suggestions for reduced versions or single-line tables hide: table.changeType === 'reduced' || !table.isMultiRow, }, diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_chart_switch.scss b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_chart_switch.scss index 008b65d8f0418..d7efab2405f3f 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_chart_switch.scss +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_chart_switch.scss @@ -7,7 +7,18 @@ } } +.lnsChartSwitch__triggerButton { + @include euiTitle('xs'); + line-height: $euiSizeXXL; +} + .lnsChartSwitch__summaryIcon { margin-right: $euiSizeS; transform: translateY(-2px); } + +// Targeting img as this won't target normal EuiIcon's only the custom svgs's +img.lnsChartSwitch__chartIcon { // sass-lint:disable-line no-qualifying-elements + // The large icons aren't square so max out the width to fill the height + width: 100%; +} diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_suggestion_panel.scss b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_suggestion_panel.scss index 01a6954671809..0e89bbe2da968 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_suggestion_panel.scss +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/_suggestion_panel.scss @@ -36,6 +36,11 @@ align-items: center; justify-content: center; padding: $euiSizeS; + + // Targeting img as this won't target normal EuiIcon's only the custom svgs's + > img { + @include size($euiSize * 4); + } } .lnsSuggestionPanel__chartWrapper { diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/chart_switch.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/chart_switch.tsx index f53687e76e819..1c94460034019 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/chart_switch.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/chart_switch.tsx @@ -12,7 +12,6 @@ import { EuiKeyPadMenu, EuiKeyPadMenuItemButton, EuiButtonEmpty, - EuiTitle, } from '@elastic/eui'; import { flatten } from 'lodash'; import { i18n } from '@kbn/i18n'; @@ -64,7 +63,7 @@ function VisualizationSummary(props: Props) { return ( <> {description.icon && ( - + )} {description.label} @@ -157,6 +156,7 @@ export function ChartSwitch(props: Props) { v.visualizationTypes.map(t => ({ visualizationId: v.id, ...t, + icon: t.largeIcon || t.icon, })) ) ).map(visualizationType => ({ @@ -178,23 +178,24 @@ export function ChartSwitch(props: Props) { ownFocus initialFocus=".lnsChartSwitch__popoverPanel" panelClassName="lnsChartSwitch__popoverPanel" + anchorClassName="eui-textTruncate" panelPaddingSize="s" button={ setFlyoutOpen(!flyoutOpen)} data-test-subj="lnsChartSwitchPopover" + flush="left" + iconSide="right" + iconType="arrowDown" + color="text" > - ( - {i18n.translate('xpack.lens.configPanel.changeVisualization', { - defaultMessage: 'change', - })} - ) + } isOpen={flyoutOpen} closePopover={() => setFlyoutOpen(false)} - anchorPosition="leftUp" + anchorPosition="downLeft" > {i18n.translate('xpack.lens.configPanel.chooseVisualization', { @@ -225,22 +226,14 @@ export function ChartSwitch(props: Props) { } betaBadgeIconType={v.selection.dataLoss !== 'nothing' ? 'alert' : undefined} > - + ))} ); - return ( -
- -

- {popover} -

-
-
- ); + return
{popover}
; } function getTopSuggestion( diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_helpers.ts b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_helpers.ts index 29db5f37a6436..d3e768a1932dc 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_helpers.ts +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_helpers.ts @@ -6,6 +6,7 @@ import _ from 'lodash'; import { Ast } from '@kbn/interpreter/common'; +import { IconType } from '@elastic/eui/src/components/icon/icon'; import { Visualization, Datasource, @@ -25,7 +26,7 @@ export interface Suggestion { title: string; visualizationState: unknown; previewExpression?: Ast | string; - previewIcon: string; + previewIcon: IconType; hide?: boolean; changeType: TableChangeType; } diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.test.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.test.tsx index 82ca3d01b73ca..8840f7dfd3b78 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.test.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.test.tsx @@ -19,6 +19,7 @@ import { ExpressionRenderer } from '../../../../../../../src/legacy/core_plugins import { SuggestionPanel, SuggestionPanelProps } from './suggestion_panel'; import { getSuggestions, Suggestion } from './suggestion_helpers'; import { EuiIcon, EuiPanel, EuiToolTip } from '@elastic/eui'; +import chartTableSVG from '../../..assets/chart_datatable.svg'; jest.mock('./suggestion_helpers'); @@ -291,7 +292,7 @@ describe('suggestion_panel', () => { getSuggestionsMock.mockReturnValue([ { datasourceState: {}, - previewIcon: 'visTable', + previewIcon: chartTableSVG, score: 0.5, visualizationState: suggestion1State, visualizationId: 'vis', @@ -319,6 +320,6 @@ describe('suggestion_panel', () => { const wrapper = mount(); expect(wrapper.find(EuiIcon)).toHaveLength(1); - expect(wrapper.find(EuiIcon).prop('type')).toEqual('visTable'); + expect(wrapper.find(EuiIcon).prop('type')).toEqual(chartTableSVG); }); }); diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx index e6511f5e7bd98..de25c2f7f638b 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/suggestion_panel.tsx @@ -17,6 +17,7 @@ import { EuiFlexItem, EuiButtonEmpty, } from '@elastic/eui'; +import { IconType } from '@elastic/eui/src/components/icon/icon'; import { Ast, toExpression } from '@kbn/interpreter/common'; import { i18n } from '@kbn/i18n'; import classNames from 'classnames'; @@ -108,7 +109,7 @@ const SuggestionPreview = ({ onSelect: () => void; preview: { expression?: Ast; - icon: string; + icon: IconType; title: string; }; ExpressionRenderer: ExpressionRenderer; diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable_factory.ts b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable_factory.ts index c340342a31ff6..d779dfa5c401f 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable_factory.ts +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/embeddable/embeddable_factory.ts @@ -39,7 +39,7 @@ export class EmbeddableFactory extends AbstractEmbeddableFactory { defaultMessage: 'Lens Visualization', }), type: DOC_TYPE, - getIconForSavedObject: () => 'faceHappy', + getIconForSavedObject: () => 'lensApp', }, }); this.chrome = chrome; diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/_datapanel.scss b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/_datapanel.scss index 24ccef4c081aa..a496cccc42a58 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/_datapanel.scss +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/_datapanel.scss @@ -11,12 +11,11 @@ align-items: center; height: $euiSize * 3; margin-top: -$euiSizeS; +} - - & > .lnsInnerIndexPatternDataPanel__changeLink { - flex: 0 0 auto; - margin: 0 (-$euiSizeS) 0 $euiSizeXS; - } +.lnsInnerIndexPatternDataPanel__triggerButton { + @include euiTitle('xs'); + line-height: $euiSizeXXL; } .lnsInnerIndexPatternDataPanel__filterWrapper { diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/change_indexpattern.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/change_indexpattern.tsx index 3da540e194dc3..eb44da493b898 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/change_indexpattern.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/change_indexpattern.tsx @@ -20,6 +20,7 @@ import { isLayerTransferable } from './state_helpers'; export interface ChangeIndexPatternTriggerProps extends EuiButtonEmptyProps { label: string; + title?: string; } export function ChangeIndexPattern({ @@ -48,12 +49,15 @@ export function ChangeIndexPattern({ })); const createTrigger = function() { - const { label, ...rest } = trigger; + const { label, title, ...rest } = trigger; return ( setPopoverIsOpen(!isPopoverOpen)} {...rest} > diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.tsx index fbe71381fd449..461b59ebd70d2 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.tsx @@ -10,7 +10,6 @@ import { EuiLoadingSpinner, EuiFlexGroup, EuiFlexItem, - EuiTitle, EuiContextMenuPanel, EuiContextMenuItem, EuiContextMenuPanelProps, @@ -324,31 +323,26 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ >
- -

{currentIndexPattern.title}

-
-
- { - onChangeIndexPattern(newId); - - setLocalState(s => ({ - ...s, - nameFilter: '', - typeFilter: [], - })); - }} - /> -
+ { + onChangeIndexPattern(newId); + + setLocalState(s => ({ + ...s, + nameFilter: '', + typeFilter: [], + })); + }} + />
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/layerpanel.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/layerpanel.tsx index 0fa2fb487b9c4..e988df754d8f4 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/layerpanel.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/layerpanel.tsx @@ -23,7 +23,9 @@ export function LayerPanel({ state, setState, layerId }: IndexPatternLayerPanelP data-test-subj="indexPattern-switcher" trigger={{ label: state.indexPatterns[state.layers[layerId].indexPatternId].title, + title: state.indexPatterns[state.layers[layerId].indexPatternId].title, 'data-test-subj': 'lns_layerIndexPatternLabel', + size: 'xs', }} layer={state.layers[layerId]} indexPatterns={state.indexPatterns} diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_suggestions.test.ts b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_suggestions.test.ts index 066a148dc2f7d..770d8594172f1 100644 --- a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_suggestions.test.ts +++ b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_suggestions.test.ts @@ -97,7 +97,7 @@ describe('metric_suggestions', () => { expect(rest).toHaveLength(0); expect(suggestion).toMatchInlineSnapshot(` Object { - "previewIcon": "visMetric", + "previewIcon": "test-file-stub", "score": 0.5, "state": Object { "accessor": "bytes", diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_suggestions.ts b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_suggestions.ts index 6d4ed21c0983b..f2b655a288270 100644 --- a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_suggestions.ts +++ b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_suggestions.ts @@ -6,6 +6,7 @@ import { SuggestionRequest, VisualizationSuggestion, TableSuggestion } from '../types'; import { State } from './types'; +import chartMetricSVG from '../assets/chart_metric.svg'; /** * Generate suggestions for the metric chart. @@ -40,7 +41,7 @@ function getSuggestion(table: TableSuggestion): VisualizationSuggestion { return { title, score: 0.5, - previewIcon: 'visMetric', + previewIcon: chartMetricSVG, state: { layerId: table.layerId, accessor: col.columnId, diff --git a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_visualization.tsx b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_visualization.tsx index d17c77e64c21a..00e945c0ce6e5 100644 --- a/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_visualization.tsx +++ b/x-pack/legacy/plugins/lens/public/metric_visualization_plugin/metric_visualization.tsx @@ -14,6 +14,7 @@ import { MetricConfigPanel } from './metric_config_panel'; import { Visualization, FramePublicAPI } from '../types'; import { State, PersistableState } from './types'; import { generateId } from '../id_generator'; +import chartMetricSVG from '../assets/chart_metric.svg'; const toExpression = ( state: State, @@ -46,6 +47,7 @@ export const metricVisualization: Visualization = { { id: 'lnsMetric', icon: 'visMetric', + largeIcon: chartMetricSVG, label: i18n.translate('xpack.lens.metric.label', { defaultMessage: 'Metric', }), @@ -54,7 +56,7 @@ export const metricVisualization: Visualization = { getDescription() { return { - icon: 'visMetric', + icon: chartMetricSVG, label: i18n.translate('xpack.lens.metric.label', { defaultMessage: 'Metric', }), diff --git a/x-pack/legacy/plugins/lens/public/register_vis_type_alias.ts b/x-pack/legacy/plugins/lens/public/register_vis_type_alias.ts index 701c351b8b149..06e62bed02d5c 100644 --- a/x-pack/legacy/plugins/lens/public/register_vis_type_alias.ts +++ b/x-pack/legacy/plugins/lens/public/register_vis_type_alias.ts @@ -18,7 +18,7 @@ visualizations.types.registerAlias({ description: i18n.translate('xpack.lens.visTypeAlias.description', { defaultMessage: `Lens is a simpler way to create basic visualizations`, }), - icon: 'faceHappy', + icon: 'lensApp', appExtensions: { visualizations: { docTypes: ['lens'], @@ -30,7 +30,7 @@ visualizations.types.registerAlias({ id, title, editUrl: getEditPath(id), - icon: 'faceHappy', + icon: 'lensApp', isExperimental: true, savedObjectType: type, typeTitle: i18n.translate('xpack.lens.visTypeAlias.type', { defaultMessage: 'Lens' }), diff --git a/x-pack/legacy/plugins/lens/public/types.ts b/x-pack/legacy/plugins/lens/public/types.ts index 71ee2d4c25963..c15bcb89e517f 100644 --- a/x-pack/legacy/plugins/lens/public/types.ts +++ b/x-pack/legacy/plugins/lens/public/types.ts @@ -5,8 +5,8 @@ */ import { Ast } from '@kbn/interpreter/common'; +import { IconType } from '@elastic/eui/src/components/icon/icon'; import { Filter } from '@kbn/es-query'; -import { EuiIconType } from '@elastic/eui/src/components/icon/icon'; import { CoreSetup } from 'src/core/public'; import { Query } from 'src/plugins/data/common'; import { SavedQuery } from 'src/legacy/core_plugins/data/public'; @@ -281,7 +281,7 @@ export interface VisualizationSuggestion { /** * An EUI icon type shown instead of the preview expression. */ - previewIcon: string; + previewIcon: IconType; } export interface FramePublicAPI { @@ -301,7 +301,8 @@ export interface FramePublicAPI { export interface VisualizationType { id: string; - icon?: EuiIconType | string; + icon?: IconType; + largeIcon?: IconType; label: string; } @@ -313,7 +314,7 @@ export interface Visualization { getDescription: ( state: T ) => { - icon?: EuiIconType | string; + icon?: IconType; label: string; }; diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/types.ts b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/types.ts index 28f72f60c3a2d..de81cc208070a 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/types.ts +++ b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/types.ts @@ -10,6 +10,15 @@ import { ExpressionFunction, ArgumentType, } from '../../../../../../src/legacy/core_plugins/interpreter/public'; + +import chartAreaSVG from '../assets/chart_area.svg'; +import chartAreaStackedSVG from '../assets/chart_area_stacked.svg'; +import chartBarSVG from '../assets/chart_bar.svg'; +import chartBarStackedSVG from '../assets/chart_bar_stacked.svg'; +import chartBarHorizontalSVG from '../assets/chart_bar_horizontal.svg'; +import chartBarHorizontalStackedSVG from '../assets/chart_bar_horizontal_stacked.svg'; +import chartLineSVG from '../assets/chart_line.svg'; + import { VisualizationType } from '..'; export interface LegendConfig { @@ -222,6 +231,7 @@ export const visualizationTypes: VisualizationType[] = [ { id: 'bar', icon: 'visBarVertical', + largeIcon: chartBarSVG, label: i18n.translate('xpack.lens.xyVisualization.barLabel', { defaultMessage: 'Bar', }), @@ -229,20 +239,23 @@ export const visualizationTypes: VisualizationType[] = [ { id: 'bar_horizontal', icon: 'visBarHorizontal', + largeIcon: chartBarHorizontalSVG, label: i18n.translate('xpack.lens.xyVisualization.barHorizontalLabel', { defaultMessage: 'Horizontal Bar', }), }, { id: 'bar_stacked', - icon: 'visBarVertical', - label: i18n.translate('xpack.lens.xyVisualization.stackedBar', { + icon: 'visBarVerticalStacked', + largeIcon: chartBarStackedSVG, + label: i18n.translate('xpack.lens.xyVisualization.stackedBarLabel', { defaultMessage: 'Stacked Bar', }), }, { id: 'bar_horizontal_stacked', - icon: 'visBarHorizontal', + icon: 'visBarHorizontalStacked', + largeIcon: chartBarHorizontalStackedSVG, label: i18n.translate('xpack.lens.xyVisualization.stackedBarHorizontalLabel', { defaultMessage: 'Stacked Horizontal Bar', }), @@ -250,6 +263,7 @@ export const visualizationTypes: VisualizationType[] = [ { id: 'line', icon: 'visLine', + largeIcon: chartLineSVG, label: i18n.translate('xpack.lens.xyVisualization.lineLabel', { defaultMessage: 'Line', }), @@ -257,13 +271,15 @@ export const visualizationTypes: VisualizationType[] = [ { id: 'area', icon: 'visArea', + largeIcon: chartAreaSVG, label: i18n.translate('xpack.lens.xyVisualization.areaLabel', { defaultMessage: 'Area', }), }, { id: 'area_stacked', - icon: 'visArea', + icon: 'visAreaStacked', + largeIcon: chartAreaStackedSVG, label: i18n.translate('xpack.lens.xyVisualization.stackedAreaLabel', { defaultMessage: 'Stacked Area', }), diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_config_panel.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_config_panel.tsx index e268c099ddc24..d6a014d9f8050 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_config_panel.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_config_panel.tsx @@ -107,6 +107,7 @@ function LayerSettings({ idSelected={layer.seriesType} onChange={seriesType => setSeriesType(seriesType as SeriesType)} isIconOnly + buttonSize="compressed" /> @@ -117,8 +118,8 @@ function LayerSettings({ data-test-subj="lnsXY_layer_remove" onClick={removeLayer} > - {i18n.translate('xpack.lens.xyChart.removeLayer', { - defaultMessage: 'Remove layer', + {i18n.translate('xpack.lens.xyChart.deleteLayer', { + defaultMessage: 'Delete layer', })}
diff --git a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.tsx b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.tsx index 29c5e5d5e4297..0c9cb3b6216bb 100644 --- a/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.tsx +++ b/x-pack/legacy/plugins/lens/public/xy_visualization_plugin/xy_visualization.tsx @@ -16,9 +16,11 @@ import { Visualization } from '../types'; import { State, PersistableState, SeriesType, visualizationTypes } from './types'; import { toExpression, toPreviewExpression } from './to_expression'; import { generateId } from '../id_generator'; +import chartBarStackedSVG from '../assets/chart_bar_stacked.svg'; +import chartMixedSVG from '../assets/chart_mixed_xy.svg'; import { isHorizontalChart } from './state_helpers'; -const defaultIcon = 'visBarVertical'; +const defaultIcon = chartBarStackedSVG; const defaultSeriesType = 'bar_stacked'; function getDescription(state?: State) { @@ -39,7 +41,10 @@ function getDescription(state?: State) { const seriesTypes = _.unique(state.layers.map(l => l.seriesType)); return { - icon: visualizationType.icon, + icon: + seriesTypes.length === 1 + ? visualizationType.largeIcon || visualizationType.icon + : chartMixedSVG, label: seriesTypes.length === 1 ? visualizationType.label diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/view.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/view.js index dac695b9c3e26..0b820e832581b 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/view.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_addpanel/view.js @@ -25,6 +25,14 @@ export class AddLayerPanel extends Component { layerImportAddReady: false, } + componentDidMount() { + this._isMounted = true; + } + + componentWillUnmount() { + this._isMounted = false; + } + componentDidUpdate() { if (!this.state.layerImportAddReady && this.props.isIndexingSuccess) { this.setState({ layerImportAddReady: true }); @@ -48,6 +56,9 @@ export class AddLayerPanel extends Component { } _viewLayer = async (source, options = {}) => { + if (!this._isMounted) { + return; + } if (!source) { this.setState({ layer: null }); this.props.removeTransientLayer(); @@ -60,6 +71,9 @@ export class AddLayerPanel extends Component { style: style }; const newLayer = source.createDefaultLayer(layerInitProps, this.props.mapColors); + if (!this._isMounted) { + return; + } this.setState( { layer: newLayer }, () => this.props.viewLayer(this.state.layer) @@ -67,6 +81,11 @@ export class AddLayerPanel extends Component { }; _clearLayerData = ({ keepSourceType = false }) => { + + if (!this._isMounted) { + return; + } + this.setState({ layer: null, ...( diff --git a/x-pack/plugins/security/server/authentication/api_keys.test.ts b/x-pack/plugins/security/server/authentication/api_keys.test.ts index fcfa1fe4f4b60..7ecff1682465c 100644 --- a/x-pack/plugins/security/server/authentication/api_keys.test.ts +++ b/x-pack/plugins/security/server/authentication/api_keys.test.ts @@ -5,7 +5,7 @@ */ import { APIKeys } from './api_keys'; -import { ClusterClient, ScopedClusterClient } from '../../../../../src/core/server'; +import { IClusterClient, IScopedClusterClient } from '../../../../../src/core/server'; import { httpServerMock, loggingServiceMock, @@ -14,15 +14,15 @@ import { describe('API Keys', () => { let apiKeys: APIKeys; - let mockClusterClient: jest.Mocked>; - let mockScopedClusterClient: jest.Mocked>; + let mockClusterClient: jest.Mocked; + let mockScopedClusterClient: jest.Mocked; const mockIsSecurityFeatureDisabled = jest.fn(); beforeEach(() => { mockClusterClient = elasticsearchServiceMock.createClusterClient(); mockScopedClusterClient = elasticsearchServiceMock.createScopedClusterClient(); mockClusterClient.asScoped.mockReturnValue((mockScopedClusterClient as unknown) as jest.Mocked< - ScopedClusterClient + IScopedClusterClient >); mockIsSecurityFeatureDisabled.mockReturnValue(false); apiKeys = new APIKeys({ diff --git a/x-pack/plugins/security/server/authentication/api_keys.ts b/x-pack/plugins/security/server/authentication/api_keys.ts index 688a3f5d944b6..3709e8e7195fe 100644 --- a/x-pack/plugins/security/server/authentication/api_keys.ts +++ b/x-pack/plugins/security/server/authentication/api_keys.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ClusterClient, KibanaRequest, Logger } from '../../../../../src/core/server'; +import { IClusterClient, KibanaRequest, Logger } from '../../../../../src/core/server'; /** * Represents the options to create an APIKey class instance that will be @@ -12,7 +12,7 @@ import { ClusterClient, KibanaRequest, Logger } from '../../../../../src/core/se */ export interface ConstructorOptions { logger: Logger; - clusterClient: PublicMethodsOf; + clusterClient: IClusterClient; isSecurityFeatureDisabled: () => boolean; } @@ -91,7 +91,7 @@ export interface InvalidateAPIKeyResult { */ export class APIKeys { private readonly logger: Logger; - private readonly clusterClient: PublicMethodsOf; + private readonly clusterClient: IClusterClient; private readonly isSecurityFeatureDisabled: () => boolean; constructor({ logger, clusterClient, isSecurityFeatureDisabled }: ConstructorOptions) { diff --git a/x-pack/plugins/security/server/authentication/authenticator.ts b/x-pack/plugins/security/server/authentication/authenticator.ts index 720bfb4c6b1e3..0f239b8005671 100644 --- a/x-pack/plugins/security/server/authentication/authenticator.ts +++ b/x-pack/plugins/security/server/authentication/authenticator.ts @@ -11,7 +11,7 @@ import { LoggerFactory, Logger, HttpServiceSetup, - ClusterClient, + IClusterClient, } from '../../../../../src/core/server'; import { ConfigType } from '../config'; import { getErrorStatusCode } from '../errors'; @@ -80,7 +80,7 @@ export interface AuthenticatorOptions { config: Pick; basePath: HttpServiceSetup['basePath']; loggers: LoggerFactory; - clusterClient: PublicMethodsOf; + clusterClient: IClusterClient; sessionStorageFactory: SessionStorageFactory; isSystemAPIRequest: (request: KibanaRequest) => boolean; getServerBaseURL: () => string; diff --git a/x-pack/plugins/security/server/authentication/index.test.ts b/x-pack/plugins/security/server/authentication/index.test.ts index 9eccc3bd4933a..07b8d70fac412 100644 --- a/x-pack/plugins/security/server/authentication/index.test.ts +++ b/x-pack/plugins/security/server/authentication/index.test.ts @@ -23,7 +23,7 @@ import { mockAuthenticatedUser } from '../../common/model/authenticated_user.moc import { AuthenticationHandler, AuthToolkit, - ClusterClient, + IClusterClient, CoreSetup, ElasticsearchErrorHelpers, KibanaRequest, @@ -57,7 +57,7 @@ describe('setupAuthentication()', () => { loggers: LoggerFactory; getLegacyAPI(): LegacyAPI; core: MockedKeys; - clusterClient: jest.Mocked>; + clusterClient: jest.Mocked; }; let mockXpackInfo: jest.Mocked; let mockScopedClusterClient: jest.Mocked>; diff --git a/x-pack/plugins/security/server/authentication/index.ts b/x-pack/plugins/security/server/authentication/index.ts index f122f3d89c207..58aef5528dc60 100644 --- a/x-pack/plugins/security/server/authentication/index.ts +++ b/x-pack/plugins/security/server/authentication/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { - ClusterClient, + IClusterClient, CoreSetup, KibanaRequest, LoggerFactory, @@ -25,7 +25,7 @@ export { CreateAPIKeyResult } from './api_keys'; interface SetupAuthenticationParams { core: CoreSetup; - clusterClient: PublicMethodsOf; + clusterClient: IClusterClient; config: ConfigType; loggers: LoggerFactory; getLegacyAPI(): LegacyAPI; diff --git a/x-pack/plugins/security/server/authentication/providers/base.ts b/x-pack/plugins/security/server/authentication/providers/base.ts index 3dcbcfa1214d9..273a40d70ae91 100644 --- a/x-pack/plugins/security/server/authentication/providers/base.ts +++ b/x-pack/plugins/security/server/authentication/providers/base.ts @@ -8,7 +8,7 @@ import { KibanaRequest, Logger, HttpServiceSetup, - ClusterClient, + IClusterClient, Headers, } from '../../../../../../src/core/server'; import { AuthenticatedUser } from '../../../common/model'; @@ -22,7 +22,7 @@ import { Tokens } from '../tokens'; export interface AuthenticationProviderOptions { getServerBaseURL: () => string; basePath: HttpServiceSetup['basePath']; - client: PublicMethodsOf; + client: IClusterClient; logger: Logger; tokens: PublicMethodsOf; } diff --git a/x-pack/plugins/security/server/authentication/tokens.test.ts b/x-pack/plugins/security/server/authentication/tokens.test.ts index baf3b1f03bc9c..8d15ea69ae392 100644 --- a/x-pack/plugins/security/server/authentication/tokens.test.ts +++ b/x-pack/plugins/security/server/authentication/tokens.test.ts @@ -8,12 +8,12 @@ import { errors } from 'elasticsearch'; import { elasticsearchServiceMock, loggingServiceMock } from '../../../../../src/core/server/mocks'; -import { ClusterClient, ElasticsearchErrorHelpers } from '../../../../../src/core/server'; +import { IClusterClient, ElasticsearchErrorHelpers } from '../../../../../src/core/server'; import { Tokens } from './tokens'; describe('Tokens', () => { let tokens: Tokens; - let mockClusterClient: jest.Mocked>; + let mockClusterClient: jest.Mocked; beforeEach(() => { mockClusterClient = elasticsearchServiceMock.createClusterClient(); diff --git a/x-pack/plugins/security/server/authentication/tokens.ts b/x-pack/plugins/security/server/authentication/tokens.ts index ae77d165a2ff5..8e91faa95b459 100644 --- a/x-pack/plugins/security/server/authentication/tokens.ts +++ b/x-pack/plugins/security/server/authentication/tokens.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ClusterClient, Logger } from '../../../../../src/core/server'; +import { IClusterClient, Logger } from '../../../../../src/core/server'; import { getErrorStatusCode } from '../errors'; /** @@ -34,9 +34,7 @@ export class Tokens { */ private readonly logger: Logger; - constructor( - private readonly options: Readonly<{ client: PublicMethodsOf; logger: Logger }> - ) { + constructor(private readonly options: Readonly<{ client: IClusterClient; logger: Logger }>) { this.logger = options.logger; } diff --git a/x-pack/plugins/security/server/plugin.test.ts b/x-pack/plugins/security/server/plugin.test.ts index 6fe28fe56c417..1135edc658d81 100644 --- a/x-pack/plugins/security/server/plugin.test.ts +++ b/x-pack/plugins/security/server/plugin.test.ts @@ -7,12 +7,12 @@ import { coreMock, elasticsearchServiceMock } from '../../../../src/core/server/mocks'; import { Plugin } from './plugin'; -import { ClusterClient, CoreSetup } from '../../../../src/core/server'; +import { IClusterClient, CoreSetup } from '../../../../src/core/server'; describe('Security Plugin', () => { let plugin: Plugin; let mockCoreSetup: MockedKeys; - let mockClusterClient: jest.Mocked>; + let mockClusterClient: jest.Mocked; beforeEach(() => { plugin = new Plugin( coreMock.createPluginInitializerContext({ @@ -27,7 +27,7 @@ describe('Security Plugin', () => { mockClusterClient = elasticsearchServiceMock.createClusterClient(); mockCoreSetup.elasticsearch.createClient.mockReturnValue( - (mockClusterClient as unknown) as jest.Mocked + (mockClusterClient as unknown) as jest.Mocked ); }); diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index 2f5bd28cf862a..a42fcbbe33472 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -6,7 +6,7 @@ import { first } from 'rxjs/operators'; import { - ClusterClient, + IClusterClient, CoreSetup, KibanaRequest, Logger, @@ -68,7 +68,7 @@ export interface PluginSetupContract { */ export class Plugin { private readonly logger: Logger; - private clusterClient?: ClusterClient; + private clusterClient?: IClusterClient; private legacyAPI?: LegacyAPI; private readonly getLegacyAPI = () => { diff --git a/x-pack/test/functional/apps/code/with_security.ts b/x-pack/test/functional/apps/code/with_security.ts index c2652e04f2a21..6e33216621942 100644 --- a/x-pack/test/functional/apps/code/with_security.ts +++ b/x-pack/test/functional/apps/code/with_security.ts @@ -23,7 +23,8 @@ export default function testWithSecurity({ getService, getPageObjects }: FtrProv const security = getService('security'); const config = getService('config'); - describe('Security', () => { + // FLAKY: https://github.com/elastic/kibana/issues/46977 + describe.skip('Security', () => { describe('with security enabled:', () => { before(async () => { await esArchiver.load('empty_kibana'); diff --git a/x-pack/test/functional/apps/machine_learning/anomaly_detection/index.ts b/x-pack/test/functional/apps/machine_learning/anomaly_detection/index.ts index 8d2e58bb0614d..bf2fb4044de3f 100644 --- a/x-pack/test/functional/apps/machine_learning/anomaly_detection/index.ts +++ b/x-pack/test/functional/apps/machine_learning/anomaly_detection/index.ts @@ -6,7 +6,8 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default function({ loadTestFile }: FtrProviderContext) { - describe('anomaly detection', function() { + // FLAKY: https://github.com/elastic/kibana/issues/47312 + describe.skip('anomaly detection', function() { loadTestFile(require.resolve('./single_metric_job')); loadTestFile(require.resolve('./multi_metric_job')); loadTestFile(require.resolve('./population_job'));