diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 7ee84b6bc9e8d..d116b1d3a41fc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,6 +9,9 @@ /dev_docs @elastic/kibana-tech-leads /packages/kbn-docs-utils/ @elastic/kibana-tech-leads @elastic/kibana-operations +# Virtual teams +/x-pack/plugins/rule_registry/ @elastic/rac + # App /x-pack/plugins/discover_enhanced/ @elastic/kibana-app /x-pack/plugins/lens/ @elastic/kibana-app @@ -31,6 +34,7 @@ /src/plugins/vis_type_pie/ @elastic/kibana-app /src/plugins/visualize/ @elastic/kibana-app /src/plugins/visualizations/ @elastic/kibana-app +/src/plugins/url_forwarding/ @elastic/kibana-app /packages/kbn-tinymath/ @elastic/kibana-app # Application Services @@ -369,6 +373,7 @@ /x-pack/test/plugin_functional/plugins/resolver_test/ @elastic/security-solution /x-pack/test/plugin_functional/test_suites/resolver/ @elastic/security-solution /x-pack/plugins/security_solution/ @elastic/security-solution +/x-pack/plugins/metrics_entities/ @elastic/security-solution /x-pack/test/detection_engine_api_integration @elastic/security-solution /x-pack/test/lists_api_integration @elastic/security-solution /x-pack/test/api_integration/apis/security_solution @elastic/security-solution diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.eskuery.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.eskuery.md index c25cd70e99b4f..e16db4415f248 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.eskuery.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.eskuery.md @@ -15,6 +15,6 @@ esKuery: { nodeTypes: import("@kbn/es-query/target_types/kuery/node_types").NodeTypes; fromKueryExpression: (expression: string | import("@elastic/elasticsearch/api/types").QueryDslQueryContainer, parseOptions?: Partial | undefined) => import("@kbn/es-query").KueryNode; - toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: Record | undefined, context?: Record | undefined) => import("@kbn/utility-types").JsonObject; + toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: import("@kbn/es-query").KueryQueryOptions | undefined, context?: Record | undefined) => import("@elastic/elasticsearch/api/types").QueryDslQueryContainer; } ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md index c7046902dac72..73261cd49d6d2 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.md @@ -21,4 +21,5 @@ export interface IKibanaSearchResponse | [loaded](./kibana-plugin-plugins-data-public.ikibanasearchresponse.loaded.md) | number | If relevant to the search strategy, return a loaded number that represents how progress is indicated. | | [rawResponse](./kibana-plugin-plugins-data-public.ikibanasearchresponse.rawresponse.md) | RawResponse | The raw response returned by the internal search method (usually the raw ES response) | | [total](./kibana-plugin-plugins-data-public.ikibanasearchresponse.total.md) | number | If relevant to the search strategy, return a total number that represents how progress is indicated. | +| [warning](./kibana-plugin-plugins-data-public.ikibanasearchresponse.warning.md) | string | Optional warnings that should be surfaced to the end user | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.warning.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.warning.md new file mode 100644 index 0000000000000..cc0b8e2bea56e --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ikibanasearchresponse.warning.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IKibanaSearchResponse](./kibana-plugin-plugins-data-public.ikibanasearchresponse.md) > [warning](./kibana-plugin-plugins-data-public.ikibanasearchresponse.warning.md) + +## IKibanaSearchResponse.warning property + +Optional warnings that should be surfaced to the end user + +Signature: + +```typescript +warning?: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.id.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.id.md new file mode 100644 index 0000000000000..88c3a7d3654be --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternListItem](./kibana-plugin-plugins-data-public.indexpatternlistitem.md) > [id](./kibana-plugin-plugins-data-public.indexpatternlistitem.id.md) + +## IndexPatternListItem.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.md new file mode 100644 index 0000000000000..609a5e0d9ef2c --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternListItem](./kibana-plugin-plugins-data-public.indexpatternlistitem.md) + +## IndexPatternListItem interface + +Signature: + +```typescript +export interface IndexPatternListItem +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-data-public.indexpatternlistitem.id.md) | string | | +| [title](./kibana-plugin-plugins-data-public.indexpatternlistitem.title.md) | string | | +| [type](./kibana-plugin-plugins-data-public.indexpatternlistitem.type.md) | string | | +| [typeMeta](./kibana-plugin-plugins-data-public.indexpatternlistitem.typemeta.md) | TypeMeta | | + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.title.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.title.md new file mode 100644 index 0000000000000..26f292bf0d17b --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.title.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternListItem](./kibana-plugin-plugins-data-public.indexpatternlistitem.md) > [title](./kibana-plugin-plugins-data-public.indexpatternlistitem.title.md) + +## IndexPatternListItem.title property + +Signature: + +```typescript +title: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.type.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.type.md new file mode 100644 index 0000000000000..467e8bb81b159 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternListItem](./kibana-plugin-plugins-data-public.indexpatternlistitem.md) > [type](./kibana-plugin-plugins-data-public.indexpatternlistitem.type.md) + +## IndexPatternListItem.type property + +Signature: + +```typescript +type?: string; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.typemeta.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.typemeta.md new file mode 100644 index 0000000000000..3b93c5111f8dd --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternlistitem.typemeta.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPatternListItem](./kibana-plugin-plugins-data-public.indexpatternlistitem.md) > [typeMeta](./kibana-plugin-plugins-data-public.indexpatternlistitem.typemeta.md) + +## IndexPatternListItem.typeMeta property + +Signature: + +```typescript +typeMeta?: TypeMeta; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.getcache.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.getcache.md index ad2a167bd8c74..1f0148df596af 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.getcache.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.getcache.md @@ -7,5 +7,5 @@ Signature: ```typescript -getCache: () => Promise[] | null | undefined>; +getCache: () => Promise>[] | null | undefined>; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.getidswithtitle.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.getidswithtitle.md index 7d29ced66afa8..b2dcddce0457c 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.getidswithtitle.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.getidswithtitle.md @@ -9,8 +9,5 @@ Get list of index pattern ids with titles Signature: ```typescript -getIdsWithTitle: (refresh?: boolean) => Promise>; +getIdsWithTitle: (refresh?: boolean) => Promise; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md index 26b393a5fb5b6..572a122066868 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md @@ -25,13 +25,13 @@ export declare class IndexPatternsService | [fieldArrayToMap](./kibana-plugin-plugins-data-public.indexpatternsservice.fieldarraytomap.md) | | (fields: FieldSpec[], fieldAttrs?: FieldAttrs | undefined) => Record<string, FieldSpec> | Converts field array to map | | [find](./kibana-plugin-plugins-data-public.indexpatternsservice.find.md) | | (search: string, size?: number) => Promise<IndexPattern[]> | Find and load index patterns by title | | [get](./kibana-plugin-plugins-data-public.indexpatternsservice.get.md) | | (id: string) => Promise<IndexPattern> | Get an index pattern by id. Cache optimized | -| [getCache](./kibana-plugin-plugins-data-public.indexpatternsservice.getcache.md) | | () => Promise<SavedObject<IndexPatternSavedObjectAttrs>[] | null | undefined> | | +| [getCache](./kibana-plugin-plugins-data-public.indexpatternsservice.getcache.md) | | () => Promise<SavedObject<Pick<IndexPatternAttributes, "type" | "title" | "typeMeta">>[] | null | undefined> | | | [getDefault](./kibana-plugin-plugins-data-public.indexpatternsservice.getdefault.md) | | () => Promise<IndexPattern | null> | Get default index pattern | | [getDefaultId](./kibana-plugin-plugins-data-public.indexpatternsservice.getdefaultid.md) | | () => Promise<string | null> | Get default index pattern id | | [getFieldsForIndexPattern](./kibana-plugin-plugins-data-public.indexpatternsservice.getfieldsforindexpattern.md) | | (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions | undefined) => Promise<any> | Get field list by providing an index patttern (or spec) | | [getFieldsForWildcard](./kibana-plugin-plugins-data-public.indexpatternsservice.getfieldsforwildcard.md) | | (options: GetFieldsOptions) => Promise<any> | Get field list by providing { pattern } | | [getIds](./kibana-plugin-plugins-data-public.indexpatternsservice.getids.md) | | (refresh?: boolean) => Promise<string[]> | Get list of index pattern ids | -| [getIdsWithTitle](./kibana-plugin-plugins-data-public.indexpatternsservice.getidswithtitle.md) | | (refresh?: boolean) => Promise<Array<{
id: string;
title: string;
}>> | Get list of index pattern ids with titles | +| [getIdsWithTitle](./kibana-plugin-plugins-data-public.indexpatternsservice.getidswithtitle.md) | | (refresh?: boolean) => Promise<IndexPatternListItem[]> | Get list of index pattern ids with titles | | [getTitles](./kibana-plugin-plugins-data-public.indexpatternsservice.gettitles.md) | | (refresh?: boolean) => Promise<string[]> | Get list of index pattern titles | | [refreshFields](./kibana-plugin-plugins-data-public.indexpatternsservice.refreshfields.md) | | (indexPattern: IndexPattern) => Promise<void> | Refresh field list for a given index pattern | | [savedObjectToSpec](./kibana-plugin-plugins-data-public.indexpatternsservice.savedobjecttospec.md) | | (savedObject: SavedObject<IndexPatternAttributes>) => IndexPatternSpec | Converts index pattern saved object to index pattern spec | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md index 760f6d8651428..185dd771c4ace 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.md @@ -66,6 +66,7 @@ | [IKibanaSearchRequest](./kibana-plugin-plugins-data-public.ikibanasearchrequest.md) | | | [IKibanaSearchResponse](./kibana-plugin-plugins-data-public.ikibanasearchresponse.md) | | | [IndexPatternAttributes](./kibana-plugin-plugins-data-public.indexpatternattributes.md) | Interface for an index pattern saved object | +| [IndexPatternListItem](./kibana-plugin-plugins-data-public.indexpatternlistitem.md) | | | [IndexPatternSpec](./kibana-plugin-plugins-data-public.indexpatternspec.md) | Static index pattern format Serialized data object, representing index pattern attributes and state | | [ISearchOptions](./kibana-plugin-plugins-data-public.isearchoptions.md) | | | [ISearchSetup](./kibana-plugin-plugins-data-public.isearchsetup.md) | The setup contract exposed by the Search plugin exposes the search strategy extension point. | @@ -84,6 +85,7 @@ | [SavedQueryService](./kibana-plugin-plugins-data-public.savedqueryservice.md) | | | [SearchSessionInfoProvider](./kibana-plugin-plugins-data-public.searchsessioninfoprovider.md) | Provide info about current search session to be stored in the Search Session saved object | | [SearchSourceFields](./kibana-plugin-plugins-data-public.searchsourcefields.md) | search source fields | +| [TypeMeta](./kibana-plugin-plugins-data-public.typemeta.md) | | | [WaitUntilNextSessionCompletesOptions](./kibana-plugin-plugins-data-public.waituntilnextsessioncompletesoptions.md) | Options for [waitUntilNextSessionCompletes$()](./kibana-plugin-plugins-data-public.waituntilnextsessioncompletes_.md) | ## Variables diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.search.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.search.md index 3c99ae4c86c63..c54ffedf61034 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.search.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.search.md @@ -47,7 +47,9 @@ search: { intervalLabel: string; })[]; getNumberHistogramIntervalByDatatableColumn: (column: import("../../expressions").DatatableColumn) => number | undefined; - getDateHistogramMetaDataByDatatableColumn: (column: import("../../expressions").DatatableColumn) => { + getDateHistogramMetaDataByDatatableColumn: (column: import("../../expressions").DatatableColumn, defaults?: Partial<{ + timeZone: string; + }>) => { interval: string | undefined; timeZone: string | undefined; timeRange: import("../common").TimeRange | undefined; diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.typemeta.aggs.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.typemeta.aggs.md new file mode 100644 index 0000000000000..d2ab7ef72a4a5 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.typemeta.aggs.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [TypeMeta](./kibana-plugin-plugins-data-public.typemeta.md) > [aggs](./kibana-plugin-plugins-data-public.typemeta.aggs.md) + +## TypeMeta.aggs property + +Signature: + +```typescript +aggs?: Record; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.typemeta.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.typemeta.md new file mode 100644 index 0000000000000..dcc6500d54c5e --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.typemeta.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [TypeMeta](./kibana-plugin-plugins-data-public.typemeta.md) + +## TypeMeta interface + +Signature: + +```typescript +export interface TypeMeta +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [aggs](./kibana-plugin-plugins-data-public.typemeta.aggs.md) | Record<string, AggregationRestrictions> | | +| [params](./kibana-plugin-plugins-data-public.typemeta.params.md) | {
rollup_index: string;
} | | + diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.typemeta.params.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.typemeta.params.md new file mode 100644 index 0000000000000..6646f3c63ecc1 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.typemeta.params.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [TypeMeta](./kibana-plugin-plugins-data-public.typemeta.md) > [params](./kibana-plugin-plugins-data-public.typemeta.params.md) + +## TypeMeta.params property + +Signature: + +```typescript +params?: { + rollup_index: string; + }; +``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.eskuery.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.eskuery.md index 620a547d30245..d4365550c2a38 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.eskuery.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.eskuery.md @@ -10,6 +10,6 @@ esKuery: { nodeTypes: import("@kbn/es-query/target_types/kuery/node_types").NodeTypes; fromKueryExpression: (expression: string | import("@elastic/elasticsearch/api/types").QueryDslQueryContainer, parseOptions?: Partial | undefined) => import("@kbn/es-query").KueryNode; - toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: Record | undefined, context?: Record | undefined) => import("@kbn/utility-types").JsonObject; + toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: import("@kbn/es-query").KueryQueryOptions | undefined, context?: Record | undefined) => import("@elastic/elasticsearch/api/types").QueryDslQueryContainer; } ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.getcache.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.getcache.md index 821c06984e55e..db765cf54d048 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.getcache.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.getcache.md @@ -7,5 +7,5 @@ Signature: ```typescript -getCache: () => Promise[] | null | undefined>; +getCache: () => Promise>[] | null | undefined>; ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.getidswithtitle.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.getidswithtitle.md index 6433c78483545..a047b056e0ed5 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.getidswithtitle.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.getidswithtitle.md @@ -9,8 +9,5 @@ Get list of index pattern ids with titles Signature: ```typescript -getIdsWithTitle: (refresh?: boolean) => Promise>; +getIdsWithTitle: (refresh?: boolean) => Promise; ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.md index f5e845ced3cd1..64c46fe4abbd8 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpatternsservice.md @@ -25,13 +25,13 @@ export declare class IndexPatternsService | [fieldArrayToMap](./kibana-plugin-plugins-data-server.indexpatternsservice.fieldarraytomap.md) | | (fields: FieldSpec[], fieldAttrs?: FieldAttrs | undefined) => Record<string, FieldSpec> | Converts field array to map | | [find](./kibana-plugin-plugins-data-server.indexpatternsservice.find.md) | | (search: string, size?: number) => Promise<IndexPattern[]> | Find and load index patterns by title | | [get](./kibana-plugin-plugins-data-server.indexpatternsservice.get.md) | | (id: string) => Promise<IndexPattern> | Get an index pattern by id. Cache optimized | -| [getCache](./kibana-plugin-plugins-data-server.indexpatternsservice.getcache.md) | | () => Promise<SavedObject<IndexPatternSavedObjectAttrs>[] | null | undefined> | | +| [getCache](./kibana-plugin-plugins-data-server.indexpatternsservice.getcache.md) | | () => Promise<SavedObject<Pick<IndexPatternAttributes, "type" | "title" | "typeMeta">>[] | null | undefined> | | | [getDefault](./kibana-plugin-plugins-data-server.indexpatternsservice.getdefault.md) | | () => Promise<IndexPattern | null> | Get default index pattern | | [getDefaultId](./kibana-plugin-plugins-data-server.indexpatternsservice.getdefaultid.md) | | () => Promise<string | null> | Get default index pattern id | | [getFieldsForIndexPattern](./kibana-plugin-plugins-data-server.indexpatternsservice.getfieldsforindexpattern.md) | | (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions | undefined) => Promise<any> | Get field list by providing an index patttern (or spec) | | [getFieldsForWildcard](./kibana-plugin-plugins-data-server.indexpatternsservice.getfieldsforwildcard.md) | | (options: GetFieldsOptions) => Promise<any> | Get field list by providing { pattern } | | [getIds](./kibana-plugin-plugins-data-server.indexpatternsservice.getids.md) | | (refresh?: boolean) => Promise<string[]> | Get list of index pattern ids | -| [getIdsWithTitle](./kibana-plugin-plugins-data-server.indexpatternsservice.getidswithtitle.md) | | (refresh?: boolean) => Promise<Array<{
id: string;
title: string;
}>> | Get list of index pattern ids with titles | +| [getIdsWithTitle](./kibana-plugin-plugins-data-server.indexpatternsservice.getidswithtitle.md) | | (refresh?: boolean) => Promise<IndexPatternListItem[]> | Get list of index pattern ids with titles | | [getTitles](./kibana-plugin-plugins-data-server.indexpatternsservice.gettitles.md) | | (refresh?: boolean) => Promise<string[]> | Get list of index pattern titles | | [refreshFields](./kibana-plugin-plugins-data-server.indexpatternsservice.refreshfields.md) | | (indexPattern: IndexPattern) => Promise<void> | Refresh field list for a given index pattern | | [savedObjectToSpec](./kibana-plugin-plugins-data-server.indexpatternsservice.savedobjecttospec.md) | | (savedObject: SavedObject<IndexPatternAttributes>) => IndexPatternSpec | Converts index pattern saved object to index pattern spec | diff --git a/examples/bfetch_explorer/kibana.json b/examples/bfetch_explorer/kibana.json index 4bd4492611812..0eda11670034c 100644 --- a/examples/bfetch_explorer/kibana.json +++ b/examples/bfetch_explorer/kibana.json @@ -4,6 +4,10 @@ "version": "0.0.1", "server": true, "ui": true, + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, "requiredPlugins": ["bfetch", "developerExamples"], "optionalPlugins": [], "requiredBundles": ["kibanaReact"] diff --git a/examples/developer_examples/kibana.json b/examples/developer_examples/kibana.json index 9e6b54c7af67c..a744b53137dc7 100644 --- a/examples/developer_examples/kibana.json +++ b/examples/developer_examples/kibana.json @@ -1,5 +1,9 @@ { "id": "developerExamples", + "owner": { + "name": "Kibana Core", + "githubTeam": "kibana-core" + }, "kibanaVersion": "kibana", "version": "0.0.1", "ui": true diff --git a/examples/expressions_explorer/kibana.json b/examples/expressions_explorer/kibana.json index 7e2062ff0a588..770ce91143d99 100644 --- a/examples/expressions_explorer/kibana.json +++ b/examples/expressions_explorer/kibana.json @@ -4,6 +4,10 @@ "version": "0.0.1", "server": false, "ui": true, + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, "requiredPlugins": ["expressions", "inspector", "uiActions", "developerExamples"], "optionalPlugins": [], "requiredBundles": [] diff --git a/examples/search_examples/public/search/app.tsx b/examples/search_examples/public/search/app.tsx index 06f9426b4965c..bfb41160ae963 100644 --- a/examples/search_examples/public/search/app.tsx +++ b/examples/search_examples/public/search/app.tsx @@ -131,12 +131,46 @@ export const SearchExamplesApp = ({ setSelectedNumericField(fields?.length ? getNumeric(fields)[0] : null); }, [fields]); - const doAsyncSearch = async (strategy?: string, sessionId?: string) => { + const doAsyncSearch = async ( + strategy?: string, + sessionId?: string, + addWarning: boolean = false, + addError: boolean = false + ) => { if (!indexPattern || !selectedNumericField) return; // Construct the query portion of the search request const query = data.query.getEsQuery(indexPattern); + if (addWarning) { + query.bool.must.push({ + // @ts-ignore + error_query: { + indices: [ + { + name: indexPattern.title, + error_type: 'warning', + message: 'Watch out!', + }, + ], + }, + }); + } + if (addError) { + query.bool.must.push({ + // @ts-ignore + error_query: { + indices: [ + { + name: indexPattern.title, + error_type: 'exception', + message: 'Watch out!', + }, + ], + }, + }); + } + // Construct the aggregations portion of the search request by using the `data.search.aggs` service. const aggs = [{ type: 'avg', params: { field: selectedNumericField!.name } }]; const aggsDsl = data.search.aggs.createAggConfigs(indexPattern, aggs).toDsl(); @@ -193,14 +227,23 @@ export const SearchExamplesApp = ({ } ); searchSubscription$.unsubscribe(); + if (res.warning) { + notifications.toasts.addWarning({ + title: 'Warning', + text: mountReactNode(res.warning), + }); + } } else if (isErrorResponse(res)) { // TODO: Make response error status clearer - notifications.toasts.addWarning('An error has occurred'); + notifications.toasts.addDanger('An error has occurred'); searchSubscription$.unsubscribe(); } }, - error: () => { - notifications.toasts.addDanger('Failed to run search'); + error: (e) => { + notifications.toasts.addDanger({ + title: 'Failed to run search', + text: e.message, + }); }, }); }; @@ -270,6 +313,14 @@ export const SearchExamplesApp = ({ doAsyncSearch('myStrategy'); }; + const onWarningSearchClickHandler = () => { + doAsyncSearch(undefined, undefined, true); + }; + + const onErrorSearchClickHandler = () => { + doAsyncSearch(undefined, undefined, false, true); + }; + const onPartialResultsClickHandler = () => { setSelectedTab(1); const req = { @@ -299,8 +350,11 @@ export const SearchExamplesApp = ({ searchSubscription$.unsubscribe(); } }, - error: () => { - notifications.toasts.addDanger('Failed to run search'); + error: (e) => { + notifications.toasts.addDanger({ + title: 'Failed to run search', + text: e.message, + }); }, }); }; @@ -530,6 +584,38 @@ export const SearchExamplesApp = ({ + +

Handling errors & warnings

+
+ + When fetching data from Elasticsearch, there are several different ways warnings and + errors may be returned. In general, it is recommended to surface these in the UX. + + + + + + + + + +

Handling partial results

diff --git a/package.json b/package.json index 98b2252cc0dba..00fa0807e0f93 100644 --- a/package.json +++ b/package.json @@ -97,9 +97,9 @@ "@elastic/apm-rum-react": "^1.2.11", "@elastic/charts": "33.2.2", "@elastic/datemath": "link:bazel-bin/packages/elastic-datemath", - "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary.14", - "@elastic/ems-client": "7.14.0", - "@elastic/eui": "36.1.0", + "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary.17", + "@elastic/ems-client": "7.15.0", + "@elastic/eui": "37.1.1", "@elastic/filesaver": "1.1.2", "@elastic/good": "^9.0.1-kibana3", "@elastic/maki": "6.3.0", @@ -632,7 +632,6 @@ "@types/strong-log-transformer": "^1.0.0", "@types/styled-components": "^5.1.0", "@types/supertest": "^2.0.5", - "@types/supertest-as-promised": "^2.0.38", "@types/tapable": "^1.0.6", "@types/tar": "^4.0.3", "@types/tar-fs": "^1.16.1", @@ -680,7 +679,7 @@ "callsites": "^3.1.0", "chai": "3.5.0", "chance": "1.0.18", - "chromedriver": "^91.0.1", + "chromedriver": "^92.0.1", "clean-webpack-plugin": "^3.0.0", "cmd-shim": "^2.1.0", "compression-webpack-plugin": "^4.0.0", @@ -824,7 +823,6 @@ "stylelint-scss": "^3.18.0", "superagent": "^3.8.2", "supertest": "^3.1.0", - "supertest-as-promised": "^4.0.2", "supports-color": "^7.0.0", "tape": "^5.0.1", "tar-fs": "^2.1.0", diff --git a/packages/kbn-es-query/src/es_query/from_kuery.ts b/packages/kbn-es-query/src/es_query/from_kuery.ts index 949f9691e9e6d..151ea6a89bb5e 100644 --- a/packages/kbn-es-query/src/es_query/from_kuery.ts +++ b/packages/kbn-es-query/src/es_query/from_kuery.ts @@ -30,7 +30,7 @@ function buildQuery( indexPattern: IndexPatternBase | undefined, queryASTs: KueryNode[], config: SerializableRecord = {} -) { +): BoolQuery { const compoundQueryAST = nodeTypes.function.buildNode('and', queryASTs); const kueryQuery = toElasticsearchQuery(compoundQueryAST, indexPattern, config); diff --git a/packages/kbn-es-query/src/kuery/ast/ast.ts b/packages/kbn-es-query/src/kuery/ast/ast.ts index 826fa194f1b30..7145eb5043c60 100644 --- a/packages/kbn-es-query/src/kuery/ast/ast.ts +++ b/packages/kbn-es-query/src/kuery/ast/ast.ts @@ -10,7 +10,7 @@ import { JsonObject } from '@kbn/utility-types'; import { estypes } from '@elastic/elasticsearch'; import { nodeTypes } from '../node_types/index'; import { KQLSyntaxError } from '../kuery_syntax_error'; -import { KueryNode, KueryParseOptions } from '../types'; +import { KueryNode, KueryParseOptions, KueryQueryOptions } from '../types'; import { parse as parseKuery } from '../grammar'; import { IndexPatternBase } from '../..'; @@ -62,18 +62,19 @@ export const fromKueryExpression = ( * * IndexPattern isn't required, but if you pass one in, we can be more intelligent * about how we craft the queries (e.g. scripted fields) + * */ export const toElasticsearchQuery = ( node: KueryNode, indexPattern?: IndexPatternBase, - config?: Record, + config: KueryQueryOptions = {}, context?: Record ): JsonObject => { if (!node || !node.type || !nodeTypes[node.type]) { return toElasticsearchQuery(nodeTypes.function.buildNode('and', []), indexPattern); } + // TODO: the return type of this function might be incorrect and it works only because of this casting const nodeType = (nodeTypes[node.type] as unknown) as any; - return nodeType.toElasticsearchQuery(node, indexPattern, config, context); }; diff --git a/packages/kbn-es-query/src/kuery/functions/exists.ts b/packages/kbn-es-query/src/kuery/functions/exists.ts index 0e05ade5181db..d1d0cb7835bca 100644 --- a/packages/kbn-es-query/src/kuery/functions/exists.ts +++ b/packages/kbn-es-query/src/kuery/functions/exists.ts @@ -6,7 +6,8 @@ * Side Public License, v 1. */ -import { IndexPatternFieldBase, IndexPatternBase, KueryNode } from '../..'; +import { estypes } from '@elastic/elasticsearch'; +import { IndexPatternFieldBase, IndexPatternBase, KueryNode, KueryQueryOptions } from '../..'; import * as literal from '../node_types/literal'; export function buildNodeParams(fieldName: string) { @@ -18,9 +19,9 @@ export function buildNodeParams(fieldName: string) { export function toElasticsearchQuery( node: KueryNode, indexPattern?: IndexPatternBase, - config: Record = {}, + config: KueryQueryOptions = {}, context: Record = {} -) { +): estypes.QueryDslQueryContainer { const { arguments: [fieldNameArg], } = node; @@ -28,7 +29,7 @@ export function toElasticsearchQuery( ...fieldNameArg, value: context?.nested ? `${context.nested.path}.${fieldNameArg.value}` : fieldNameArg.value, }; - const fieldName = literal.toElasticsearchQuery(fullFieldNameArg); + const fieldName = literal.toElasticsearchQuery(fullFieldNameArg) as string; const field = indexPattern?.fields?.find((fld: IndexPatternFieldBase) => fld.name === fieldName); if (field?.scripted) { diff --git a/packages/kbn-es-query/src/kuery/functions/geo_bounding_box.test.ts b/packages/kbn-es-query/src/kuery/functions/geo_bounding_box.test.ts index 028c5e39bf5da..45e6474b22986 100644 --- a/packages/kbn-es-query/src/kuery/functions/geo_bounding_box.test.ts +++ b/packages/kbn-es-query/src/kuery/functions/geo_bounding_box.test.ts @@ -12,6 +12,7 @@ import { fields } from '../../filters/stubs'; import { IndexPatternBase } from '../..'; import * as geoBoundingBox from './geo_bounding_box'; +import { JsonObject } from '@kbn/utility-types'; jest.mock('../grammar'); @@ -78,8 +79,14 @@ describe('kuery functions', () => { const result = geoBoundingBox.toElasticsearchQuery(node, indexPattern); expect(result).toHaveProperty('geo_bounding_box'); - expect(result.geo_bounding_box.geo).toHaveProperty('top_left', '73.12, -174.37'); - expect(result.geo_bounding_box.geo).toHaveProperty('bottom_right', '50.73, -135.35'); + expect((result.geo_bounding_box as JsonObject).geo).toHaveProperty( + 'top_left', + '73.12, -174.37' + ); + expect((result.geo_bounding_box as JsonObject).geo).toHaveProperty( + 'bottom_right', + '50.73, -135.35' + ); }); test('should return an ES geo_bounding_box query without an index pattern', () => { @@ -87,15 +94,22 @@ describe('kuery functions', () => { const result = geoBoundingBox.toElasticsearchQuery(node); expect(result).toHaveProperty('geo_bounding_box'); - expect(result.geo_bounding_box.geo).toHaveProperty('top_left', '73.12, -174.37'); - expect(result.geo_bounding_box.geo).toHaveProperty('bottom_right', '50.73, -135.35'); + expect((result.geo_bounding_box as JsonObject).geo).toHaveProperty( + 'top_left', + '73.12, -174.37' + ); + expect((result.geo_bounding_box as JsonObject).geo).toHaveProperty( + 'bottom_right', + '50.73, -135.35' + ); }); test('should use the ignore_unmapped parameter', () => { const node = nodeTypes.function.buildNode('geoBoundingBox', 'geo', params); const result = geoBoundingBox.toElasticsearchQuery(node, indexPattern); - expect(result.geo_bounding_box.ignore_unmapped).toBe(true); + // @ts-expect-error @elastic/elasticsearch doesn't support ignore_unmapped in QueryDslGeoBoundingBoxQuery + expect(result.geo_bounding_box!.ignore_unmapped).toBe(true); }); test('should throw an error for scripted fields', () => { @@ -116,7 +130,7 @@ describe('kuery functions', () => { ); expect(result).toHaveProperty('geo_bounding_box'); - expect(result.geo_bounding_box['nestedField.geo']).toBeDefined(); + expect((result.geo_bounding_box as JsonObject)['nestedField.geo']).toBeDefined(); }); }); }); diff --git a/packages/kbn-es-query/src/kuery/functions/geo_bounding_box.ts b/packages/kbn-es-query/src/kuery/functions/geo_bounding_box.ts index b1fd8680af604..1dae0b40ff08e 100644 --- a/packages/kbn-es-query/src/kuery/functions/geo_bounding_box.ts +++ b/packages/kbn-es-query/src/kuery/functions/geo_bounding_box.ts @@ -7,9 +7,10 @@ */ import _ from 'lodash'; +import { estypes } from '@elastic/elasticsearch'; import { nodeTypes } from '../node_types'; import * as ast from '../ast'; -import { IndexPatternBase, KueryNode, LatLon } from '../..'; +import { IndexPatternBase, KueryNode, KueryQueryOptions, LatLon } from '../..'; export function buildNodeParams(fieldName: string, params: any) { params = _.pick(params, 'topLeft', 'bottomRight'); @@ -27,9 +28,9 @@ export function buildNodeParams(fieldName: string, params: any) { export function toElasticsearchQuery( node: KueryNode, indexPattern?: IndexPatternBase, - config: Record = {}, + config: KueryQueryOptions = {}, context: Record = {} -) { +): estypes.QueryDslQueryContainer { const [fieldNameArg, ...args] = node.arguments; const fullFieldNameArg = { ...fieldNameArg, @@ -52,6 +53,7 @@ export function toElasticsearchQuery( } return { + // @ts-expect-error @elastic/elasticsearch doesn't support ignore_unmapped in QueryDslGeoBoundingBoxQuery geo_bounding_box: { [fieldName]: queryParams, ignore_unmapped: true, diff --git a/packages/kbn-es-query/src/kuery/functions/geo_polygon.test.ts b/packages/kbn-es-query/src/kuery/functions/geo_polygon.test.ts index f16ca378866f0..2d1d6ed6cd6de 100644 --- a/packages/kbn-es-query/src/kuery/functions/geo_polygon.test.ts +++ b/packages/kbn-es-query/src/kuery/functions/geo_polygon.test.ts @@ -79,9 +79,9 @@ describe('kuery functions', () => { const result = geoPolygon.toElasticsearchQuery(node, indexPattern); expect(result).toHaveProperty('geo_polygon'); - expect(result.geo_polygon.geo).toHaveProperty('points'); + expect((result.geo_polygon as any).geo).toHaveProperty('points'); - (result.geo_polygon.geo as any).points.forEach((point: any, index: number) => { + (result.geo_polygon as any).geo.points.forEach((point: any, index: number) => { const expectedLatLon = `${points[index].lat}, ${points[index].lon}`; expect(point).toBe(expectedLatLon); @@ -93,9 +93,9 @@ describe('kuery functions', () => { const result = geoPolygon.toElasticsearchQuery(node); expect(result).toHaveProperty('geo_polygon'); - expect(result.geo_polygon.geo).toHaveProperty('points'); + expect((result.geo_polygon as any).geo).toHaveProperty('points'); - (result.geo_polygon.geo as any).points.forEach((point: any, index: number) => { + (result.geo_polygon as any).geo.points.forEach((point: any, index: number) => { const expectedLatLon = `${points[index].lat}, ${points[index].lon}`; expect(point).toBe(expectedLatLon); @@ -106,7 +106,7 @@ describe('kuery functions', () => { const node = nodeTypes.function.buildNode('geoPolygon', 'geo', points); const result = geoPolygon.toElasticsearchQuery(node, indexPattern); - expect(result.geo_polygon.ignore_unmapped).toBe(true); + expect((result.geo_polygon as any).ignore_unmapped).toBe(true); }); test('should throw an error for scripted fields', () => { @@ -126,7 +126,7 @@ describe('kuery functions', () => { ); expect(result).toHaveProperty('geo_polygon'); - expect(result.geo_polygon['nestedField.geo']).toBeDefined(); + expect((result.geo_polygon as any)['nestedField.geo']).toBeDefined(); }); }); }); diff --git a/packages/kbn-es-query/src/kuery/functions/geo_polygon.ts b/packages/kbn-es-query/src/kuery/functions/geo_polygon.ts index d02ba84237c7f..cf0bcdafa04c7 100644 --- a/packages/kbn-es-query/src/kuery/functions/geo_polygon.ts +++ b/packages/kbn-es-query/src/kuery/functions/geo_polygon.ts @@ -6,9 +6,10 @@ * Side Public License, v 1. */ +import { estypes } from '@elastic/elasticsearch'; import { nodeTypes } from '../node_types'; import * as ast from '../ast'; -import { IndexPatternBase, KueryNode, LatLon } from '../..'; +import { IndexPatternBase, KueryNode, KueryQueryOptions, LatLon } from '../..'; import { LiteralTypeBuildNode } from '../node_types/types'; export function buildNodeParams(fieldName: string, points: LatLon[]) { @@ -26,9 +27,9 @@ export function buildNodeParams(fieldName: string, points: LatLon[]) { export function toElasticsearchQuery( node: KueryNode, indexPattern?: IndexPatternBase, - config: Record = {}, + config: KueryQueryOptions = {}, context: Record = {} -) { +): estypes.QueryDslQueryContainer { const [fieldNameArg, ...points] = node.arguments; const fullFieldNameArg = { ...fieldNameArg, @@ -48,6 +49,7 @@ export function toElasticsearchQuery( } return { + // @ts-expect-error @elastic/elasticsearch doesn't support ignore_unmapped in QueryDslGeoPolygonQuery geo_polygon: { [fieldName]: queryParams, ignore_unmapped: true, diff --git a/packages/kbn-es-query/src/kuery/functions/is.test.ts b/packages/kbn-es-query/src/kuery/functions/is.test.ts index 292159e727a92..bc1bbb2508438 100644 --- a/packages/kbn-es-query/src/kuery/functions/is.test.ts +++ b/packages/kbn-es-query/src/kuery/functions/is.test.ts @@ -11,6 +11,7 @@ import { fields } from '../../filters/stubs'; import * as is from './is'; import { IndexPatternBase } from '../..'; +import { estypes } from '@elastic/elasticsearch'; jest.mock('../grammar'); @@ -125,7 +126,9 @@ describe('kuery functions', () => { const result = is.toElasticsearchQuery(node, indexPattern); expect(result).toHaveProperty('bool'); - expect(result.bool!.should!.length).toBe(indexPattern.fields.length); + expect((result.bool!.should! as estypes.QueryDslQueryContainer[]).length).toBe( + indexPattern.fields.length + ); }); test('should return an ES exists query when value is "*"', () => { @@ -204,7 +207,9 @@ describe('kuery functions', () => { const node = nodeTypes.function.buildNode('is', 'script string', 'foo'); const result = is.toElasticsearchQuery(node, indexPattern); - expect(result.bool!.should![0]).toHaveProperty('script'); + expect((result.bool!.should as estypes.QueryDslQueryContainer[])[0]).toHaveProperty( + 'script' + ); }); test('should support date fields without a dateFormat provided', () => { diff --git a/packages/kbn-es-query/src/kuery/functions/is.ts b/packages/kbn-es-query/src/kuery/functions/is.ts index c8d33921b084a..4dc0a66d3d9fa 100644 --- a/packages/kbn-es-query/src/kuery/functions/is.ts +++ b/packages/kbn-es-query/src/kuery/functions/is.ts @@ -7,11 +7,12 @@ */ import { get, isUndefined } from 'lodash'; +import { estypes } from '@elastic/elasticsearch'; import { getPhraseScript } from '../../filters'; import { getFields } from './utils/get_fields'; import { getTimeZoneFromSettings } from '../../utils'; import { getFullFieldNameNode } from './utils/get_full_field_name_node'; -import { IndexPatternBase, KueryNode, IndexPatternFieldBase } from '../..'; +import { IndexPatternBase, KueryNode, IndexPatternFieldBase, KueryQueryOptions } from '../..'; import * as ast from '../ast'; @@ -40,9 +41,9 @@ export function buildNodeParams(fieldName: string, value: any, isPhrase: boolean export function toElasticsearchQuery( node: KueryNode, indexPattern?: IndexPatternBase, - config: Record = {}, + config: KueryQueryOptions = {}, context: Record = {} -) { +): estypes.QueryDslQueryContainer { const { arguments: [fieldNameArg, valueArg, isPhraseArg], } = node; @@ -75,7 +76,7 @@ export function toElasticsearchQuery( return { multi_match: { type, - query: value, + query: (value as unknown) as string, lenient: true, }, }; diff --git a/packages/kbn-es-query/src/kuery/functions/nested.test.ts b/packages/kbn-es-query/src/kuery/functions/nested.test.ts index 47e515b9bd47f..7b6b7b695db2d 100644 --- a/packages/kbn-es-query/src/kuery/functions/nested.test.ts +++ b/packages/kbn-es-query/src/kuery/functions/nested.test.ts @@ -48,8 +48,8 @@ describe('kuery functions', () => { expect(result).toHaveProperty('nested'); expect(Object.keys(result).length).toBe(1); - expect(result.nested.path).toBe('nestedField'); - expect(result.nested.score_mode).toBe('none'); + expect(result.nested?.path).toBe('nestedField'); + expect(result.nested?.score_mode).toBe('none'); }); test('should pass the nested path to subqueries so the full field name can be used', () => { @@ -59,7 +59,7 @@ describe('kuery functions', () => { nodeTypes.function.buildNode('is', 'nestedField.child', 'foo') ); - expect(result.nested.query).toEqual(expectedSubQuery); + expect(result.nested!.query).toEqual(expectedSubQuery); }); }); }); diff --git a/packages/kbn-es-query/src/kuery/functions/nested.ts b/packages/kbn-es-query/src/kuery/functions/nested.ts index 248de1c40d62a..3a3be4c10eade 100644 --- a/packages/kbn-es-query/src/kuery/functions/nested.ts +++ b/packages/kbn-es-query/src/kuery/functions/nested.ts @@ -6,9 +6,10 @@ * Side Public License, v 1. */ +import { estypes } from '@elastic/elasticsearch'; import * as ast from '../ast'; import * as literal from '../node_types/literal'; -import { IndexPatternBase, KueryNode } from '../..'; +import { IndexPatternBase, KueryNode, KueryQueryOptions } from '../..'; export function buildNodeParams(path: any, child: any) { const pathNode = @@ -21,11 +22,11 @@ export function buildNodeParams(path: any, child: any) { export function toElasticsearchQuery( node: KueryNode, indexPattern?: IndexPatternBase, - config: Record = {}, + config: KueryQueryOptions = {}, context: Record = {} -) { +): estypes.QueryDslQueryContainer { const [path, child] = node.arguments; - const stringPath = ast.toElasticsearchQuery(path); + const stringPath = (ast.toElasticsearchQuery(path) as unknown) as string; const fullPath = context?.nested?.path ? `${context.nested.path}.${stringPath}` : stringPath; return { @@ -34,7 +35,7 @@ export function toElasticsearchQuery( query: ast.toElasticsearchQuery(child, indexPattern, config, { ...context, nested: { path: fullPath }, - }), + }) as estypes.QueryDslQueryContainer, score_mode: 'none', }, }; diff --git a/packages/kbn-es-query/src/kuery/functions/not.test.ts b/packages/kbn-es-query/src/kuery/functions/not.test.ts index a44f3e9c5dda8..af1e8108b40f5 100644 --- a/packages/kbn-es-query/src/kuery/functions/not.test.ts +++ b/packages/kbn-es-query/src/kuery/functions/not.test.ts @@ -46,9 +46,9 @@ describe('kuery functions', () => { expect(Object.keys(result).length).toBe(1); expect(result.bool).toHaveProperty('must_not'); - expect(Object.keys(result.bool).length).toBe(1); + expect(Object.keys(result.bool!).length).toBe(1); - expect(result.bool.must_not).toEqual(ast.toElasticsearchQuery(childNode, indexPattern)); + expect(result.bool!.must_not).toEqual(ast.toElasticsearchQuery(childNode, indexPattern)); }); }); }); diff --git a/packages/kbn-es-query/src/kuery/functions/not.ts b/packages/kbn-es-query/src/kuery/functions/not.ts index 96404ee800010..01ec89e9b499d 100644 --- a/packages/kbn-es-query/src/kuery/functions/not.ts +++ b/packages/kbn-es-query/src/kuery/functions/not.ts @@ -6,8 +6,9 @@ * Side Public License, v 1. */ +import { estypes } from '@elastic/elasticsearch'; import * as ast from '../ast'; -import { IndexPatternBase, KueryNode } from '../..'; +import { IndexPatternBase, KueryNode, KueryQueryOptions } from '../..'; export function buildNodeParams(child: KueryNode) { return { @@ -18,14 +19,19 @@ export function buildNodeParams(child: KueryNode) { export function toElasticsearchQuery( node: KueryNode, indexPattern?: IndexPatternBase, - config: Record = {}, + config: KueryQueryOptions = {}, context: Record = {} -) { +): estypes.QueryDslQueryContainer { const [argument] = node.arguments; return { bool: { - must_not: ast.toElasticsearchQuery(argument, indexPattern, config, context), + must_not: ast.toElasticsearchQuery( + argument, + indexPattern, + config, + context + ) as estypes.QueryDslQueryContainer, }, }; } diff --git a/packages/kbn-es-query/src/kuery/functions/or.test.ts b/packages/kbn-es-query/src/kuery/functions/or.test.ts index 15faa7e1753d3..eb7db62b22162 100644 --- a/packages/kbn-es-query/src/kuery/functions/or.test.ts +++ b/packages/kbn-es-query/src/kuery/functions/or.test.ts @@ -48,7 +48,7 @@ describe('kuery functions', () => { expect(result).toHaveProperty('bool'); expect(Object.keys(result).length).toBe(1); expect(result.bool).toHaveProperty('should'); - expect(result.bool.should).toEqual( + expect(result.bool!.should).toEqual( [childNode1, childNode2].map((childNode) => ast.toElasticsearchQuery(childNode, indexPattern) ) diff --git a/packages/kbn-es-query/src/kuery/functions/or.ts b/packages/kbn-es-query/src/kuery/functions/or.ts index b94814e1f7c05..d48ddb4c32d73 100644 --- a/packages/kbn-es-query/src/kuery/functions/or.ts +++ b/packages/kbn-es-query/src/kuery/functions/or.ts @@ -6,8 +6,9 @@ * Side Public License, v 1. */ +import { estypes } from '@elastic/elasticsearch'; import * as ast from '../ast'; -import { IndexPatternBase, KueryNode } from '../..'; +import { IndexPatternBase, KueryNode, KueryQueryOptions } from '../..'; export function buildNodeParams(children: KueryNode[]) { return { @@ -18,9 +19,9 @@ export function buildNodeParams(children: KueryNode[]) { export function toElasticsearchQuery( node: KueryNode, indexPattern?: IndexPatternBase, - config: Record = {}, + config: KueryQueryOptions = {}, context: Record = {} -) { +): estypes.QueryDslQueryContainer { const children = node.arguments || []; return { diff --git a/packages/kbn-es-query/src/kuery/functions/range.test.ts b/packages/kbn-es-query/src/kuery/functions/range.test.ts index fa1805e64887c..42005a3fe702d 100644 --- a/packages/kbn-es-query/src/kuery/functions/range.test.ts +++ b/packages/kbn-es-query/src/kuery/functions/range.test.ts @@ -13,6 +13,7 @@ import { IndexPatternBase } from '../..'; import { RangeFilterParams } from '../../filters'; import * as range from './range'; +import { estypes } from '@elastic/elasticsearch'; jest.mock('../grammar'); describe('kuery functions', () => { @@ -128,7 +129,9 @@ describe('kuery functions', () => { const node = nodeTypes.function.buildNode('range', 'script number', { gt: 1000, lt: 8000 }); const result = range.toElasticsearchQuery(node, indexPattern); - expect(result.bool.should[0]).toHaveProperty('script'); + expect((result.bool!.should as estypes.QueryDslQueryContainer[])[0]).toHaveProperty( + 'script' + ); }); test('should support date fields without a dateFormat provided', () => { diff --git a/packages/kbn-es-query/src/kuery/functions/range.ts b/packages/kbn-es-query/src/kuery/functions/range.ts index e80a365441c43..6b5810bb7518f 100644 --- a/packages/kbn-es-query/src/kuery/functions/range.ts +++ b/packages/kbn-es-query/src/kuery/functions/range.ts @@ -7,13 +7,14 @@ */ import _ from 'lodash'; +import { estypes } from '@elastic/elasticsearch'; import { nodeTypes } from '../node_types'; import * as ast from '../ast'; import { getRangeScript, RangeFilterParams } from '../../filters'; import { getFields } from './utils/get_fields'; import { getTimeZoneFromSettings } from '../../utils'; import { getFullFieldNameNode } from './utils/get_full_field_name_node'; -import { IndexPatternBase, KueryNode } from '../..'; +import { IndexPatternBase, KueryNode, KueryQueryOptions } from '../..'; export function buildNodeParams(fieldName: string, params: RangeFilterParams) { const paramsToMap = _.pick(params, 'gt', 'lt', 'gte', 'lte', 'format'); @@ -34,9 +35,9 @@ export function buildNodeParams(fieldName: string, params: RangeFilterParams) { export function toElasticsearchQuery( node: KueryNode, indexPattern?: IndexPatternBase, - config: Record = {}, + config: KueryQueryOptions = {}, context: Record = {} -) { +): estypes.QueryDslQueryContainer { const [fieldNameArg, ...args] = node.arguments; const fullFieldNameArg = getFullFieldNameNode( fieldNameArg, diff --git a/packages/kbn-es-query/src/kuery/index.ts b/packages/kbn-es-query/src/kuery/index.ts index dd1e39307b27e..15f3a768ebbd3 100644 --- a/packages/kbn-es-query/src/kuery/index.ts +++ b/packages/kbn-es-query/src/kuery/index.ts @@ -6,7 +6,21 @@ * Side Public License, v 1. */ +import { estypes } from '@elastic/elasticsearch'; +import { toElasticsearchQuery as astToElasticsearchQuery } from './ast'; + +/** + * @params {String} indexPattern + * @params {Object} config - contains the dateFormatTZ + * + * IndexPattern isn't required, but if you pass one in, we can be more intelligent + * about how we craft the queries (e.g. scripted fields) + */ +export const toElasticsearchQuery = (...params: Parameters) => { + return astToElasticsearchQuery(...params) as estypes.QueryDslQueryContainer; +}; + export { KQLSyntaxError } from './kuery_syntax_error'; export { nodeTypes, nodeBuilder } from './node_types'; -export { fromKueryExpression, toElasticsearchQuery } from './ast'; +export { fromKueryExpression } from './ast'; export { DslQuery, KueryNode, KueryQueryOptions } from './types'; diff --git a/packages/kbn-es-query/src/kuery/node_types/function.ts b/packages/kbn-es-query/src/kuery/node_types/function.ts index e72f8a6b1e77a..57954948b48c6 100644 --- a/packages/kbn-es-query/src/kuery/node_types/function.ts +++ b/packages/kbn-es-query/src/kuery/node_types/function.ts @@ -9,7 +9,7 @@ import _ from 'lodash'; import { functions } from '../functions'; -import { IndexPatternBase, KueryNode } from '../..'; +import { IndexPatternBase, KueryNode, KueryQueryOptions } from '../..'; import { FunctionName, FunctionTypeBuildNode } from './types'; export function buildNode(functionName: FunctionName, ...args: any[]) { @@ -46,7 +46,7 @@ export function buildNodeWithArgumentNodes( export function toElasticsearchQuery( node: KueryNode, indexPattern?: IndexPatternBase, - config?: Record, + config?: KueryQueryOptions, context?: Record ) { const kueryFunction = functions[node.function as FunctionName]; diff --git a/packages/kbn-es-query/src/kuery/node_types/types.ts b/packages/kbn-es-query/src/kuery/node_types/types.ts index 7e6f454418555..8ee83971c833b 100644 --- a/packages/kbn-es-query/src/kuery/node_types/types.ts +++ b/packages/kbn-es-query/src/kuery/node_types/types.ts @@ -11,7 +11,7 @@ */ import { JsonValue } from '@kbn/utility-types'; -import { KueryNode } from '..'; +import { KueryNode, KueryQueryOptions } from '..'; import { IndexPatternBase } from '../..'; export type FunctionName = @@ -31,7 +31,7 @@ interface FunctionType { toElasticsearchQuery: ( node: any, indexPattern?: IndexPatternBase, - config?: Record, + config?: KueryQueryOptions, context?: Record ) => JsonValue; } diff --git a/packages/kbn-es-query/src/kuery/types.ts b/packages/kbn-es-query/src/kuery/types.ts index 656e06e712079..1ab2d07a60a11 100644 --- a/packages/kbn-es-query/src/kuery/types.ts +++ b/packages/kbn-es-query/src/kuery/types.ts @@ -7,6 +7,7 @@ */ import { estypes } from '@elastic/elasticsearch'; +import { SerializableRecord } from '@kbn/utility-types'; import { NodeTypes } from './node_types'; /** @public */ @@ -22,9 +23,7 @@ export type DslQuery = estypes.QueryDslQueryContainer; /** @internal */ export interface KueryParseOptions { - helpers: { - [key: string]: any; - }; + helpers: SerializableRecord; startRule: string; allowLeadingWildcards: boolean; cursorSymbol?: string; diff --git a/packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts b/packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts index 476425487df1b..719301bce8e06 100644 --- a/packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts +++ b/packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts @@ -13,9 +13,6 @@ import type { EsQueryConfig } from '@kbn/es-query'; * registering a new instance of the rule data client * in a new plugin will require updating the below data structure * to include the index name where the alerts as data will be written to. - * - * This doesn't work in combination with the `xpack.ruleRegistry.index` - * setting, with which the user can change the index prefix. */ export const AlertConsumers = { @@ -24,7 +21,7 @@ export const AlertConsumers = { INFRASTRUCTURE: 'infrastructure', OBSERVABILITY: 'observability', SIEM: 'siem', - SYNTHETICS: 'synthetics', + UPTIME: 'uptime', } as const; export type AlertConsumers = typeof AlertConsumers[keyof typeof AlertConsumers]; export type STATUS_VALUES = 'open' | 'acknowledged' | 'closed' | 'in-progress'; // TODO: remove 'in-progress' after migration to 'acknowledged' @@ -35,7 +32,7 @@ export const mapConsumerToIndexName: Record = infrastructure: '.alerts-observability.metrics', observability: '.alerts-observability', siem: ['.alerts-security.alerts', '.siem-signals'], - synthetics: '.alerts-observability-synthetics', + uptime: '.alerts-observability.uptime', }; export type ValidFeatureId = keyof typeof mapConsumerToIndexName; diff --git a/src/plugins/kibana_overview/public/components/getting_started/index.ts b/packages/kbn-rule-data-utils/src/alerts_as_data_severity.ts similarity index 64% rename from src/plugins/kibana_overview/public/components/getting_started/index.ts rename to packages/kbn-rule-data-utils/src/alerts_as_data_severity.ts index 10977941afeee..c23af291fbefc 100644 --- a/src/plugins/kibana_overview/public/components/getting_started/index.ts +++ b/packages/kbn-rule-data-utils/src/alerts_as_data_severity.ts @@ -6,4 +6,6 @@ * Side Public License, v 1. */ -export * from './getting_started'; +export const ALERT_SEVERITY_WARNING = 'warning'; +export const ALERT_SEVERITY_CRITICAL = 'critical'; +export type AlertSeverity = typeof ALERT_SEVERITY_WARNING | typeof ALERT_SEVERITY_CRITICAL; diff --git a/packages/kbn-rule-data-utils/src/index.ts b/packages/kbn-rule-data-utils/src/index.ts index f60ad31286c9c..ef06d5777b5ab 100644 --- a/packages/kbn-rule-data-utils/src/index.ts +++ b/packages/kbn-rule-data-utils/src/index.ts @@ -8,3 +8,4 @@ export * from './technical_field_names'; export * from './alerts_as_data_rbac'; +export * from './alerts_as_data_severity'; diff --git a/packages/kbn-test/src/functional_test_runner/lib/docker_servers/README.md b/packages/kbn-test/src/functional_test_runner/lib/docker_servers/README.md index d75faf4c854aa..11315834f4f60 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/docker_servers/README.md +++ b/packages/kbn-test/src/functional_test_runner/lib/docker_servers/README.md @@ -53,7 +53,7 @@ export default function () { To consume the test server, use can use something like supertest to send request. Just make sure that you disable your test suite if the user doesn't choose to enable your docker server: ```ts -import makeSupertest from 'supertest-as-promised'; +import supertest from 'supertest'; import { FtrProviderContext } from '../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { @@ -61,7 +61,7 @@ export default function ({ getService }: FtrProviderContext) { const log = getService('log'); const server = dockerServers.get('helloWorld'); - const supertest = makeSupertest(server.url); + const request = supertest(server.url); describe('test suite name', function () { if (!server.enabled) { @@ -72,7 +72,7 @@ export default function ({ getService }: FtrProviderContext) { } it('test name', async () => { - await supertest.get('/foo/bar').expect(200); + await request.get('/foo/bar').expect(200); }); }); } diff --git a/src/cli_keystore/utils/prompt.js b/src/cli_keystore/utils/prompt.js index 195f794db3e6e..06fa151ec2ef4 100644 --- a/src/cli_keystore/utils/prompt.js +++ b/src/cli_keystore/utils/prompt.js @@ -66,6 +66,8 @@ export function question(question, options = {}) { break; default: if (options.mask) { + const cursorPos = rl.getCursorPos(); + output.moveCursor(0, -cursorPos.rows); output.cursorTo(questionPrompt.length); output.write(Array(rl.line.length + 1).join(options.mask || '*')); } diff --git a/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap b/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap index f723cf5bca23a..1f932d62c94b9 100644 --- a/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap +++ b/src/core/public/i18n/__snapshots__/i18n_service.test.tsx.snap @@ -100,6 +100,8 @@ exports[`#start() returns \`Context\` component 1`] = ` "euiDataGridSchema.jsonSortTextDesc": "Large-Small", "euiDataGridSchema.numberSortTextAsc": "Low-High", "euiDataGridSchema.numberSortTextDesc": "High-Low", + "euiDatePopoverButton.invalidTitle": [Function], + "euiDatePopoverButton.outdatedTitle": [Function], "euiFieldPassword.maskPassword": "Mask password", "euiFieldPassword.showPassword": "Show password as plain text. Note: this will visually expose your password on the screen.", "euiFilePicker.clearSelectedFiles": "Clear selected files", diff --git a/src/core/public/i18n/i18n_eui_mapping.tsx b/src/core/public/i18n/i18n_eui_mapping.tsx index 0a6c7a05e1c75..98b3fa8f81211 100644 --- a/src/core/public/i18n/i18n_eui_mapping.tsx +++ b/src/core/public/i18n/i18n_eui_mapping.tsx @@ -497,6 +497,16 @@ export const getEuiContextMapping = (): EuiTokensObject => { description: 'Descending size label', } ), + 'euiDatePopoverButton.invalidTitle': ({ title }: EuiValues) => + i18n.translate('core.euiDatePopoverButton.invalidTitle', { + defaultMessage: 'Invalid date: {title}', + values: { title }, + }), + 'euiDatePopoverButton.outdatedTitle': ({ title }: EuiValues) => + i18n.translate('core.euiDatePopoverButton.outdatedTitle', { + defaultMessage: 'Update needed: {title}', + values: { title }, + }), 'euiFieldPassword.showPassword': i18n.translate('core.euiFieldPassword.showPassword', { defaultMessage: 'Show password as plain text. Note: this will visually expose your password on the screen.', diff --git a/src/core/server/elasticsearch/client/configure_client.test.ts b/src/core/server/elasticsearch/client/configure_client.test.ts index ed23bf02d23ae..f954b121320fe 100644 --- a/src/core/server/elasticsearch/client/configure_client.test.ts +++ b/src/core/server/elasticsearch/client/configure_client.test.ts @@ -58,6 +58,7 @@ const createApiResponse = ({ headers, warnings, meta: { + body, request: { params: params!, options: requestOptions, @@ -367,7 +368,7 @@ describe('configureClient', () => { it('logs default error info when the error response body is empty', () => { const client = configureClient(createFakeConfig(), { logger, type: 'test', scoped: false }); - let response = createApiResponse({ + let response: RequestEvent = createApiResponse({ statusCode: 400, headers: {}, params: { @@ -384,7 +385,7 @@ describe('configureClient', () => { Array [ Array [ "400 - GET /_path [undefined]: Response Error", + GET /_path [undefined]: {\\"error\\":{}}", undefined, ], ] @@ -399,7 +400,7 @@ describe('configureClient', () => { method: 'GET', path: '/_path', }, - body: {} as any, + body: undefined, }); client.emit('response', new errors.ResponseError(response), response); diff --git a/src/core/server/environment/resolve_uuid.test.ts b/src/core/server/environment/resolve_uuid.test.ts index 60d740ef12193..40db2d697906b 100644 --- a/src/core/server/environment/resolve_uuid.test.ts +++ b/src/core/server/environment/resolve_uuid.test.ts @@ -227,7 +227,7 @@ describe('resolveInstanceUuid', () => { await expect( resolveInstanceUuid({ pathConfig, serverConfig, logger }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unable to read Kibana UUID file, please check the uuid.server configuration value in kibana.yml and ensure Kibana has sufficient permissions to read / write to this file. Error was: EACCES"` + `"Unable to read UUID file at data-folder/uuid. Ensure Kibana has sufficient permissions to read / write to this file. Error was: EACCES"` ); }); it('throws an explicit error for file write errors', async () => { @@ -235,7 +235,7 @@ describe('resolveInstanceUuid', () => { await expect( resolveInstanceUuid({ pathConfig, serverConfig, logger }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Unable to write Kibana UUID file, please check the uuid.server configuration value in kibana.yml and ensure Kibana has sufficient permissions to read / write to this file. Error was: EISDIR"` + `"Unable to write to UUID file at data-folder/uuid. Ensure Kibana has sufficient permissions to read / write to this file. Error was: EISDIR"` ); }); }); diff --git a/src/core/server/environment/resolve_uuid.ts b/src/core/server/environment/resolve_uuid.ts index aaee205dfbb90..74201a7ffa04f 100644 --- a/src/core/server/environment/resolve_uuid.ts +++ b/src/core/server/environment/resolve_uuid.ts @@ -79,8 +79,8 @@ async function readUuidFromFile(filepath: string, logger: Logger): Promise/R +function withContextMock(context: KibanaExecutionContext | undefined, fn: () => any): any { + return fn(); +} + const createExecutionContextMock = () => { const mock: jest.Mocked = { set: jest.fn(), @@ -21,6 +27,7 @@ const createExecutionContextMock = () => { getParentContextFrom: jest.fn(), getAsHeader: jest.fn(), }; + mock.withContext.mockImplementation(withContextMock); return mock; }; const createInternalSetupContractMock = () => { @@ -32,6 +39,7 @@ const createSetupContractMock = () => { const mock: jest.Mocked = { withContext: jest.fn(), }; + mock.withContext.mockImplementation(withContextMock); return mock; }; diff --git a/src/core/server/execution_context/execution_context_service.test.ts b/src/core/server/execution_context/execution_context_service.test.ts index 3abaa13d11103..3fa4de34ebda0 100644 --- a/src/core/server/execution_context/execution_context_service.test.ts +++ b/src/core/server/execution_context/execution_context_service.test.ts @@ -346,7 +346,7 @@ describe('ExecutionContextService', () => { id: 'id-a', description: 'description-a', }, - (i) => i + () => null ); expect(loggingSystemMock.collect(core.logger).debug).toMatchInlineSnapshot(` Array [ @@ -378,6 +378,26 @@ describe('ExecutionContextService', () => { expect(result).toBeUndefined(); }); + it('executes provided function when disabled', async () => { + const coreWithDisabledService = mockCoreContext.create(); + coreWithDisabledService.configService.atPath.mockReturnValue( + new BehaviorSubject({ enabled: false }) + ); + const disabledService = new ExecutionContextService(coreWithDisabledService).setup(); + const fn = jest.fn(); + + disabledService.withContext( + { + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', + }, + fn + ); + + expect(fn).toHaveBeenCalledTimes(1); + }); }); describe('getAsHeader', () => { @@ -387,6 +407,21 @@ describe('ExecutionContextService', () => { expect(service.getAsHeader()).toBe('1234'); }); + it('falls back to "unknownId" if no id provided', async () => { + expect(service.getAsHeader()).toBe('unknownId'); + }); + + it('falls back to "unknownId" and context if no id provided', async () => { + service.set({ + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + }); + + expect(service.getAsHeader()).toBe('unknownId;kibana:type-a:name-a:id-a'); + }); + it('returns request id and registered context', async () => { service.setRequestId('1234'); service.set({ diff --git a/src/core/server/execution_context/execution_context_service.ts b/src/core/server/execution_context/execution_context_service.ts index 5a8d104cebcd9..41b225cf1d0f3 100644 --- a/src/core/server/execution_context/execution_context_service.ts +++ b/src/core/server/execution_context/execution_context_service.ts @@ -34,7 +34,7 @@ export interface IExecutionContext { * https://nodejs.org/api/async_context.html#async_context_asynclocalstorage_enterwith_store */ get(): IExecutionContextContainer | undefined; - withContext(context: KibanaExecutionContext | undefined, fn: (...args: any[]) => R): R; + withContext(context: KibanaExecutionContext | undefined, fn: () => R): R; /** * returns serialized representation to send as a header **/ @@ -153,8 +153,11 @@ export class ExecutionContextService private getAsHeader(): string | undefined { if (!this.enabled) return; - const stringifiedCtx = this.contextStore.getStore()?.toString(); - const requestId = this.requestIdStore.getStore()?.requestId; - return stringifiedCtx ? `${requestId};kibana:${stringifiedCtx}` : requestId; + // requestId may not be present in the case of FakeRequest + const requestId = this.requestIdStore.getStore()?.requestId ?? 'unknownId'; + const executionContext = this.contextStore.getStore()?.toString(); + const executionContextStr = executionContext ? `;kibana:${executionContext}` : ''; + + return `${requestId}${executionContextStr}`; } } diff --git a/src/core/server/execution_context/integration_tests/tracing.test.ts b/src/core/server/execution_context/integration_tests/tracing.test.ts index 5451ee222d776..f07546d44e956 100644 --- a/src/core/server/execution_context/integration_tests/tracing.test.ts +++ b/src/core/server/execution_context/integration_tests/tracing.test.ts @@ -40,6 +40,9 @@ describe('trace', () => { allowFromAnyIp: true, }, }, + execution_context: { + enabled: true, + }, }); await root.preboot(); }, 30000); diff --git a/src/core/server/saved_objects/migrationsv2/actions/integration_tests/actions.test.ts b/src/core/server/saved_objects/migrationsv2/actions/integration_tests/actions.test.ts index 65be45e49190d..0ae6464f2623d 100644 --- a/src/core/server/saved_objects/migrationsv2/actions/integration_tests/actions.test.ts +++ b/src/core/server/saved_objects/migrationsv2/actions/integration_tests/actions.test.ts @@ -421,17 +421,13 @@ describe('migration actions', () => { timeout: '0s', })(); - await cloneIndexPromise.then((res) => { - expect(res).toMatchInlineSnapshot(` - Object { - "_tag": "Left", - "left": Object { - "error": [ResponseError: Response Error], - "message": "Response Error", - "type": "retryable_es_client_error", - }, - } - `); + await expect(cloneIndexPromise).resolves.toMatchObject({ + _tag: 'Left', + left: { + error: expect.any(ResponseError), + message: expect.stringMatching(/\"timed_out\":true/), + type: 'retryable_es_client_error', + }, }); }); }); diff --git a/src/core/server/saved_objects/migrationsv2/actions/integration_tests/es_errors.test.ts b/src/core/server/saved_objects/migrationsv2/actions/integration_tests/es_errors.test.ts index 9895efb5fd9f9..e259b375736d5 100644 --- a/src/core/server/saved_objects/migrationsv2/actions/integration_tests/es_errors.test.ts +++ b/src/core/server/saved_objects/migrationsv2/actions/integration_tests/es_errors.test.ts @@ -64,6 +64,7 @@ describe('Elasticsearch Errors', () => { { ignore: [403] } ); + // @ts-expect-error @elastic/elasticsearch doesn't declare error on IndexResponse expect(isWriteBlockException(res.body.error!)).toEqual(true); }); @@ -79,6 +80,7 @@ describe('Elasticsearch Errors', () => { { ignore: [403] } ); + // @ts-expect-error @elastic/elasticsearch doesn't declare error on IndexResponse expect(isWriteBlockException(res.body.error!)).toEqual(true); }); diff --git a/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts b/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts index 32f12193306e7..9dd8959d49293 100644 --- a/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts +++ b/src/core/server/saved_objects/service/lib/decorate_es_error.test.ts @@ -124,7 +124,7 @@ describe('savedObjectsClient/decorateEsError', () => { expect(SavedObjectsErrorHelpers.isGeneralError(error)).toBe(false); const genericError = decorateEsError(error); expect(genericError.message).toEqual( - `Saved object index alias [.kibana_8.0.0] not found: Response Error` + `Saved object index alias [.kibana_8.0.0] not found: {\"error\":{\"reason\":\"no such index [.kibana_8.0.0] and [require_alias] request flag is [true] and [.kibana_8.0.0] is not an alias\"}}` ); expect(genericError.output.statusCode).toBe(500); expect(SavedObjectsErrorHelpers.isGeneralError(error)).toBe(true); diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index 17b0f10ef67c8..2e8e3189fae2d 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -665,6 +665,7 @@ export class SavedObjectsRepository { } const deleteDocNotFound = body.result === 'not_found'; + // @ts-expect-error @elastic/elasticsearch doesn't declare error on DeleteResponse const deleteIndexNotFound = body.error && body.error.type === 'index_not_found_exception'; const esServerSupported = isSupportedEsServer(headers); if (deleteDocNotFound || deleteIndexNotFound) { diff --git a/src/dev/build/tasks/copy_source_task.ts b/src/dev/build/tasks/copy_source_task.ts index 06ec40e8fcfa0..0f073e383d2c8 100644 --- a/src/dev/build/tasks/copy_source_task.ts +++ b/src/dev/build/tasks/copy_source_task.ts @@ -20,7 +20,7 @@ export const CopySource: Task = { 'src/**', '!src/**/*.{test,test.mocks,mock}.{js,ts,tsx}', '!src/**/mocks.ts', // special file who imports .mock files - '!src/**/{target,__tests__,__snapshots__,__mocks__}/**', + '!src/**/{target,__tests__,__snapshots__,__mocks__,integration_tests}/**', '!src/core/server/core_app/assets/favicons/favicon.distribution.png', '!src/core/server/core_app/assets/favicons/favicon.distribution.svg', '!src/test_utils/**', @@ -29,10 +29,11 @@ export const CopySource: Task = { '!src/cli/dev.js', '!src/functional_test_runner/**', '!src/dev/**', + '!**/jest.config.js', '!src/plugins/telemetry/schema/**', // Skip telemetry schemas // this is the dev-only entry '!src/setup_node_env/index.js', - '!**/public/**/*.{js,ts,tsx,json}', + '!**/public/**/*.{js,ts,tsx,json,scss}', 'typings/**', 'config/kibana.yml', 'config/node.options', diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index e1900019a5b30..9c81d077b5b1b 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -74,8 +74,8 @@ export const LICENSE_OVERRIDES = { 'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts '@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint 'node-sql-parser@3.6.1': ['(GPL-2.0 OR MIT)'], // GPL-2.0* https://github.com/taozhi8833998/node-sql-parser - '@elastic/ems-client@7.14.0': ['Elastic License 2.0'], - '@elastic/eui@36.0.0': ['SSPL-1.0 OR Elastic License 2.0'], + '@elastic/ems-client@7.15.0': ['Elastic License 2.0'], + '@elastic/eui@37.1.1': ['SSPL-1.0 OR Elastic License 2.0'], // TODO can be removed if the https://github.com/jindw/xmldom/issues/239 is released 'xmldom@0.1.27': ['MIT'], diff --git a/src/dev/typescript/projects.ts b/src/dev/typescript/projects.ts index 419d4f0854ecc..0244cb2cd9115 100644 --- a/src/dev/typescript/projects.ts +++ b/src/dev/typescript/projects.ts @@ -40,6 +40,22 @@ export const PROJECTS = [ createProject('x-pack/plugins/security_solution/cypress/tsconfig.json', { name: 'security_solution/cypress', }), + createProject( + 'x-pack/plugins/enterprise_search/public/applications/shared/cypress/tsconfig.json', + { name: 'enterprise_search/shared/cypress' } + ), + createProject( + 'x-pack/plugins/enterprise_search/public/applications/enterprise_search/cypress/tsconfig.json', + { name: 'enterprise_search/overview/cypress' } + ), + createProject( + 'x-pack/plugins/enterprise_search/public/applications/app_search/cypress/tsconfig.json', + { name: 'enterprise_search/app_search/cypress' } + ), + createProject( + 'x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress/tsconfig.json', + { name: 'enterprise_search/workplace_search/cypress' } + ), createProject('x-pack/plugins/osquery/cypress/tsconfig.json', { name: 'osquery/cypress', }), diff --git a/src/plugins/advanced_settings/kibana.json b/src/plugins/advanced_settings/kibana.json index e524d78a53e80..cf00241ee2766 100644 --- a/src/plugins/advanced_settings/kibana.json +++ b/src/plugins/advanced_settings/kibana.json @@ -5,7 +5,7 @@ "ui": true, "requiredPlugins": ["management"], "optionalPlugins": ["home", "usageCollection"], - "requiredBundles": ["kibanaReact", "kibanaUtils", "home"], + "requiredBundles": ["kibanaReact", "kibanaUtils", "home", "esUiShared"], "owner": { "name": "Kibana App", "githubTeam": "kibana-app" diff --git a/src/plugins/advanced_settings/public/management_app/components/field/field.tsx b/src/plugins/advanced_settings/public/management_app/components/field/field.tsx index 759e1f992808f..745452a31ff9c 100644 --- a/src/plugins/advanced_settings/public/management_app/components/field/field.tsx +++ b/src/plugins/advanced_settings/public/management_app/components/field/field.tsx @@ -8,7 +8,6 @@ import React, { PureComponent, Fragment } from 'react'; import classNames from 'classnames'; - import 'brace/theme/textmate'; import 'brace/mode/markdown'; import 'brace/mode/json'; @@ -19,7 +18,6 @@ import { EuiCodeBlock, EuiColorPicker, EuiScreenReaderOnly, - EuiCodeEditor, EuiDescribedFormGroup, EuiFieldNumber, EuiFieldText, @@ -40,6 +38,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { FieldSetting, FieldState } from '../../types'; import { isDefaultValue } from '../../lib'; import { UiSettingsType, DocLinksStart, ToastsStart } from '../../../../../../core/public'; +import { EuiCodeEditor } from '../../../../../es_ui_shared/public'; interface FieldProps { setting: FieldSetting; diff --git a/src/plugins/advanced_settings/tsconfig.json b/src/plugins/advanced_settings/tsconfig.json index b207f600cbd4e..5bf4ce3d6248b 100644 --- a/src/plugins/advanced_settings/tsconfig.json +++ b/src/plugins/advanced_settings/tsconfig.json @@ -16,5 +16,6 @@ { "path": "../home/tsconfig.json" }, { "path": "../usage_collection/tsconfig.json" }, { "path": "../kibana_react/tsconfig.json" }, + { "path": "../es_ui_shared/tsconfig.json" }, ] } diff --git a/src/plugins/console/kibana.json b/src/plugins/console/kibana.json index ca43e4f258add..9452f43647a19 100644 --- a/src/plugins/console/kibana.json +++ b/src/plugins/console/kibana.json @@ -3,6 +3,10 @@ "version": "kibana", "server": true, "ui": true, + "owner": { + "name": "Stack Management", + "githubTeam": "kibana-stack-management" + }, "requiredPlugins": ["devTools"], "optionalPlugins": ["usageCollection", "home"], "requiredBundles": ["esUiShared", "kibanaReact", "kibanaUtils", "home"] diff --git a/src/plugins/data/common/es_query/stubs/phrases_filter.ts b/src/plugins/data/common/es_query/stubs/phrases_filter.ts index 56c3af56175da..112066ab3ae8e 100644 --- a/src/plugins/data/common/es_query/stubs/phrases_filter.ts +++ b/src/plugins/data/common/es_query/stubs/phrases_filter.ts @@ -22,4 +22,5 @@ export const phrasesFilter: PhrasesFilter = { $state: { store: FilterStateStore.APP_STATE, }, + query: {}, }; diff --git a/src/plugins/data/common/index_patterns/index.ts b/src/plugins/data/common/index_patterns/index.ts index 340162e8bda70..f493b417b47ef 100644 --- a/src/plugins/data/common/index_patterns/index.ts +++ b/src/plugins/data/common/index_patterns/index.ts @@ -10,6 +10,6 @@ export * from './constants'; export * from './fields'; export * from './types'; export { IndexPatternsService, IndexPatternsContract } from './index_patterns'; -export type { IndexPattern } from './index_patterns'; +export type { IndexPattern, IndexPatternListItem } from './index_patterns'; export * from './errors'; export * from './expressions'; diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts index a80e97b4e2cab..c6715fac5d9af 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts @@ -137,11 +137,11 @@ describe('IndexPatterns', () => { expect((await indexPatterns.get(id)).fields.length).toBe(1); }); - test('savedObjectCache pre-fetches only title', async () => { + test('savedObjectCache pre-fetches title, type, typeMeta', async () => { expect(await indexPatterns.getIds()).toEqual(['id']); expect(savedObjectsClient.find).toHaveBeenCalledWith({ type: 'index-pattern', - fields: ['title'], + fields: ['title', 'type', 'typeMeta'], perPage: 10000, }); }); diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts index 64628f7165f27..d20cfc98ba059 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts @@ -28,6 +28,7 @@ import { FieldAttrs, FieldSpec, IndexPatternFieldMap, + TypeMeta, } from '../types'; import { FieldFormatsStartCommon, FORMATS_UI_SETTINGS } from '../../../../field_formats/common/'; import { UI_SETTINGS, SavedObject } from '../../../common'; @@ -39,8 +40,21 @@ import { castEsToKbnFieldTypeName } from '../../kbn_field_types'; const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3; -export interface IndexPatternSavedObjectAttrs { +export type IndexPatternSavedObjectAttrs = Pick< + IndexPatternAttributes, + 'title' | 'type' | 'typeMeta' +>; + +export type IndexPatternListSavedObjectAttrs = Pick< + IndexPatternAttributes, + 'title' | 'type' | 'typeMeta' +>; + +export interface IndexPatternListItem { + id: string; title: string; + type?: string; + typeMeta?: TypeMeta; } interface IndexPatternsServiceDeps { @@ -94,7 +108,7 @@ export class IndexPatternsService { private async refreshSavedObjectsCache() { const so = await this.savedObjectsClient.find({ type: INDEX_PATTERN_SAVED_OBJECT_TYPE, - fields: ['title'], + fields: ['title', 'type', 'typeMeta'], perPage: 10000, }); this.savedObjectsCache = so; @@ -152,9 +166,7 @@ export class IndexPatternsService { * Get list of index pattern ids with titles * @param refresh Force refresh of index pattern list */ - getIdsWithTitle = async ( - refresh: boolean = false - ): Promise> => { + getIdsWithTitle = async (refresh: boolean = false): Promise => { if (!this.savedObjectsCache || refresh) { await this.refreshSavedObjectsCache(); } @@ -164,6 +176,8 @@ export class IndexPatternsService { return this.savedObjectsCache.map((obj) => ({ id: obj?.id, title: obj?.attributes?.title, + type: obj?.attributes?.type, + typeMeta: obj?.attributes?.typeMeta && JSON.parse(obj?.attributes?.typeMeta), })); }; @@ -559,7 +573,7 @@ export class IndexPatternsService { const createdIndexPattern = await this.initFromSavedObject(response); this.indexPatternCache.set(createdIndexPattern.id!, Promise.resolve(createdIndexPattern)); if (this.savedObjectsCache) { - this.savedObjectsCache.push(response as SavedObject); + this.savedObjectsCache.push(response as SavedObject); } return createdIndexPattern; } diff --git a/src/plugins/data/common/search/aggs/utils/get_date_histogram_meta.ts b/src/plugins/data/common/search/aggs/utils/get_date_histogram_meta.ts index 0a3aab6286d89..87086edd56e72 100644 --- a/src/plugins/data/common/search/aggs/utils/get_date_histogram_meta.ts +++ b/src/plugins/data/common/search/aggs/utils/get_date_histogram_meta.ts @@ -17,7 +17,12 @@ import { BUCKET_TYPES } from '../buckets/bucket_agg_types'; * If the column is not a column created by a date_histogram aggregation of the esaggs data source, * this function will return undefined. */ -export const getDateHistogramMetaDataByDatatableColumn = (column: DatatableColumn) => { +export const getDateHistogramMetaDataByDatatableColumn = ( + column: DatatableColumn, + defaults: Partial<{ + timeZone: string; + }> = {} +) => { if (column.meta.source !== 'esaggs') return; if (column.meta.sourceParams?.type !== BUCKET_TYPES.DATE_HISTOGRAM) return; const params = (column.meta.sourceParams.params as unknown) as AggParamsDateHistogram; @@ -29,7 +34,7 @@ export const getDateHistogramMetaDataByDatatableColumn = (column: DatatableColum return { interval, - timeZone: params.used_time_zone, + timeZone: params.used_time_zone || defaults.timeZone, timeRange: column.meta.sourceParams.appliedTimeRange as TimeRange | undefined, }; }; diff --git a/src/plugins/data/common/search/search_source/search_source.test.ts b/src/plugins/data/common/search/search_source/search_source.test.ts index 4e62b49938ade..90a13c076839b 100644 --- a/src/plugins/data/common/search/search_source/search_source.test.ts +++ b/src/plugins/data/common/search/search_source/search_source.test.ts @@ -627,7 +627,7 @@ describe('SearchSource', () => { expect(request.fields).toEqual(['@timestamp']); expect(request.script_fields).toEqual({ hello: {} }); expect(request.stored_fields).toEqual(['@timestamp', 'bar']); - expect(request.runtime_mappings).toEqual({ runtime_field: runtimeFieldDef }); + expect(request.runtime_mappings).toEqual(runtimeFields); }); test('filters request when a specific list of fields is provided with fieldsFromSource or fields', async () => { diff --git a/src/plugins/data/common/search/search_source/search_source.ts b/src/plugins/data/common/search/search_source/search_source.ts index f2b801ebac29f..16ec3d5c6c6e0 100644 --- a/src/plugins/data/common/search/search_source/search_source.ts +++ b/src/plugins/data/common/search/search_source/search_source.ts @@ -757,10 +757,6 @@ export class SearchSource { body.script_fields, Object.keys(body.script_fields).filter((f) => uniqFieldNames.includes(f)) ); - body.runtime_mappings = pick( - body.runtime_mappings, - Object.keys(body.runtime_mappings).filter((f) => uniqFieldNames.includes(f)) - ); } // request the remaining fields from stored_fields just in case, since the diff --git a/src/plugins/data/common/search/types.ts b/src/plugins/data/common/search/types.ts index cffba6203dfe2..68a25d4c4d69d 100644 --- a/src/plugins/data/common/search/types.ts +++ b/src/plugins/data/common/search/types.ts @@ -70,6 +70,11 @@ export interface IKibanaSearchResponse { */ isRestored?: boolean; + /** + * Optional warnings that should be surfaced to the end user + */ + warning?: string; + /** * The raw response returned by the internal search method (usually the raw ES response) */ diff --git a/src/plugins/data/public/autocomplete/providers/kql_query_suggestion/index.ts b/src/plugins/data/public/autocomplete/providers/kql_query_suggestion/index.ts index c5c1626ae74f6..d76c71182b8fa 100644 --- a/src/plugins/data/public/autocomplete/providers/kql_query_suggestion/index.ts +++ b/src/plugins/data/public/autocomplete/providers/kql_query_suggestion/index.ts @@ -9,12 +9,12 @@ import { CoreSetup } from 'kibana/public'; import { $Keys } from 'utility-types'; import { flatten, uniqBy } from 'lodash'; +import { fromKueryExpression } from '@kbn/es-query'; import { setupGetFieldSuggestions } from './field'; import { setupGetValueSuggestions } from './value'; import { setupGetOperatorSuggestions } from './operator'; import { setupGetConjunctionSuggestions } from './conjunction'; import { - esKuery, QuerySuggestion, QuerySuggestionGetFnArgs, QuerySuggestionGetFn, @@ -43,7 +43,7 @@ export const setupKqlQuerySuggestionProvider = ( querySuggestionsArgs: QuerySuggestionGetFnArgs ): Array> | [] => { try { - const cursorNode = esKuery.fromKueryExpression(cursoredQuery, { + const cursorNode = fromKueryExpression(cursoredQuery, { cursorSymbol, parseCursor: true, }); diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index 99c89ac69b795..0602f51889a6c 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -62,7 +62,7 @@ export const indexPatterns = { flattenHitWrapper, }; -export { IndexPatternsContract, IndexPattern, IndexPatternField } from './index_patterns'; +export { IndexPatternsContract, IndexPattern, IndexPatternField, TypeMeta } from './index_patterns'; export { IIndexPattern, @@ -79,6 +79,7 @@ export { INDEX_PATTERN_SAVED_OBJECT_TYPE, AggregationRestrictions, IndexPatternType, + IndexPatternListItem, } from '../common'; export { DuplicateIndexPatternError } from '../common/index_patterns/errors'; diff --git a/src/plugins/data/public/index_patterns/index.ts b/src/plugins/data/public/index_patterns/index.ts index 1bdd17af2a78d..e23fc789656af 100644 --- a/src/plugins/data/public/index_patterns/index.ts +++ b/src/plugins/data/public/index_patterns/index.ts @@ -16,7 +16,7 @@ export { } from '../../common/index_patterns/lib'; export { flattenHitWrapper, formatHitProvider, onRedirectNoIndexPattern } from './index_patterns'; -export { IndexPatternField, IIndexPatternFieldList } from '../../common/index_patterns'; +export { IndexPatternField, IIndexPatternFieldList, TypeMeta } from '../../common/index_patterns'; export { IndexPatternsService, diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 995a1e7a908c5..485dad1daea9d 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -792,7 +792,7 @@ export const esFilters: { export const esKuery: { nodeTypes: import("@kbn/es-query/target_types/kuery/node_types").NodeTypes; fromKueryExpression: (expression: string | import("@elastic/elasticsearch/api/types").QueryDslQueryContainer, parseOptions?: Partial | undefined) => import("@kbn/es-query").KueryNode; - toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: Record | undefined, context?: Record | undefined) => import("@kbn/utility-types").JsonObject; + toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: import("@kbn/es-query").KueryQueryOptions | undefined, context?: Record | undefined) => import("@elastic/elasticsearch/api/types").QueryDslQueryContainer; }; // Warning: (ae-missing-release-tag) "esQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1147,6 +1147,7 @@ export interface IKibanaSearchResponse { loaded?: number; rawResponse: RawResponse; total?: number; + warning?: string; } // Warning: (ae-forgotten-export) The symbol "MetricAggType" needs to be exported by the entry point index.d.ts @@ -1268,7 +1269,6 @@ export class IndexPattern implements IIndexPattern { title: string; toSpec(): IndexPatternSpec; type: string | undefined; - // Warning: (ae-forgotten-export) The symbol "TypeMeta" needs to be exported by the entry point index.d.ts typeMeta?: TypeMeta; version: string | undefined; } @@ -1368,6 +1368,20 @@ export class IndexPatternField implements IFieldType { get visualizable(): boolean; } +// Warning: (ae-missing-release-tag) "IndexPatternListItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface IndexPatternListItem { + // (undocumented) + id: string; + // (undocumented) + title: string; + // (undocumented) + type?: string; + // (undocumented) + typeMeta?: TypeMeta; +} + // Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "Input" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "Arguments" needs to be exported by the entry point index.d.ts @@ -1456,19 +1470,14 @@ export class IndexPatternsService { fieldArrayToMap: (fields: FieldSpec[], fieldAttrs?: FieldAttrs | undefined) => Record; find: (search: string, size?: number) => Promise; get: (id: string) => Promise; - // Warning: (ae-forgotten-export) The symbol "IndexPatternSavedObjectAttrs" needs to be exported by the entry point index.d.ts - // // (undocumented) - getCache: () => Promise[] | null | undefined>; + getCache: () => Promise>[] | null | undefined>; getDefault: () => Promise; getDefaultId: () => Promise; getFieldsForIndexPattern: (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions | undefined) => Promise; getFieldsForWildcard: (options: GetFieldsOptions) => Promise; getIds: (refresh?: boolean) => Promise; - getIdsWithTitle: (refresh?: boolean) => Promise>; + getIdsWithTitle: (refresh?: boolean) => Promise; getTitles: (refresh?: boolean) => Promise; refreshFields: (indexPattern: IndexPattern) => Promise; savedObjectToSpec: (savedObject: SavedObject) => IndexPatternSpec; @@ -2035,7 +2044,9 @@ export const search: { intervalLabel: string; })[]; getNumberHistogramIntervalByDatatableColumn: (column: import("../../expressions").DatatableColumn) => number | undefined; - getDateHistogramMetaDataByDatatableColumn: (column: import("../../expressions").DatatableColumn) => { + getDateHistogramMetaDataByDatatableColumn: (column: import("../../expressions").DatatableColumn, defaults?: Partial<{ + timeZone: string; + }>) => { interval: string | undefined; timeZone: string | undefined; timeRange: import("../common").TimeRange | undefined; @@ -2272,6 +2283,18 @@ export type TimeRange = { mode?: 'absolute' | 'relative'; }; +// Warning: (ae-missing-release-tag) "TypeMeta" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface TypeMeta { + // (undocumented) + aggs?: Record; + // (undocumented) + params?: { + rollup_index: string; + }; +} + // Warning: (ae-missing-release-tag) "UI_SETTINGS" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -2331,20 +2354,20 @@ export interface WaitUntilNextSessionCompletesOptions { // src/plugins/data/public/index.ts:53:27 - (ae-forgotten-export) The symbol "isNestedField" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:53:27 - (ae-forgotten-export) The symbol "validateIndexPattern" needs to be exported by the entry point index.d.ts // src/plugins/data/public/index.ts:53:27 - (ae-forgotten-export) The symbol "flattenHitWrapper" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:210:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:210:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:210:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:212:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:213:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:222:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:223:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:224:1 - (ae-forgotten-export) The symbol "IpAddress" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:225:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:229:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:230:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:233:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:234:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts -// src/plugins/data/public/index.ts:237:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:211:20 - (ae-forgotten-export) The symbol "getResponseInspectorStats" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:211:20 - (ae-forgotten-export) The symbol "tabifyAggResponse" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:211:20 - (ae-forgotten-export) The symbol "tabifyGetColumns" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:213:1 - (ae-forgotten-export) The symbol "CidrMask" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:214:1 - (ae-forgotten-export) The symbol "dateHistogramInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:223:1 - (ae-forgotten-export) The symbol "InvalidEsCalendarIntervalError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:224:1 - (ae-forgotten-export) The symbol "InvalidEsIntervalFormatError" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:225:1 - (ae-forgotten-export) The symbol "IpAddress" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:226:1 - (ae-forgotten-export) The symbol "isDateHistogramBucketAggConfig" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:230:1 - (ae-forgotten-export) The symbol "isValidEsInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:231:1 - (ae-forgotten-export) The symbol "isValidInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:234:1 - (ae-forgotten-export) The symbol "parseInterval" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:235:1 - (ae-forgotten-export) The symbol "propFilter" needs to be exported by the entry point index.d.ts +// src/plugins/data/public/index.ts:238:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/public/search/session/session_service.ts:62:5 - (ae-forgotten-export) The symbol "UrlGeneratorStateMapping" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts b/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts index 0daaf804e7b40..397754d2bd6d3 100644 --- a/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts @@ -11,21 +11,21 @@ import { FilterManager } from '../filter_manager'; import { Filter, - IFieldType, - IIndexPattern, + IndexPatternFieldBase, + IndexPatternBase, isExistsFilter, buildExistsFilter, PhraseFilter, isPhraseFilter, RangeFilter, isRangeFilter, -} from '../../../../common'; +} from '@kbn/es-query'; const INDEX_NAME = 'my-index'; const EXISTS_FIELD_NAME = '_exists_'; const FIELD = { name: 'my-field', -} as IFieldType; +} as IndexPatternFieldBase; const PHRASE_VALUE = 'my-value'; describe('Generate filters', () => { @@ -70,7 +70,7 @@ describe('Generate filters', () => { }); it('should update and re-enable EXISTING exists filter', () => { - const filter = buildExistsFilter(FIELD, { id: INDEX_NAME } as IIndexPattern); + const filter = buildExistsFilter(FIELD, { id: INDEX_NAME } as IndexPatternBase); filter.meta.disabled = true; filtersArray.push(filter); @@ -110,7 +110,7 @@ describe('Generate filters', () => { { name: 'my-field', type: 'ip_range', - } as IFieldType, + } as IndexPatternFieldBase, { gt: '192.168.0.0', lte: '192.168.255.255', @@ -136,7 +136,7 @@ describe('Generate filters', () => { { name: 'my-field', type: 'number_range', - } as IFieldType, + } as IndexPatternFieldBase, 10000, '+', INDEX_NAME diff --git a/src/plugins/data/public/search/fetch/handle_response.tsx b/src/plugins/data/public/search/fetch/handle_response.tsx index 58e4da6b95fae..f4acebfb36060 100644 --- a/src/plugins/data/public/search/fetch/handle_response.tsx +++ b/src/plugins/data/public/search/fetch/handle_response.tsx @@ -16,7 +16,18 @@ import { getNotifications } from '../../services'; import { SearchRequest } from '..'; export function handleResponse(request: SearchRequest, response: IKibanaSearchResponse) { - const { rawResponse } = response; + const { rawResponse, warning } = response; + if (warning) { + getNotifications().toasts.addWarning({ + title: i18n.translate('data.search.searchSource.fetch.warningMessage', { + defaultMessage: 'Warning: {warning}', + values: { + warning, + }, + }), + }); + } + if (rawResponse.timed_out) { getNotifications().toasts.addWarning({ title: i18n.translate('data.search.searchSource.fetch.requestTimedOutNotificationMessage', { diff --git a/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts b/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts index eb39417ac535f..75a4ddf051418 100644 --- a/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts +++ b/src/plugins/data/server/search/strategies/ese_search/ese_search_strategy.ts @@ -71,12 +71,14 @@ export const enhancedEsSearchStrategyProvider = ( const promise = id ? client.asyncSearch.get({ ...params, id }) : client.asyncSearch.submit(params); - const { body } = await shimAbortSignal(promise, options.abortSignal); + const { body, headers } = await shimAbortSignal(promise, options.abortSignal); + const response = shimHitsTotal(body.response, options); return toAsyncKibanaSearchResponse( // @ts-expect-error @elastic/elasticsearch start_time_in_millis expected to be number - { ...body, response } + { ...body, response }, + headers?.warning ); }; diff --git a/src/plugins/data/server/search/strategies/ese_search/response_utils.ts b/src/plugins/data/server/search/strategies/ese_search/response_utils.ts index ae3d258e2205d..0a92c95dac615 100644 --- a/src/plugins/data/server/search/strategies/ese_search/response_utils.ts +++ b/src/plugins/data/server/search/strategies/ese_search/response_utils.ts @@ -12,12 +12,13 @@ import { getTotalLoaded } from '../es_search'; /** * Get the Kibana representation of an async search response (see `IKibanaSearchResponse`). */ -export function toAsyncKibanaSearchResponse(response: AsyncSearchResponse) { +export function toAsyncKibanaSearchResponse(response: AsyncSearchResponse, warning?: string) { return { id: response.id, rawResponse: response.response, isPartial: response.is_partial, isRunning: response.is_running, + ...(warning ? { warning } : {}), ...getTotalLoaded(response.response), }; } diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index c1f22d1be1d01..f684586917fe7 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -125,7 +125,7 @@ export const esFilters: { export const esKuery: { nodeTypes: import("@kbn/es-query/target_types/kuery/node_types").NodeTypes; fromKueryExpression: (expression: string | import("@elastic/elasticsearch/api/types").QueryDslQueryContainer, parseOptions?: Partial | undefined) => import("@kbn/es-query").KueryNode; - toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: Record | undefined, context?: Record | undefined) => import("@kbn/utility-types").JsonObject; + toElasticsearchQuery: (node: import("@kbn/es-query").KueryNode, indexPattern?: import("@kbn/es-query").IndexPatternBase | undefined, config?: import("@kbn/es-query").KueryQueryOptions | undefined, context?: Record | undefined) => import("@elastic/elasticsearch/api/types").QueryDslQueryContainer; }; // Warning: (ae-missing-release-tag) "esQuery" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -517,20 +517,16 @@ class IndexPatternsService { fieldArrayToMap: (fields: FieldSpec[], fieldAttrs?: FieldAttrs | undefined) => Record; find: (search: string, size?: number) => Promise; get: (id: string) => Promise; - // Warning: (ae-forgotten-export) The symbol "IndexPatternSavedObjectAttrs" needs to be exported by the entry point index.d.ts - // // (undocumented) - getCache: () => Promise[] | null | undefined>; + getCache: () => Promise>[] | null | undefined>; getDefault: () => Promise; getDefaultId: () => Promise; getFieldsForIndexPattern: (indexPattern: IndexPattern | IndexPatternSpec, options?: GetFieldsOptions | undefined) => Promise; // Warning: (ae-forgotten-export) The symbol "GetFieldsOptions" needs to be exported by the entry point index.d.ts getFieldsForWildcard: (options: GetFieldsOptions) => Promise; getIds: (refresh?: boolean) => Promise; - getIdsWithTitle: (refresh?: boolean) => Promise>; + // Warning: (ae-forgotten-export) The symbol "IndexPatternListItem" needs to be exported by the entry point index.d.ts + getIdsWithTitle: (refresh?: boolean) => Promise; getTitles: (refresh?: boolean) => Promise; refreshFields: (indexPattern: IndexPattern) => Promise; savedObjectToSpec: (savedObject: SavedObject_2) => IndexPatternSpec; diff --git a/src/plugins/dev_tools/kibana.json b/src/plugins/dev_tools/kibana.json index f1c6c9ecf87e6..75a1e82f1d910 100644 --- a/src/plugins/dev_tools/kibana.json +++ b/src/plugins/dev_tools/kibana.json @@ -3,5 +3,9 @@ "version": "kibana", "server": false, "ui": true, + "owner": { + "name": "Stack Management", + "githubTeam": "kibana-stack-management" + }, "requiredPlugins": ["urlForwarding"] } diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/actions/columns.ts b/src/plugins/discover/public/application/apps/main/components/doc_table/actions/columns.ts index 130b43539d9b5..9b69a98ca7996 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/actions/columns.ts +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/actions/columns.ts @@ -78,9 +78,7 @@ export function getStateColumnActions({ state: DiscoverState | ContextState; }) { function onAddColumn(columnName: string) { - if (capabilities.discover.save) { - popularizeField(indexPattern, columnName, indexPatterns); - } + popularizeField(indexPattern, columnName, indexPatterns, capabilities); const columns = addColumn(state.columns || [], columnName, useNewFieldsApi); const defaultOrder = config.get(SORT_DEFAULT_ORDER_SETTING); const sort = @@ -89,9 +87,7 @@ export function getStateColumnActions({ } function onRemoveColumn(columnName: string) { - if (capabilities.discover.save) { - popularizeField(indexPattern, columnName, indexPatterns); - } + popularizeField(indexPattern, columnName, indexPatterns, capabilities); const columns = removeColumn(state.columns || [], columnName, useNewFieldsApi); // The state's sort property is an array of [sortByColumn,sortDirection] const sort = diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx index 94e28c3f1d54c..6d241468bdf74 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx +++ b/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx @@ -122,7 +122,7 @@ export function DiscoverLayout({ const onAddFilter = useCallback( (field: IndexPatternField | string, values: string, operation: '+' | '-') => { const fieldName = typeof field === 'string' ? field : field.name; - popularizeField(indexPattern, fieldName, indexPatterns); + popularizeField(indexPattern, fieldName, indexPatterns, capabilities); const newFilters = esFilters.generateFilters( filterManager, field, @@ -135,7 +135,7 @@ export function DiscoverLayout({ } return filterManager.addFilters(newFilters); }, - [filterManager, indexPattern, indexPatterns, trackUiMetric] + [filterManager, indexPattern, indexPatterns, trackUiMetric, capabilities] ); const onEditRuntimeField = useCallback(() => { diff --git a/src/plugins/discover/public/application/components/context_app/context_app.test.tsx b/src/plugins/discover/public/application/components/context_app/context_app.test.tsx index 7ac6a9d0e8de3..a21b035c335df 100644 --- a/src/plugins/discover/public/application/components/context_app/context_app.test.tsx +++ b/src/plugins/discover/public/application/components/context_app/context_app.test.tsx @@ -54,6 +54,9 @@ describe('ContextApp test', () => { discover: { save: true, }, + indexPatterns: { + save: true, + }, }, indexPatterns: indexPatternsMock, toastNotifications: { addDanger: () => {} }, diff --git a/src/plugins/discover/public/application/components/context_app/context_app.tsx b/src/plugins/discover/public/application/components/context_app/context_app.tsx index 37963eb2dfa93..25590f331839e 100644 --- a/src/plugins/discover/public/application/components/context_app/context_app.tsx +++ b/src/plugins/discover/public/application/components/context_app/context_app.tsx @@ -109,10 +109,10 @@ export const ContextApp = ({ indexPattern, indexPatternId, anchorId }: ContextAp filterManager.addFilters(newFilters); if (indexPatterns) { const fieldName = typeof field === 'string' ? field : field.name; - await popularizeField(indexPattern, fieldName, indexPatterns); + await popularizeField(indexPattern, fieldName, indexPatterns, capabilities); } }, - [filterManager, indexPatternId, indexPatterns, indexPattern] + [filterManager, indexPatternId, indexPatterns, indexPattern, capabilities] ); const TopNavMenu = navigation.ui.TopNavMenu; diff --git a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.scss b/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.scss index e845ba7238303..83b5ce2849c90 100644 --- a/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.scss +++ b/src/plugins/discover/public/application/components/doc_viewer/doc_viewer.scss @@ -44,6 +44,11 @@ padding: $euiSizeXS; } +.kbnDocViewer__tableValueCell { + flex-direction: column; + align-items: flex-start; +} + .kbnDocViewer__value { word-break: break-all; word-wrap: break-word; diff --git a/src/plugins/discover/public/application/components/field_name/__snapshots__/field_name.test.tsx.snap b/src/plugins/discover/public/application/components/field_name/__snapshots__/field_name.test.tsx.snap index 284c77c96db78..42d6271cdb39c 100644 --- a/src/plugins/discover/public/application/components/field_name/__snapshots__/field_name.test.tsx.snap +++ b/src/plugins/discover/public/application/components/field_name/__snapshots__/field_name.test.tsx.snap @@ -98,3 +98,36 @@ Array [ , ] `; + +exports[`FieldName renders unknown field 1`] = ` +Array [ +
+ + + +
, +
+
+ + + test.test.test + + +
+
, +] +`; diff --git a/src/plugins/discover/public/application/components/field_name/field_name.test.tsx b/src/plugins/discover/public/application/components/field_name/field_name.test.tsx index 6570c1b352fed..d2f961392c43c 100644 --- a/src/plugins/discover/public/application/components/field_name/field_name.test.tsx +++ b/src/plugins/discover/public/application/components/field_name/field_name.test.tsx @@ -26,3 +26,8 @@ test('FieldName renders a geo field', () => { const component = render(); expect(component).toMatchSnapshot(); }); + +test('FieldName renders unknown field', () => { + const component = render(); + expect(component).toMatchSnapshot(); +}); diff --git a/src/plugins/discover/public/application/components/field_name/field_name.tsx b/src/plugins/discover/public/application/components/field_name/field_name.tsx index e8b6765b738a5..a180c35fb2653 100644 --- a/src/plugins/discover/public/application/components/field_name/field_name.tsx +++ b/src/plugins/discover/public/application/components/field_name/field_name.tsx @@ -19,7 +19,7 @@ import { IndexPatternField } from '../../../../../data/public'; // this should be changed when both components are deangularized interface Props { fieldName: string; - fieldType: string; + fieldType?: string; fieldMapping?: IndexPatternField; fieldIconProps?: Omit; scripted?: boolean; @@ -41,7 +41,7 @@ export function FieldName({ return ( - + diff --git a/src/plugins/discover/public/application/components/field_name/field_type_name.ts b/src/plugins/discover/public/application/components/field_name/field_type_name.ts index e2d4c2f7ddcf2..3d3e97aba624b 100644 --- a/src/plugins/discover/public/application/components/field_name/field_type_name.ts +++ b/src/plugins/discover/public/application/components/field_name/field_type_name.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; -export function getFieldTypeName(type: string) { +export function getFieldTypeName(type?: string) { switch (type) { case 'boolean': return i18n.translate('discover.fieldNameIcons.booleanAriaLabel', { diff --git a/src/plugins/discover/public/application/components/table/table.tsx b/src/plugins/discover/public/application/components/table/table.tsx index 2d261805d8eb8..d1b2d27245616 100644 --- a/src/plugins/discover/public/application/components/table/table.tsx +++ b/src/plugins/discover/public/application/components/table/table.tsx @@ -36,13 +36,14 @@ export interface FieldRecord { flattenedField: unknown; }; field: { - fieldName: string; - fieldType: string; - fieldMapping: IndexPatternField | undefined; + displayName: string; + field: string; scripted: boolean; + fieldType?: string; + fieldMapping?: IndexPatternField; }; value: { - formattedField: unknown; + formattedValue: string; }; } @@ -56,7 +57,7 @@ export const DocViewerTable = ({ }: DocViewRenderProps) => { const showMultiFields = getServices().uiSettings.get(SHOW_MULTIFIELDS); - const mapping = useCallback((name) => indexPattern?.fields.getByName(name), [ + const mapping = useCallback((name: string) => indexPattern?.fields.getByName(name), [ indexPattern?.fields, ]); @@ -82,10 +83,11 @@ export const DocViewerTable = ({ [onRemoveColumn, onAddColumn, columns] ); - const onSetRowProps = useCallback(({ field: { fieldName } }: FieldRecord) => { + const onSetRowProps = useCallback(({ field: { field } }: FieldRecord) => { return { + key: field, className: 'kbnDocViewer__tableRow', - 'data-test-subj': `tableDocViewRow-${fieldName}`, + 'data-test-subj': `tableDocViewRow-${field}`, }; }, []); @@ -117,31 +119,34 @@ export const DocViewerTable = ({ const nameB = !mappingB || !mappingB.displayName ? fieldB : mappingB.displayName; return nameA.localeCompare(nameB); }) - .map((fieldName) => { - const fieldMapping = mapping(fieldName); - const fieldType = isNestedFieldParent(fieldName, indexPattern) - ? 'nested' - : fieldMapping?.type; + .map((field) => { + const fieldMapping = mapping(field); + const displayName = fieldMapping?.displayName ?? field; + const fieldType = isNestedFieldParent(field, indexPattern) ? 'nested' : fieldMapping?.type; return { action: { onToggleColumn, onFilter: filter, - isActive: !!columns?.includes(fieldName), - flattenedField: flattened[fieldName], + isActive: !!columns?.includes(field), + flattenedField: flattened[field], }, field: { - fieldName, - fieldType: fieldType!, - scripted: Boolean(fieldMapping?.scripted), + field, + displayName, fieldMapping, + fieldType, + scripted: Boolean(fieldMapping?.scripted), + }, + value: { + formattedValue: formattedHit[field], }, - value: { formattedField: formattedHit[fieldName] }, }; }); return ( void; } export const TableActions = ({ isActive, - fieldName, + field, fieldMapping, flattenedField, onToggleColumn, onFilter, }: TableActionsProps) => { - const toggleColumn = () => { - onToggleColumn(fieldName); - }; - return (
onToggleColumn(field)} /> onFilter('_exists_', fieldName, '+')} + onClick={() => onFilter('_exists_', field, '+')} scripted={fieldMapping && fieldMapping.scripted} />
diff --git a/src/plugins/discover/public/application/components/table/table_cell_value.tsx b/src/plugins/discover/public/application/components/table/table_cell_value.tsx index de29068a82718..ba2fb707940bf 100644 --- a/src/plugins/discover/public/application/components/table/table_cell_value.tsx +++ b/src/plugins/discover/public/application/components/table/table_cell_value.tsx @@ -7,31 +7,21 @@ */ import classNames from 'classnames'; -import React, { useCallback, useState } from 'react'; -import { IndexPatternField } from '../../../../../data/public'; +import React, { Fragment, useState } from 'react'; import { FieldRecord } from './table'; import { trimAngularSpan } from './table_helper'; import { DocViewTableRowBtnCollapse } from './table_row_btn_collapse'; -import { DocViewTableRowIconUnderscore } from './table_row_icon_underscore'; const COLLAPSE_LINE_LENGTH = 350; -type TableFieldValueProps = FieldRecord['value'] & { - fieldName: string; - fieldMapping: IndexPatternField | undefined; -}; +type TableFieldValueProps = FieldRecord['value'] & Pick; -export const TableFieldValue = ({ - formattedField, - fieldName, - fieldMapping, -}: TableFieldValueProps) => { +export const TableFieldValue = ({ formattedValue, field }: TableFieldValueProps) => { const [fieldOpen, setFieldOpen] = useState(false); - const value = trimAngularSpan(String(formattedField)); + const value = trimAngularSpan(String(formattedValue)); const isCollapsible = value.length > COLLAPSE_LINE_LENGTH; const isCollapsed = isCollapsible && !fieldOpen; - const displayUnderscoreWarning = !fieldMapping && fieldName.indexOf('_') === 0; const valueClassName = classNames({ // eslint-disable-next-line @typescript-eslint/naming-convention @@ -39,28 +29,23 @@ export const TableFieldValue = ({ 'truncate-by-height': isCollapsible && isCollapsed, }); - const onToggleCollapse = useCallback( - () => setFieldOpen((fieldOpenPrev: boolean) => !fieldOpenPrev), - [] - ); + const onToggleCollapse = () => setFieldOpen((fieldOpenPrev) => !fieldOpenPrev); return ( -
+ {isCollapsible && ( )} - {displayUnderscoreWarning && } - {fieldName ? null :
{fieldName}: 
}
-
+
); }; diff --git a/src/plugins/discover/public/application/components/table/table_columns.tsx b/src/plugins/discover/public/application/components/table/table_columns.tsx index 462362d543e7a..5bd92fe9166e9 100644 --- a/src/plugins/discover/public/application/components/table/table_columns.tsx +++ b/src/plugins/discover/public/application/components/table/table_columns.tsx @@ -18,6 +18,7 @@ export const ACTIONS_COLUMN: EuiBasicTableColumn = { field: 'action', className: 'kbnDocViewer__tableActionsCell', width: '108px', + mobileOptions: { header: false }, name: ( @@ -30,12 +31,12 @@ export const ACTIONS_COLUMN: EuiBasicTableColumn = { ), render: ( { flattenedField, isActive, onFilter, onToggleColumn }: FieldRecord['action'], - { field: { fieldName, fieldMapping } }: FieldRecord + { field: { field, fieldMapping } }: FieldRecord ) => { return ( > = [ { field: 'field', className: 'kbnDocViewer__tableFieldNameCell', + mobileOptions: { header: false }, name: ( @@ -56,19 +58,23 @@ export const MAIN_COLUMNS: Array> = [ ), - render: ({ fieldName, fieldType, fieldMapping, scripted }: FieldRecord['field']) => { - return ( + render: ({ field, fieldType, displayName, fieldMapping, scripted }: FieldRecord['field']) => { + return field ? ( + ) : ( +   ); }, }, { field: 'value', + className: 'kbnDocViewer__tableValueCell', + mobileOptions: { header: false }, name: ( @@ -76,17 +82,8 @@ export const MAIN_COLUMNS: Array> = [ ), - render: ( - { formattedField }: FieldRecord['value'], - { field: { fieldName, fieldMapping } }: FieldRecord - ) => { - return ( - - ); + render: ({ formattedValue }: FieldRecord['value'], { field: { field } }: FieldRecord) => { + return ; }, }, ]; diff --git a/src/plugins/discover/public/application/components/table/table_row_icon_underscore.tsx b/src/plugins/discover/public/application/components/table/table_row_icon_underscore.tsx deleted file mode 100644 index aa0ccbcadfb73..0000000000000 --- a/src/plugins/discover/public/application/components/table/table_row_icon_underscore.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { EuiIconTip } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -export function DocViewTableRowIconUnderscore() { - const ariaLabel = i18n.translate( - 'discover.docViews.table.fieldNamesBeginningWithUnderscoreUnsupportedAriaLabel', - { - defaultMessage: 'Warning', - } - ); - const tooltipContent = i18n.translate( - 'discover.docViews.table.fieldNamesBeginningWithUnderscoreUnsupportedTooltip', - { - defaultMessage: 'Field names beginning with {underscoreSign} are not supported', - values: { underscoreSign: '_' }, - } - ); - - return ( - - ); -} diff --git a/src/plugins/discover/public/application/helpers/popularize_field.test.ts b/src/plugins/discover/public/application/helpers/popularize_field.test.ts index 8be23c4270438..7ae3994abd21a 100644 --- a/src/plugins/discover/public/application/helpers/popularize_field.test.ts +++ b/src/plugins/discover/public/application/helpers/popularize_field.test.ts @@ -6,15 +6,27 @@ * Side Public License, v 1. */ +import { Capabilities } from 'kibana/public'; import { IndexPattern, IndexPatternsService } from '../../../../data/public'; import { popularizeField } from './popularize_field'; +const capabilities = ({ + indexPatterns: { + save: true, + }, +} as unknown) as Capabilities; + describe('Popularize field', () => { test('returns undefined if index pattern lacks id', async () => { const indexPattern = ({} as unknown) as IndexPattern; const fieldName = '@timestamp'; const indexPatternsService = ({} as unknown) as IndexPatternsService; - const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + const result = await popularizeField( + indexPattern, + fieldName, + indexPatternsService, + capabilities + ); expect(result).toBeUndefined(); }); @@ -26,7 +38,12 @@ describe('Popularize field', () => { } as unknown) as IndexPattern; const fieldName = '@timestamp'; const indexPatternsService = ({} as unknown) as IndexPatternsService; - const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + const result = await popularizeField( + indexPattern, + fieldName, + indexPatternsService, + capabilities + ); expect(result).toBeUndefined(); }); @@ -44,7 +61,12 @@ describe('Popularize field', () => { const indexPatternsService = ({ updateSavedObject: async () => {}, } as unknown) as IndexPatternsService; - const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + const result = await popularizeField( + indexPattern, + fieldName, + indexPatternsService, + capabilities + ); expect(result).toBeUndefined(); expect(field.count).toEqual(1); }); @@ -65,7 +87,34 @@ describe('Popularize field', () => { throw new Error('unknown error'); }, } as unknown) as IndexPatternsService; - const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + const result = await popularizeField( + indexPattern, + fieldName, + indexPatternsService, + capabilities + ); + expect(result).toBeUndefined(); + }); + + test('should not try to update index pattern without permissions', async () => { + const field = { + count: 0, + }; + const indexPattern = ({ + id: 'id', + fields: { + getByName: () => field, + }, + } as unknown) as IndexPattern; + const fieldName = '@timestamp'; + const indexPatternsService = ({ + updateSavedObject: jest.fn(), + } as unknown) as IndexPatternsService; + const result = await popularizeField(indexPattern, fieldName, indexPatternsService, ({ + indexPatterns: { save: false }, + } as unknown) as Capabilities); expect(result).toBeUndefined(); + expect(indexPatternsService.updateSavedObject).not.toHaveBeenCalled(); + expect(field.count).toEqual(0); }); }); diff --git a/src/plugins/discover/public/application/helpers/popularize_field.ts b/src/plugins/discover/public/application/helpers/popularize_field.ts index 4ade7d1768419..90968dd7c3d58 100644 --- a/src/plugins/discover/public/application/helpers/popularize_field.ts +++ b/src/plugins/discover/public/application/helpers/popularize_field.ts @@ -6,14 +6,16 @@ * Side Public License, v 1. */ +import type { Capabilities } from 'kibana/public'; import { IndexPattern, IndexPatternsContract } from '../../../../data/public'; async function popularizeField( indexPattern: IndexPattern, fieldName: string, - indexPatternsService: IndexPatternsContract + indexPatternsService: IndexPatternsContract, + capabilities: Capabilities ) { - if (!indexPattern.id) return; + if (!indexPattern.id || !capabilities?.indexPatterns?.save) return; const field = indexPattern.fields.getByName(fieldName); if (!field) { return; diff --git a/src/plugins/embeddable/kibana.json b/src/plugins/embeddable/kibana.json index 1ecf76dbbd5c2..42dc716fe64e9 100644 --- a/src/plugins/embeddable/kibana.json +++ b/src/plugins/embeddable/kibana.json @@ -3,16 +3,11 @@ "version": "kibana", "server": true, "ui": true, - "requiredPlugins": [ - "inspector", - "uiActions" - ], - "extraPublicDirs": [ - "public/lib/test_samples" - ], - "requiredBundles": [ - "savedObjects", - "kibanaReact", - "kibanaUtils" - ] + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, + "requiredPlugins": ["inspector", "uiActions"], + "extraPublicDirs": ["public/lib/test_samples"], + "requiredBundles": ["savedObjects", "kibanaReact", "kibanaUtils"] } diff --git a/src/plugins/es_ui_shared/__packages_do_not_import__/errors/handle_es_error.test.ts b/src/plugins/es_ui_shared/__packages_do_not_import__/errors/handle_es_error.test.ts index cff179f64ea08..240eeb59f9a45 100644 --- a/src/plugins/es_ui_shared/__packages_do_not_import__/errors/handle_es_error.test.ts +++ b/src/plugins/es_ui_shared/__packages_do_not_import__/errors/handle_es_error.test.ts @@ -59,7 +59,7 @@ describe('handleEsError', () => { expect(payload).toEqual({ attributes: { causes: undefined, error: undefined }, - message: 'Response Error', + message: '{}', }); expect(status).toBe(400); diff --git a/src/plugins/es_ui_shared/kibana.json b/src/plugins/es_ui_shared/kibana.json index d442bfb93d5af..2735b153f738c 100644 --- a/src/plugins/es_ui_shared/kibana.json +++ b/src/plugins/es_ui_shared/kibana.json @@ -3,6 +3,10 @@ "version": "kibana", "ui": true, "server": true, + "owner": { + "name": "Stack Management", + "githubTeam": "kibana-stack-management" + }, "extraPublicDirs": [ "static/validators/string", "static/forms/hook_form_lib", @@ -10,7 +14,5 @@ "static/forms/components", "static/forms/helpers/field_validators/types" ], - "requiredBundles": [ - "data" - ] + "requiredBundles": ["data"] } diff --git a/src/plugins/expressions/kibana.json b/src/plugins/expressions/kibana.json index 23c7fe722fdb3..46e6ef8b4ea75 100644 --- a/src/plugins/expressions/kibana.json +++ b/src/plugins/expressions/kibana.json @@ -3,9 +3,10 @@ "version": "kibana", "server": true, "ui": true, + "owner": { + "name": "App Services", + "githubTeam": "kibana-app-services" + }, "extraPublicDirs": ["common", "common/fonts"], - "requiredBundles": [ - "kibanaUtils", - "inspector" - ] + "requiredBundles": ["kibanaUtils", "inspector"] } diff --git a/src/plugins/home/public/application/components/__snapshots__/home.test.js.snap b/src/plugins/home/public/application/components/__snapshots__/home.test.js.snap index 153438b34eb47..9b3bc3e354005 100644 --- a/src/plugins/home/public/application/components/__snapshots__/home.test.js.snap +++ b/src/plugins/home/public/application/components/__snapshots__/home.test.js.snap @@ -1,39 +1,31 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`home change home route should render a link to change the default route in advanced settings if advanced settings is enabled 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - + `; exports[`home directories should not render directory entry when showOnHomePage is false 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - + `; exports[`home directories should render ADMIN directory entry in "Manage your data" panel 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - -`; - -exports[`home directories should render DATA directory entry in "Ingest your data" panel 1`] = ` -, - "rightSideItems": Array [], + - - - - - - - - - + `; exports[`home directories should render solutions in the "solution section" 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - -`; - -exports[`home header render 1`] = ` -, - "rightSideItems": Array [], - } - } - template="empty" -> - - - - - - - - - + `; -exports[`home header should show "Dev tools" link if console is available 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - -`; - -exports[`home header should show "Manage" link if stack management is available 1`] = ` -, - "rightSideItems": Array [], - } - } - template="empty" -> - - - - - - - - - + `; -exports[`home isNewKibanaInstance should safely handle execeptions 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - -`; - -exports[`home isNewKibanaInstance should set isNewKibanaInstance to false when there are index patterns 1`] = ` -, - "rightSideItems": Array [], - } - } - template="empty" -> - - - - - - - - - + `; exports[`home isNewKibanaInstance should set isNewKibanaInstance to true when there are no index patterns 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - + `; exports[`home should render home component 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - + `; exports[`home welcome should show the normal home page if loading fails 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - + `; exports[`home welcome should show the normal home page if welcome screen is disabled locally 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - + `; exports[`home welcome should show the welcome screen if enabled, and there are no index patterns defined 1`] = ` @@ -712,39 +411,31 @@ exports[`home welcome should show the welcome screen if enabled, and there are n `; exports[`home welcome stores skip welcome setting if skipped 1`] = ` -, - "rightSideItems": Array [], } } template="empty" > - - - - - - - - - + `; diff --git a/src/plugins/home/public/application/components/__snapshots__/synopsis.test.js.snap b/src/plugins/home/public/application/components/__snapshots__/synopsis.test.js.snap index ec192ce1eb32f..8e04e70ed92b6 100644 --- a/src/plugins/home/public/application/components/__snapshots__/synopsis.test.js.snap +++ b/src/plugins/home/public/application/components/__snapshots__/synopsis.test.js.snap @@ -3,7 +3,7 @@ exports[`props iconType 1`] = ` * { - margin-bottom: 0 !important; - margin-top: 0 !important; - } -} diff --git a/src/plugins/home/public/application/components/_index.scss b/src/plugins/home/public/application/components/_index.scss index 5e2f58c7ebefa..8d7139d895714 100644 --- a/src/plugins/home/public/application/components/_index.scss +++ b/src/plugins/home/public/application/components/_index.scss @@ -5,11 +5,9 @@ // homChart__legend--small // homChart__legend-isLoading -@import 'home'; +@import 'welcome'; +@import 'solutions_section'; @import 'add_data'; +@import 'manage_data'; @import 'sample_data_set_cards'; -@import 'solutions_section'; -@import 'synopsis'; -@import 'welcome'; - @import 'tutorial/tutorial'; diff --git a/src/plugins/home/public/application/components/_manage_data.scss b/src/plugins/home/public/application/components/_manage_data.scss new file mode 100644 index 0000000000000..df0219636e17c --- /dev/null +++ b/src/plugins/home/public/application/components/_manage_data.scss @@ -0,0 +1,5 @@ +.homDataManage__item { + @include euiBreakpoint('l', 'xl') { + max-width: calc(50% - #{$euiSizeM * 2}); + } +} \ No newline at end of file diff --git a/src/plugins/home/public/application/components/_solutions_section.scss b/src/plugins/home/public/application/components/_solutions_section.scss index 965447f689f98..d563b13ac7e07 100644 --- a/src/plugins/home/public/application/components/_solutions_section.scss +++ b/src/plugins/home/public/application/components/_solutions_section.scss @@ -1,98 +1,23 @@ -.homSolutions__content { - min-height: $euiSize * 16; - - @include euiBreakpoint('xs', 's') { - flex-direction: column; - } -} - -.homSolutions__group { - @include euiBreakpoint('l') { - max-width: calc(75% - #{$euiSizeM * 2}); - } - - @include euiBreakpoint('xl') { +.homSolutions__item { + @include euiBreakpoint('l', 'xl') { max-width: calc(50% - #{$euiSizeM * 2}); } } -.homSolutionPanel { - border-radius: $euiBorderRadius; - color: inherit; - flex: 1; - transition: all $euiAnimSpeedFast $euiAnimSlightResistance; - - &:hover, - &:focus { - @include euiSlightShadowHover; - transform: translateY(-2px); - - .homSolutionPanel__title { - text-decoration: underline; - } +.euiCard__image { + .homSolutionPanel & { + background-color: $euiColorPrimary; } -} - -.homSolutionPanel, -.homSolutionPanel__inner { - display: flex; - flex-direction: column; -} - -.homSolutionPanel__inner { - overflow: hidden; -} - -.homSolutionPanel__icon { - background-color: $euiColorEmptyShade !important; - box-shadow: none !important; - margin: 0 auto $euiSizeS; - padding: $euiSizeS; -} - -.homSolutionPanel__subtitle { - margin-top: $euiSizeXS; -} - -.homSolutionPanel__content { - flex-direction: column; - justify-content: center; - padding: $euiSize; - - @include euiBreakpoint('xs', 's') { - text-align: center; - } -} - -.homSolutionPanel__header { - color: $euiColorEmptyShade; - padding: $euiSize; - background-color: $euiColorPrimary; - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQYAAAFjCAYAAADfDKXVAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAfiSURBVHgB7d1JblRZGobh45SrhJiWGOQ6EENLSKyABTBmOcwRq2EnTKtUdInBuEln/OkMdB3HTTjiNqd5HinA3YBUSq++24UPUkq/J+jE+/fv09HRURrD27dv0+vXr1OLfksAG4QByAgDkBEGICMMQEYYgIwwABlhADLCAGSEAcgIA5ARBiAjDEBGGICMMAAZYQAywgBkhAHICAOQEQZg05/CAGy6FAYgIwzApnNhADLCAGy6EAZgkzAAGVclgIyTj0DGYgAyZ8IADP2ZLAZgw1n8IQzA0Hn8IQzA0EX8IQzAkEMJICMMwDURhcv44DDBlp4+fZrevHmTxvLq1av04cOHRDHO1h8IA1t7/PhxOjo6SjTrdP2BQwlg7ddiEAYgxGXK8/UnwgCEs+EnwgCEk+EnwgCE0+EnwgDEYcTF8AvCAJxufkEYgO+bXxAG6Nu1y5RrwgB9O7npi8IAfTu+6YvCAP3KrkasCQP06/i2bwgD9Ov0tm8IA/QpLlFe3PZNYYA+/bjrm8IA/YmTjqd3/YAwQH+O7/sBYYC+xHmFH/f9kDBAX/7Y5oeEAfqx1VoIwgD9+L7tDwoD9GHrtRCEAfoQ5xYutv1hYYD2PWgtBGGA9m11JWJIGKBtD14LQRigbf9POxAGaNedT1DeRRigTRGEb2lHwgBtetDlyU3CAO35mXY44TgkDNCWy9XrS9qTMEBb9jqEWBMGaEdchbj3TVi2IQzQhr2uQmwSBmjD5zTCIcSaMED94rzCaRqRMEDd4tLkaIcQa8IA9YpDh70vTd5EGKBOcb9CPCA12nmFIWGAOo16snGTMEB94mTjSZqQMEBdIgqjn2zcJAxQj7ircfIoBGGAOsTtzl/TTIQByhe/nXqSy5K3EQYoW0Rhp/dt3MdhAkoVdzV+Slf3LMxKGKBMcU5h1sOHIYcSUJ5FoxAsBijLLPcp3EcYoBxxOXKUd2DalzDA8uLk4sc08nsq7EMYYFnxINRkT0nuShhgOfEgVDwlOfvlyPsIAyyjmPMJNxEGmFccMsRKKOZ8wk2EAeZT7KHDJmGA6UUI4v6EYg8dNgkDTCued4i7GIu66nAfYYBpVLcShoQBxlflShgSBhhP1SthSBhgHNWvhCFhgP00sxKGhAF29OTJkyKfcxiDN2qBHb18+TIOH5qLQhAGICMMQEYYgIwwABlhADLCAGSEAcgIA5ARBiAjDEBGGICMMNCTy0ePHhX/RqwlEAZ6EQ88/e/Zs2dniXt57JrWNfl+CVMTBloW6+BTavTR6CkJA62KlfAtsRNhoDWxEr788zc7EgZaYiWMRBhogZUwMmGgdlbCBISBWlkJExIGamQlTEwYqImVMBNhoBZx5+LXxCyEgdLFXYufV6/TxGyEgZLFSojzCZ6InJkwUCIrYWHCQGmshAIIA6WwEgoiDJTASiiMMLCYw8NDK6FQ3tqNxbx79+5jEoUiCQOLef78uUOHQgkDkBEGICMMQEYYgIwwABlhADLCAGSEAcgIA5ARBiAjDEBGGNjWxYsXL/5IdOFg9fo9wd3+fr+Ey8vLf63+/k8az38PDg5m/RX1q/+G+Pf/O43j++rf/yU1yPsxcBfvl9ApYeA23lWpY8LAJisBYeAaK4G/CQMhQhAr4SRBEgauYhBRsBL4RRj6ZSVwK2Hok5XAnYShL1YCWxGGflgJbE0Y2mcl8GDC0DYrgZ0IQ5usBPYiDO35uXrFE3+zPrVIW4ShHbES4nbm4wR7EoY2WAmMShjqZiUwCWGol5XAZIShPlYCkxOGulgJzEIY6mAlMCthKJ+VwOyEoVxWAosRhjJZCSxKGMpiJVAEYSiHlUAxhGF5VgLFEYZlWQkUSRiWYSVQNGGYn5VA8YRhPlYC1RCGeVgJVEUYpmUlUCVhmI6VQLWEYXxWAtUThnFZCTRBGMZhJdAUYdiflUBzhGF3VgLNEobdnK1en5KVQKOE4eFiJXxL0DBh2F6shC///A1NE4btWAl0RRjuZiXQJWG4nZVAt4QhZyXQPWG4zkqAJAxrVgIMCMPVnYtfE/BLz2GIuxY/r16nCbim1zDESojzCZeJ3sTh4lj/389To3oLg5XQuYODA4eNW+gpDFYCbKmHMFgJ8ECth8FKgB20GgYrAfbQYhisBNhTS2GwEmAkrYTBSoAR1R4GKwEmUHMYrASYSI1hsBJgYrWFwUqAGdQSBisBZlRDGKwEmFnJYbASYCGlhsFKgAWVFgYrAQpQUhisBChECWGwEqAwS4fBSoACLRUGKwEKtkQYrAQo3JxhsBKgEnOFwUqAikwdhghBrISTBFRjyjBEDCIKVgJUZoowOJcAlRs7DM4lQAPGCsPP1etbshKgCfuGIQ4bYiH8SEAzdg1DHCrEQjhODhugOQ8NgyBAB7YNgyBAR+4LgyBAh24Lg6sM0LFhGGIRfE9XdywKAnQswrBeB2fJ4QKQrsLwMQEM/JYANggDkBEGICMMQEYYgIwwABlhADLCAGSEAcgIA5ARBiAjDEBGGICMMAAZYQAywgBkhAHICAOQEQYgIwxARhiAjDAAGWEAMg/9bdf0LX4h0XkCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACq8hdouPfUCk+KHQAAAABJRU5ErkJggg=='), - url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAWgAAAFKCAYAAAAwgcXoAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAjGSURBVHgB7d27ctRaFoDh1WBzsQ9wLkVsngHHfglSIOUdgJQiJSfmIUjhJUwGjiGaU7hmzoB7vLA1GPCt21vSlvR9Vao+5lAFbbf+EktbUgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUaxYAEzCfz/NldX9biTK+zGaz/0aLSv1FAYbg6v52I8r4e39rNdCXAoAqCTRApQQaoFICDVApgQaolEADVEqgASol0ACVEmiASgk0QKUEGqBSAg1QKYEGqJRAA1RKoAEqJdAAlRJogEp5ogowJV/3t/9EGV8DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFjELABOMZ/Po6TZrL/sDO29rATA6Vb3t/UoY29/+1f04DDO1w63Ev59uLVGoIGz5GHi9Sjja/QU6EPZvFLv5Uu07FIAUCWBBqiUQANUSqABKiXQAJUSaIBKCTRApQQaoFICDVApgQaolEADVEqgASol0ACVEmiASgl0ANRJoAEqJdAAlfJEFeAs+RSUv6OMsg8FXNw/Ue69/BMAAAAAAAAAAAAAAAAAAAAAQCdmAcBpspNn3flzL1q4EZRAA2PRhLR5vXz4683ryk+/7+j/ixO+vqiM9t6Rr78e899ffvq9za9/FWigdhnNbNVqfA/wyuHr5fgxxqMi0EDfMq4Z3ya4K4fbaMN7XgINdKGJ8OUjW/M1JxBooKSj4c3X5mhYa5bgmwYsoxlHXA0hbo1vJnCW5gRds10Jo4lOCDTws4xvRjiPjvOoeDXohUDDtB09Or4W31dTUAE/CJiWJshNjK8E1RJoGDdBHjCBhvHJCBtZjIAfHAxf7scZ46uHr/brkfCDhGFqVllcCWOL0RJoGIajs+S16Hjfnc3K/XHzefG7cp7b0N6HQEO9qhhdbG5uxosXL6KET58+xb1796IPGef79+/Ho0ePooSXL1/Gq1evok0rAdSkiXIeJVdxgm9tbS22traihJ2dnejTxsZGsffy+vXraJtAQ/+qizJ1EGjoRzNTvhGizAkEGrqVKy56OdHH8Ag0tC9vPpRBXg9RZgECDe3IEGeU82jZOmWWItBQlhEGxQg0XFyG+Lc4CLN9imJ8mGB5ebScc+W8kMTRMsUJNCzGbJnOCDScj5UYdE6g4XR5lHwjHC3TA4GGXx299FqY6Y1Aw3fNagxjDKog0CDMVEqgmbIcX+QY43pAhQSaKXLij0EQaKZEmJfU52OqShvSexFopkCYL2B7ezsePnwYJezu7kZfMsz5FJQPHz5ECe/evYu2OSHCmAkzgybQjJEwMwoCzZgIM6Mi0IxB3ifjZhxc/QejIdAMWX5+84h5PWCEBJohcuUfk+DDzdBklPOo2WeX0fMhZyjyxN/vcTBvhkkQaGq3GgcnAK3MYHIEmlo5AcjkCTQ1MmeGsANQlxxj5DhjNQCBpgr5ObwV7ssMPxBo+macASewU9AX982AMwg0XbM6A85JoOmSi01gAQJNF9xtDpYg0LTNSUBYkp2GtuRRc44znASEJQk0bXDUDAXYgSjJUTMUJNCU4qgZCrMzcVGOmqElAs1F5LK5jLPPEbTAjsUyXA0IHRBoFuVqQOiIQLOIPGr+LZic2axcKubzefSl5PtIbb+XSwFny6Plv0KcJ2lrayv29vaKbO/fv4++ZJyfPHlS7L08fvw42rYScDonAqEnAs1JnAiEngk0x8mRxh/h2YDQK4HmZ2txcGtQIw3omUBzVIbZSAMqIdAkIw2okEDjwhOolEBPW44zbgZQJYGepjwBeGt/ux5AtQR6epqrAo00oHICPS05b/4zLKGDQRDo6TBvhoER6GmwvhkGSKDHzfpmGDCBHi8nA2HgBHqcnAyEERDo8XEyEEZCoMfFI6loRZ+PqSptSO/FP4HHI++n4cpAWrGxsRGl7OzsRF/W1tbi9u3bUcLHjx9jd3c32iTQw5c/wzwZaKUGjIxAD5uVGjBiAj1c4gwjJ9DDlOOMjLOfH4yYHXx4PDMQJsJOPiwZ51sBTIJAD4c1zjAxAj0M4gwTJND1E2eYKIGum/s4w4QJdL1cug0TJ9B1EmdAoCskzsA3Al0XcQb+T6DrIc7ADwS6DuIM/EKg+yfOwLEEul/iDJxIoPsjzsCpLgV9yCsExRk4lUB3L++t4fJt4ExGHN1y4yPg3AS6O+IMLESguyHOwMLMoNuXj6kSZ2BhAt2ua+EZgsCSBLo9q3Gw1hlgKStBGy7vb3+EGT8jsL6+Hpubm1HK27dvoy8bGxvfthJ2dna+bW0S6PIyzn8dvsLg3b17N968eRMlZNDu3LkTfZjNZvHgwYN49uxZlPD06dN4/vx5tMmIo6w8YhZnoAiBLuvPEGegEIEuJ++vcSUAChHoMtxfAyhOoC8uw+xCFKA4gb6YXOt8MwBaINDLa9Y6A7RCoJdjOR3QOoFeTl7CLc5AqwR6cbli41oAtEygF2PFBtAZgT4/KzaATgn0+VixAXROoM8n4+ykINApgT5bjjVWA6BjAn269XCPDaAnAn2yHGk4KQj8Yj6fRxc8UeV4zVNRYPJ2d3dje3s7Smj7EVFn+fz5c5H3koHO70vbPDPveHlS0MUoQK+MOH7lSkGgCgL9o3wiiisFgSoI9Hc5d/49ACoh0N+5Qx1QFYE+kHNnD3wFqiLQ5s5ApaYeaHNnoFpTD3SONsydgSpNOdB5j43rAVCpqQbafTaA6k010O6zAVRvioE2dwYGYWqBtqQOGIwpBdqSOmBQphRoow1gUKYS6OthSR0wMFMIdB413wiAgZlCoI02gEEae6CNNoDBGnOgjTaAQRtzoI02gEEba6CNNoDBG2OgZ2G0AYzA/wBP5hsF50HhogAAAABJRU5ErkJggg=='); - background-repeat: no-repeat; - background-position: top 0 left 0, bottom 0 right 0; - background-size: $euiSizeXL * 4, $euiSizeXL * 6; .homSolutionPanel--enterpriseSearch & { - background-color: $euiColorSecondary; - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAABKCAYAAADJwhY8AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAANMSURBVHgBzZp7buIwEMYHKC1QuqsF7Up7Hs4Al+Ff4DCcAonrtPuAPjcL1B/YyA0p2JkZK580SuQm6Y+xx4+xiSqumrG+d7/z/rYx9t+WZdZ2lFhXxq4jngfkP2Ov9qquq8jnm9Zu6eBNgD6TImwsoC80ibY1NIe1sRcSVsPYHfFVN9Yy1jG2pUPbFZEUoJMP+kYHWJakAZ0AemuvrPZZJ10B8jsdHFFKWh70BSe07X1GkUoBCCHib+w1qsq1qzivLkU6JDUgTSaT7m63C4ZMCmjgaDwe4zYYMhmgB+cEyPal95IAFsA5fTGQZ4dbdcAzcO7/9wxk7bMH8AfMTvJDUsO+fG2tSfJwvp5qtdqKPgEMEYABekeBo0IEnNODgTzpI0MBfaFhnwUtAQdlBvA+X1gG0Kmw0y0J57QykE9+ASdIHo3hF29cARMO6uYDhhvFGPwfjG0E4BxPxy/gVPFR8/m8MRwOsTosPa3y9KEtigBCpmoAJwV5jGixjtp8EG3xD8noOASKjiT2V6+Jr5YLFo2hDuvkDfEErqa7EZXx4naxWKyIr9b+e6QkU0U/iBcw+2jWnM08E09NtMMqA0JNNUC0ReInlRraE9bodXBOzaoD1rQBuVku9SpmZ7eSL9wjVa864LbqgOpVzJ4bagNyv7/RBozZgymSOuAN8bRTA7RrFM4+DJRpepBbvZAqIDf3jQmrThXbxCS3i5FdduYksXOAjUp5QJt75npvK75whwwclopd4uvV3YgB2m7lG8nouK0rAojkEcnlZTZ+plUCsDEajfom9SYBB31InXA/is64h+8sl0vKsowGgwExBO/99QvKDkXISHQpFxCz2Wx/nU6nVFIniacyHkTOpGevJ2J48sR7UKgHnceCRoiSnvxVVOj2P6C6ZyjHVKljwb7a54KDKtKT2MgpPDECD/ZJSYGedEdaCqW+437BkzgcdG/zOIVKciTgDOTawL2dezfVmYUiyHV+V6lIyQAhDxJwjyHvoPv4SWmFgAiCg1JnFqLgIO6qK1SIVowS0afjUgCin/tNJZOZ2oCIUlRr6aOlWoDwFjZz2CczpQHhKXjsYv8WKilAeAwBgL0R0ZPCHECAvFirzCFb/5hyknPV7zL4DLH0CVGgAAAAAElFTkSuQmCC'), - url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAA+CAYAAACbQR1vAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACBSURBVHgB7dpBDcAwDMVQdyzGH9xojEQjtbIfBEu5fGUx62WPjyEPcgVArgDIFQC5AiBXAOQKgFwBkCsAcgVATh9gsW+4vFIngFwBkCsAcgVArgDIFQC5AiBXAORahJjVm9zpCoBcAZArAHIFQK4AyBUAuQIgVwDkCoBcAZDTB/gBLrgCk8OhuvYAAAAASUVORK5CYII='); - background-position: top $euiSizeS left 0, bottom $euiSizeS right $euiSizeS; - background-size: $euiSize * 1.25, $euiSizeXL; + background-color: $euiColorWarning; } .homSolutionPanel--observability & { background-color: $euiColorAccent; - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAYAAABV7bNHAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADNSURBVHgB7duxCcIAEEDR08IFrGyz/0pZwVYEIcYF/FWKwHtwXP/hyrvMQbZtu+3rPid3Hf4SKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgIFAQKAgUBAoCBYGCQEGgcJmDnt6WZfms6/qak/sFeswx3vs85+ScWBAoCBQECgIFgYJAQaAgUBAoCBQECgIFgYJAQaAgUBAoCBQECgKFLx4KCqcIFEJnAAAAAElFTkSuQmCC'); - background-position: top $euiSizeS right $euiSizeS; - background-size: $euiSizeL * 1.5; } .homSolutionPanel--securitySolution & { - background-color: $euiColorDarkestShade; - background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGIAAABiCAYAAACrpQYOAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAKRSURBVHgB7d3tSgMxEIXhMeqPQoWC9f4vte5Z3dLvTbKZzCQ5LyxqKwg+tNjdUxQR+RJmXpiOvRDDvPD/kRjGhYvPgbETZlK4+fogxDApPLiNGAaFJ7cD40NYtcKL+76FGNUKK/cRo1Ih4n5gvAtTbQ1i+R5iKBcDgYBADMViIRAxFEuBQMRQKhUCEUOhHAi0YLwJK1IuBCJGwbZAoE8hRpG2QqAFg22oBAQCxkFYdqUgEE6dEyOzkhCIGJmVhkDA4PXvxDQgEMcIiWlBIGIkpAmBiBGZNgQiRkQ1IBAxVqoFgThge1FNCMTN1JNqQyBiPMgCAnHAdpMVBOJm6iJLCA7YLrKEWH4+r3+LPYQIMeY8QKDhlyFeINDQGJ4g0LAY3iDQkBgeIdBwmymvEGgoDM8QaJgBm3cINMSArQUI1P2ArRUI1PVmqiUI1C1GaxCoywFbixCouzFCqxCIyxBPnU6nLjBafkQs7YExHdJyPUCg+WmqZYxeIBAwmv3TticItJseFYcWHxm9QaD5RV9rGD1CIGAcJ4xmztr2CoHms7atYPQMgc4Y3p+qeodAwPiZjnfPGCNAoPMgwSvGKBDINcZIEMgtxmgQyCXGiBDIHcaoEAgYx+n48IAxMgQ6v1nGGmN0COQCgxB/4feAF307KwxCXDe/9dgCgxD3mWAQ4nHAqHrplRDPq3odnBCvq4ZBiPWqYBAiLnUMQsSnikGItObtlAYGIdJTmesQIq/iGITIr+h2ihDbKradIsT2imynCFGmzdspQpRr03VwQpQtG4MQ5cvCIIROyRiE0CsJgxC6RW+nCKFf1FyHEHVaxSBEvV5upwhRv4dzHULYdIdBCLuutlOEsO18HZz/u8E+YMgvrbKfmp8y7IEAAAAASUVORK5CYII='); - background-position: top $euiSizeS left $euiSizeS; - background-size: $euiSizeL * 2; + background-color: $euiColorSecondary; } -} +} \ No newline at end of file diff --git a/src/plugins/home/public/application/components/_synopsis.scss b/src/plugins/home/public/application/components/_synopsis.scss deleted file mode 100644 index 3eac2bc9705e0..0000000000000 --- a/src/plugins/home/public/application/components/_synopsis.scss +++ /dev/null @@ -1,16 +0,0 @@ -.homSynopsis__card { - &.homSynopsis__card--noPanel { - // SASSTODO: Add a prop to EuiCard to allow for no "panel" style - border: none; - box-shadow: none; - } - - .homSynopsis__cardTitle { - display: flex; - } - - // SASSTODO: Fix in EUI - .euiCard__content { - padding-top: 0 !important; - } -} diff --git a/src/plugins/home/public/application/components/add_data/__snapshots__/add_data.test.tsx.snap b/src/plugins/home/public/application/components/add_data/__snapshots__/add_data.test.tsx.snap index 5724d46fca10c..26b5697f008b6 100644 --- a/src/plugins/home/public/application/components/add_data/__snapshots__/add_data.test.tsx.snap +++ b/src/plugins/home/public/application/components/add_data/__snapshots__/add_data.test.tsx.snap @@ -1,100 +1,93 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`AddData render 1`] = ` -
- +
- - -

+ - -

-
-
- -
- + + + + + +

+ +

+
+ + - -
-
-
- - + + + + + + + + + + + + + + + + + +
+ - - - - - - - - - - - -
+ `; diff --git a/src/plugins/home/public/application/components/add_data/add_data.test.tsx b/src/plugins/home/public/application/components/add_data/add_data.test.tsx index 10119632c01b7..3e324685c8402 100644 --- a/src/plugins/home/public/application/components/add_data/add_data.test.tsx +++ b/src/plugins/home/public/application/components/add_data/add_data.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { AddData } from './add_data'; import { shallowWithIntl } from '@kbn/test/jest'; -import { FeatureCatalogueEntry, FeatureCatalogueCategory } from '../../../services'; +import { ApplicationStart } from 'kibana/public'; jest.mock('../app_navigation_handler', () => { return { @@ -27,45 +27,18 @@ beforeEach(() => { jest.clearAllMocks(); }); -const addBasePathMock = jest.fn((path: string) => (path ? path : 'path')); +const applicationStartMock = ({} as unknown) as ApplicationStart; -const mockFeatures: FeatureCatalogueEntry[] = [ - { - category: FeatureCatalogueCategory.DATA, - description: 'Ingest data from popular apps and services.', - showOnHomePage: true, - icon: 'indexOpen', - id: 'home_tutorial_directory', - order: 500, - path: '/app/home#/tutorial_directory', - title: 'Ingest data', - }, - { - category: FeatureCatalogueCategory.ADMIN, - description: 'Add and manage your fleet of Elastic Agents and integrations.', - showOnHomePage: true, - icon: 'indexManagementApp', - id: 'ingestManager', - order: 510, - path: '/app/ingestManager', - title: 'Add Elastic Agent', - }, - { - category: FeatureCatalogueCategory.DATA, - description: 'Import your own CSV, NDJSON, or log file', - showOnHomePage: true, - icon: 'document', - id: 'ml_file_data_visualizer', - order: 520, - path: '/app/ml#/filedatavisualizer', - title: 'Upload a file', - }, -]; +const addBasePathMock = jest.fn((path: string) => (path ? path : 'path')); describe('AddData', () => { test('render', () => { const component = shallowWithIntl( - + ); expect(component).toMatchSnapshot(); }); diff --git a/src/plugins/home/public/application/components/add_data/add_data.tsx b/src/plugins/home/public/application/components/add_data/add_data.tsx index e20abab271f29..97ba28a04a07e 100644 --- a/src/plugins/home/public/application/components/add_data/add_data.tsx +++ b/src/plugins/home/public/application/components/add_data/add_data.tsx @@ -7,90 +7,115 @@ */ import React, { FC, MouseEvent } from 'react'; -import PropTypes from 'prop-types'; -import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui'; +import { + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, + EuiImage, + EuiSpacer, + EuiText, + EuiTitle, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { METRIC_TYPE } from '@kbn/analytics'; -import type { FeatureCatalogueEntry } from '../../../services'; +import { ApplicationStart } from 'kibana/public'; import { createAppNavigationHandler } from '../app_navigation_handler'; // @ts-expect-error untyped component import { Synopsis } from '../synopsis'; import { getServices } from '../../kibana_services'; +import { RedirectAppLinks } from '../../../../../kibana_react/public'; interface Props { addBasePath: (path: string) => string; - features: FeatureCatalogueEntry[]; + application: ApplicationStart; + isDarkMode: boolean; } -export const AddData: FC = ({ addBasePath, features }) => { +export const AddData: FC = ({ addBasePath, application, isDarkMode }) => { const { trackUiMetric } = getServices(); return ( -
- - - -

- -

-
-
+ <> +
+ + + +

+ +

+
- -
- - - -
-
-
+ - + +

+ +

+
- - {features.map((feature) => ( - - { - trackUiMetric(METRIC_TYPE.CLICK, `ingest_data_card_${feature.id}`); - createAppNavigationHandler(feature.path)(event); - }} - description={feature.description} - iconType={feature.icon} - title={feature.title} - url={addBasePath(feature.path)} - wrapInPanel + + + + + + {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} + { + trackUiMetric(METRIC_TYPE.CLICK, 'home_tutorial_directory'); + createAppNavigationHandler('/app/home#/tutorial_directory')(event); + }} + > + + + + + + + + + + + + + + + - ))} - -
- ); -}; +
+
-AddData.propTypes = { - addBasePath: PropTypes.func.isRequired, - features: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, - icon: PropTypes.string.isRequired, - path: PropTypes.string.isRequired, - showOnHomePage: PropTypes.bool.isRequired, - category: PropTypes.string.isRequired, - order: PropTypes.number, - }) - ), + + + ); }; diff --git a/src/plugins/home/public/application/components/home.js b/src/plugins/home/public/application/components/home.js index fdaaeef01f47a..e9e996cac39ef 100644 --- a/src/plugins/home/public/application/components/home.js +++ b/src/plugins/home/public/application/components/home.js @@ -9,14 +9,9 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui'; import { METRIC_TYPE } from '@kbn/analytics'; import { i18n } from '@kbn/i18n'; -import { - KibanaPageTemplate, - overviewPageActions, - OverviewPageFooter, -} from '../../../../../../src/plugins/kibana_react/public'; +import { KibanaPageTemplate, OverviewPageFooter } from '../../../../kibana_react/public'; import { HOME_APP_BASE_PATH } from '../../../common/constants'; import { FeatureCatalogueCategory } from '../../services'; import { getServices } from '../kibana_services'; @@ -113,10 +108,10 @@ export class Home extends Component { .sort((directoryA, directoryB) => directoryA.order - directoryB.order); renderNormal() { - const { addBasePath, solutions, directories } = this.props; + const { addBasePath, solutions } = this.props; const { application, trackUiMetric } = getServices(); + const isDarkMode = getServices().uiSettings?.get('theme:darkMode') || false; const devTools = this.findDirectoryById('console'); - const addDataFeatures = this.getFeaturesByCategory(FeatureCatalogueCategory.DATA); const manageDataFeatures = this.getFeaturesByCategory(FeatureCatalogueCategory.ADMIN); // Show card for console if none of the manage data plugins are available, most likely in OSS @@ -128,41 +123,20 @@ export class Home extends Component { , - rightSideItems: overviewPageActions({ - addBasePath, - application, - showDevToolsLink: true, - showManagementLink: true, - }), + bottomBorder: false, + pageTitle: , }} template="empty" > - {solutions.length ? ( - - ) : null} - - - - - - - - - - - -