diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2382e7fa5d984..4feba30f8b169 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -132,6 +132,7 @@ x-pack/examples/files_example @elastic/kibana-app-services /x-pack/test/fleet_api_integration @elastic/fleet /x-pack/test/fleet_cypress @elastic/fleet /x-pack/test/fleet_functional @elastic/fleet +/src/dev/build/tasks/bundle_fleet_packages.ts # APM /x-pack/plugins/apm/ @elastic/apm-ui @@ -356,6 +357,7 @@ x-pack/examples/files_example @elastic/kibana-app-services # Enterprise Search /x-pack/plugins/enterprise_search @elastic/enterprise-search-frontend /x-pack/test/functional_enterprise_search/ @elastic/enterprise-search-frontend +/x-pack/plugins/enterprise_search/public/applications/shared/doc_links @elastic/ent-search-docs-team # Management Experience - Deployment Management /src/plugins/dev_tools/ @elastic/platform-deployment-management @@ -745,6 +747,8 @@ packages/core/http/core-http-browser-mocks @elastic/kibana-core packages/core/http/core-http-common @elastic/kibana-core packages/core/http/core-http-context-server-internal @elastic/kibana-core packages/core/http/core-http-context-server-mocks @elastic/kibana-core +packages/core/http/core-http-request-handler-context-server @elastic/kibana-core +packages/core/http/core-http-request-handler-context-server-internal @elastic/kibana-core packages/core/http/core-http-router-server-internal @elastic/kibana-core packages/core/http/core-http-router-server-mocks @elastic/kibana-core packages/core/http/core-http-server @elastic/kibana-core diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index c298d8a395df6..4d0790ec95184 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index 6da505acae8b7..88e4157414a7f 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 4e5199b31ef9c..c3bd7eb349a07 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index df1ba878d7e68..cb7a1008b0bc5 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 84c92a1ce8643..d9218c6f9c48f 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index e10dd6028fafe..b574eadcc22f7 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 504dc027276f0..e8fa3ead871d7 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index 5dc73b2b9000b..9c484f7dfc615 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index aaa279d698443..2ec486a4957e7 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 5e129b2343ca0..b204ddb7b0ee0 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 5c1a4fea8ca5c..fdf2f80ec284b 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 6314cca4f901b..33e6421081033 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 9c7112ee6e3ad..8cdffb406e1d3 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index a673eebc1e1c6..e365d6a87afe3 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 849d5fc71f968..69b2dfc22a263 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/core.devdocs.json b/api_docs/core.devdocs.json index 08008a2bfe5c5..607bae8fad1fc 100644 --- a/api_docs/core.devdocs.json +++ b/api_docs/core.devdocs.json @@ -584,6 +584,10 @@ "plugin": "@kbn/core-analytics-server-internal", "path": "packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts" }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.ts" + }, { "plugin": "@kbn/core-status-server-internal", "path": "packages/core/status/core-status-server-internal/src/status_service.ts" @@ -620,6 +624,30 @@ "plugin": "@kbn/core-analytics-browser-mocks", "path": "packages/core/analytics/core-analytics-browser-mocks/src/analytics_service.mock.ts" }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, { "plugin": "@kbn/core-analytics-browser-mocks", "path": "packages/core/analytics/core-analytics-browser-mocks/src/analytics_service.mock.ts" @@ -19295,6 +19323,10 @@ "plugin": "@kbn/core-analytics-server-internal", "path": "packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts" }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.ts" + }, { "plugin": "@kbn/core-status-server-internal", "path": "packages/core/status/core-status-server-internal/src/status_service.ts" @@ -19331,6 +19363,30 @@ "plugin": "@kbn/core-analytics-browser-mocks", "path": "packages/core/analytics/core-analytics-browser-mocks/src/analytics_service.mock.ts" }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, + { + "plugin": "@kbn/core-root-browser-internal", + "path": "packages/core/root/core-root-browser-internal/src/core_system.test.ts" + }, { "plugin": "@kbn/core-analytics-browser-mocks", "path": "packages/core/analytics/core-analytics-browser-mocks/src/analytics_service.mock.ts" diff --git a/api_docs/core.mdx b/api_docs/core.mdx index d63230e7ed586..d554613d1ec1e 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github description: API docs for the core plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] --- import coreObj from './core.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 7c8ab77b2d5ac..b25052db9516d 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 507845391c779..609a9e0925333 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index ef9680b1325db..ae6e7c69b3a88 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index f849f08374ded..b8c91c02caa2d 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3211 | 33 | 2508 | 23 | +| 3213 | 33 | 2509 | 23 | ## Client diff --git a/api_docs/data_query.devdocs.json b/api_docs/data_query.devdocs.json index 2507050e905fc..23849f6641368 100644 --- a/api_docs/data_query.devdocs.json +++ b/api_docs/data_query.devdocs.json @@ -3785,10 +3785,10 @@ }, { "parentPluginId": "data", - "id": "def-common.queryStateToExpressionAst", + "id": "def-common.textBasedQueryStateToAstWithValidation", "type": "Function", "tags": [], - "label": "queryStateToExpressionAst", + "label": "textBasedQueryStateToAstWithValidation", "description": [ "\nConverts QueryState to expression AST" ], @@ -3801,15 +3801,15 @@ "section": "def-common.ExpressionAstExpression", "text": "ExpressionAstExpression" }, - ">" + " | undefined>" ], - "path": "src/plugins/data/common/query/to_expression_ast.ts", + "path": "src/plugins/data/common/query/text_based_query_state_to_ast_with_validation.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "data", - "id": "def-common.queryStateToExpressionAst.$1", + "id": "def-common.textBasedQueryStateToAstWithValidation.$1", "type": "Object", "tags": [], "label": "{\n filters,\n query,\n inputQuery,\n time,\n dataViewsService,\n}", @@ -3817,7 +3817,49 @@ "signature": [ "Args" ], - "path": "src/plugins/data/common/query/to_expression_ast.ts", + "path": "src/plugins/data/common/query/text_based_query_state_to_ast_with_validation.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "data", + "id": "def-common.textBasedQueryStateToExpressionAst", + "type": "Function", + "tags": [], + "label": "textBasedQueryStateToExpressionAst", + "description": [ + "\nConverts QueryState to expression AST" + ], + "signature": [ + "({\n filters,\n query,\n inputQuery,\n time,\n timeFieldName,\n}: Args) => ", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.ExpressionAstExpression", + "text": "ExpressionAstExpression" + } + ], + "path": "src/plugins/data/common/query/text_based_query_state_to_ast.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.textBasedQueryStateToExpressionAst.$1", + "type": "Object", + "tags": [], + "label": "{\n filters,\n query,\n inputQuery,\n time,\n timeFieldName,\n}", + "description": [], + "signature": [ + "Args" + ], + "path": "src/plugins/data/common/query/text_based_query_state_to_ast.ts", "deprecated": false, "trackAdoption": false, "isRequired": true diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index bb88b05d16a92..b81d02840aba1 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3211 | 33 | 2508 | 23 | +| 3213 | 33 | 2509 | 23 | ## Client diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 3cf065a957729..12e4806b7ea2b 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3211 | 33 | 2508 | 23 | +| 3213 | 33 | 2509 | 23 | ## Client diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 6fca87db82f91..1384a135bfbe8 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 9e4d3deac15c4..4b95039f7981c 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index cf43b6fa9dd9e..3608114bd15af 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index a5ea60ca6db86..c6389cc090a71 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 797cd5596c31f..69bcfa932c46f 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index ec45435a4e875..b658b5b795600 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 430ba54813520..dabf6a7945b9a 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 30143657a7b1e..643d002885ef8 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 95bc923cc9da0..ddeb12beb9a7a 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 8f51330d8bc6d..4a2a4abc7d5ef 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 7263ed936315a..104fc1d5cde65 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index f5d8586e5194b..3203b4c957545 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 326d612509b6c..e5e64a70e8012 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index e5a8bb47a0520..6d488adbda835 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 23ae523bade64..2d3bbbfe7ad85 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index d5982b5a2a865..e6eb098f3c9cd 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-ma | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 114 | 3 | 110 | 3 | +| 114 | 3 | 110 | 5 | ## Client diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 705fa73b04c1d..54a7269ef5325 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 53b40226f0d78..dff00025d47a5 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 51a1fd22bc039..ba5e5e742f4c5 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index c23d6a727bb38..331af14bbd784 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index 1196f07945026..36ea696e53359 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 046b3c31f107b..97052c63f7476 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index 9a3e6bd0dc825..95950d42e4473 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 76fd8a4068f19..ee6b2d7e353f4 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 337717de0a65a..c1edcc43088dd 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 32c3971bd0909..672e12f360d34 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index ca6a5be21ec3a..7fbd70637ed36 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index 90854571dc71c..09f5c55834635 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 898224f9aba1a..8414051020d06 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index f6686201cb138..42b6c0963d951 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index c090283f69746..340a2de8e8e21 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index cc0dfccc59154..74c3fd828f44f 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 116d58a6218b9..7b4880c40f8d6 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index dbb19f977cc78..8c4ebd13fe23d 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 31c1b78e94389..c0963ced99a2c 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.devdocs.json b/api_docs/files.devdocs.json index 358859310c797..7c94fcdac9025 100644 --- a/api_docs/files.devdocs.json +++ b/api_docs/files.devdocs.json @@ -438,10 +438,10 @@ "tags": [], "label": "getDownloadHref", "description": [ - "\nGet a string for downloading a file that can be passed to a button element's\nhref for download." + "\nGet a string for downloading a file that can be passed to a button element's\nhref for download.\n" ], "signature": [ - "(file: ", + "(args: Pick<", { "pluginId": "files", "scope": "common", @@ -449,7 +449,7 @@ "section": "def-common.FileJSON", "text": "FileJSON" }, - ") => string" + ", \"id\" | \"fileKind\">) => string" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -460,9 +460,12 @@ "id": "def-public.FilesClient.getDownloadHref.$1", "type": "Object", "tags": [], - "label": "file", - "description": [], + "label": "args", + "description": [ + "- get download URL args" + ], "signature": [ + "Pick<", { "pluginId": "files", "scope": "common", @@ -470,7 +473,7 @@ "section": "def-common.FileJSON", "text": "FileJSON" }, - "" + ", \"id\" | \"fileKind\">" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -1129,7 +1132,7 @@ "section": "def-common.FileJSON", "text": "FileJSON" }, - "; }>; upload: (arg: Omit & Readonly<{ selfDestructOnAbort?: boolean | undefined; } & {}> & { body: unknown; kind: string; abortSignal?: AbortSignal | undefined; contentType?: string | undefined; }, \"kind\">) => Promise<{ ok: true; size: number; }>; download: (arg: Omit & { kind: string; }, \"kind\">) => Promise; getDownloadHref: (arg: Omit<", + "; }>; upload: (arg: Omit & Readonly<{ selfDestructOnAbort?: boolean | undefined; } & {}> & { body: unknown; kind: string; abortSignal?: AbortSignal | undefined; contentType?: string | undefined; }, \"kind\">) => Promise<{ ok: true; size: number; }>; download: (arg: Omit & { kind: string; }, \"kind\">) => Promise; getDownloadHref: (arg: Omit, \"kind\">) => string; share: (arg: Omit & Readonly<{} & { fileId: string; }> & { kind: string; }, \"kind\">) => Promise<", + ", \"id\" | \"fileKind\">, \"kind\">) => string; share: (arg: Omit & Readonly<{} & { fileId: string; }> & { kind: string; }, \"kind\">) => Promise<", { "pluginId": "files", "scope": "common", diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 149bec1a8acb5..96ec1e67bf2bf 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/tea | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 263 | 0 | 15 | 2 | +| 263 | 0 | 14 | 2 | ## Client diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index a35508ec3930f..d068e061e494b 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -1225,6 +1225,146 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyCreateMultiStepExtension", + "type": "Interface", + "tags": [], + "label": "PackagePolicyCreateMultiStepExtension", + "description": [ + "Extension point registration contract for Integration Policy Create views in multi-step onboarding" + ], + "path": "x-pack/plugins/fleet/public/types/ui_extensions.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyCreateMultiStepExtension.package", + "type": "string", + "tags": [], + "label": "package", + "description": [], + "path": "x-pack/plugins/fleet/public/types/ui_extensions.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyCreateMultiStepExtension.view", + "type": "string", + "tags": [], + "label": "view", + "description": [], + "signature": [ + "\"package-policy-create-multi-step\"" + ], + "path": "x-pack/plugins/fleet/public/types/ui_extensions.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyCreateMultiStepExtension.Component", + "type": "Function", + "tags": [], + "label": "Component", + "description": [], + "signature": [ + "React.ExoticComponent<(", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyCreateMultiStepExtensionComponentProps", + "text": "PackagePolicyCreateMultiStepExtensionComponentProps" + }, + " & React.RefAttributes>) | (", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyCreateMultiStepExtensionComponentProps", + "text": "PackagePolicyCreateMultiStepExtensionComponentProps" + }, + " & { children?: React.ReactNode; })> & { readonly _result: ", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyCreateMultiStepExtensionComponent", + "text": "PackagePolicyCreateMultiStepExtensionComponent" + }, + "; }" + ], + "path": "x-pack/plugins/fleet/public/types/ui_extensions.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyCreateMultiStepExtension.Component.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyCreateMultiStepExtensionComponentProps", + "type": "Interface", + "tags": [], + "label": "PackagePolicyCreateMultiStepExtensionComponentProps", + "description": [], + "path": "x-pack/plugins/fleet/public/types/ui_extensions.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyCreateMultiStepExtensionComponentProps.newPolicy", + "type": "Object", + "tags": [], + "label": "newPolicy", + "description": [ + "The integration policy being created" + ], + "signature": [ + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.NewPackagePolicy", + "text": "NewPackagePolicy" + } + ], + "path": "x-pack/plugins/fleet/public/types/ui_extensions.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-public.PackagePolicyEditExtension", @@ -1925,10 +2065,10 @@ "id": "def-public.UIExtensionsStorage.Unnamed", "type": "IndexSignature", "tags": [], - "label": "[key: string]: Partial>", + "label": "[key: string]: Partial>", "description": [], "signature": [ - "[key: string]: Partial | React.FunctionComponent<", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyCreateMultiStepExtensionComponentProps", + "text": "PackagePolicyCreateMultiStepExtensionComponentProps" + }, + ">" + ], + "path": "x-pack/plugins/fleet/public/types/ui_extensions.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-public.PackagePolicyEditExtensionComponent", @@ -2269,6 +2442,14 @@ "docId": "kibFleetPluginApi", "section": "def-public.AgentEnrollmentFlyoutFinalStepExtension", "text": "AgentEnrollmentFlyoutFinalStepExtension" + }, + " | ", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyCreateMultiStepExtension", + "text": "PackagePolicyCreateMultiStepExtension" } ], "path": "x-pack/plugins/fleet/public/types/ui_extensions.ts", @@ -2365,6 +2546,14 @@ "docId": "kibFleetPluginApi", "section": "def-public.AgentEnrollmentFlyoutFinalStepExtension", "text": "AgentEnrollmentFlyoutFinalStepExtension" + }, + " | ", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyCreateMultiStepExtension", + "text": "PackagePolicyCreateMultiStepExtension" } ], "path": "x-pack/plugins/fleet/public/types/ui_extensions.ts", @@ -3725,6 +3914,14 @@ "docId": "kibFleetPluginApi", "section": "def-public.AgentEnrollmentFlyoutFinalStepExtension", "text": "AgentEnrollmentFlyoutFinalStepExtension" + }, + " | ", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyCreateMultiStepExtension", + "text": "PackagePolicyCreateMultiStepExtension" } ], "path": "x-pack/plugins/fleet/public/types/ui_extensions.ts", @@ -6227,7 +6424,7 @@ "section": "def-common.AuthenticatedUser", "text": "AuthenticatedUser" }, - " | undefined; force?: boolean | undefined; } | undefined, currentVersion?: string | undefined) => Promise<", + " | undefined; force?: boolean | undefined; skipUniqueNameVerification?: boolean | undefined; } | undefined, currentVersion?: string | undefined) => Promise<", { "pluginId": "fleet", "scope": "common", @@ -6352,6 +6549,20 @@ "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.update.$5.skipUniqueNameVerification", + "type": "CompoundType", + "tags": [], + "label": "skipUniqueNameVerification", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false } ] }, @@ -9276,14 +9487,14 @@ { "parentPluginId": "fleet", "id": "def-common.FleetServerAgent.upgraded_at", - "type": "string", + "type": "CompoundType", "tags": [], "label": "upgraded_at", "description": [ "\nDate/time the Elastic Agent was last upgraded" ], "signature": [ - "string | undefined" + "string | null | undefined" ], "path": "x-pack/plugins/fleet/common/types/models/agent.ts", "deprecated": false, @@ -9305,22 +9516,6 @@ "deprecated": false, "trackAdoption": false }, - { - "parentPluginId": "fleet", - "id": "def-common.FleetServerAgent.upgrade_status", - "type": "CompoundType", - "tags": [], - "label": "upgrade_status", - "description": [ - "\nUpgrade status" - ], - "signature": [ - "\"completed\" | \"started\" | undefined" - ], - "path": "x-pack/plugins/fleet/common/types/models/agent.ts", - "deprecated": false, - "trackAdoption": false - }, { "parentPluginId": "fleet", "id": "def-common.FleetServerAgent.access_api_key_id", @@ -14202,21 +14397,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "fleet", - "id": "def-common.ENDPOINT_PRIVILEGES", - "type": "Array", - "tags": [], - "label": "ENDPOINT_PRIVILEGES", - "description": [], - "signature": [ - "string[]" - ], - "path": "x-pack/plugins/fleet/common/constants/authz.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "fleet", "id": "def-common.EsAssetReference", @@ -16546,6 +16726,21 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.ENDPOINT_PRIVILEGES", + "type": "Object", + "tags": [], + "label": "ENDPOINT_PRIVILEGES", + "description": [], + "signature": [ + "readonly [\"writeEndpointList\", \"readEndpointList\", \"writeTrustedApplications\", \"readTrustedApplications\", \"writeHostIsolationExceptions\", \"readHostIsolationExceptions\", \"writeBlocklist\", \"readBlocklist\", \"writeEventFilters\", \"readEventFilters\", \"writePolicyManagement\", \"readPolicyManagement\", \"writeActionsLogManagement\", \"readActionsLogManagement\", \"writeHostIsolation\", \"writeProcessOperations\", \"writeFileOperations\"]" + ], + "path": "x-pack/plugins/fleet/common/constants/authz.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.EPM_API_ROUTES", diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 173f9f76092f4..6f966dbb5a316 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Fleet](https://github.com/orgs/elastic/teams/fleet) for questions regar | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 988 | 3 | 888 | 17 | +| 996 | 3 | 893 | 17 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index c689891e7444b..63433541ece2b 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index 5dfb91864c060..c28c8b2fef872 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index 62db97259ee59..8c285e037a355 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 87bd3e83a63b9..2d1523f302cb2 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index eee8cda64e245..46b6303673ab9 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index fd32cbab99193..d86809062de00 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 00175e67b30b5..0a75d4c550c42 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 33ee5123bb5cd..1b2ce0d5a84c2 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index bf08287ddc424..3ca0d95b596d9 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index d4cb51aa5139f..7e469da7a40b8 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 389117150bd55..9e1d8daed9b7c 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index 749a781cf0e47..294c0b5ebb04b 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] --- import kbnAlertsObj from './kbn_alerts.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index c0f7031e47a7a..e991378eefb61 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 1595bab913e80..61ec0f495851f 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index ba7823ee64ac1..af69ccaa66458 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 105ff1b565b71..c80fb067196d2 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index ef9a534fa3470..c8fd4ef979406 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 6a263b0defbb9..102c627e9ef5e 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index defb49cbe69ea..88ae4fc21aca0 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 0a80a8f9d7c64..951b6896fa528 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index f87f80a173bee..a679b1a252dad 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index 465473d3ef7cd..c330c66a3b511 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index 8bc8181b1c666..4cf5662b020cc 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 26ac1ad8da546..4396f3ffe02e1 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 79c65aec69dbb..1857d82ee013a 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 4b5645cc4b132..f3779a0488fb4 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index fb74c109385e8..e2d60d46020af 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 6dfdbdc6a7e19..e0475bc85ecd2 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index e5787da85b661..32514d096d20f 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 9f30996b585d7..b93c70c8a0eb5 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 97256b7516108..78d758c0f2fe3 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list.mdx b/api_docs/kbn_content_management_table_list.mdx index 12779749648df..812ca543dea50 100644 --- a/api_docs/kbn_content_management_table_list.mdx +++ b/api_docs/kbn_content_management_table_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list title: "@kbn/content-management-table-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list'] --- import kbnContentManagementTableListObj from './kbn_content_management_table_list.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 89fc744b1c703..c29081c8b626d 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index bad36ac54b215..739c7e7af5969 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index 5db786b7754f0..2c0999666ff1f 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 0141718a2ccd2..f58a16ef732ad 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 2d21be701e133..ced023377219a 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index 1dc30aff04e5d..cbea4bff1bf86 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 7e999f21f3e1a..b1580098a3652 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index c957561aa4eca..f704df4a7f345 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index 6ba6188770d4c..4767d8fa50538 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index 09bb2339c9782..7c6ce13416170 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index a036a5bb51c0e..17402d105d5b5 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index 42db1a2581375..48cb4145874c7 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index cd0875458844d..28228f4c74761 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 468ebd13bf1b3..09afb9dd896c7 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index c986f9acf0ef3..bf845366f8e62 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index d6cd91c67140a..bf1d2e6b25458 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 7a6ba37310aaf..a2eb49783d4be 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index 24b234f7f811d..aa1d950326fc9 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index c5359e8345a38..3d8690f8d6f7d 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index b847a51cd7a0d..78563e898c03a 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index cc02f6073ea91..4b44cbfe07571 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index b1d46f4e5fe8c..f8052fad772a5 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index ee601e6352e35..79da95fae9e67 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 6eec129fe2615..ad16ad6aea2e6 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index 983047e82691a..7fe5dba92aa5c 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 0190b56cf9739..2547deec251f6 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 60d444ced08da..d96ff821c4365 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index e9f8e03e21a24..74dee4cd3fdcc 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index cd76ecc1e5de7..da6a21361ea25 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index adcf635bd0895..617a402d35fcc 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index d8f11b0a78906..1217a7b8fa20d 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 04891d7eee772..0ccaad98b392b 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index a211477391f89..14eccd7c10c34 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index cabbd8bcaf86c..f5f017918ee4a 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index c6a7f734219d8..477917148b690 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 7af48bcbf5f1b..399790680e068 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index ca2a47bc99331..318e2f19b36d7 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index 5c6a4b84856c7..b4e402b1d85a7 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index dd0e97e30fc7c..1263eb43812bf 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 2d4f36ed093a2..efd3c4dce7d8e 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 587243bb64061..4b8b92e29d47e 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index 96b79793ed095..12f2b1b89aaa5 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index d8cfe4d9f349d..22703ff1d56c5 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index fe90efd441051..58d7084730b09 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index e7b47436fa761..9f241f79f3092 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 8fa86908f719d..2d3ce9691dbc3 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index 76ca7ae6c111b..db3e364e96ff7 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 3e17e9ed94637..cbeb87f2524be 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index 01d683396e2b7..e838dfc832fd6 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 891c8d8767547..6bdcb4cd9e37a 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index a935d019adeb4..afb5974de9a1d 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index 04f71c530c9a5..8e28ebbe2ff12 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index 53f1d9fe670a0..463b56f364292 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index f8ff0087dbbfc..bf4cf64d7a58a 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index c93bb2546524b..4047f8a6f4847 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index 6121b09f8c1b4..650426f493570 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index 49dffda39dcc6..0df0a232ed7e3 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 74c3216b75ebc..404f13d3ca12a 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index 50ebcbe4058b9..524b236008cfb 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index c7649dcf597cf..94a0469ff1071 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index 7e8106d7e3c66..aac9e17df421b 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index 32e6b9184dbe1..e83f6e8553d82 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index 4e5cbf65974a7..a89d07338f781 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index 93c620cca65a7..3575cc0d18a98 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index 13734215059b0..ce24eb49860c5 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser.mdx b/api_docs/kbn_core_injected_metadata_browser.mdx index 08dbe296b4323..92e9d0e07cfe5 100644 --- a/api_docs/kbn_core_injected_metadata_browser.mdx +++ b/api_docs/kbn_core_injected_metadata_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser title: "@kbn/core-injected-metadata-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser'] --- import kbnCoreInjectedMetadataBrowserObj from './kbn_core_injected_metadata_browser.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index b88675d50c204..17e4abfa2a1aa 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index fc53dc77eda1c..d8c9f151e2f4f 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index 2526e6dc2b6b9..574ff5014691b 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index 8b557e2e502b2..62c8d4f2358e5 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index 74231286ffe09..8deee157e3d42 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index a4e8cb4241bef..cf1126fe73e2a 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index f56eecbd69552..bc4d09292edbf 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index 2067fdbc72fda..485e124d97e42 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index a7e7a11ae05ea..4b17dbaac8c84 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index febc5d3038933..36c1e8c0f9a42 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index 47cc583e2df0e..a1a8ce47aed54 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index 9e16d8304decd..6b4a55f82676d 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index 5db83c7383b67..d1494db236370 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index 8fafac5831639..ad35d06977cc0 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index 9fbffa9c5df93..5b5b8a9421411 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index d253278b97f15..bf95da355c9e9 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 5dd3d790c3eaa..3a07f7a676064 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index ed0c7c4e240ce..130bddee31d14 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 5c44022f60828..fef5e6c2f9a85 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index ef4b9a440b592..724251e5e502f 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index 559df72a076e4..3837e623f29c4 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index 6160c98032fef..0f7f597d06d38 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index 5765d85478d62..42846c64f33d6 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index 09d09fe708575..a52c3697e57dd 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index 5416044cac958..238252f104b3c 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 962d718e0042b..d5b97eb1a0cbb 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 07d55b8bdc9ad..20a753b66ea99 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index f31451fde9e77..c074d0f80cb88 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 97d1f20eba7af..949af62592ecb 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index 1c1ec6407d249..6fa09c36e31f1 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_internal.mdx b/api_docs/kbn_core_saved_objects_api_server_internal.mdx index 678cf37d24e81..7c588cdc511e2 100644 --- a/api_docs/kbn_core_saved_objects_api_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-internal title: "@kbn/core-saved-objects-api-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-internal'] --- import kbnCoreSavedObjectsApiServerInternalObj from './kbn_core_saved_objects_api_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index da93d1e0b8552..447e323f6f6c3 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index 73d6c70c1a9ac..9931b55fa4f21 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index 2b499a47657b8..deb24928a107a 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index fcec7c16e5f85..3bfa422bdff98 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index 197152a6dae02..1a306a18a3eb1 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 80320e7312485..a34e632cf249f 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 63fa1e47ac1bf..59d4d1841c7fa 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 127679f751476..f0610e31ec803 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index f633f52c6174d..cd9ba3c71908b 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index bc446d004b249..f2dd4437d43e1 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index ecbb1447d1e5c..88c329e9ae344 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index c694b3c9f6584..df7eaa590f6db 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 39099151043aa..5534b4652be59 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 73e0b05504386..ccf532e33ba38 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 0012db4e553fb..5b78e21ba58ce 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 1ef8c6abfc97a..f4f9cc899056b 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 7c9440c92271b..86d04a0b4ff7f 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index bd5556b6ce877..52e756da1a554 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index 364b20ab80d66..432a7d95007ec 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index aa7990a556b57..8ccca542c4b7d 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index d4a0a789572fb..ab86530abfbbd 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 826ee5d1b3459..9de9031c75db8 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index e68a43d0ce9fe..9c59e5a04b8e4 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 8c938db4082e1..02d479962f929 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 0cbb8955ac42e..71eada8e5603f 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 67a42c6099d97..b8b744e259c54 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index 791006e8cea6b..a89cdf92e9ac2 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index b1ae46812b1d2..290774ac1f9eb 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index ef778256b7997..004e652235478 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 545b597ef2b8b..84190ae50348c 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index 99402f8c657ce..2f362f1ede3ff 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index a5081a8a512eb..e214233f02eb7 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index b490e18b99885..b8ac7249cb2af 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index 01b13b900344a..4f5cca38779c3 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index 90ea1b666c8aa..bc10003b1203b 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index a9fb17b3cd06f..d95c8ad7295ed 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 0afac1bca8d36..06ce6dd999351 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index d2e4558115131..4bcac88980eb1 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 42e02f9783509..42846a27d0d57 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index 5169411f49a2a..5db4302dd4cd2 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 5872d911b8f47..968955efd32a8 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 8f8299fb3972b..e047906625c28 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 93faea017a0fb..c7d4d0fe3d260 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index f29fe40eb21d1..30e9b543d9d8d 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 2d7b26292e0e8..8590060b07965 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index da7db13bb38b1..1e69af86cfda4 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index 3d7f8993dd9fb..695ed989dfe99 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index db9354454f22f..b329278d82729 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 5bee2fdbf5f66..9a2cfbe08a28b 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index f6c2a308c267e..2e0b9742678dc 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 52dcd1a4217e9..0373e71bbf94c 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index e8d91e141f195..f0a54f4a6740d 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 93882b49ca42b..a2bfedd08171e 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 5955c7f01158f..2a9f62b4f3f36 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_get_repo_files.mdx b/api_docs/kbn_get_repo_files.mdx index e50741bdb3a60..b1b28470de32e 100644 --- a/api_docs/kbn_get_repo_files.mdx +++ b/api_docs/kbn_get_repo_files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-get-repo-files title: "@kbn/get-repo-files" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/get-repo-files plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/get-repo-files'] --- import kbnGetRepoFilesObj from './kbn_get_repo_files.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 24eedfb0387a4..b675d4d8f4da0 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 1d4fddcc02250..b7abe8b512959 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 59d37e8a5d09f..e7a5d6fe0f7ec 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index 5e218789e57f1..f716a25e4408f 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index 15647319a90f0..25ba31dee6a69 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 56039851af766..c36a372e85d74 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 807a82e9cbff7..6051ff9b96e16 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index dfb4aea12e2d7..0554879f31ad2 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 28487fab71400..c005d1ea66f6e 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 01244be181bf2..b2cd34e94a506 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 7d70916d448e4..1b91d601c2246 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 63d9dc96362af..13444331d9fcc 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 6b1049cee9be2..d6db9caa5dd01 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index a175904d02573..12ab660fc1764 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index ca5e2566d884c..a0fbd8c5ef3c9 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 78c0d9fbb8369..6808dca6dbe35 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index ffdc48a0fb0d3..8da4778d8b81f 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index a1f168d3fc91d..e9cf6c1838c51 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 7da86649ddf39..4ec4c4ef7c9eb 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 29b3596a8bc29..757c4018832a9 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index fb729fc0747ed..11961ef3d602b 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index 54d57200bd5a1..a980b80bd7a38 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index ba91201a52c6c..b1051ed927c86 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 493ca235ab7a9..98d5196dc24f1 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index b16b234ee0f50..a04f5630c37b4 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index f7d3bada225b9..af33c58333e71 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 65a1a0d424f15..2a373248eac93 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index ef453ad073e4f..61d440950cbf3 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index f441cc10aa506..4ca4605d2eb99 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index c81350b38632b..99858a653681a 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 8e6bdc15f9807..c74046c4b1fa8 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.devdocs.json b/api_docs/kbn_securitysolution_io_ts_alerting_types.devdocs.json index b42cebbc4fb84..f9869d88c91cd 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.devdocs.json +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.devdocs.json @@ -877,21 +877,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "@kbn/securitysolution-io-ts-alerting-types", - "id": "def-common.ThrottleOrUndefinedOrNull", - "type": "Type", - "tags": [], - "label": "ThrottleOrUndefinedOrNull", - "description": [], - "signature": [ - "string | null | undefined" - ], - "path": "packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "@kbn/securitysolution-io-ts-alerting-types", "id": "def-common.Type", @@ -1383,24 +1368,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "@kbn/securitysolution-io-ts-alerting-types", - "id": "def-common.DefaultThrottleNull", - "type": "Object", - "tags": [], - "label": "DefaultThrottleNull", - "description": [ - "\nTypes the DefaultThrottleNull as:\n - If null or undefined, then a null will be set" - ], - "signature": [ - "Type", - "" - ], - "path": "packages/kbn-securitysolution-io-ts-alerting-types/src/default_throttle_null/index.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "@kbn/securitysolution-io-ts-alerting-types", "id": "def-common.DefaultToString", @@ -2921,7 +2888,14 @@ "label": "throttle", "description": [], "signature": [ - "StringC" + "UnionC", + "<[", + "LiteralC", + "<\"no_actions\">, ", + "LiteralC", + "<\"rule\">, ", + "Type", + "]>" ], "path": "packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts", "deprecated": false, @@ -2938,31 +2912,15 @@ "signature": [ "UnionC", "<[", - "StringC", - ", ", - "NullC", - "]>" - ], - "path": "packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/securitysolution-io-ts-alerting-types", - "id": "def-common.throttleOrNullOrUndefined", - "type": "Object", - "tags": [], - "label": "throttleOrNullOrUndefined", - "description": [], - "signature": [ "UnionC", "<[", - "StringC", - ", ", + "LiteralC", + "<\"no_actions\">, ", + "LiteralC", + "<\"rule\">, ", + "Type", + "]>, ", "NullC", - ", ", - "UndefinedC", "]>" ], "path": "packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts", diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 4066f50c33520..5f200ca33cd52 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 148 | 0 | 129 | 0 | +| 145 | 0 | 127 | 0 | ## Common diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index 720ede9fa9e87..75beb67b94d03 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.devdocs.json b/api_docs/kbn_securitysolution_io_ts_types.devdocs.json index 2ec94e9e8c1c0..ef934492d28ef 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.devdocs.json +++ b/api_docs/kbn_securitysolution_io_ts_types.devdocs.json @@ -405,6 +405,41 @@ ], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/securitysolution-io-ts-types", + "id": "def-common.TimeDuration", + "type": "Function", + "tags": [], + "label": "TimeDuration", + "description": [], + "signature": [ + "({ allowedUnits, allowedDurations }: TimeDurationType) => ", + "Type", + "" + ], + "path": "packages/kbn-securitysolution-io-ts-types/src/time_duration/index.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/securitysolution-io-ts-types", + "id": "def-common.TimeDuration.$1", + "type": "CompoundType", + "tags": [], + "label": "{ allowedUnits, allowedDurations }", + "description": [], + "signature": [ + "TimeDurationType" + ], + "path": "packages/kbn-securitysolution-io-ts-types/src/time_duration/index.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [], @@ -644,12 +679,30 @@ "label": "TimeDurationC", "description": [], "signature": [ + "({ allowedUnits, allowedDurations }: TimeDurationType) => ", "Type", "" ], "path": "packages/kbn-securitysolution-io-ts-types/src/time_duration/index.ts", "deprecated": false, "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/securitysolution-io-ts-types", + "id": "def-common.TimeDurationC.$1", + "type": "CompoundType", + "tags": [], + "label": "__0", + "description": [], + "signature": [ + "TimeDurationWithAllowedDurations | TimeDurationWithAllowedUnits" + ], + "path": "packages/kbn-securitysolution-io-ts-types/src/time_duration/index.ts", + "deprecated": false, + "trackAdoption": false + } + ], "initialIsOpen": false }, { @@ -1042,24 +1095,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "@kbn/securitysolution-io-ts-types", - "id": "def-common.TimeDuration", - "type": "Object", - "tags": [], - "label": "TimeDuration", - "description": [ - "\nTypes the TimeDuration as:\n - A string that is not empty, and composed of a positive integer greater than 0 followed by a unit of time\n - in the format {safe_integer}{timeUnit}, e.g. \"30s\", \"1m\", \"2h\"" - ], - "signature": [ - "Type", - "" - ], - "path": "packages/kbn-securitysolution-io-ts-types/src/time_duration/index.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "@kbn/securitysolution-io-ts-types", "id": "def-common.UUID", diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index f2220252df9f4..2525d36a83930 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 63 | 0 | 33 | 0 | +| 65 | 0 | 36 | 0 | ## Common diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 4ddd805beceec..1729eb1e31923 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 837b102f35b7c..e7ea35711a930 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 5e117e7fdd5ff..061d996305ac9 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index a0d87f4a94bbb..19a2ed45a48ba 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index a42cbdfe87318..247718cc1d2a7 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index c978507107c7d..53f33ec3d564b 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index d7cd694497c7f..0be9d3e0886f9 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index c6c4f053e9525..b3d353cc6987e 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index fc18c7757d1d9..aefc65e7066a3 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 2c9d51b468868..25cf89691a720 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 1a40ade046a8a..aaf7c6592481a 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 6d9064ab9d9ac..b12d28f86530e 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index e28b92febd738..4fafd24671035 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 3515b5ee35bf4..401b8763ce31c 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index ba2f64392e72c..25b21295a4ebd 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index 6942dcbd38fca..5867910e33d25 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index 69a6794fbccd5..757324760d8eb 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index a8465df7126e6..19d3fcf3f0acc 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 9e930a85deb81..f75c2846a0475 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index d96c9079cf5fd..89d4d761d558c 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index 86595fb7cfb1f..2056f2314bce9 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 9132796651764..495d91eac2545 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index e5b6a7845bbeb..7767a12066d24 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index 09f6ed5cf1fa0..e0d65073b737e 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index ef0e7d2b60bf3..8c798dd34a9a4 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index 43ef0de76bb28..243de44838e10 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index eecbe82f148c7..38664c4b62fdf 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index 001790b9086e2..3f237d268f073 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index 42efbc3a489cc..3ff43ae1b6263 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index 71404d9e00a6f..48e497a99004b 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index a24b3d7d985a9..15f626088ad23 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index b833764dfacbc..2e0d73cc43623 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index bf5525e9d8ea8..e9accf72f5a02 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index 16c867044187d..6309733dc1bab 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index ef2f54962c583..c770dd8671956 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 8fa73d4c68dad..4b531126964e6 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_package_json.mdx b/api_docs/kbn_sort_package_json.mdx index 8a049d4872b72..8073cadd73d80 100644 --- a/api_docs/kbn_sort_package_json.mdx +++ b/api_docs/kbn_sort_package_json.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-package-json title: "@kbn/sort-package-json" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-package-json plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-package-json'] --- import kbnSortPackageJsonObj from './kbn_sort_package_json.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index f1ba970a48042..c05c4d734c490 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 2ff62c2d04f35..660e36ef4374e 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index b77c7bfc44e93..93828baf05442 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index f81111a502799..fc2ed806bd5a7 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index eaf2d94c9a05d..fe8a35b282802 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 96f5d4d6ab2a7..b072b928a5fee 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index db3273ea8883f..2cc7dbb077e4d 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index fe4e9cade439f..4c380a6aada55 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer.mdx b/api_docs/kbn_type_summarizer.mdx index 9744d7e40941f..4658f66ec9f02 100644 --- a/api_docs/kbn_type_summarizer.mdx +++ b/api_docs/kbn_type_summarizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer title: "@kbn/type-summarizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer'] --- import kbnTypeSummarizerObj from './kbn_type_summarizer.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer_core.mdx b/api_docs/kbn_type_summarizer_core.mdx index 5bf8d7c641755..5c785be7541a2 100644 --- a/api_docs/kbn_type_summarizer_core.mdx +++ b/api_docs/kbn_type_summarizer_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer-core title: "@kbn/type-summarizer-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer-core plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer-core'] --- import kbnTypeSummarizerCoreObj from './kbn_type_summarizer_core.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 24144f46636bc..058bbf15a8534 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index fe7f2f02b8192..ffad848d71c2b 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 7855bb68d62db..b7a7e0d49898e 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index 5adb3b961a126..9c4fac9fc2223 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 879d594892e8b..a08a1f8c35b21 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 13a63d5a655f6..484f22d4d3fad 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 17c5bc67927ee..86360f220dc24 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 661dda80a0227..db2dd293c3e4b 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 3a54ee39d7116..a8b6bbd605637 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 62af983d79330..e8b72f7cee2d1 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index c101218ee3f45..fc9a2e294a610 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json index 4fc56c34842e9..4d4561547ed2a 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -1527,6 +1527,24 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "lens", + "id": "def-public.DatasourcePublicAPI.isTextBasedLanguage", + "type": "Function", + "tags": [], + "label": "isTextBasedLanguage", + "description": [ + "\nReturns true if this is a text based language datasource" + ], + "signature": [ + "() => boolean" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "lens", "id": "def-public.DatasourcePublicAPI.getFilters", @@ -11347,6 +11365,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "lens", + "id": "def-common.ENABLE_SQL", + "type": "string", + "tags": [], + "label": "ENABLE_SQL", + "description": [], + "signature": [ + "\"discover:enableSql\"" + ], + "path": "x-pack/plugins/lens/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "lens", "id": "def-common.FormatFactory", @@ -11495,6 +11528,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "lens", + "id": "def-common.OriginalColumn", + "type": "Type", + "tags": [], + "label": "OriginalColumn", + "description": [], + "signature": [ + "{ id: string; label: string; } & ({ operationType: \"date_histogram\"; sourceField: string; } | { operationType: string; sourceField: never; })" + ], + "path": "x-pack/plugins/lens/common/expressions/map_to_columns/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "lens", "id": "def-common.PieChartType", diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index e6eb90ca75ba8..75d2cd54a2d8b 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 646 | 0 | 558 | 42 | +| 649 | 0 | 560 | 42 | ## Client diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 745b2e56c1c9d..42f4d0805fc3c 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 3aa129254bb54..ca3e9e1a23c12 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index f4406dfe719d8..67cd87e28a5ce 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 6aa4f4f225193..c0fba6cbabbb7 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 92b5f7e806788..7a332ae0f68be 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 2e5da06f70dd9..c821d5118393a 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index a2dd183ea48bc..30e6fc5864b60 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 55b3f0eff7da0..83e81edff74a4 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index dbf1d15ca06df..8b27dbc3d7849 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index 16eb11d15bbf2..d0c0e4b930125 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index e9f3d869a2077..c8d4e9b1fbf7c 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 95e0ce94137e7..79f080105b7b9 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 7d399eaa890b1..d4d3483ef247c 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -3704,11 +3704,29 @@ "description": [], "signature": [ "{ get: (id: string) => ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, "; list: () => ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, "[]; register: (objectType: ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, ") => void; has: (id: string) => boolean; }" ], "path": "x-pack/plugins/observability/public/plugin.ts", diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index afdb6cd4fbb3c..4c2ca8b17a13f 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index a634c2e2206cc..942900853abdb 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 00a92aa5b8132..bcddc85faf5c2 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,13 +15,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 473 | 395 | 38 | +| 474 | 395 | 38 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 31772 | 179 | 21354 | 1002 | +| 31860 | 179 | 21432 | 1007 | ## Plugin Directory @@ -47,7 +47,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 103 | 0 | 84 | 1 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 144 | 0 | 139 | 10 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 52 | 0 | 51 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3211 | 33 | 2508 | 23 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3213 | 33 | 2509 | 23 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | This plugin provides the ability to create data views via a modal flyout inside Kibana apps | 15 | 0 | 7 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Reusable data view field editor across Kibana | 60 | 0 | 30 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data view management app | 2 | 0 | 2 | 0 | @@ -60,7 +60,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides encryption and decryption utilities for saved objects containing sensitive information. | 51 | 0 | 42 | 0 | | | [Enterprise Search](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 9 | 0 | 9 | 0 | -| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 114 | 3 | 110 | 3 | +| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 114 | 3 | 110 | 5 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | The Event Annotation service contains expressions for event annotations | 174 | 0 | 174 | 3 | | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 106 | 0 | 106 | 10 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'error' renderer to expressions | 17 | 0 | 15 | 2 | @@ -80,8 +80,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 222 | 0 | 95 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 5 | 249 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | -| | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 263 | 0 | 15 | 2 | -| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 988 | 3 | 888 | 17 | +| | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 263 | 0 | 14 | 2 | +| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 996 | 3 | 893 | 17 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | globalSearchProviders | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | @@ -101,7 +101,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | kibanaUsageCollection | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 0 | 0 | 0 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 615 | 3 | 418 | 9 | | | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 3 | 0 | 3 | 1 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 646 | 0 | 558 | 42 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 649 | 0 | 560 | 42 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 8 | 0 | 8 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 3 | 0 | 3 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | @@ -152,7 +152,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 452 | 1 | 346 | 33 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [Kibana Localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 437 | 1 | 416 | 45 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 513 | 1 | 486 | 48 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds UI Actions service to Kibana | 132 | 0 | 91 | 11 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 206 | 0 | 142 | 9 | | | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the field list which can be integrated into apps | 61 | 0 | 59 | 2 | @@ -389,9 +389,9 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Owner missing] | Security Solution auto complete | 56 | 1 | 41 | 1 | | | [Owner missing] | security solution elastic search utilities to use across plugins such lists, security_solution, cases, etc... | 67 | 0 | 61 | 1 | | | [Owner missing] | Security Solution utilities for React hooks | 15 | 0 | 7 | 0 | -| | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 148 | 0 | 129 | 0 | +| | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 145 | 0 | 127 | 0 | | | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 505 | 1 | 492 | 0 | -| | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 63 | 0 | 33 | 0 | +| | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 65 | 0 | 36 | 0 | | | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 28 | 0 | 21 | 0 | | | [Owner missing] | security solution list REST API | 67 | 0 | 64 | 0 | | | [Owner missing] | security solution list constants to use across plugins such lists, security_solution, cases, etc... | 33 | 0 | 17 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 971ed39aee0ed..191e4e563cb34 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 8d2be8c0f9dd7..fb048ac82442b 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 916ffb9e1e4e0..c0b505ed6394d 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index aa8b69de45190..4088e39f97108 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 7ecab5c862bf0..4f8cf9c8e8dbf 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 42e1a51c2ed9f..15c672f3f6fee 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 4c4a4a4be8d7f..001d245e9adf3 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index d180b9df678f8..51bc9b36316c4 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index d8ee1bd800f99..3a6b9b0a9e738 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index a57ba63fec003..8fb7925eb7808 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 785d7f8ea6a32..9a0469a70f642 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index bf65a9aa5c648..8abc78f1fdc7e 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index 5e294d8d6ea59..a39c3adbc8200 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 4c436c7b23e66..6eaf962f670fa 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 5bc1fcd058003..8cb0692d0c854 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 952c20eac620f..e6f2900462223 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 9cf5459a07a3e..c59c106fce254 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 23f8e18b5e278..ad4253bd0d7e5 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 7ba452349a66b..e6f9de45dbb58 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 194b818f081bf..8a45ec4089ad2 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 95118ea8b8058..94f8821728343 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index b3467e6a698dc..cb3df93effb09 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index aabbd1805b61d..a71b61831fb69 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index d35966ac57c9c..b84502a5d8c55 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index 1dbef1ee43f39..dfdbd20746f57 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 438e8d307b1de..edb998b57d6f5 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index f032f6eee5e0a..c23dd99eb95e3 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 0b1523b1a10d3..5e8ae624dfe82 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index b584556618afe..80ac38a8ed990 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 14ef93c594cc2..ecb0a115ea511 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index b66dc03b52acd..70b733e2c869e 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index 59be983bb00f5..316d5941b9d23 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -303,6 +303,38 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ButtonGroupField", + "type": "Function", + "tags": [], + "label": "ButtonGroupField", + "description": [], + "signature": [ + "React.NamedExoticComponent" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/button_group_field.tsx", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ButtonGroupField.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.CreateConnectorFlyout", @@ -832,6 +864,145 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.hasMustacheTokens", + "type": "Function", + "tags": [], + "label": "hasMustacheTokens", + "description": [], + "signature": [ + "(str: string) => boolean" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/has_mustache_tokens.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.hasMustacheTokens.$1", + "type": "string", + "tags": [], + "label": "str", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/has_mustache_tokens.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.HiddenField", + "type": "Function", + "tags": [], + "label": "HiddenField", + "description": [], + "signature": [ + "React.NamedExoticComponent<", + "Props", + "> & { readonly type: (props: ", + "Props", + ") => JSX.Element; }" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/hidden_field.tsx", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.HiddenField.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.JsonEditorWithMessageVariables", + "type": "Function", + "tags": [], + "label": "JsonEditorWithMessageVariables", + "description": [], + "signature": [ + "({ buttonTitle, messageVariables, paramsProperty, inputTargetValue, label, errors, areaLabel, onDocumentsChange, helpText, onBlur, showButtonTitle, euiCodeEditorProps, }: React.PropsWithChildren) => JSX.Element" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.JsonEditorWithMessageVariables.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n buttonTitle,\n messageVariables,\n paramsProperty,\n inputTargetValue,\n label,\n errors,\n areaLabel,\n onDocumentsChange,\n helpText,\n onBlur,\n showButtonTitle,\n euiCodeEditorProps = {},\n}", + "description": [], + "signature": [ + "React.PropsWithChildren" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/json_editor_with_message_variables.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.JsonFieldWrapper", + "type": "Function", + "tags": [], + "label": "JsonFieldWrapper", + "description": [], + "signature": [ + "({ field, ...rest }: Props) => JSX.Element" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/json_field_wrapper.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.JsonFieldWrapper.$1", + "type": "Object", + "tags": [], + "label": "{ field, ...rest }", + "description": [], + "signature": [ + "Props" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/json_field_wrapper.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.loadActionErrorLog", @@ -1398,6 +1569,39 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.MustacheTextFieldWrapper", + "type": "Function", + "tags": [], + "label": "MustacheTextFieldWrapper", + "description": [], + "signature": [ + "({ field, euiFieldProps, idAria, ...rest }: Props) => JSX.Element" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/mustache_text_field_wrapper.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.MustacheTextFieldWrapper.$1", + "type": "Object", + "tags": [], + "label": "{ field, euiFieldProps, idAria, ...rest }", + "description": [], + "signature": [ + "Props" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/mustache_text_field_wrapper.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.muteRule", @@ -1490,6 +1694,70 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.PasswordField", + "type": "Function", + "tags": [], + "label": "PasswordField", + "description": [], + "signature": [ + "React.NamedExoticComponent" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/password_field.tsx", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.PasswordField.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.SimpleConnectorForm", + "type": "Function", + "tags": [], + "label": "SimpleConnectorForm", + "description": [], + "signature": [ + "React.NamedExoticComponent" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/simple_connector_form.tsx", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.SimpleConnectorForm.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.snoozeRule", @@ -1614,72 +1882,185 @@ }, { "parentPluginId": "triggersActionsUi", - "id": "def-public.ThresholdExpression", + "id": "def-public.templateActionVariable", "type": "Function", "tags": [], - "label": "ThresholdExpression", + "label": "templateActionVariable", "description": [], "signature": [ - "(props: ", - "ThresholdExpressionProps", - ") => JSX.Element" + "(variable: ", + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.ActionVariable", + "text": "ActionVariable" + }, + ") => string" ], - "path": "x-pack/plugins/triggers_actions_ui/public/common/expression_items/index.ts", + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/template_action_variable.ts", "deprecated": false, "trackAdoption": false, - "returnComment": [], "children": [ { "parentPluginId": "triggersActionsUi", - "id": "def-public.ThresholdExpression.$1", - "type": "Uncategorized", + "id": "def-public.templateActionVariable.$1", + "type": "Object", "tags": [], - "label": "props", + "label": "variable", "description": [], "signature": [ - "T" + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.ActionVariable", + "text": "ActionVariable" + } ], - "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/suspended_component_with_props.tsx", + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/template_action_variable.ts", "deprecated": false, - "trackAdoption": false + "trackAdoption": false, + "isRequired": true } ], + "returnComment": [], "initialIsOpen": false }, { "parentPluginId": "triggersActionsUi", - "id": "def-public.unmuteRule", + "id": "def-public.TextAreaWithMessageVariables", "type": "Function", "tags": [], - "label": "unmuteRule", + "label": "TextAreaWithMessageVariables", "description": [], "signature": [ - "({ id, http }: { id: string; http: ", - "HttpSetup", - "; }) => Promise" + "({ messageVariables, paramsProperty, index, inputTargetValue, isDisabled, editAction, label, errors, }: React.PropsWithChildren) => JSX.Element" ], - "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unmute.ts", + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_message_variables.tsx", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "triggersActionsUi", - "id": "def-public.unmuteRule.$1", - "type": "Object", + "id": "def-public.TextAreaWithMessageVariables.$1", + "type": "CompoundType", "tags": [], - "label": "{ id, http }", + "label": "{\n messageVariables,\n paramsProperty,\n index,\n inputTargetValue,\n isDisabled = false,\n editAction,\n label,\n errors,\n}", "description": [], - "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unmute.ts", + "signature": [ + "React.PropsWithChildren" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_message_variables.tsx", "deprecated": false, "trackAdoption": false, - "children": [ - { - "parentPluginId": "triggersActionsUi", - "id": "def-public.unmuteRule.$1.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.TextFieldWithMessageVariables", + "type": "Function", + "tags": [], + "label": "TextFieldWithMessageVariables", + "description": [], + "signature": [ + "({ buttonTitle, messageVariables, paramsProperty, index, inputTargetValue, editAction, errors, formRowProps, defaultValue, wrapField, showButtonTitle, }: React.PropsWithChildren) => JSX.Element" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/text_field_with_message_variables.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.TextFieldWithMessageVariables.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n buttonTitle,\n messageVariables,\n paramsProperty,\n index,\n inputTargetValue,\n editAction,\n errors,\n formRowProps,\n defaultValue,\n wrapField = false,\n showButtonTitle,\n}", + "description": [], + "signature": [ + "React.PropsWithChildren" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/text_field_with_message_variables.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ThresholdExpression", + "type": "Function", + "tags": [], + "label": "ThresholdExpression", + "description": [], + "signature": [ + "(props: ", + "ThresholdExpressionProps", + ") => JSX.Element" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/common/expression_items/index.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ThresholdExpression.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "T" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/suspended_component_with_props.tsx", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.unmuteRule", + "type": "Function", + "tags": [], + "label": "unmuteRule", + "description": [], + "signature": [ + "({ id, http }: { id: string; http: ", + "HttpSetup", + "; }) => Promise" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unmute.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.unmuteRule.$1", + "type": "Object", + "tags": [], + "label": "{ id, http }", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unmute.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.unmuteRule.$1.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unmute.ts", "deprecated": false, "trackAdoption": false @@ -1776,6 +2157,106 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.updateActionConnector", + "type": "Function", + "tags": [], + "label": "updateActionConnector", + "description": [], + "signature": [ + "({\n http,\n connector,\n id,\n}: { http: ", + "HttpSetup", + "; connector: Pick<", + "ActionConnectorWithoutId", + ", Record>, \"name\" | \"config\" | \"secrets\">; id: string; }) => Promise<", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionConnector", + "text": "ActionConnector" + }, + ", Record>>" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.updateActionConnector.$1", + "type": "Object", + "tags": [], + "label": "{\n http,\n connector,\n id,\n}", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.updateActionConnector.$1.http", + "type": "Object", + "tags": [], + "label": "http", + "description": [], + "signature": [ + "HttpSetup" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.updateActionConnector.$1.connector", + "type": "Object", + "tags": [], + "label": "connector", + "description": [], + "signature": [ + "{ name: string; config: Record; secrets: Record; }" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.updateActionConnector.$1.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/update.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.useConnectorContext", + "type": "Function", + "tags": [], + "label": "useConnectorContext", + "description": [], + "signature": [ + "() => ", + "ConnectorContextValue" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/context/use_connector_context.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.useLoadRuleTypes", @@ -1819,6 +2300,41 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.useTypedKibana", + "type": "Function", + "tags": [], + "label": "useTypedKibana", + "description": [], + "signature": [ + "() => ", + { + "pluginId": "kibanaReact", + "scope": "public", + "docId": "kibKibanaReactPluginApi", + "section": "def-public.KibanaReactContextValue", + "text": "KibanaReactContextValue" + }, + " & ", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.TriggersAndActionsUiServices", + "text": "TriggersAndActionsUiServices" + }, + ">" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/kibana/kibana_react.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.ValueExpression", @@ -1891,95 +2407,651 @@ "interfaces": [ { "parentPluginId": "triggersActionsUi", - "id": "def-public.ActionType", + "id": "def-public.ActionConnectorFieldsProps", "type": "Interface", "tags": [], - "label": "ActionType", + "label": "ActionConnectorFieldsProps", "description": [], - "path": "x-pack/plugins/actions/common/types.ts", + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "triggersActionsUi", - "id": "def-public.ActionType.id", - "type": "string", + "id": "def-public.ActionConnectorFieldsProps.readOnly", + "type": "boolean", "tags": [], - "label": "id", + "label": "readOnly", "description": [], - "path": "x-pack/plugins/actions/common/types.ts", + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "triggersActionsUi", - "id": "def-public.ActionType.name", - "type": "string", + "id": "def-public.ActionConnectorFieldsProps.isEdit", + "type": "boolean", "tags": [], - "label": "name", + "label": "isEdit", "description": [], - "path": "x-pack/plugins/actions/common/types.ts", + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "triggersActionsUi", - "id": "def-public.ActionType.enabled", - "type": "boolean", + "id": "def-public.ActionConnectorFieldsProps.registerPreSubmitValidator", + "type": "Function", "tags": [], - "label": "enabled", + "label": "registerPreSubmitValidator", "description": [], - "path": "x-pack/plugins/actions/common/types.ts", + "signature": [ + "(validator: ", + "ConnectorValidationFunc", + ") => void" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, - "trackAdoption": false - }, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionConnectorFieldsProps.registerPreSubmitValidator.$1", + "type": "Function", + "tags": [], + "label": "validator", + "description": [], + "signature": [ + "ConnectorValidationFunc" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps", + "type": "Interface", + "tags": [], + "label": "ActionParamsProps", + "description": [], + "signature": [ { - "parentPluginId": "triggersActionsUi", - "id": "def-public.ActionType.enabledInConfig", - "type": "boolean", + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionParamsProps", + "text": "ActionParamsProps" + }, + "" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.actionParams", + "type": "Object", + "tags": [], + "label": "actionParams", + "description": [], + "signature": [ + "{ [P in keyof TParams]?: TParams[P] | undefined; }" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.index", + "type": "number", + "tags": [], + "label": "index", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.editAction", + "type": "Function", + "tags": [], + "label": "editAction", + "description": [], + "signature": [ + "(key: string, value: ", + "SavedObjectAttribute", + ", index: number) => void" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.editAction.$1", + "type": "string", + "tags": [], + "label": "key", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.editAction.$2", + "type": "CompoundType", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "SavedObjectAttribute" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.editAction.$3", + "type": "number", + "tags": [], + "label": "index", + "description": [], + "signature": [ + "number" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.errors", + "type": "Object", + "tags": [], + "label": "errors", + "description": [], + "signature": [ + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.IErrorObject", + "text": "IErrorObject" + } + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.messageVariables", + "type": "Array", + "tags": [], + "label": "messageVariables", + "description": [], + "signature": [ + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.ActionVariable", + "text": "ActionVariable" + }, + "[] | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.defaultMessage", + "type": "string", + "tags": [], + "label": "defaultMessage", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.actionConnector", + "type": "CompoundType", + "tags": [], + "label": "actionConnector", + "description": [], + "signature": [ + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionConnector", + "text": "ActionConnector" + }, + ", Record> | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.isLoading", + "type": "CompoundType", + "tags": [], + "label": "isLoading", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.isDisabled", + "type": "CompoundType", + "tags": [], + "label": "isDisabled", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionParamsProps.showEmailSubjectAndMessage", + "type": "CompoundType", + "tags": [], + "label": "showEmailSubjectAndMessage", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionType", + "type": "Interface", + "tags": [], + "label": "ActionType", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionType.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionType.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionType.enabled", + "type": "boolean", + "tags": [], + "label": "enabled", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionType.enabledInConfig", + "type": "boolean", + "tags": [], + "label": "enabledInConfig", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionType.enabledInLicense", + "type": "boolean", + "tags": [], + "label": "enabledInLicense", + "description": [], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionType.minimumLicenseRequired", + "type": "CompoundType", + "tags": [], + "label": "minimumLicenseRequired", + "description": [], + "signature": [ + "\"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\"" + ], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionType.supportedFeatureIds", + "type": "Array", + "tags": [], + "label": "supportedFeatureIds", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/actions/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel", + "type": "Interface", + "tags": [], + "label": "ActionTypeModel", + "description": [], + "signature": [ + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, + "" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel.iconClass", + "type": "CompoundType", + "tags": [], + "label": "iconClass", + "description": [], + "signature": [ + "string | React.ComponentType<{}>" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel.selectMessage", + "type": "string", + "tags": [], + "label": "selectMessage", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel.actionTypeTitle", + "type": "string", + "tags": [], + "label": "actionTypeTitle", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel.validateParams", + "type": "Function", + "tags": [], + "label": "validateParams", + "description": [], + "signature": [ + "(actionParams: ActionParams) => Promise<", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.GenericValidationResult", + "text": "GenericValidationResult" + }, + ">" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel.validateParams.$1", + "type": "Uncategorized", + "tags": [], + "label": "actionParams", + "description": [], + "signature": [ + "ActionParams" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel.actionConnectorFields", + "type": "CompoundType", + "tags": [], + "label": "actionConnectorFields", + "description": [], + "signature": [ + "React.LazyExoticComponent> | null" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel.actionParamsFields", + "type": "Function", + "tags": [], + "label": "actionParamsFields", + "description": [], + "signature": [ + "React.ExoticComponent<(", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionParamsProps", + "text": "ActionParamsProps" + }, + " & React.RefAttributes, any, any>>) | (", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionParamsProps", + "text": "ActionParamsProps" + }, + " & { children?: React.ReactNode; })> & { readonly _result: React.ComponentType<", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionParamsProps", + "text": "ActionParamsProps" + }, + ">; }" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel.actionParamsFields.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ActionTypeModel.defaultActionParams", + "type": "Object", "tags": [], - "label": "enabledInConfig", + "label": "defaultActionParams", "description": [], - "path": "x-pack/plugins/actions/common/types.ts", + "signature": [ + "Partial | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "triggersActionsUi", - "id": "def-public.ActionType.enabledInLicense", - "type": "boolean", + "id": "def-public.ActionTypeModel.defaultRecoveredActionParams", + "type": "Object", "tags": [], - "label": "enabledInLicense", + "label": "defaultRecoveredActionParams", "description": [], - "path": "x-pack/plugins/actions/common/types.ts", + "signature": [ + "Partial | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "triggersActionsUi", - "id": "def-public.ActionType.minimumLicenseRequired", - "type": "CompoundType", + "id": "def-public.ActionTypeModel.customConnectorSelectItem", + "type": "Object", "tags": [], - "label": "minimumLicenseRequired", + "label": "customConnectorSelectItem", "description": [], "signature": [ - "\"basic\" | \"standard\" | \"gold\" | \"platinum\" | \"enterprise\" | \"trial\"" + "CustomConnectorSelectionItem | undefined" ], - "path": "x-pack/plugins/actions/common/types.ts", + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "triggersActionsUi", - "id": "def-public.ActionType.supportedFeatureIds", - "type": "Array", + "id": "def-public.ActionTypeModel.isExperimental", + "type": "CompoundType", "tags": [], - "label": "supportedFeatureIds", + "label": "isExperimental", "description": [], "signature": [ - "string[]" + "boolean | undefined" ], - "path": "x-pack/plugins/actions/common/types.ts", + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", "deprecated": false, "trackAdoption": false } @@ -2805,6 +3877,45 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ConfigFieldSchema", + "type": "Interface", + "tags": [], + "label": "ConfigFieldSchema", + "description": [], + "signature": [ + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ConfigFieldSchema", + "text": "ConfigFieldSchema" + }, + " extends ", + "CommonFieldSchema" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/simple_connector_form.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ConfigFieldSchema.isUrlField", + "type": "CompoundType", + "tags": [], + "label": "isUrlField", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/simple_connector_form.tsx", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.FieldBrowserOptions", @@ -3010,6 +4121,44 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.GenericValidationResult", + "type": "Interface", + "tags": [], + "label": "GenericValidationResult", + "description": [], + "signature": [ + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.GenericValidationResult", + "text": "GenericValidationResult" + }, + "" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.GenericValidationResult.errors", + "type": "Object", + "tags": [], + "label": "errors", + "description": [], + "signature": [ + "{ [P in Extract]: unknown; }" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.IErrorObject", @@ -3218,11 +4367,29 @@ "description": [], "signature": [ "{ get: (id: string) => ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, "; list: () => ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, "[]; register: (objectType: ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, ") => void; has: (id: string) => boolean; }" ], "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", @@ -4147,6 +5314,45 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.SecretsFieldSchema", + "type": "Interface", + "tags": [], + "label": "SecretsFieldSchema", + "description": [], + "signature": [ + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.SecretsFieldSchema", + "text": "SecretsFieldSchema" + }, + " extends ", + "CommonFieldSchema" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/simple_connector_form.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.SecretsFieldSchema.isPasswordField", + "type": "CompoundType", + "tags": [], + "label": "isPasswordField", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/components/simple_connector_form.tsx", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.TriggersAndActionsUiServices", @@ -4390,11 +5596,29 @@ "description": [], "signature": [ "{ get: (id: string) => ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, "; list: () => ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, "[]; register: (objectType: ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, ") => void; has: (id: string) => boolean; }" ], "path": "x-pack/plugins/triggers_actions_ui/public/application/app.tsx", @@ -4603,6 +5827,18 @@ } ], "enums": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertProvidedActionVariables", + "type": "Enum", + "tags": [], + "label": "AlertProvidedActionVariables", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_variables.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.COMPARATORS", @@ -4690,11 +5926,29 @@ "description": [], "signature": [ "{ get: (id: string) => ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, "; list: () => ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, "[]; register: (objectType: ", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, ") => void; has: (id: string) => boolean; }" ], "path": "x-pack/plugins/triggers_actions_ui/public/types.ts", @@ -4717,6 +5971,63 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ALERT_HISTORY_PREFIX", + "type": "string", + "tags": [], + "label": "ALERT_HISTORY_PREFIX", + "description": [], + "signature": [ + "\"kibana-alert-history-\"" + ], + "path": "x-pack/plugins/actions/common/alert_history_schema.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertHistoryDefaultIndexName", + "type": "string", + "tags": [], + "label": "AlertHistoryDefaultIndexName", + "description": [], + "path": "x-pack/plugins/actions/common/alert_history_schema.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertHistoryDocumentTemplate", + "type": "CompoundType", + "tags": [], + "label": "AlertHistoryDocumentTemplate", + "description": [], + "signature": [ + "Readonly<{ event: { kind: string; }; kibana?: { alert: { actionGroupName?: string | undefined; actionGroup?: string | undefined; context?: { [x: string]: Record; } | undefined; id?: string | undefined; }; } | undefined; rule?: { type?: string | undefined; space?: string | undefined; params?: { [x: string]: Record; } | undefined; name?: string | undefined; id?: string | undefined; } | undefined; message?: unknown; tags?: string[] | undefined; '@timestamp': string; }> | null" + ], + "path": "x-pack/plugins/actions/common/alert_history_schema.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.AlertHistoryEsIndexConnectorId", + "type": "string", + "tags": [], + "label": "AlertHistoryEsIndexConnectorId", + "description": [], + "signature": [ + "\"preconfigured-alert-history-es-index\"" + ], + "path": "x-pack/plugins/actions/common/alert_history_schema.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.AlertsTableConfigurationRegistryContract", @@ -4784,6 +6095,51 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.connectorDeprecatedMessage", + "type": "string", + "tags": [], + "label": "connectorDeprecatedMessage", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/common/connectors_selection.tsx", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.ConnectorFormSchema", + "type": "Type", + "tags": [], + "label": "ConnectorFormSchema", + "description": [ + "\nThe following type is equivalent to:\n\ninterface ConnectorFormSchema {\n id?: string,\n name?: string,\n actionTypeId: string,\n isDeprecated: boolean,\n config: Config,\n secrets: Secrets,\n}" + ], + "signature": [ + "Pick<", + "UserConfiguredActionConnector", + ", \"config\" | \"secrets\" | \"actionTypeId\" | \"isDeprecated\"> & Partial, \"name\" | \"id\">>" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.deprecatedMessage", + "type": "string", + "tags": [], + "label": "deprecatedMessage", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/common/connectors_selection.tsx", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.GetRenderCellValue", @@ -5801,7 +7157,13 @@ "signature": [ "TypeRegistry", "<", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, ">" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", @@ -5873,7 +7235,13 @@ "signature": [ "TypeRegistry", "<", - "ActionTypeModel", + { + "pluginId": "triggersActionsUi", + "scope": "public", + "docId": "kibTriggersActionsUiPluginApi", + "section": "def-public.ActionTypeModel", + "text": "ActionTypeModel" + }, ">" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 0a3cbb630285f..cfa8f8965332e 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 437 | 1 | 416 | 45 | +| 513 | 1 | 486 | 48 | ## Client diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 2a01df283087a..25fd9d32aac51 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index f46cdf9d62ee1..f85563ce18a73 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_field_list.mdx b/api_docs/unified_field_list.mdx index f70e303ebe4d7..2aae0fbddf27b 100644 --- a/api_docs/unified_field_list.mdx +++ b/api_docs/unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedFieldList title: "unifiedFieldList" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedFieldList plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedFieldList'] --- import unifiedFieldListObj from './unified_field_list.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 2e10e0a54e2cd..261ef25b80e9b 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 18b782fa7081b..1e75d7da1deb9 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 7a9ded502796d..d2cdaf4d89c84 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index 34bbb721a3728..5f6baf6d86c5f 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index c3afd8d86827c..470423b8266a7 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 271d79629a0b7..ff57731114146 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index f28ab39c716fb..1da13d1fcc094 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index 32a96558c72f8..d30f1b6a560aa 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 827eb1f6f0969..f8d894bdaa7de 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index d9fc5b663679c..deb819de77df3 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index e8dfbf76d6ffa..042fb74b10af4 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index c962200fe1fdc..2458fbb4d9dee 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index abe648760bf12..606b4dcf05e16 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 4260c1aaeb253..e56cd5d8f509d 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index f03c9b37afbb4..9ac63dfe30ccc 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index c4ea2e6c61e76..e5907aaf8a8a5 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2022-09-27 +date: 2022-09-28 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; diff --git a/docs/user/alerting/alerting-setup.asciidoc b/docs/user/alerting/alerting-setup.asciidoc index 819f20005d7a4..36c8b46e7b801 100644 --- a/docs/user/alerting/alerting-setup.asciidoc +++ b/docs/user/alerting/alerting-setup.asciidoc @@ -98,3 +98,10 @@ user without those privileges updates the rule, the rule will no longer function. Conversely, if a user with greater or administrator privileges modifies the rule, it will begin running with increased privileges. ============================================== + +[float] +[[alerting-ccs-setup]] +=== {ccs-cap} + +If you want to use alerting rules with {ccs}, you must configure +{ref}/remote-clusters-privileges.html#clusters-privileges-ccs-kibana[privileges for {ccs-init} and {kib}]. \ No newline at end of file diff --git a/docs/user/reporting/script-example.asciidoc b/docs/user/reporting/script-example.asciidoc index 1d8e824798e75..937e140bd67a0 100644 --- a/docs/user/reporting/script-example.asciidoc +++ b/docs/user/reporting/script-example.asciidoc @@ -3,7 +3,7 @@ URL that you use to download the report. Use the `GET` method in the HTTP reques To queue CSV report generation using the `POST` URL with cURL: -["source","sh",subs="attributes"] +[source,curl] --------------------------------------------------------- curl \ -XPOST \ <1> @@ -11,7 +11,6 @@ curl \ -H 'kbn-xsrf: true' \ <3> 'http://0.0.0.0:5601/api/reporting/generate/csv?jobParams=...' <4> --------------------------------------------------------- -// CONSOLE <1> The required `POST` method. <2> The user credentials for a user with permission to access {kib} and {report-features}. @@ -20,7 +19,7 @@ curl \ An example response for a successfully queued report: -[source,json] +[source,js] --------------------------------------------------------- { "path": "/api/reporting/jobs/download/jxzaofkc0ykpf4062305t068", <1> @@ -35,7 +34,6 @@ An example response for a successfully queued report: } } --------------------------------------------------------- -// CONSOLE <1> The relative path on the {kib} host for downloading the report. <2> (Not included in the example) Internal representation of the reporting job, as found in the `.reporting-*` index. diff --git a/fleet_packages.json b/fleet_packages.json index c4a7f87127f10..4651e86287588 100644 --- a/fleet_packages.json +++ b/fleet_packages.json @@ -20,7 +20,7 @@ [ { "name": "apm", - "version": "8.4.0", + "version": "8.6.0-preview-1663775281", "forceAlignStackVersion": true }, { @@ -29,7 +29,7 @@ }, { "name": "endpoint", - "version": "8.4.1" + "version": "8.5.0" }, { "name": "fleet_server", @@ -39,4 +39,4 @@ "name": "synthetics", "version": "0.10.2" } -] +] \ No newline at end of file diff --git a/package.json b/package.json index 6c0913394e246..ebbff20d91733 100644 --- a/package.json +++ b/package.json @@ -213,6 +213,8 @@ "@kbn/core-http-common": "link:bazel-bin/packages/core/http/core-http-common", "@kbn/core-http-context-server-internal": "link:bazel-bin/packages/core/http/core-http-context-server-internal", "@kbn/core-http-context-server-mocks": "link:bazel-bin/packages/core/http/core-http-context-server-mocks", + "@kbn/core-http-request-handler-context-server": "link:bazel-bin/packages/core/http/core-http-request-handler-context-server", + "@kbn/core-http-request-handler-context-server-internal": "link:bazel-bin/packages/core/http/core-http-request-handler-context-server-internal", "@kbn/core-http-router-server-internal": "link:bazel-bin/packages/core/http/core-http-router-server-internal", "@kbn/core-http-router-server-mocks": "link:bazel-bin/packages/core/http/core-http-router-server-mocks", "@kbn/core-http-server": "link:bazel-bin/packages/core/http/core-http-server", @@ -934,6 +936,8 @@ "@types/kbn__core-http-common": "link:bazel-bin/packages/core/http/core-http-common/npm_module_types", "@types/kbn__core-http-context-server-internal": "link:bazel-bin/packages/core/http/core-http-context-server-internal/npm_module_types", "@types/kbn__core-http-context-server-mocks": "link:bazel-bin/packages/core/http/core-http-context-server-mocks/npm_module_types", + "@types/kbn__core-http-request-handler-context-server": "link:bazel-bin/packages/core/http/core-http-request-handler-context-server/npm_module_types", + "@types/kbn__core-http-request-handler-context-server-internal": "link:bazel-bin/packages/core/http/core-http-request-handler-context-server-internal/npm_module_types", "@types/kbn__core-http-router-server-internal": "link:bazel-bin/packages/core/http/core-http-router-server-internal/npm_module_types", "@types/kbn__core-http-router-server-mocks": "link:bazel-bin/packages/core/http/core-http-router-server-mocks/npm_module_types", "@types/kbn__core-http-server": "link:bazel-bin/packages/core/http/core-http-server/npm_module_types", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 62cc4b4ce9ad2..455b851a4936f 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -79,6 +79,8 @@ filegroup( "//packages/core/http/core-http-common:build", "//packages/core/http/core-http-context-server-internal:build", "//packages/core/http/core-http-context-server-mocks:build", + "//packages/core/http/core-http-request-handler-context-server:build", + "//packages/core/http/core-http-request-handler-context-server-internal:build", "//packages/core/http/core-http-router-server-internal:build", "//packages/core/http/core-http-router-server-mocks:build", "//packages/core/http/core-http-server:build", @@ -410,6 +412,8 @@ filegroup( "//packages/core/http/core-http-common:build_types", "//packages/core/http/core-http-context-server-internal:build_types", "//packages/core/http/core-http-context-server-mocks:build_types", + "//packages/core/http/core-http-request-handler-context-server:build_types", + "//packages/core/http/core-http-request-handler-context-server-internal:build_types", "//packages/core/http/core-http-router-server-internal:build_types", "//packages/core/http/core-http-router-server-mocks:build_types", "//packages/core/http/core-http-server:build_types", diff --git a/packages/core/http/core-http-request-handler-context-server-internal/BUILD.bazel b/packages/core/http/core-http-request-handler-context-server-internal/BUILD.bazel new file mode 100644 index 0000000000000..82040b5fb1ad8 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/BUILD.bazel @@ -0,0 +1,116 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-http-request-handler-context-server-internal" +PKG_REQUIRE_NAME = "@kbn/core-http-request-handler-context-server-internal" + +SOURCE_FILES = glob( + [ + "**/*.ts", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__/**", + "**/integration_tests/**", + "**/mocks/**", + "**/scripts/**", + "**/storybook/**", + "**/test_fixtures/**", + "**/test_helpers/**", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ + "//packages/core/elasticsearch/core-elasticsearch-server-internal", + "//packages/core/saved-objects/core-saved-objects-server-internal", + "//packages/core/deprecations/core-deprecations-server-internal", + "//packages/core/ui-settings/core-ui-settings-server-internal", +] + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "//packages/core/http/core-http-server:npm_module_types", + "//packages/core/http/core-http-request-handler-context-server:npm_module_types", + "//packages/core/elasticsearch/core-elasticsearch-server-internal:npm_module_types", + "//packages/core/saved-objects/core-saved-objects-server-internal:npm_module_types", + "//packages/core/deprecations/core-deprecations-server-internal:npm_module_types", + "//packages/core/ui-settings/core-ui-settings-server:npm_module_types", + "//packages/core/ui-settings/core-ui-settings-server-internal:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/http/core-http-request-handler-context-server-internal/README.md b/packages/core/http/core-http-request-handler-context-server-internal/README.md new file mode 100644 index 0000000000000..aa27c116c4f6d --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/README.md @@ -0,0 +1,3 @@ +# @kbn/core-http-request-handler-context-server-internal + +This package contains the internal types and implementation of Core's `CoreRequestHandlerContext` diff --git a/packages/core/http/core-http-request-handler-context-server-internal/index.ts b/packages/core/http/core-http-request-handler-context-server-internal/index.ts new file mode 100644 index 0000000000000..2ee514f67265b --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { CoreRouteHandlerContext, PrebootCoreRouteHandlerContext } from './src'; +export type { CoreRouteHandlerContextParams, PrebootCoreRouteHandlerContextParams } from './src'; diff --git a/packages/core/http/core-http-request-handler-context-server-internal/jest.config.js b/packages/core/http/core-http-request-handler-context-server-internal/jest.config.js new file mode 100644 index 0000000000000..68a5f2b3a03a8 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../../../..', + roots: ['/packages/core/http/core-http-request-handler-context-server-internal'], +}; diff --git a/packages/core/http/core-http-request-handler-context-server-internal/kibana.jsonc b/packages/core/http/core-http-request-handler-context-server-internal/kibana.jsonc new file mode 100644 index 0000000000000..98b452aec0d97 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/kibana.jsonc @@ -0,0 +1,7 @@ +{ + "type": "shared-common", + "id": "@kbn/core-http-request-handler-context-server-internal", + "owner": "@elastic/kibana-core", + "runtimeDeps": [], + "typeDeps": [], +} diff --git a/packages/core/http/core-http-request-handler-context-server-internal/package.json b/packages/core/http/core-http-request-handler-context-server-internal/package.json new file mode 100644 index 0000000000000..672bb6ce72715 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/core-http-request-handler-context-server-internal", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "author": "Kibana Core", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/src/core/server/core_route_handler_context.test.ts b/packages/core/http/core-http-request-handler-context-server-internal/src/core_route_handler_context.test.ts similarity index 86% rename from src/core/server/core_route_handler_context.test.ts rename to packages/core/http/core-http-request-handler-context-server-internal/src/core_route_handler_context.test.ts index ace0144eae54f..f8e906650fcf1 100644 --- a/src/core/server/core_route_handler_context.test.ts +++ b/packages/core/http/core-http-request-handler-context-server-internal/src/core_route_handler_context.test.ts @@ -7,13 +7,14 @@ */ import { CoreRouteHandlerContext } from './core_route_handler_context'; -import { coreMock, httpServerMock } from './mocks'; +import { httpServerMock } from '@kbn/core-http-server-mocks'; +import { createCoreRouteHandlerContextParamsMock } from './test_helpers'; describe('#elasticsearch', () => { describe('#client', () => { test('returns the results of coreStart.elasticsearch.client.asScoped', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const client = context.elasticsearch.client; @@ -22,7 +23,7 @@ describe('#elasticsearch', () => { test('lazily created', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); expect(coreStart.elasticsearch.client.asScoped).not.toHaveBeenCalled(); @@ -33,7 +34,7 @@ describe('#elasticsearch', () => { test('only creates one instance', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const client1 = context.elasticsearch.client; @@ -50,7 +51,7 @@ describe('#savedObjects', () => { describe('#client', () => { test('returns the results of coreStart.savedObjects.getScopedClient', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const client = context.savedObjects.client; @@ -59,7 +60,7 @@ describe('#savedObjects', () => { test('lazily created', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const savedObjects = context.savedObjects; @@ -71,7 +72,7 @@ describe('#savedObjects', () => { test('only creates one instance', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const client1 = context.savedObjects.client; @@ -86,7 +87,7 @@ describe('#savedObjects', () => { describe('#typeRegistry', () => { test('returns the results of coreStart.savedObjects.getTypeRegistry', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const typeRegistry = context.savedObjects.typeRegistry; @@ -95,7 +96,7 @@ describe('#savedObjects', () => { test('lazily created', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); expect(coreStart.savedObjects.getTypeRegistry).not.toHaveBeenCalled(); @@ -106,7 +107,7 @@ describe('#savedObjects', () => { test('only creates one instance', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const typeRegistry1 = context.savedObjects.typeRegistry; @@ -123,7 +124,7 @@ describe('#uiSettings', () => { describe('#client', () => { test('returns the results of coreStart.uiSettings.asScopedToClient', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const client = context.uiSettings.client; @@ -132,7 +133,7 @@ describe('#uiSettings', () => { test('lazily created', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); expect(coreStart.uiSettings.asScopedToClient).not.toHaveBeenCalled(); @@ -143,7 +144,7 @@ describe('#uiSettings', () => { test('only creates one instance', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const client1 = context.uiSettings.client; @@ -160,7 +161,7 @@ describe('#deprecations', () => { describe('#client', () => { test('returns the results of coreStart.deprecations.asScopedToClient', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const client = context.deprecations.client; @@ -169,7 +170,7 @@ describe('#deprecations', () => { test('lazily created', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); expect(coreStart.deprecations.asScopedToClient).not.toHaveBeenCalled(); @@ -180,7 +181,7 @@ describe('#deprecations', () => { test('only creates one instance', () => { const request = httpServerMock.createKibanaRequest(); - const coreStart = coreMock.createInternalStart(); + const coreStart = createCoreRouteHandlerContextParamsMock(); const context = new CoreRouteHandlerContext(coreStart, request); const client1 = context.deprecations.client; diff --git a/packages/core/http/core-http-request-handler-context-server-internal/src/core_route_handler_context.ts b/packages/core/http/core-http-request-handler-context-server-internal/src/core_route_handler_context.ts new file mode 100644 index 0000000000000..6cc54130a575c --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/src/core_route_handler_context.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { KibanaRequest } from '@kbn/core-http-server'; +import type { CoreRequestHandlerContext } from '@kbn/core-http-request-handler-context-server'; +import { + CoreElasticsearchRouteHandlerContext, + type InternalElasticsearchServiceStart, +} from '@kbn/core-elasticsearch-server-internal'; +import { + CoreSavedObjectsRouteHandlerContext, + type InternalSavedObjectsServiceStart, +} from '@kbn/core-saved-objects-server-internal'; +import { + CoreDeprecationsRouteHandlerContext, + type InternalDeprecationsServiceStart, +} from '@kbn/core-deprecations-server-internal'; +import { + CoreUiSettingsRouteHandlerContext, + type InternalUiSettingsServiceStart, +} from '@kbn/core-ui-settings-server-internal'; + +/** + * Subset of `InternalCoreStart` used by {@link CoreRouteHandlerContext} + * @internal + */ +export interface CoreRouteHandlerContextParams { + elasticsearch: InternalElasticsearchServiceStart; + savedObjects: InternalSavedObjectsServiceStart; + uiSettings: InternalUiSettingsServiceStart; + deprecations: InternalDeprecationsServiceStart; +} + +/** + * The concrete implementation for Core's route handler context. + * + * @internal + */ +export class CoreRouteHandlerContext implements CoreRequestHandlerContext { + readonly elasticsearch: CoreElasticsearchRouteHandlerContext; + readonly savedObjects: CoreSavedObjectsRouteHandlerContext; + readonly uiSettings: CoreUiSettingsRouteHandlerContext; + readonly deprecations: CoreDeprecationsRouteHandlerContext; + + constructor(coreStart: CoreRouteHandlerContextParams, request: KibanaRequest) { + this.elasticsearch = new CoreElasticsearchRouteHandlerContext(coreStart.elasticsearch, request); + this.savedObjects = new CoreSavedObjectsRouteHandlerContext(coreStart.savedObjects, request); + this.uiSettings = new CoreUiSettingsRouteHandlerContext( + coreStart.uiSettings, + this.savedObjects + ); + this.deprecations = new CoreDeprecationsRouteHandlerContext( + coreStart.deprecations, + this.elasticsearch, + this.savedObjects + ); + } +} diff --git a/packages/core/http/core-http-request-handler-context-server-internal/src/index.ts b/packages/core/http/core-http-request-handler-context-server-internal/src/index.ts new file mode 100644 index 0000000000000..48d93f78b2a48 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/src/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { CoreRouteHandlerContext } from './core_route_handler_context'; +export type { CoreRouteHandlerContextParams } from './core_route_handler_context'; +export { PrebootCoreRouteHandlerContext } from './preboot_core_route_handler_context'; +export type { PrebootCoreRouteHandlerContextParams } from './preboot_core_route_handler_context'; diff --git a/src/core/server/preboot_core_route_handler_context.test.ts b/packages/core/http/core-http-request-handler-context-server-internal/src/preboot_core_route_handler_context.test.ts similarity index 85% rename from src/core/server/preboot_core_route_handler_context.test.ts rename to packages/core/http/core-http-request-handler-context-server-internal/src/preboot_core_route_handler_context.test.ts index 8d090d8644637..75bfc39bfdc9a 100644 --- a/src/core/server/preboot_core_route_handler_context.test.ts +++ b/packages/core/http/core-http-request-handler-context-server-internal/src/preboot_core_route_handler_context.test.ts @@ -7,12 +7,12 @@ */ import { PrebootCoreRouteHandlerContext } from './preboot_core_route_handler_context'; -import { coreMock } from './mocks'; +import { createPrebootCoreRouteHandlerContextParamsMock } from './test_helpers'; describe('#uiSettings', () => { describe('#client', () => { test('returns the results of corePreboot.uiSettings.createDefaultsClient', () => { - const corePreboot = coreMock.createInternalPreboot(); + const corePreboot = createPrebootCoreRouteHandlerContextParamsMock(); const context = new PrebootCoreRouteHandlerContext(corePreboot); const client = context.uiSettings.client; @@ -21,7 +21,7 @@ describe('#uiSettings', () => { }); test('only creates one instance', () => { - const corePreboot = coreMock.createInternalPreboot(); + const corePreboot = createPrebootCoreRouteHandlerContextParamsMock(); const context = new PrebootCoreRouteHandlerContext(corePreboot); const client1 = context.uiSettings.client; diff --git a/src/core/server/preboot_core_route_handler_context.ts b/packages/core/http/core-http-request-handler-context-server-internal/src/preboot_core_route_handler_context.ts similarity index 71% rename from src/core/server/preboot_core_route_handler_context.ts rename to packages/core/http/core-http-request-handler-context-server-internal/src/preboot_core_route_handler_context.ts index ec5ef594180d1..c0bf184d8c985 100644 --- a/src/core/server/preboot_core_route_handler_context.ts +++ b/packages/core/http/core-http-request-handler-context-server-internal/src/preboot_core_route_handler_context.ts @@ -8,13 +8,17 @@ // eslint-disable-next-line max-classes-per-file import type { IUiSettingsClient } from '@kbn/core-ui-settings-server'; -import type { InternalCorePreboot } from './internal_types'; +import type { + PrebootUiSettingsRequestHandlerContext, + PrebootCoreRequestHandlerContext, +} from '@kbn/core-http-request-handler-context-server'; +import type { InternalUiSettingsServicePreboot } from '@kbn/core-ui-settings-server-internal'; /** - * @public + * @internal */ -export interface PrebootUiSettingsRequestHandlerContext { - client: IUiSettingsClient; +export interface PrebootCoreRouteHandlerContextParams { + uiSettings: InternalUiSettingsServicePreboot; } /** @@ -25,13 +29,6 @@ class PrebootCoreUiSettingsRouteHandlerContext implements PrebootUiSettingsReque constructor(public readonly client: IUiSettingsClient) {} } -/** - * @public - */ -export interface PrebootCoreRequestHandlerContext { - uiSettings: PrebootUiSettingsRequestHandlerContext; -} - /** * Implementation of {@link PrebootCoreRequestHandlerContext}. * @internal @@ -39,7 +36,7 @@ export interface PrebootCoreRequestHandlerContext { export class PrebootCoreRouteHandlerContext implements PrebootCoreRequestHandlerContext { readonly uiSettings: PrebootUiSettingsRequestHandlerContext; - constructor(private readonly corePreboot: InternalCorePreboot) { + constructor(private readonly corePreboot: PrebootCoreRouteHandlerContextParams) { this.uiSettings = new PrebootCoreUiSettingsRouteHandlerContext( this.corePreboot.uiSettings.createDefaultsClient() ); diff --git a/packages/core/http/core-http-request-handler-context-server-internal/src/test_helpers/core_route_handler_context_params.mock.ts b/packages/core/http/core-http-request-handler-context-server-internal/src/test_helpers/core_route_handler_context_params.mock.ts new file mode 100644 index 0000000000000..eaf46eae3c8b6 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/src/test_helpers/core_route_handler_context_params.mock.ts @@ -0,0 +1,21 @@ +/* + * 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 { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks'; +import { savedObjectsServiceMock } from '@kbn/core-saved-objects-server-mocks'; +import { uiSettingsServiceMock } from '@kbn/core-ui-settings-server-mocks'; +import { deprecationsServiceMock } from '@kbn/core-deprecations-server-mocks'; + +export const createCoreRouteHandlerContextParamsMock = () => { + return { + elasticsearch: elasticsearchServiceMock.createInternalStart(), + savedObjects: savedObjectsServiceMock.createInternalStartContract(), + uiSettings: uiSettingsServiceMock.createStartContract(), + deprecations: deprecationsServiceMock.createInternalStartContract(), + }; +}; diff --git a/packages/core/http/core-http-request-handler-context-server-internal/src/test_helpers/index.ts b/packages/core/http/core-http-request-handler-context-server-internal/src/test_helpers/index.ts new file mode 100644 index 0000000000000..5556547d4602f --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/src/test_helpers/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { createCoreRouteHandlerContextParamsMock } from './core_route_handler_context_params.mock'; +export { createPrebootCoreRouteHandlerContextParamsMock } from './preboot_core_route_handler_context_params.mock'; diff --git a/packages/core/http/core-http-request-handler-context-server-internal/src/test_helpers/preboot_core_route_handler_context_params.mock.ts b/packages/core/http/core-http-request-handler-context-server-internal/src/test_helpers/preboot_core_route_handler_context_params.mock.ts new file mode 100644 index 0000000000000..dc4eab6b55672 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/src/test_helpers/preboot_core_route_handler_context_params.mock.ts @@ -0,0 +1,15 @@ +/* + * 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 { uiSettingsServiceMock } from '@kbn/core-ui-settings-server-mocks'; + +export const createPrebootCoreRouteHandlerContextParamsMock = () => { + return { + uiSettings: uiSettingsServiceMock.createPrebootContract(), + }; +}; diff --git a/packages/core/http/core-http-request-handler-context-server-internal/tsconfig.json b/packages/core/http/core-http-request-handler-context-server-internal/tsconfig.json new file mode 100644 index 0000000000000..71bb40fe57f3f --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server-internal/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "**/*.ts", + ] +} diff --git a/packages/core/http/core-http-request-handler-context-server/BUILD.bazel b/packages/core/http/core-http-request-handler-context-server/BUILD.bazel new file mode 100644 index 0000000000000..45c5ebc08776f --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server/BUILD.bazel @@ -0,0 +1,110 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-http-request-handler-context-server" +PKG_REQUIRE_NAME = "@kbn/core-http-request-handler-context-server" + +SOURCE_FILES = glob( + [ + "**/*.ts", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__/**", + "**/integration_tests/**", + "**/mocks/**", + "**/scripts/**", + "**/storybook/**", + "**/test_fixtures/**", + "**/test_helpers/**", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ +] + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "//packages/core/http/core-http-server:npm_module_types", + "//packages/core/elasticsearch/core-elasticsearch-server:npm_module_types", + "//packages/core/saved-objects/core-saved-objects-server:npm_module_types", + "//packages/core/deprecations/core-deprecations-server:npm_module_types", + "//packages/core/ui-settings/core-ui-settings-server:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/http/core-http-request-handler-context-server/README.md b/packages/core/http/core-http-request-handler-context-server/README.md new file mode 100644 index 0000000000000..b7b191f7345f3 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server/README.md @@ -0,0 +1,3 @@ +# @kbn/core-http-request-handler-context-server + +This package contains the public types for Core's server-side `RequestHandlerContext` http subdomain. diff --git a/packages/core/http/core-http-request-handler-context-server/index.ts b/packages/core/http/core-http-request-handler-context-server/index.ts new file mode 100644 index 0000000000000..125c466d25d2c --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export type { + RequestHandlerContext, + CoreRequestHandlerContext, + CustomRequestHandlerContext, + PrebootCoreRequestHandlerContext, + PrebootRequestHandlerContext, + PrebootUiSettingsRequestHandlerContext, +} from './src'; diff --git a/packages/core/http/core-http-request-handler-context-server/jest.config.js b/packages/core/http/core-http-request-handler-context-server/jest.config.js new file mode 100644 index 0000000000000..dc60767ed0880 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../../../..', + roots: ['/packages/core/http/core-http-request-handler-context-server'], +}; diff --git a/packages/core/http/core-http-request-handler-context-server/kibana.jsonc b/packages/core/http/core-http-request-handler-context-server/kibana.jsonc new file mode 100644 index 0000000000000..3fba38b6444e4 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server/kibana.jsonc @@ -0,0 +1,7 @@ +{ + "type": "shared-common", + "id": "@kbn/core-http-request-handler-context-server", + "owner": "@elastic/kibana-core", + "runtimeDeps": [], + "typeDeps": [], +} diff --git a/packages/core/http/core-http-request-handler-context-server/package.json b/packages/core/http/core-http-request-handler-context-server/package.json new file mode 100644 index 0000000000000..da85fc826828d --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/core-http-request-handler-context-server", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "author": "Kibana Core", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/core/http/core-http-request-handler-context-server/src/index.ts b/packages/core/http/core-http-request-handler-context-server/src/index.ts new file mode 100644 index 0000000000000..2ab372a0ab975 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server/src/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export type { + RequestHandlerContext, + CoreRequestHandlerContext, + CustomRequestHandlerContext, +} from './request_handler_context'; +export type { + PrebootRequestHandlerContext, + PrebootCoreRequestHandlerContext, + PrebootUiSettingsRequestHandlerContext, +} from './preboot_request_handler_context'; diff --git a/packages/core/http/core-http-request-handler-context-server/src/preboot_request_handler_context.ts b/packages/core/http/core-http-request-handler-context-server/src/preboot_request_handler_context.ts new file mode 100644 index 0000000000000..62caefe5619c6 --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server/src/preboot_request_handler_context.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { RequestHandlerContextBase } from '@kbn/core-http-server'; +import type { IUiSettingsClient } from '@kbn/core-ui-settings-server'; + +/** + * @public + */ +export interface PrebootUiSettingsRequestHandlerContext { + client: IUiSettingsClient; +} + +/** + * @public + */ +export interface PrebootCoreRequestHandlerContext { + uiSettings: PrebootUiSettingsRequestHandlerContext; +} + +/** + * @public + */ +export interface PrebootRequestHandlerContext extends RequestHandlerContextBase { + core: Promise; +} diff --git a/src/core/server/core_route_handler_context.ts b/packages/core/http/core-http-request-handler-context-server/src/request_handler_context.ts similarity index 53% rename from src/core/server/core_route_handler_context.ts rename to packages/core/http/core-http-request-handler-context-server/src/request_handler_context.ts index 14cc99b501436..07704752bd8ed 100644 --- a/src/core/server/core_route_handler_context.ts +++ b/packages/core/http/core-http-request-handler-context-server/src/request_handler_context.ts @@ -6,16 +6,11 @@ * Side Public License, v 1. */ -import type { KibanaRequest } from '@kbn/core-http-server'; +import type { RequestHandlerContextBase } from '@kbn/core-http-server'; import type { ElasticsearchRequestHandlerContext } from '@kbn/core-elasticsearch-server'; -import { CoreElasticsearchRouteHandlerContext } from '@kbn/core-elasticsearch-server-internal'; import type { SavedObjectsRequestHandlerContext } from '@kbn/core-saved-objects-server'; -import { CoreSavedObjectsRouteHandlerContext } from '@kbn/core-saved-objects-server-internal'; import type { DeprecationsRequestHandlerContext } from '@kbn/core-deprecations-server'; -import { CoreDeprecationsRouteHandlerContext } from '@kbn/core-deprecations-server-internal'; import type { UiSettingsRequestHandlerContext } from '@kbn/core-ui-settings-server'; -import { CoreUiSettingsRouteHandlerContext } from '@kbn/core-ui-settings-server-internal'; -import type { InternalCoreStart } from './internal_types'; /** * The `core` context provided to route handler. @@ -39,27 +34,19 @@ export interface CoreRequestHandlerContext { } /** - * The concrete implementation for Core's route handler context. + * Base context passed to a route handler, containing the `core` context part. * - * @internal + * @public */ -export class CoreRouteHandlerContext implements CoreRequestHandlerContext { - readonly elasticsearch: CoreElasticsearchRouteHandlerContext; - readonly savedObjects: CoreSavedObjectsRouteHandlerContext; - readonly uiSettings: CoreUiSettingsRouteHandlerContext; - readonly deprecations: CoreDeprecationsRouteHandlerContext; - - constructor(coreStart: InternalCoreStart, request: KibanaRequest) { - this.elasticsearch = new CoreElasticsearchRouteHandlerContext(coreStart.elasticsearch, request); - this.savedObjects = new CoreSavedObjectsRouteHandlerContext(coreStart.savedObjects, request); - this.uiSettings = new CoreUiSettingsRouteHandlerContext( - coreStart.uiSettings, - this.savedObjects - ); - this.deprecations = new CoreDeprecationsRouteHandlerContext( - coreStart.deprecations, - this.elasticsearch, - this.savedObjects - ); - } +export interface RequestHandlerContext extends RequestHandlerContextBase { + core: Promise; } + +/** + * Mixin allowing plugins to define their own request handler contexts. + * + * @public + */ +export type CustomRequestHandlerContext = RequestHandlerContext & { + [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; +}; diff --git a/packages/core/http/core-http-request-handler-context-server/tsconfig.json b/packages/core/http/core-http-request-handler-context-server/tsconfig.json new file mode 100644 index 0000000000000..71bb40fe57f3f --- /dev/null +++ b/packages/core/http/core-http-request-handler-context-server/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "**/*.ts", + ] +} diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/index.ts index c2e00482cd2d3..75d5352c9f63e 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/index.ts @@ -18,7 +18,6 @@ export * from './src/default_per_page'; export * from './src/default_risk_score_mapping_array'; export * from './src/default_severity_mapping_array'; export * from './src/default_threat_array'; -export * from './src/default_throttle_null'; export * from './src/default_to_string'; export * from './src/default_uuid'; export * from './src/from'; diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_throttle_null/index.test.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/default_throttle_null/index.test.ts deleted file mode 100644 index b92815d4fe828..0000000000000 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_throttle_null/index.test.ts +++ /dev/null @@ -1,44 +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 { pipe } from 'fp-ts/lib/pipeable'; -import { left } from 'fp-ts/lib/Either'; -import { Throttle } from '../throttle'; -import { DefaultThrottleNull } from '.'; -import { foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; - -describe('default_throttle_null', () => { - test('it should validate a throttle string', () => { - const payload: Throttle = 'some string'; - const decoded = DefaultThrottleNull.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - - test('it should not validate an array with a number', () => { - const payload = 5; - const decoded = DefaultThrottleNull.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "5" supplied to "DefaultThreatNull"', - ]); - expect(message.schema).toEqual({}); - }); - - test('it should return a default "null" if not provided a value', () => { - const payload = undefined; - const decoded = DefaultThrottleNull.decode(payload); - const message = pipe(decoded, foldLeftRight); - - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(null); - }); -}); diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_throttle_null/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/default_throttle_null/index.ts deleted file mode 100644 index e9b9ec27ea418..0000000000000 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_throttle_null/index.ts +++ /dev/null @@ -1,23 +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 * as t from 'io-ts'; -import { Either } from 'fp-ts/lib/Either'; -import { throttle, ThrottleOrNull } from '../throttle'; - -/** - * Types the DefaultThrottleNull as: - * - If null or undefined, then a null will be set - */ -export const DefaultThrottleNull = new t.Type( - 'DefaultThreatNull', - throttle.is, - (input, context): Either => - input == null ? t.success(null) : throttle.validate(input, context), - t.identity -); diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts index 19e75dcc3be07..d7d636ad0994e 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts @@ -6,13 +6,15 @@ * Side Public License, v 1. */ +import { TimeDuration } from '@kbn/securitysolution-io-ts-types'; import * as t from 'io-ts'; -export const throttle = t.string; +export const throttle = t.union([ + t.literal('no_actions'), + t.literal('rule'), + TimeDuration({ allowedUnits: ['h', 'd'] }), +]); export type Throttle = t.TypeOf; export const throttleOrNull = t.union([throttle, t.null]); export type ThrottleOrNull = t.TypeOf; - -export const throttleOrNullOrUndefined = t.union([throttle, t.null, t.undefined]); -export type ThrottleOrUndefinedOrNull = t.TypeOf; diff --git a/packages/kbn-securitysolution-io-ts-types/src/time_duration/index.test.ts b/packages/kbn-securitysolution-io-ts-types/src/time_duration/index.test.ts index 872affa9989a7..dc6b5e61ebbf6 100644 --- a/packages/kbn-securitysolution-io-ts-types/src/time_duration/index.test.ts +++ b/packages/kbn-securitysolution-io-ts-types/src/time_duration/index.test.ts @@ -6,122 +6,315 @@ * Side Public License, v 1. */ -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; import { TimeDuration } from '.'; import { foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; describe('TimeDuration', () => { - test('it should validate a correctly formed TimeDuration with time unit of seconds', () => { - const payload = '1s'; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + describe('with allowedDurations', () => { + test('it should validate a correctly formed TimeDuration with an allowed duration of 1s', () => { + const payload = '1s'; + const decoded = TimeDuration({ + allowedDurations: [ + [1, 's'], + [2, 'h'], + [7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); - test('it should validate a correctly formed TimeDuration with time unit of minutes', () => { - const payload = '100m'; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + test('it should validate a correctly formed TimeDuration with an allowed duration of 7d', () => { + const payload = '1s'; + const decoded = TimeDuration({ + allowedDurations: [ + [1, 's'], + [2, 'h'], + [7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); - test('it should validate a correctly formed TimeDuration with time unit of hours', () => { - const payload = '10000000h'; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + test('it should NOT validate a time duration if the allowed durations does not include it', () => { + const payload = '24h'; + const decoded = TimeDuration({ + allowedDurations: [ + [1, 's'], + [2, 'h'], + [7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "24h" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); - test('it should NOT validate a TimeDuration of 0 length', () => { - const payload = '0s'; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + test('it should NOT validate a an allowed duration with a negative number', () => { + const payload = '10s'; + const decoded = TimeDuration({ + allowedDurations: [ + [1, 's'], + [-7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "0s" supplied to "TimeDuration"', - ]); - expect(message.schema).toEqual({}); - }); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "[[1,"s"],[-7,"d"]]" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); - test('it should NOT validate a negative TimeDuration', () => { - const payload = '-10s'; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + test('it should NOT validate an allowed duration with a fractional number', () => { + const payload = '1.5s'; + const decoded = TimeDuration({ + allowedDurations: [ + [1, 's'], + [-7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "-10s" supplied to "TimeDuration"', - ]); - expect(message.schema).toEqual({}); - }); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "1.5s" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); - test('it should NOT validate a decimal TimeDuration', () => { - const payload = '1.5s'; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + test('it should NOT validate a an allowed duration with a duration of 0', () => { + const payload = '10s'; + const decoded = TimeDuration({ + allowedDurations: [ + [0, 's'], + [7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "1.5s" supplied to "TimeDuration"', - ]); - expect(message.schema).toEqual({}); - }); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "[[0,"s"],[7,"d"]]" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); - test('it should NOT validate a TimeDuration with some other time unit', () => { - const payload = '10000000w'; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + test('it should NOT validate a TimeDuration with an invalid time unit', () => { + const payload = '10000000days'; + const decoded = TimeDuration({ + allowedDurations: [ + [1, 'h'], + [1, 'd'], + [7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "10000000w" supplied to "TimeDuration"', - ]); - expect(message.schema).toEqual({}); - }); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "10000000days" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); - test('it should NOT validate a TimeDuration with a time interval with incorrect format', () => { - const payload = '100ff0000w'; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + test('it should NOT validate a TimeDuration with a time interval with incorrect format', () => { + const payload = '100ff0000w'; + const decoded = TimeDuration({ + allowedDurations: [ + [1, 'h'], + [1, 'd'], + [7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "100ff0000w" supplied to "TimeDuration"', - ]); - expect(message.schema).toEqual({}); - }); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "100ff0000w" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); - test('it should NOT validate an empty string', () => { - const payload = ''; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + test('it should NOT validate an empty string', () => { + const payload = ''; + const decoded = TimeDuration({ + allowedDurations: [ + [1, 'h'], + [1, 'd'], + [7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "TimeDuration"']); - expect(message.schema).toEqual({}); - }); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate an number', () => { + const payload = 100; + const decoded = TimeDuration({ + allowedDurations: [ + [1, 'h'], + [1, 'd'], + [7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); - test('it should NOT validate an number', () => { - const payload = 100; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "100" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "100" supplied to "TimeDuration"', - ]); - expect(message.schema).toEqual({}); + test('it should NOT validate an TimeDuration with a valid time unit but unsafe integer', () => { + const payload = `${Math.pow(2, 53)}h`; + const decoded = TimeDuration({ + allowedDurations: [ + [1, 'h'], + [1, 'd'], + [7, 'd'], + ], + }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([ + `Invalid value "${Math.pow(2, 53)}h" supplied to "TimeDuration"`, + ]); + expect(message.schema).toEqual({}); + }); }); + describe('with allowedUnits', () => { + test('it should validate a correctly formed TimeDuration with time unit of seconds', () => { + const payload = '1s'; + const decoded = TimeDuration({ allowedUnits: ['s'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate a correctly formed TimeDuration with time unit of minutes', () => { + const payload = '100m'; + const decoded = TimeDuration({ allowedUnits: ['s', 'm'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate a correctly formed TimeDuration with time unit of hours', () => { + const payload = '10000000h'; + const decoded = TimeDuration({ allowedUnits: ['s', 'm', 'h'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should validate a correctly formed TimeDuration with time unit of days', () => { + const payload = '7d'; + const decoded = TimeDuration({ allowedUnits: ['s', 'm', 'h', 'd'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + + test('it should NOT validate a correctly formed TimeDuration with time unit of seconds if it is not an allowed unit', () => { + const payload = '30s'; + const decoded = TimeDuration({ allowedUnits: ['m', 'h', 'd'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "30s" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate a negative TimeDuration', () => { + const payload = '-10s'; + const decoded = TimeDuration({ allowedUnits: ['s', 'm', 'h', 'd'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "-10s" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate a fractional number', () => { + const payload = '1.5s'; + const decoded = TimeDuration({ allowedUnits: ['s', 'm', 'h', 'd'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "1.5s" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate a TimeDuration with an invalid time unit', () => { + const payload = '10000000days'; + const decoded = TimeDuration({ allowedUnits: ['s', 'm', 'h', 'd'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "10000000days" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate a TimeDuration with a time interval with incorrect format', () => { + const payload = '100ff0000w'; + const decoded = TimeDuration({ allowedUnits: ['s', 'm', 'h'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "100ff0000w" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate an empty string', () => { + const payload = ''; + const decoded = TimeDuration({ allowedUnits: ['s', 'm', 'h'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); + + test('it should NOT validate an number', () => { + const payload = 100; + const decoded = TimeDuration({ allowedUnits: ['s', 'm', 'h'] }).decode(payload); + const message = foldLeftRight(decoded); + + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "100" supplied to "TimeDuration"', + ]); + expect(message.schema).toEqual({}); + }); - test('it should NOT validate an TimeDuration with a valid time unit but unsafe integer', () => { - const payload = `${Math.pow(2, 53)}h`; - const decoded = TimeDuration.decode(payload); - const message = pipe(decoded, foldLeftRight); + test('it should NOT validate an TimeDuration with a valid time unit but unsafe integer', () => { + const payload = `${Math.pow(2, 53)}h`; + const decoded = TimeDuration({ allowedUnits: ['s', 'm', 'h'] }).decode(payload); + const message = foldLeftRight(decoded); - expect(getPaths(left(message.errors))).toEqual([ - `Invalid value "${Math.pow(2, 53)}h" supplied to "TimeDuration"`, - ]); - expect(message.schema).toEqual({}); + expect(getPaths(left(message.errors))).toEqual([ + `Invalid value "${Math.pow(2, 53)}h" supplied to "TimeDuration"`, + ]); + expect(message.schema).toEqual({}); + }); }); }); diff --git a/packages/kbn-securitysolution-io-ts-types/src/time_duration/index.ts b/packages/kbn-securitysolution-io-ts-types/src/time_duration/index.ts index 5549979ac68de..0b69c62e0d2f5 100644 --- a/packages/kbn-securitysolution-io-ts-types/src/time_duration/index.ts +++ b/packages/kbn-securitysolution-io-ts-types/src/time_duration/index.ts @@ -12,38 +12,60 @@ import { Either } from 'fp-ts/lib/Either'; /** * Types the TimeDuration as: * - A string that is not empty, and composed of a positive integer greater than 0 followed by a unit of time - * - in the format {safe_integer}{timeUnit}, e.g. "30s", "1m", "2h" + * - in the format {safe_integer}{timeUnit}, e.g. "30s", "1m", "2h", "7d" */ -export const TimeDuration = new t.Type( - 'TimeDuration', - t.string.is, - (input, context): Either => { - if (typeof input === 'string' && input.trim() !== '') { - try { - const inputLength = input.length; - const unit = input.trim().at(-1); - const time = parseFloat(input.trim().substring(0, inputLength - 1)); - if (!Number.isInteger(time)) { - return t.failure(input, context); - } - if ( - time >= 1 && - Number.isSafeInteger(time) && - (unit === 's' || unit === 'm' || unit === 'h') - ) { - return t.success(input); - } else { +type TimeUnits = 's' | 'm' | 'h' | 'd' | 'w' | 'y'; +interface TimeDurationWithAllowedDurations { + allowedDurations: Array<[number, TimeUnits]>; + allowedUnits?: never; +} +interface TimeDurationWithAllowedUnits { + allowedUnits: TimeUnits[]; + allowedDurations?: never; +} + +type TimeDurationType = TimeDurationWithAllowedDurations | TimeDurationWithAllowedUnits; + +const isTimeSafe = (time: number) => time >= 1 && Number.isSafeInteger(time); + +export const TimeDuration = ({ allowedUnits, allowedDurations }: TimeDurationType) => { + return new t.Type( + 'TimeDuration', + t.string.is, + (input, context): Either => { + if (typeof input === 'string' && input.trim() !== '') { + try { + const inputLength = input.length; + const time = Number(input.trim().substring(0, inputLength - 1)); + const unit = input.trim().at(-1); + if (!isTimeSafe(time)) { + return t.failure(input, context); + } + if (allowedDurations) { + for (const [allowedTime, allowedUnit] of allowedDurations) { + if (!isTimeSafe(allowedTime)) { + return t.failure(allowedDurations, context); + } + if (allowedTime === time && allowedUnit === unit) { + return t.success(input); + } + } + return t.failure(input, context); + } else if (allowedUnits.includes(unit as TimeUnits)) { + return t.success(input); + } else { + return t.failure(input, context); + } + } catch (error) { return t.failure(input, context); } - } catch (error) { + } else { return t.failure(input, context); } - } else { - return t.failure(input, context); - } - }, - t.identity -); + }, + t.identity + ); +}; export type TimeDurationC = typeof TimeDuration; diff --git a/renovate.json b/renovate.json index 6eed31366c409..4075b2452bea1 100644 --- a/renovate.json +++ b/renovate.json @@ -125,7 +125,7 @@ ], "reviewers": ["team:kibana-security"], "matchBaseBranches": ["main"], - "labels": ["Team:Security", "release_note:skip", "auto-backport"], + "labels": ["Team:Security", "release_note:skip", "backport:all-open"], "enabled": true }, { diff --git a/src/core/server/http_resources/http_resources_service.ts b/src/core/server/http_resources/http_resources_service.ts index 7e95dc9e302d9..5db20bf45e409 100644 --- a/src/core/server/http_resources/http_resources_service.ts +++ b/src/core/server/http_resources/http_resources_service.ts @@ -18,7 +18,7 @@ import type { InternalHttpServiceSetup, InternalHttpServicePreboot, } from '@kbn/core-http-server-internal'; -import { RequestHandlerContext } from '..'; +import type { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server'; import { InternalRenderingServicePreboot, InternalRenderingServiceSetup } from '../rendering'; import { InternalHttpResourcesSetup, diff --git a/src/core/server/http_resources/types.ts b/src/core/server/http_resources/types.ts index 397f03098dd13..246a7394c3ade 100644 --- a/src/core/server/http_resources/types.ts +++ b/src/core/server/http_resources/types.ts @@ -15,7 +15,7 @@ import type { KibanaResponseFactory, RequestHandler, } from '@kbn/core-http-server'; -import type { RequestHandlerContext } from '..'; +import type { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server'; /** * Allows to configure HTTP response parameters diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 6e72b1d2623cf..020975c15fb1b 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -42,7 +42,6 @@ import type { ExecutionContextStart, } from '@kbn/core-execution-context-server'; import type { - RequestHandlerContextBase, IRouter, RequestHandler, KibanaResponseFactory, @@ -69,12 +68,11 @@ import type { CoreUsageDataStart, CoreUsageDataSetup } from '@kbn/core-usage-dat import type { I18nServiceSetup } from '@kbn/core-i18n-server'; import type { StatusServiceSetup } from '@kbn/core-status-server'; import type { UiSettingsServiceSetup, UiSettingsServiceStart } from '@kbn/core-ui-settings-server'; - +import type { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server'; import { HttpResources } from './http_resources'; -import { PluginsServiceSetup, PluginsServiceStart, PluginOpaqueId } from './plugins'; -import type { CoreRequestHandlerContext } from './core_route_handler_context'; -import type { PrebootCoreRequestHandlerContext } from './preboot_core_route_handler_context'; +import { PluginsServiceSetup, PluginsServiceStart } from './plugins'; +export type { PluginOpaqueId } from '@kbn/core-base-common'; export type { CoreUsageStats, CoreUsageData, @@ -462,33 +460,13 @@ export type { AnalyticsServicePreboot, AnalyticsServiceStart, } from '@kbn/core-analytics-server'; - -export type { CoreRequestHandlerContext } from './core_route_handler_context'; - -/** - * Base context passed to a route handler, containing the `core` context part. - * - * @public - */ -export interface RequestHandlerContext extends RequestHandlerContextBase { - core: Promise; -} - -/** - * @internal - */ -export interface PrebootRequestHandlerContext extends RequestHandlerContextBase { - core: Promise; -} - -/** - * Mixin allowing plugins to define their own request handler contexts. - * - * @public - */ -export type CustomRequestHandlerContext = RequestHandlerContext & { - [Key in keyof T]: T[Key] extends Promise ? T[Key] : Promise; -}; +export type { + RequestHandlerContext, + CoreRequestHandlerContext, + CustomRequestHandlerContext, + PrebootRequestHandlerContext, + PrebootCoreRequestHandlerContext, +} from '@kbn/core-http-request-handler-context-server'; /** * Context passed to the `setup` method of `preboot` plugins. @@ -599,7 +577,6 @@ export type { HttpResources, PluginsServiceSetup, PluginsServiceStart, - PluginOpaqueId, }; /** diff --git a/src/core/server/server.ts b/src/core/server/server.ts index aa747a1023b35..e333e8b81a404 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -58,16 +58,21 @@ import { import { CoreUsageDataService } from '@kbn/core-usage-data-server-internal'; import { StatusService, statusConfig } from '@kbn/core-status-server-internal'; import { UiSettingsService, uiSettingsConfig } from '@kbn/core-ui-settings-server-internal'; +import { + CoreRouteHandlerContext, + PrebootCoreRouteHandlerContext, +} from '@kbn/core-http-request-handler-context-server-internal'; +import type { + RequestHandlerContext, + PrebootRequestHandlerContext, +} from '@kbn/core-http-request-handler-context-server'; import { CoreApp } from './core_app'; import { HttpResourcesService } from './http_resources'; import { RenderingService } from './rendering'; import { PluginsService, config as pluginsConfig } from './plugins'; import { InternalCorePreboot, InternalCoreSetup, InternalCoreStart } from './internal_types'; -import { CoreRouteHandlerContext } from './core_route_handler_context'; -import { PrebootCoreRouteHandlerContext } from './preboot_core_route_handler_context'; import { DiscoveredPlugins } from './plugins'; -import type { RequestHandlerContext, PrebootRequestHandlerContext } from '.'; const coreId = Symbol('core'); const rootConfigPath = ''; diff --git a/src/dev/build/tasks/bundle_fleet_packages.ts b/src/dev/build/tasks/bundle_fleet_packages.ts index 4ba5e79d29928..30cfc1d22b0e6 100644 --- a/src/dev/build/tasks/bundle_fleet_packages.ts +++ b/src/dev/build/tasks/bundle_fleet_packages.ts @@ -15,6 +15,10 @@ import { Task, read, downloadToDisk, unzipBuffer, createZipFile } from '../lib'; const BUNDLED_PACKAGES_DIR = 'x-pack/plugins/fleet/target/bundled_packages'; +// APM needs to directly request its versions from Package Storage v2 - this should +// be removed when Package Storage v2 is in production +const PACKAGE_STORAGE_V2_URL = 'https://epr-v2.ea-web.elastic.dev'; + interface FleetPackage { name: string; version: string; @@ -64,7 +68,12 @@ export const BundleFleetPackages: Task = { } const archivePath = `${fleetPackage.name}-${versionToWrite}.zip`; - const archiveUrl = `${eprUrl}/epr/${fleetPackage.name}/${fleetPackage.name}-${fleetPackage.version}.zip`; + let archiveUrl = `${eprUrl}/epr/${fleetPackage.name}/${fleetPackage.name}-${fleetPackage.version}.zip`; + + // Point APM to package storage v2 + if (fleetPackage.name === 'apm') { + archiveUrl = `${PACKAGE_STORAGE_V2_URL}/epr/${fleetPackage.name}/${fleetPackage.name}-${fleetPackage.version}.zip`; + } const destination = build.resolvePath(BUNDLED_PACKAGES_DIR, archivePath); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts index 435335fe9dd25..309f066b18f29 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.test.ts @@ -40,7 +40,7 @@ describe('convertTSVBtoLensConfiguration', () => { test('should return null for a not supported chart', async () => { const metricModel = { ...model, - type: 'metric', + type: 'markdown', } as Panel; const triggerOptions = await convertTSVBtoLensConfiguration(metricModel); expect(triggerOptions).toBeNull(); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts index 5b92c0ab21668..a64118a1cb507 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/index.ts @@ -21,6 +21,10 @@ const getConvertFnByType = (type: PANEL_TYPES) => { const { convertToLens } = await import('./top_n'); return convertToLens; }, + [PANEL_TYPES.METRIC]: async () => { + const { convertToLens } = await import('./metric'); + return convertToLens; + }, }; return convertionFns[type]?.(); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/metric/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/metric/index.ts new file mode 100644 index 0000000000000..d1f24485d7646 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/metric/index.ts @@ -0,0 +1,67 @@ +/* + * 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 { MetricVisConfiguration } from '@kbn/visualizations-plugin/common'; +import { Metric, Panel, Series } from '../../../../../common/types'; +import { Column, Layer } from '../../convert'; +import { getSeriesAgg } from '../../series'; +import { getPalette } from './palette'; + +const getMetricWithCollapseFn = (series: Series | undefined) => { + if (!series) { + return; + } + const { metrics, seriesAgg } = getSeriesAgg(series.metrics); + const visibleMetric = metrics[metrics.length - 1]; + return { metric: visibleMetric, collapseFn: seriesAgg }; +}; + +const findMetricColumn = (metric: Metric | undefined, columns: Column[]) => { + if (!metric) { + return; + } + + return columns.find((column) => 'meta' in column && column.meta.metricId === metric.id); +}; + +export const getConfigurationForMetric = ( + model: Panel, + layer: Layer, + bucket?: Column +): MetricVisConfiguration | null => { + const [primarySeries, secondarySeries] = model.series.filter(({ hidden }) => !hidden); + + const primaryMetricWithCollapseFn = getMetricWithCollapseFn(primarySeries); + + if (!primaryMetricWithCollapseFn || !primaryMetricWithCollapseFn.metric) { + return null; + } + + const secondaryMetricWithCollapseFn = getMetricWithCollapseFn(secondarySeries); + const primaryColumn = findMetricColumn(primaryMetricWithCollapseFn.metric, layer.columns); + const secondaryColumn = findMetricColumn(secondaryMetricWithCollapseFn?.metric, layer.columns); + + if (primaryMetricWithCollapseFn.collapseFn && secondaryMetricWithCollapseFn?.collapseFn) { + return null; + } + + const palette = getPalette(model.background_color_rules ?? []); + if (palette === null) { + return null; + } + + return { + layerId: layer.layerId, + layerType: 'data', + metricAccessor: primaryColumn?.columnId, + secondaryMetricAccessor: secondaryColumn?.columnId, + breakdownByAccessor: bucket?.columnId, + palette, + collapseFn: primaryMetricWithCollapseFn.collapseFn ?? secondaryMetricWithCollapseFn?.collapseFn, + }; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/metric/palette.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/metric/palette.test.ts new file mode 100644 index 0000000000000..827dc15ff171b --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/metric/palette.test.ts @@ -0,0 +1,177 @@ +/* + * 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 { getPalette } from './palette'; + +describe('getPalette', () => { + const invalidRules = [ + { id: 'some-id-0' }, + { id: 'some-id-1', value: 10 }, + { id: 'some-id-2', operator: 'gte' }, + { id: 'some-id-3', color: '#000' }, + { id: 'some-id-4', background_color: '#000' }, + ]; + test('should return undefined if no filled rules was provided', () => { + expect(getPalette([])).toBeUndefined(); + expect(getPalette(invalidRules)).toBeUndefined(); + }); + + test('should return undefined if only one valid rule is provided and it is not lte', () => { + expect(getPalette([])).toBeUndefined(); + expect( + getPalette([ + ...invalidRules, + { id: 'some-id-5', operator: 'gt', value: 100, background_color: '#000' }, + ]) + ).toBeUndefined(); + }); + + test('should return custom palette if only one valid rule is provided and it is lte', () => { + expect(getPalette([])).toBeUndefined(); + expect( + getPalette([ + ...invalidRules, + { id: 'some-id-5', operator: 'lte', value: 100, background_color: '#000' }, + ]) + ).toEqual({ + name: 'custom', + params: { + colorStops: [{ color: '#000000', stop: 100 }], + continuity: 'below', + maxSteps: 5, + name: 'custom', + progression: 'fixed', + rangeMax: 100, + rangeMin: -Infinity, + rangeType: 'number', + reverse: false, + steps: 1, + stops: [{ color: '#000000', stop: 100 }], + }, + type: 'palette', + }); + }); + + test('should return undefined if more than two types of rules', () => { + expect(getPalette([])).toBeUndefined(); + expect( + getPalette([ + ...invalidRules, + { id: 'some-id-5', operator: 'lte', value: 100, background_color: '#000' }, + { id: 'some-id-6', operator: 'gte', value: 150, background_color: '#000' }, + { id: 'some-id-7', operator: 'lt', value: 200, background_color: '#000' }, + ]) + ).toBeUndefined(); + }); + + test('should return undefined if two types of rules and last rule is not lte', () => { + expect(getPalette([])).toBeUndefined(); + expect( + getPalette([ + ...invalidRules, + { id: 'some-id-5', operator: 'gte', value: 100, background_color: '#000' }, + { id: 'some-id-7', operator: 'lt', value: 200, background_color: '#000' }, + { id: 'some-id-6', operator: 'gte', value: 150, background_color: '#000' }, + ]) + ).toBeUndefined(); + }); + + test('should return undefined if all rules are lte', () => { + expect(getPalette([])).toBeUndefined(); + expect( + getPalette([ + ...invalidRules, + { id: 'some-id-5', operator: 'lte', value: 100, background_color: '#000' }, + { id: 'some-id-7', operator: 'lte', value: 200, background_color: '#000' }, + { id: 'some-id-6', operator: 'lte', value: 150, background_color: '#000' }, + ]) + ).toBeUndefined(); + }); + + test('should return undefined if two types of rules and all except last one are lt and last one is not lte', () => { + expect(getPalette([])).toBeUndefined(); + expect( + getPalette([ + ...invalidRules, + { id: 'some-id-5', operator: 'lt', value: 100, background_color: '#000' }, + { id: 'some-id-7', operator: 'gte', value: 200, background_color: '#000' }, + { id: 'some-id-6', operator: 'lt', value: 150, background_color: '#000' }, + ]) + ).toBeUndefined(); + }); + + test('should return custom palette if two types of rules and all except last one is lt and last one is lte', () => { + expect(getPalette([])).toBeUndefined(); + expect( + getPalette([ + ...invalidRules, + { id: 'some-id-5', operator: 'lt', value: 100, background_color: '#000' }, + { id: 'some-id-7', operator: 'lte', value: 200, background_color: '#000' }, + { id: 'some-id-6', operator: 'lt', value: 150, background_color: '#000' }, + ]) + ).toEqual({ + name: 'custom', + params: { + colorStops: [ + { color: '#000000', stop: -Infinity }, + { color: '#000000', stop: 100 }, + { color: '#000000', stop: 150 }, + ], + continuity: 'below', + maxSteps: 5, + name: 'custom', + progression: 'fixed', + rangeMax: 200, + rangeMin: -Infinity, + rangeType: 'number', + reverse: false, + steps: 4, + stops: [ + { color: '#000000', stop: 100 }, + { color: '#000000', stop: 150 }, + { color: '#000000', stop: 200 }, + ], + }, + type: 'palette', + }); + }); + + test('should return custom palette if last one is lte and all previous are gte', () => { + expect(getPalette([])).toBeUndefined(); + expect( + getPalette([ + ...invalidRules, + { id: 'some-id-5', operator: 'gte', value: 100, background_color: '#000' }, + { id: 'some-id-7', operator: 'lte', value: 200, background_color: '#000' }, + { id: 'some-id-6', operator: 'gte', value: 150, background_color: '#000' }, + ]) + ).toEqual({ + name: 'custom', + params: { + colorStops: [ + { color: '#000000', stop: 100 }, + { color: '#000000', stop: 150 }, + ], + continuity: 'none', + maxSteps: 5, + name: 'custom', + progression: 'fixed', + rangeMax: 200, + rangeMin: 100, + rangeType: 'number', + reverse: false, + steps: 2, + stops: [ + { color: '#000000', stop: 150 }, + { color: '#000000', stop: 200 }, + ], + }, + type: 'palette', + }); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/metric/palette.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/metric/palette.ts new file mode 100644 index 0000000000000..55741c57595e7 --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/configurations/metric/palette.ts @@ -0,0 +1,214 @@ +/* + * 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 color from 'color'; +import { ColorStop, CustomPaletteParams, PaletteOutput } from '@kbn/coloring'; +import { uniqBy } from 'lodash'; +import { Panel } from '../../../../../common/types'; + +const Operators = { + GTE: 'gte', + GT: 'gt', + LTE: 'lte', + LT: 'lt', +} as const; + +type ColorStopsWithMinMax = Pick< + CustomPaletteParams, + 'colorStops' | 'stops' | 'steps' | 'rangeMax' | 'rangeMin' | 'continuity' +>; + +const getColorStopsWithMinMaxForAllGteOrWithLte = ( + rules: Exclude, + tailOperator: string +): ColorStopsWithMinMax => { + const lastRule = rules[rules.length - 1]; + const lastRuleColor = (lastRule.background_color ?? lastRule.color)!; + + const colorStops = rules.reduce((colors, rule, index, rulesArr) => { + const rgbColor = (rule.background_color ?? rule.color)!; + if (index === rulesArr.length - 1 && tailOperator === Operators.LTE) { + return colors; + } + // if last operation is LTE, color of gte should be replaced by lte + if (index === rulesArr.length - 2 && tailOperator === Operators.LTE) { + return [ + ...colors, + { + color: color(lastRuleColor).hex(), + stop: rule.value!, + }, + ]; + } + return [ + ...colors, + { + color: color(rgbColor).hex(), + stop: rule.value!, + }, + ]; + }, []); + + const stops = colorStops.reduce((prevStops, colorStop, index, colorStopsArr) => { + if (index === colorStopsArr.length - 1) { + return [ + ...prevStops, + { + color: colorStop.color, + stop: tailOperator === Operators.LTE ? lastRule.value! : colorStop.stop + 1, + }, + ]; + } + return [...prevStops, { color: colorStop.color, stop: colorStopsArr[index + 1].stop }]; + }, []); + + const [rule] = rules; + return { + rangeMin: rule.value, + rangeMax: tailOperator === Operators.LTE ? lastRule.value : Infinity, + colorStops, + stops, + steps: colorStops.length, + continuity: tailOperator === Operators.LTE ? 'none' : 'above', + }; +}; + +const getColorStopsWithMinMaxForLtWithLte = ( + rules: Exclude +): ColorStopsWithMinMax => { + const lastRule = rules[rules.length - 1]; + const colorStops = rules.reduce((colors, rule, index, rulesArr) => { + if (index === 0) { + return [{ color: color((rule.background_color ?? rule.color)!).hex(), stop: -Infinity }]; + } + const rgbColor = (rule.background_color ?? rule.color)!; + return [ + ...colors, + { + color: color(rgbColor).hex(), + stop: rulesArr[index - 1].value!, + }, + ]; + }, []); + + const stops = colorStops.reduce((prevStops, colorStop, index, colorStopsArr) => { + if (index === colorStopsArr.length - 1) { + return [ + ...prevStops, + { + color: colorStop.color, + stop: lastRule.value!, + }, + ]; + } + return [...prevStops, { color: colorStop.color, stop: colorStopsArr[index + 1].stop }]; + }, []); + + return { + rangeMin: -Infinity, + rangeMax: lastRule.value, + colorStops, + stops, + steps: colorStops.length + 1, + continuity: 'below', + }; +}; + +const getColorStopWithMinMaxForLte = ( + rule: Exclude[number] +): ColorStopsWithMinMax => { + const colorStop = { + color: color((rule.background_color ?? rule.color)!).hex(), + stop: rule.value!, + }; + return { + rangeMin: -Infinity, + rangeMax: rule.value!, + colorStops: [colorStop], + stops: [colorStop], + steps: 1, + continuity: 'below', + }; +}; + +const getCustomPalette = ( + colorStopsWithMinMax: ColorStopsWithMinMax +): PaletteOutput => { + return { + name: 'custom', + params: { + continuity: 'all', + maxSteps: 5, + name: 'custom', + progression: 'fixed', + rangeMax: Infinity, + rangeMin: -Infinity, + rangeType: 'number', + reverse: false, + ...colorStopsWithMinMax, + }, + type: 'palette', + }; +}; + +export const getPalette = ( + rules: Exclude +): PaletteOutput | null | undefined => { + const validRules = + rules.filter( + ({ operator, color: textColor, value, background_color: bColor }) => + operator && (bColor ?? textColor) && value !== undefined + ) ?? []; + + validRules.sort((rule1, rule2) => { + return rule1.value! - rule2.value!; + }); + + const kindOfRules = uniqBy(validRules, 'operator'); + + if (!kindOfRules.length) { + return; + } + + // lnsMetric is supporting lte only, if one rule is defined + if (validRules.length === 1) { + if (validRules[0].operator !== Operators.LTE) { + return; + } + return getCustomPalette(getColorStopWithMinMaxForLte(validRules[0])); + } + + const headRules = validRules.slice(0, -1); + const tailRule = validRules[validRules.length - 1]; + const kindOfHeadRules = uniqBy(headRules, 'operator'); + + if ( + kindOfHeadRules.length > 1 || + (kindOfHeadRules[0].operator !== tailRule.operator && tailRule.operator !== Operators.LTE) + ) { + return; + } + + const [rule] = kindOfHeadRules; + + if (rule.operator === Operators.LTE) { + return; + } + + if (rule.operator === Operators.LT) { + if (tailRule.operator !== Operators.LTE) { + return; + } + return getCustomPalette(getColorStopsWithMinMaxForLtWithLte(validRules)); + } + + if (rule.operator === Operators.GTE) { + return getCustomPalette( + getColorStopsWithMinMaxForAllGteOrWithLte(validRules, tailRule.operator!) + ); + } +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts index 36f05c440bdc2..e03701e6ea153 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/index.ts @@ -17,7 +17,7 @@ export { export { convertToCumulativeSumColumns } from './cumulative_sum'; export { convertFilterRatioToFormulaColumn } from './filter_ratio'; export { convertToLastValueColumn } from './last_value'; -export { convertToStaticValueColumn } from './static_value'; +export { convertToStaticValueColumn, convertStaticValueToFormulaColumn } from './static_value'; export { convertToFiltersColumn } from './filters'; export { convertToDateHistogramColumn } from './date_histogram'; export { convertToTermsColumn } from './terms'; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts index c4400f72b289b..e03a9d7821364 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts @@ -7,9 +7,10 @@ */ import { StaticValueParams } from '@kbn/visualizations-plugin/common/convert_to_lens'; -import { CommonColumnsConverterArgs, StaticValueColumn } from './types'; +import { CommonColumnsConverterArgs, FormulaColumn, StaticValueColumn } from './types'; import type { Metric } from '../../../../common/types'; import { createColumn, getFormat } from './column'; +import { createFormulaColumn } from './formula'; export const convertToStaticValueParams = ({ value }: Metric): StaticValueParams => ({ value, @@ -37,3 +38,22 @@ export const convertToStaticValueColumn = ( }, }; }; + +export const convertStaticValueToFormulaColumn = ( + { series, metrics, dataView }: CommonColumnsConverterArgs, + { + visibleSeriesCount = 0, + reducedTimeRange, + }: { visibleSeriesCount?: number; reducedTimeRange?: string } = {} +): FormulaColumn | null => { + // Lens support reference lines only when at least one layer data exists + if (visibleSeriesCount === 1) { + return null; + } + const currentMetric = metrics[metrics.length - 1]; + return createFormulaColumn(currentMetric.value ?? '', { + series, + metric: currentMetric, + dataView, + }); +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts index d21291dc2622a..e5b862a0fe70f 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/types.ts @@ -85,7 +85,7 @@ export type MovingAverageColumn = GenericColumnWithMeta; export type StaticValueColumn = GenericColumnWithMeta; -type ColumnsWithoutMeta = FiltersColumn | TermsColumn | DateHistogramColumn; +export type ColumnsWithoutMeta = FiltersColumn | TermsColumn | DateHistogramColumn; export type AnyColumnWithReferences = GenericColumnWithMeta; type CommonColumns = Exclude; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts index 933e7e344b7fd..76d15793f4516 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/metrics/supported_metrics.ts @@ -62,7 +62,12 @@ export type SupportedMetrics = LocalSupportedMetrics & { [Key in UnsupportedSupportedMetrics]?: null; }; -const supportedPanelTypes: readonly PANEL_TYPES[] = [PANEL_TYPES.TIMESERIES, PANEL_TYPES.TOP_N]; +const supportedPanelTypes: readonly PANEL_TYPES[] = [ + PANEL_TYPES.TIMESERIES, + PANEL_TYPES.TOP_N, + PANEL_TYPES.METRIC, +]; + const supportedTimeRangeModes: readonly TIME_RANGE_DATA_MODES[] = [ TIME_RANGE_DATA_MODES.ENTIRE_TIME_RANGE, TIME_RANGE_DATA_MODES.LAST_VALUE, diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts index 5ca1fe71a0ada..4461072c8df62 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.test.ts @@ -20,6 +20,7 @@ const mockConvertToCounterRateColumn = jest.fn(); const mockConvertOtherAggsToFormulaColumn = jest.fn(); const mockConvertToLastValueColumn = jest.fn(); const mockConvertToStaticValueColumn = jest.fn(); +const mockConvertStaticValueToFormulaColumn = jest.fn(); const mockConvertToStandartDeviationColumn = jest.fn(); const mockConvertMetricAggregationColumnWithoutSpecialParams = jest.fn(); @@ -32,6 +33,7 @@ jest.mock('../convert', () => ({ convertOtherAggsToFormulaColumn: jest.fn(() => mockConvertOtherAggsToFormulaColumn()), convertToLastValueColumn: jest.fn(() => mockConvertToLastValueColumn()), convertToStaticValueColumn: jest.fn(() => mockConvertToStaticValueColumn()), + convertStaticValueToFormulaColumn: jest.fn(() => mockConvertStaticValueToFormulaColumn()), convertToStandartDeviationColumn: jest.fn(() => mockConvertToStandartDeviationColumn()), convertMetricAggregationColumnWithoutSpecialParams: jest.fn(() => mockConvertMetricAggregationColumnWithoutSpecialParams() @@ -138,8 +140,18 @@ describe('getMetricsColumns', () => { mockConvertToLastValueColumn, ], [ - 'call convertToStaticValueColumn if metric type is static', + 'call convertStaticValueToFormulaColumn if metric type is static', [createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.STATIC, id: '1' }] }), dataView, 1], + mockConvertStaticValueToFormulaColumn, + ], + [ + 'call convertToStaticValueColumn if metric type is static and isStaticValueColumnSupported is true', + [ + createSeries({ metrics: [{ type: TSVB_METRIC_TYPES.STATIC, id: '1' }] }), + dataView, + 1, + { isStaticValueColumnSupported: true }, + ], mockConvertToStaticValueColumn, ], [ diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts index 07294a3a61aaa..8f7d4ded0d076 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/series/metrics_columns.ts @@ -21,6 +21,7 @@ import { convertFilterRatioToFormulaColumn, convertToLastValueColumn, convertToStaticValueColumn, + convertStaticValueToFormulaColumn, convertMetricAggregationColumnWithoutSpecialParams, convertToCounterRateColumn, convertToStandartDeviationColumn, @@ -31,7 +32,10 @@ export const getMetricsColumns = ( series: Series, dataView: DataView, visibleSeriesCount: number, - reducedTimeRange?: string + { + isStaticValueColumnSupported = false, + reducedTimeRange, + }: { reducedTimeRange?: string; isStaticValueColumnSupported?: boolean } = {} ): Column[] | null => { const { metrics: validMetrics, seriesAgg } = getSeriesAgg( series.metrics as [Metric, ...Metric[]] @@ -117,10 +121,12 @@ export const getMetricsColumns = ( return getValidColumns(column); } case 'static': { - const column = convertToStaticValueColumn(columnsConverterArgs, { - visibleSeriesCount, - reducedTimeRange, - }); + const column = isStaticValueColumnSupported + ? convertToStaticValueColumn(columnsConverterArgs, { + visibleSeriesCount, + reducedTimeRange, + }) + : convertStaticValueToFormulaColumn(columnsConverterArgs); return getValidColumns(column); } case 'std_deviation': { diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/index.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/index.test.ts new file mode 100644 index 0000000000000..9407599573d9d --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/index.test.ts @@ -0,0 +1,272 @@ +/* + * 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 { METRIC_TYPES } from '@kbn/data-plugin/public'; +import { stubLogstashDataView } from '@kbn/data-views-plugin/common/data_view.stub'; +import { convertToLens } from '.'; +import { createPanel, createSeries } from '../lib/__mocks__'; + +const mockGetMetricsColumns = jest.fn(); +const mockGetBucketsColumns = jest.fn(); +const mockGetConfigurationForMetric = jest.fn(); +const mockIsValidMetrics = jest.fn(); +const mockGetDatasourceValue = jest + .fn() + .mockImplementation(() => Promise.resolve(stubLogstashDataView)); +const mockGetDataSourceInfo = jest.fn(); + +jest.mock('../../services', () => ({ + getDataViewsStart: jest.fn(() => mockGetDatasourceValue), +})); + +jest.mock('../lib/series', () => ({ + getMetricsColumns: jest.fn(() => mockGetMetricsColumns()), + getBucketsColumns: jest.fn(() => mockGetBucketsColumns()), +})); + +jest.mock('../lib/configurations/metric', () => ({ + getConfigurationForMetric: jest.fn(() => mockGetConfigurationForMetric()), +})); + +jest.mock('../lib/metrics', () => ({ + isValidMetrics: jest.fn(() => mockIsValidMetrics()), + getReducedTimeRange: jest.fn().mockReturnValue('10'), +})); + +jest.mock('../lib/datasource', () => ({ + getDataSourceInfo: jest.fn(() => mockGetDataSourceInfo()), +})); + +describe('convertToLens', () => { + const model = createPanel({ + series: [ + createSeries({ + metrics: [ + { id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }, + { id: 'some-id-1', type: METRIC_TYPES.COUNT }, + ], + }), + ], + }); + + const bucket = { + isBucketed: true, + isSplit: true, + operationType: 'terms', + params: { + exclude: [], + excludeIsRegex: true, + include: [], + includeIsRegex: true, + orderAgg: { + columnId: 'some-id-0', + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'average', + params: {}, + sourceField: 'bytes', + }, + orderBy: { columnId: 'some-id-0', type: 'column' }, + orderDirection: 'asc', + otherBucket: false, + parentFormat: { id: 'terms' }, + secondaryFields: [], + size: 3, + }, + sourceField: 'bytes', + }; + + const bucket2 = { + isBucketed: true, + isSplit: true, + operationType: 'terms', + params: { + exclude: [], + excludeIsRegex: true, + include: [], + includeIsRegex: true, + orderAgg: { + columnId: 'some-id-1', + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'average', + params: {}, + sourceField: 'bytes', + }, + orderBy: { columnId: 'some-id-1', type: 'column' }, + orderDirection: 'desc', + otherBucket: false, + parentFormat: { id: 'terms' }, + secondaryFields: [], + size: 10, + }, + sourceField: 'bytes', + }; + + const metric = { + meta: { metricId: 'some-id-0' }, + operationType: 'last_value', + params: { showArrayValues: false, sortField: '@timestamp' }, + reducedTimeRange: '10m', + }; + + beforeEach(() => { + mockIsValidMetrics.mockReturnValue(true); + mockGetDataSourceInfo.mockReturnValue({ + indexPatternId: 'test-index-pattern', + timeField: 'timeField', + indexPattern: { id: 'test-index-pattern' }, + }); + mockGetMetricsColumns.mockReturnValue([{}]); + mockGetBucketsColumns.mockReturnValue([{}]); + mockGetConfigurationForMetric.mockReturnValue({}); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + test('should return null for invalid metrics', async () => { + mockIsValidMetrics.mockReturnValue(null); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockIsValidMetrics).toBeCalledTimes(1); + }); + + test('should return null for invalid or unsupported metrics', async () => { + mockGetMetricsColumns.mockReturnValue(null); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockGetMetricsColumns).toBeCalledTimes(1); + }); + + test('should return null for invalid or unsupported buckets', async () => { + mockGetBucketsColumns.mockReturnValue(null); + const result = await convertToLens(model); + expect(result).toBeNull(); + expect(mockGetBucketsColumns).toBeCalledTimes(1); + }); + + test('should return state for valid model', async () => { + const result = await convertToLens(model); + expect(result).toBeDefined(); + expect(result?.type).toBe('lnsMetric'); + expect(mockGetBucketsColumns).toBeCalledTimes(model.series.length); + expect(mockGetConfigurationForMetric).toBeCalledTimes(1); + }); + + test('should skip hidden series', async () => { + const result = await convertToLens( + createPanel({ + series: [ + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: true, + }), + ], + }) + ); + expect(result).toBeDefined(); + expect(result?.type).toBe('lnsMetric'); + expect(mockIsValidMetrics).toBeCalledTimes(0); + }); + + test('should return null if multiple indexPatterns are provided', async () => { + mockGetDataSourceInfo.mockReturnValueOnce({ + indexPatternId: 'test-index-pattern-1', + timeField: 'timeField', + indexPattern: { id: 'test-index-pattern-1' }, + }); + + const result = await convertToLens( + createPanel({ + series: [ + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: false, + }), + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: false, + }), + ], + }) + ); + expect(result).toBeNull(); + }); + + test('should return null if visible series is 2 and bucket is 1', async () => { + mockGetBucketsColumns.mockReturnValueOnce([bucket]); + mockGetBucketsColumns.mockReturnValueOnce([]); + mockGetMetricsColumns.mockReturnValueOnce([metric]); + + const result = await convertToLens( + createPanel({ + series: [ + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: false, + }), + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: false, + }), + ], + }) + ); + expect(result).toBeNull(); + }); + + test('should return null if visible series is 2 and two not unique buckets', async () => { + mockGetBucketsColumns.mockReturnValueOnce([bucket]); + mockGetBucketsColumns.mockReturnValueOnce([bucket2]); + mockGetMetricsColumns.mockReturnValueOnce([metric]); + + const result = await convertToLens( + createPanel({ + series: [ + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: false, + }), + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: false, + }), + ], + }) + ); + expect(result).toBeNull(); + }); + + test('should return state if visible series is 2 and two unique buckets', async () => { + mockGetBucketsColumns.mockReturnValueOnce([bucket]); + mockGetBucketsColumns.mockReturnValueOnce([bucket]); + mockGetMetricsColumns.mockReturnValueOnce([metric]); + + const result = await convertToLens( + createPanel({ + series: [ + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: false, + }), + createSeries({ + metrics: [{ id: 'some-id', type: METRIC_TYPES.AVG, field: 'test-field' }], + hidden: false, + }), + ], + }) + ); + expect(result).toBeDefined(); + expect(result?.type).toBe('lnsMetric'); + expect(mockGetConfigurationForMetric).toBeCalledTimes(1); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/index.ts new file mode 100644 index 0000000000000..25f55b5a1c44c --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/index.ts @@ -0,0 +1,130 @@ +/* + * 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 uuid from 'uuid'; +import { DataView, parseTimeShift } from '@kbn/data-plugin/common'; +import { getIndexPatternIds } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { PANEL_TYPES } from '../../../common/enums'; +import { getDataViewsStart } from '../../services'; +import { getDataSourceInfo } from '../lib/datasource'; +import { getMetricsColumns, getBucketsColumns } from '../lib/series'; +import { getConfigurationForMetric as getConfiguration } from '../lib/configurations/metric'; +import { getReducedTimeRange, isValidMetrics } from '../lib/metrics'; +import { ConvertTsvbToLensVisualization } from '../types'; +import { ColumnsWithoutMeta, Layer as ExtendedLayer } from '../lib/convert'; +import { excludeMetaFromLayers, getUniqueBuckets } from './utils'; + +const MAX_SERIES = 2; +const MAX_BUCKETS = 2; + +export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeRange) => { + const dataViews = getDataViewsStart(); + const seriesNum = model.series.filter((series) => !series.hidden).length; + + const indexPatternIds = new Set(); + const visibleSeries = model.series.filter(({ hidden }) => !hidden); + let currentIndexPattern: DataView | null = null; + for (const series of visibleSeries) { + const datasourceInfo = await getDataSourceInfo( + model.index_pattern, + model.time_field, + Boolean(series.override_index_pattern), + series.series_index_pattern, + series.series_time_field, + dataViews + ); + + if (!datasourceInfo) { + return null; + } + + const { indexPatternId, indexPattern } = datasourceInfo; + indexPatternIds.add(indexPatternId); + currentIndexPattern = indexPattern; + } + + if (indexPatternIds.size > 1) { + return null; + } + + const [indexPatternId] = indexPatternIds.values(); + + const buckets = []; + const metrics = []; + + // handle multiple layers/series + for (const series of visibleSeries) { + // not valid time shift + if (series.offset_time && parseTimeShift(series.offset_time) === 'invalid') { + return null; + } + + if (!isValidMetrics(series.metrics, PANEL_TYPES.METRIC, series.time_range_mode)) { + return null; + } + + const reducedTimeRange = getReducedTimeRange(model, series, timeRange); + + // handle multiple metrics + const metricsColumns = getMetricsColumns(series, currentIndexPattern!, seriesNum, { + reducedTimeRange, + }); + if (metricsColumns === null) { + return null; + } + + const bucketsColumns = getBucketsColumns( + model, + series, + metricsColumns, + currentIndexPattern!, + false + ); + + if (bucketsColumns === null) { + return null; + } + + buckets.push(...bucketsColumns); + metrics.push(...metricsColumns); + } + + let uniqueBuckets = buckets; + if (visibleSeries.length === MAX_SERIES && buckets.length) { + if (buckets.length !== MAX_BUCKETS) { + return null; + } + + uniqueBuckets = getUniqueBuckets(buckets as ColumnsWithoutMeta[]); + if (uniqueBuckets.length !== 1) { + return null; + } + } + + const [bucket] = uniqueBuckets; + + const extendedLayer: ExtendedLayer = { + indexPatternId: indexPatternId as string, + layerId: uuid(), + columns: [...metrics, ...(bucket ? [bucket] : [])], + columnOrder: [], + }; + + const configuration = getConfiguration(model, extendedLayer, bucket); + if (!configuration) { + return null; + } + + const layers = Object.values(excludeMetaFromLayers({ 0: extendedLayer })); + return { + type: 'lnsMetric', + layers, + configuration, + indexPatternIds: getIndexPatternIds(layers), + }; +}; diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/utils.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/utils.test.ts new file mode 100644 index 0000000000000..8f880dfe95c5e --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/utils.test.ts @@ -0,0 +1,104 @@ +/* + * 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 { Column, DateHistogramColumn, TermsColumn } from '../lib/convert'; +import { getUniqueBuckets } from './utils'; + +describe('getUniqueBuckets', () => { + const bucket2: TermsColumn = { + columnId: '12', + dataType: 'string', + isBucketed: true, + isSplit: true, + operationType: 'terms', + params: { + exclude: [], + excludeIsRegex: true, + include: [], + includeIsRegex: true, + orderAgg: { + columnId: 'some-id-1', + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'average', + params: {}, + sourceField: 'bytes', + }, + orderBy: { columnId: 'some-id-1', type: 'column' }, + orderDirection: 'desc', + otherBucket: false, + parentFormat: { id: 'terms' }, + secondaryFields: [], + size: 10, + }, + sourceField: 'bytes', + }; + + it('should return unique buckets', () => { + expect(getUniqueBuckets([bucket2, bucket2])).toEqual([bucket2]); + }); + + it('should ignore columnIds', () => { + const bucketWithOtherColumnIds = { + ...bucket2, + columnId: '22', + params: { + ...bucket2.params, + orderAgg: { ...bucket2.params.orderAgg, columnId: '---1' } as Column, + orderBy: { ...bucket2.params.orderBy, columnId: '---2' } as { + type: 'column'; + columnId: string; + }, + }, + }; + expect(getUniqueBuckets([bucket2, bucketWithOtherColumnIds])).toEqual([bucket2]); + }); + + it('should respect differences of terms', () => { + const bucketWithOtherColumnIds = { + ...bucket2, + columnId: '22', + params: { + ...bucket2.params, + orderAgg: { ...bucket2.params.orderAgg, columnId: '---1' } as Column, + orderBy: { ...bucket2.params.orderBy, columnId: '---2' } as { + type: 'column'; + columnId: string; + }, + }, + sourceField: 'name', + }; + expect(getUniqueBuckets([bucket2, bucketWithOtherColumnIds])).toEqual([ + bucket2, + bucketWithOtherColumnIds, + ]); + }); + + it('should respect differences of other buckets', () => { + const bucket: DateHistogramColumn = { + dataType: 'number', + isBucketed: true, + isSplit: false, + operationType: 'date_histogram', + params: { dropPartials: false, includeEmptyRows: true, interval: 'auto' }, + sourceField: 'field1', + columnId: '1', + }; + const bucket1 = { + ...bucket, + columnId: '22', + }; + expect(getUniqueBuckets([bucket, bucket1])).toEqual([bucket]); + const bucket3 = { + ...bucket, + field: 'some-other-field', + }; + expect(getUniqueBuckets([bucket, bucket3])).toEqual([bucket, bucket3]); + }); +}); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/utils.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/utils.ts new file mode 100644 index 0000000000000..8df1b0f40f8be --- /dev/null +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/utils.ts @@ -0,0 +1,65 @@ +/* + * 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 { uniqWith } from 'lodash'; +import deepEqual from 'react-fast-compare'; +import { Layer, Operations, TermsColumn } from '@kbn/visualizations-plugin/common/convert_to_lens'; +import { Layer as ExtendedLayer, excludeMetaFromColumn, ColumnsWithoutMeta } from '../lib/convert'; + +export const excludeMetaFromLayers = ( + layers: Record +): Record => { + const newLayers: Record = {}; + Object.entries(layers).forEach(([layerId, layer]) => { + const columns = layer.columns.map(excludeMetaFromColumn); + newLayers[layerId] = { ...layer, columns }; + }); + + return newLayers; +}; + +const excludeColumnIdsFromBucket = (bucket: ColumnsWithoutMeta) => { + const { columnId, ...restBucket } = bucket; + if (bucket.operationType === Operations.TERMS) { + const { orderBy, orderAgg, ...restParams } = bucket.params; + let orderByWithoutColumn: Omit = orderBy; + if ('columnId' in orderBy) { + const { columnId: orderByColumnId, ...restOrderBy } = orderBy; + orderByWithoutColumn = restOrderBy; + } + + let orderAggWithoutColumn: Omit | undefined = + orderAgg; + if (orderAgg) { + const { columnId: cId, ...restOrderAgg } = orderAgg; + orderAggWithoutColumn = restOrderAgg; + } + + return { + ...restBucket, + params: { + ...restParams, + orderBy: orderByWithoutColumn, + orderAgg: orderAggWithoutColumn, + }, + }; + } + return restBucket; +}; + +export const getUniqueBuckets = (buckets: ColumnsWithoutMeta[]) => + uniqWith(buckets, (bucket1, bucket2) => { + if (bucket1.operationType !== bucket2.operationType) { + return false; + } + + const bucketWithoutColumnIds1 = excludeColumnIdsFromBucket(bucket1); + const bucketWithoutColumnIds2 = excludeColumnIdsFromBucket(bucket2); + + return deepEqual(bucketWithoutColumnIds1, bucketWithoutColumnIds2); + }); diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts index 4610310c1b378..8cbbbf0f9e739 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/timeseries/index.ts @@ -86,7 +86,9 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model: Panel return null; } // handle multiple metrics - const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum); + const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum, { + isStaticValueColumnSupported: true, + }); if (metricsColumns === null) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts index 630a9e5cf4c97..020aaec28f573 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/top_n/index.ts @@ -65,7 +65,9 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (model, timeR const reducedTimeRange = getReducedTimeRange(model, series, timeRange); // handle multiple metrics - const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum, reducedTimeRange); + const metricsColumns = getMetricsColumns(series, indexPattern!, seriesNum, { + reducedTimeRange, + }); if (!metricsColumns) { return null; } diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts index acee3c2a1e83a..69a90c7864eb3 100644 --- a/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts +++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/types.ts @@ -6,14 +6,18 @@ * Side Public License, v 1. */ -import { NavigateToLensContext, XYConfiguration } from '@kbn/visualizations-plugin/common'; +import { + MetricVisConfiguration, + NavigateToLensContext, + XYConfiguration, +} from '@kbn/visualizations-plugin/common'; import { TimeRange } from '@kbn/data-plugin/common'; import type { Panel } from '../../common/types'; export type ConvertTsvbToLensVisualization = ( model: Panel, timeRange?: TimeRange -) => Promise | null>; +) => Promise | null>; export interface Filter { kql?: string | { [key: string]: any } | undefined; diff --git a/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts b/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts index 8c348fec4c2fa..fc1e440db3506 100644 --- a/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts +++ b/src/plugins/visualizations/common/convert_to_lens/types/configurations.ts @@ -6,9 +6,9 @@ * Side Public License, v 1. */ -import { HorizontalAlignment, Position, VerticalAlignment } from '@elastic/charts'; +import { HorizontalAlignment, LayoutDirection, Position, VerticalAlignment } from '@elastic/charts'; import { $Values } from '@kbn/utility-types'; -import type { PaletteOutput } from '@kbn/coloring'; +import type { CustomPaletteParams, PaletteOutput } from '@kbn/coloring'; import { KibanaQueryOutput } from '@kbn/data-plugin/common'; import { LegendSize } from '../../constants'; @@ -199,4 +199,22 @@ export interface TableVisConfiguration { paging?: PagingState; } -export type Configuration = XYConfiguration | TableVisConfiguration; +export interface MetricVisConfiguration { + layerId: string; + layerType: 'data'; + metricAccessor?: string; + secondaryMetricAccessor?: string; + maxAccessor?: string; + breakdownByAccessor?: string; + // the dimensions can optionally be single numbers + // computed by collapsing all rows + collapseFn?: string; + subtitle?: string; + secondaryPrefix?: string; + progressDirection?: LayoutDirection; + color?: string; + palette?: PaletteOutput; + maxCols?: number; +} + +export type Configuration = XYConfiguration | TableVisConfiguration | MetricVisConfiguration; diff --git a/x-pack/plugins/aiops/public/components/log_categorization/information_text.tsx b/x-pack/plugins/aiops/public/components/log_categorization/information_text.tsx new file mode 100644 index 0000000000000..bf80b55fee37c --- /dev/null +++ b/x-pack/plugins/aiops/public/components/log_categorization/information_text.tsx @@ -0,0 +1,101 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; + +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiEmptyPrompt } from '@elastic/eui'; + +interface Props { + eventRateLength: number; + fieldSelected: boolean; + categoriesLength: number | null; + loading: boolean; +} + +export const InformationText: FC = ({ + eventRateLength, + fieldSelected, + categoriesLength, + loading, +}) => { + if (loading === true) { + return null; + } + return ( + <> + {eventRateLength === 0 ? ( + + + + } + titleSize="xs" + body={ +

+ +

+ } + data-test-subj="aiopsNoWindowParametersEmptyPrompt" + /> + ) : null} + + {eventRateLength > 0 && categoriesLength === null ? ( + + + + } + titleSize="xs" + body={ +

+ +

+ } + data-test-subj="aiopsNoWindowParametersEmptyPrompt" + /> + ) : null} + + {eventRateLength > 0 && categoriesLength !== null && categoriesLength === 0 ? ( + + + + } + titleSize="xs" + body={ +

+ +

+ } + data-test-subj="aiopsNoWindowParametersEmptyPrompt" + /> + ) : null} + + ); +}; diff --git a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_page.tsx b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_page.tsx index 845a4239f1104..4eb6da0e58b9f 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_page.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_page.tsx @@ -40,6 +40,7 @@ import { useCategorizeRequest } from './use_categorize_request'; import type { EventRate, Category, SparkLinesPerCategory } from './use_categorize_request'; import { CategoryTable } from './category_table'; import { DocumentCountChart } from './document_count_chart'; +import { InformationText } from './information_text'; export interface LogCategorizationPageProps { dataView: DataView; @@ -160,6 +161,7 @@ export const LogCategorizationPage: FC = ({ docCount, })) ); + setCategories(null); setTotalCount(documentStats.totalCount); } }, [documentStats, earliest, latest, searchQueryLanguage, searchString, searchQuery]); @@ -210,6 +212,7 @@ export const LogCategorizationPage: FC = ({ ]); const onFieldChange = (value: EuiComboBoxOptionOption[] | undefined) => { + setCategories(null); setSelectedField(value && value.length ? value[0].label : undefined); }; @@ -313,8 +316,17 @@ export const LogCategorizationPage: FC = ({ ) : null} + {loading === true ? : null} - {categories !== null ? ( + + + + {selectedField !== undefined && categories !== null && categories.length > 0 ? ( typeof s.id === 'undefined') || []; + + return { + snoozeSchedule: [...unscheduledSnooze, ...newSchedules], + muteAll: attributes.muteAll, + }; + } + + // Bulk unsnoozing, don't touch current snooze schedules that are NOT active + return { + snoozeSchedule: clearCurrentActiveSnooze(attributes), + muteAll: false, + }; +} + function clearUnscheduledSnooze(attributes: RawRule) { // Clear any snoozes that have no ID property. These are "simple" snoozes created with the quick UI, e.g. snooze for 3 days starting now return attributes.snoozeSchedule diff --git a/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts index 1cafcd652349a..5e440d2e6b6d7 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/bulk_edit.test.ts @@ -26,9 +26,11 @@ jest.mock('../../invalidate_pending_api_keys/bulk_mark_api_keys_for_invalidation })); jest.mock('../../lib/snooze/is_snooze_active', () => ({ - isSnoozeActive: jest.fn(() => true), + isSnoozeActive: jest.fn(), })); +const { isSnoozeActive } = jest.requireMock('../../lib/snooze/is_snooze_active'); + const taskManager = taskManagerMock.createStart(); const ruleTypeRegistry = ruleTypeRegistryMock.create(); const unsecuredSavedObjectsClient = savedObjectsClientMock.create(); @@ -310,9 +312,13 @@ describe('bulkEdit()', () => { }); describe('snoozeSchedule operations', () => { - const getSnoozeSchedule = () => { + afterEach(() => { + isSnoozeActive.mockImplementation(() => false); + }); + + const getSnoozeSchedule = (useId: boolean = true) => { return { - id: uuid.v4(), + ...(useId && { id: uuid.v4() }), duration: 28800000, rRule: { dtstart: '2010-09-19T11:49:59.329Z', @@ -321,8 +327,10 @@ describe('bulkEdit()', () => { }, }; }; - test('should add snooze', async () => { - unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const getMockAttribute = (override: Record = {}) => { + return { saved_objects: [ { id: '1', @@ -339,15 +347,137 @@ describe('bulkEdit()', () => { notifyWhen: null, actions: [], snoozeSchedule: [], + ...override, }, references: [], version: '123', }, ], + }; + }; + + test('should snooze', async () => { + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue(getMockAttribute()); + const snoozePayload = getSnoozeSchedule(false); + await rulesClient.bulkEdit({ + filter: '', + operations: [ + { + operation: 'set', + field: 'snoozeSchedule', + value: snoozePayload, + }, + ], + }); + + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledTimes(1); + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledWith( + [ + expect.objectContaining({ + id: '1', + type: 'alert', + attributes: expect.objectContaining({ + snoozeSchedule: [snoozePayload], + }), + }), + ], + { overwrite: true } + ); + }); + + test('should add snooze schedule', async () => { + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue(getMockAttribute()); + + const snoozePayload = getSnoozeSchedule(); + await rulesClient.bulkEdit({ + filter: '', + operations: [ + { + operation: 'set', + field: 'snoozeSchedule', + value: snoozePayload, + }, + ], + }); + + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledTimes(1); + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledWith( + [ + expect.objectContaining({ + id: '1', + type: 'alert', + attributes: expect.objectContaining({ + snoozeSchedule: [snoozePayload], + }), + }), + ], + { overwrite: true } + ); + }); + + test('should not unsnooze a snoozed rule when bulk adding snooze schedules', async () => { + const existingSnooze = [getSnoozeSchedule(false), getSnoozeSchedule()]; + + mockCreatePointInTimeFinderAsInternalUser({ + saved_objects: [ + { + ...existingDecryptedRule, + attributes: { + ...existingDecryptedRule.attributes, + snoozeSchedule: existingSnooze, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any, + }, + ], }); + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue(getMockAttribute()); + const snoozePayload = getSnoozeSchedule(); + await rulesClient.bulkEdit({ + filter: '', + operations: [ + { + operation: 'set', + field: 'snoozeSchedule', + value: snoozePayload, + }, + ], + }); + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledTimes(1); + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledWith( + [ + expect.objectContaining({ + id: '1', + type: 'alert', + attributes: expect.objectContaining({ + snoozeSchedule: [...existingSnooze, snoozePayload], + }), + }), + ], + { overwrite: true } + ); + }); + + test('should not unsnooze an indefinitely snoozed rule when bulk adding snooze schedules', async () => { + mockCreatePointInTimeFinderAsInternalUser({ + saved_objects: [ + { + ...existingDecryptedRule, + attributes: { + ...existingDecryptedRule.attributes, + muteAll: true, + snoozeSchedule: [], + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any, + }, + ], + }); + + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue(getMockAttribute()); + + const snoozePayload = getSnoozeSchedule(); await rulesClient.bulkEdit({ filter: '', operations: [ @@ -366,6 +496,7 @@ describe('bulkEdit()', () => { id: '1', type: 'alert', attributes: expect.objectContaining({ + muteAll: true, snoozeSchedule: [snoozePayload], }), }), @@ -374,39 +505,74 @@ describe('bulkEdit()', () => { ); }); - test('should delete snooze', async () => { - const existingSnooze = [getSnoozeSchedule(), getSnoozeSchedule()]; + test('should unsnooze', async () => { + const existingSnooze = [getSnoozeSchedule(false), getSnoozeSchedule(), getSnoozeSchedule()]; - unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ + mockCreatePointInTimeFinderAsInternalUser({ saved_objects: [ { + ...existingDecryptedRule, + attributes: { + ...existingDecryptedRule.attributes, + snoozeSchedule: existingSnooze, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any, + }, + ], + }); + + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue(getMockAttribute()); + + await rulesClient.bulkEdit({ + filter: '', + operations: [ + { + operation: 'delete', + field: 'snoozeSchedule', + }, + ], + }); + + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledTimes(1); + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledWith( + [ + expect.objectContaining({ id: '1', type: 'alert', + attributes: expect.objectContaining({ + snoozeSchedule: [existingSnooze[1], existingSnooze[2]], + }), + }), + ], + { overwrite: true } + ); + }); + + test('should remove snooze schedules', async () => { + const existingSnooze = [getSnoozeSchedule(), getSnoozeSchedule()]; + + mockCreatePointInTimeFinderAsInternalUser({ + saved_objects: [ + { + ...existingDecryptedRule, attributes: { - enabled: true, - tags: ['foo', 'test-1'], - alertTypeId: 'myType', - schedule: { interval: '1m' }, - consumer: 'myApp', - scheduledTaskId: 'task-123', - params: {}, - throttle: null, - notifyWhen: null, - actions: [], + ...existingDecryptedRule.attributes, snoozeSchedule: existingSnooze, - }, - references: [], - version: '123', + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any, }, ], }); + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue(getMockAttribute()); + await rulesClient.bulkEdit({ filter: '', operations: [ { operation: 'delete', field: 'snoozeSchedule', + value: [], }, ], }); @@ -426,14 +592,8 @@ describe('bulkEdit()', () => { ); }); - test('should error if adding snooze schedule to rule with 5 schedules', async () => { - const existingSnooze = [ - getSnoozeSchedule(), - getSnoozeSchedule(), - getSnoozeSchedule(), - getSnoozeSchedule(), - getSnoozeSchedule(), - ]; + test('should not unsnooze rule when removing snooze schedules', async () => { + const existingSnooze = [getSnoozeSchedule(false), getSnoozeSchedule(), getSnoozeSchedule()]; mockCreatePointInTimeFinderAsInternalUser({ saved_objects: [ @@ -448,30 +608,58 @@ describe('bulkEdit()', () => { ], }); - unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ - saved_objects: [ + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue(getMockAttribute()); + + await rulesClient.bulkEdit({ + filter: '', + operations: [ { + operation: 'delete', + field: 'snoozeSchedule', + value: [], + }, + ], + }); + + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledTimes(1); + expect(unsecuredSavedObjectsClient.bulkCreate).toHaveBeenCalledWith( + [ + expect.objectContaining({ id: '1', type: 'alert', + attributes: expect.objectContaining({ + snoozeSchedule: [existingSnooze[0]], + }), + }), + ], + { overwrite: true } + ); + }); + + test('should error if adding snooze schedule to rule with 5 schedules', async () => { + const existingSnooze = [ + getSnoozeSchedule(), + getSnoozeSchedule(), + getSnoozeSchedule(), + getSnoozeSchedule(), + getSnoozeSchedule(), + ]; + + mockCreatePointInTimeFinderAsInternalUser({ + saved_objects: [ + { + ...existingDecryptedRule, attributes: { - enabled: true, - tags: ['foo', 'test-1'], - alertTypeId: 'myType', - schedule: { interval: '1m' }, - consumer: 'myApp', - scheduledTaskId: 'task-123', - params: {}, - throttle: null, - notifyWhen: null, - actions: [], + ...existingDecryptedRule.attributes, snoozeSchedule: existingSnooze, - }, - references: [], - version: '123', + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } as any, }, ], }); + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue(getMockAttribute()); + const snoozePayload = getSnoozeSchedule(); const response = await rulesClient.bulkEdit({ @@ -501,29 +689,7 @@ describe('bulkEdit()', () => { ], }); - unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue({ - saved_objects: [ - { - id: '1', - type: 'alert', - attributes: { - enabled: true, - tags: ['foo', 'test-1'], - alertTypeId: 'myType', - schedule: { interval: '1m' }, - consumer: 'myApp', - scheduledTaskId: 'task-123', - params: {}, - throttle: null, - notifyWhen: null, - actions: [], - snoozeSchedule: [], - }, - references: [], - version: '123', - }, - ], - }); + unsecuredSavedObjectsClient.bulkCreate.mockResolvedValue(getMockAttribute()); const snoozePayload = getSnoozeSchedule(); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/find.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/find.test.ts index e26004de99a31..4cfa13f69b84d 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/find.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/find.test.ts @@ -176,7 +176,7 @@ describe('find()', () => { Array [ Object { "fields": undefined, - "filter": undefined, + "filter": null, "sortField": undefined, "type": "alert", }, @@ -277,7 +277,7 @@ describe('find()', () => { Array [ Object { "fields": undefined, - "filter": undefined, + "filter": null, "sortField": undefined, "type": "alert", }, @@ -730,6 +730,8 @@ describe('find()', () => { expect(unsecuredSavedObjectsClient.find).toHaveBeenCalledWith({ fields: ['tags', 'alertTypeId', 'consumer'], + filter: null, + sortField: undefined, type: 'alert', }); expect(ensureRuleTypeIsAuthorized).toHaveBeenCalledWith('myType', 'myApp', 'rule'); diff --git a/x-pack/plugins/cases/public/components/user_profiles/no_matches.test.tsx b/x-pack/plugins/cases/public/components/user_profiles/no_matches.test.tsx index 3471aad3fec3c..e2d23dfd988e1 100644 --- a/x-pack/plugins/cases/public/components/user_profiles/no_matches.test.tsx +++ b/x-pack/plugins/cases/public/components/user_profiles/no_matches.test.tsx @@ -13,6 +13,6 @@ describe('NoMatches', () => { it('renders the no matches messages', () => { render(); - expect(screen.getByText('No matching users with required access.')); + expect(screen.getByText("User doesn't exist or is unavailable")); }); }); diff --git a/x-pack/plugins/cases/public/components/user_profiles/no_matches.tsx b/x-pack/plugins/cases/public/components/user_profiles/no_matches.tsx index 638d705fade86..ccd27b123f235 100644 --- a/x-pack/plugins/cases/public/components/user_profiles/no_matches.tsx +++ b/x-pack/plugins/cases/public/components/user_profiles/no_matches.tsx @@ -5,7 +5,15 @@ * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiSpacer, EuiText, EuiTextAlign } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiLink, + EuiSpacer, + EuiText, + EuiTextAlign, +} from '@elastic/eui'; import React from 'react'; import * as i18n from './translations'; @@ -25,11 +33,18 @@ const NoMatchesComponent: React.FC = () => { - {i18n.NO_MATCHING_USERS} + {i18n.USER_DOES_NOT_EXIST}
- {i18n.TRY_MODIFYING_SEARCH} + {i18n.MODIFY_SEARCH} +
+ + {i18n.LEARN_PRIVILEGES_GRANT_ACCESS} +
diff --git a/x-pack/plugins/cases/public/components/user_profiles/translations.ts b/x-pack/plugins/cases/public/components/user_profiles/translations.ts index db76408759bec..2624ec834cd2e 100644 --- a/x-pack/plugins/cases/public/components/user_profiles/translations.ts +++ b/x-pack/plugins/cases/public/components/user_profiles/translations.ts @@ -44,12 +44,19 @@ export const ASSIGNEES = i18n.translate('xpack.cases.userProfile.assigneesTitle' defaultMessage: 'Assignees', }); -export const NO_MATCHING_USERS = i18n.translate('xpack.cases.userProfiles.noMatchingUsers', { - defaultMessage: 'No matching users with required access.', +export const USER_DOES_NOT_EXIST = i18n.translate('xpack.cases.userProfiles.userDoesNotExist', { + defaultMessage: "User doesn't exist or is unavailable", }); -export const TRY_MODIFYING_SEARCH = i18n.translate('xpack.cases.userProfiles.tryModifyingSearch', { - defaultMessage: 'Try modifying your search.', +export const LEARN_PRIVILEGES_GRANT_ACCESS = i18n.translate( + 'xpack.cases.userProfiles.learnPrivileges', + { + defaultMessage: 'Learn what privileges grant access to cases.', + } +); + +export const MODIFY_SEARCH = i18n.translate('xpack.cases.userProfiles.modifySearch', { + defaultMessage: "Modify your search or check the user's privileges.", }); export const INVALID_ASSIGNEES = i18n.translate('xpack.cases.create.invalidAssignees', { diff --git a/x-pack/plugins/enterprise_search/common/types/pipelines.ts b/x-pack/plugins/enterprise_search/common/types/pipelines.ts index 60fd87ca523b9..269f7149cc7b3 100644 --- a/x-pack/plugins/enterprise_search/common/types/pipelines.ts +++ b/x-pack/plugins/enterprise_search/common/types/pipelines.ts @@ -6,7 +6,16 @@ */ export interface InferencePipeline { - isDeployed: boolean; + modelState: TrainedModelState; + modelStateReason?: string; pipelineName: string; types: string[]; } + +export enum TrainedModelState { + NotDeployed = '', + Starting = 'starting', + Stopping = 'stopping', + Started = 'started', + Failed = 'failed', +} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.test.tsx index 1c79cff0244e3..27dc055564bd8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.test.tsx @@ -11,14 +11,16 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { EuiBadge, EuiHealth, EuiPanel, EuiTitle } from '@elastic/eui'; +import { EuiBadge, EuiPanel, EuiTitle } from '@elastic/eui'; + +import { InferencePipeline, TrainedModelState } from '../../../../../../common/types/pipelines'; import { InferencePipelineCard } from './inference_pipeline_card'; +import { TrainedModelHealth } from './ml_model_health'; -export const DEFAULT_VALUES = { - isDeployed: true, +export const DEFAULT_VALUES: InferencePipeline = { + modelState: TrainedModelState.Started, pipelineName: 'Sample Processor', - trainedModelName: 'example_trained_model', types: ['pytorch'], }; @@ -34,8 +36,6 @@ describe('InferencePipelineCard', () => { expect(wrapper.find(EuiPanel)).toHaveLength(1); expect(wrapper.find(EuiTitle)).toHaveLength(1); expect(wrapper.find(EuiBadge)).toHaveLength(1); - - const health = wrapper.find(EuiHealth); - expect(health.prop('children')).toEqual('Deployed'); + expect(wrapper.find(TrainedModelHealth)).toHaveLength(1); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.tsx index b73121f947d73..e8017ff15a198 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/inference_pipeline_card.tsx @@ -12,31 +12,30 @@ import { useActions, useValues } from 'kea'; import { EuiBadge, EuiButtonEmpty, + EuiButtonIcon, EuiConfirmModal, EuiFlexGroup, EuiFlexItem, - EuiHealth, EuiPanel, EuiPopover, EuiPopoverTitle, EuiText, EuiTitle, + EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { InferencePipeline } from '../../../../../../common/types/pipelines'; +import { InferencePipeline, TrainedModelState } from '../../../../../../common/types/pipelines'; import { CANCEL_BUTTON_LABEL, DELETE_BUTTON_LABEL } from '../../../../shared/constants'; import { HttpLogic } from '../../../../shared/http'; +import { ML_MANAGE_TRAINED_MODELS_PATH } from '../../../routes'; import { IndexNameLogic } from '../index_name_logic'; +import { TrainedModelHealth } from './ml_model_health'; import { PipelinesLogic } from './pipelines_logic'; -export const InferencePipelineCard: React.FC = ({ - pipelineName, - isDeployed, - types, -}) => { +export const InferencePipelineCard: React.FC = (pipeline) => { const { http } = useValues(HttpLogic); const { indexName } = useValues(IndexNameLogic); const [isPopOverOpen, setIsPopOverOpen] = useState(false); @@ -46,10 +45,7 @@ export const InferencePipelineCard: React.FC = ({ setShowConfirmDelete(true); setIsPopOverOpen(false); }; - - const deployedText = i18n.translate('xpack.enterpriseSearch.inferencePipelineCard.isDeployed', { - defaultMessage: 'Deployed', - }); + const { pipelineName, types } = pipeline; const actionButton = ( = ({ - - {isDeployed && ( - - {deployedText} + + + + + {pipeline.modelState === TrainedModelState.NotDeployed && ( + + + + )} {types.map((type) => ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ingest_pipelines_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ingest_pipelines_card.tsx index ca6140b7b9625..7bf1ef06e1e75 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ingest_pipelines_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ingest_pipelines_card.tsx @@ -26,6 +26,7 @@ import { KibanaLogic } from '../../../../shared/kibana'; import { LicensingLogic } from '../../../../shared/licensing'; import { CreateCustomPipelineApiLogic } from '../../../api/index/create_custom_pipeline_api_logic'; import { FetchCustomPipelineApiLogic } from '../../../api/index/fetch_custom_pipeline_api_logic'; +import { isApiIndex } from '../../../utils/indices'; import { CurlRequest } from '../components/curl_request/curl_request'; import { IndexViewLogic } from '../index_view_logic'; @@ -36,7 +37,7 @@ import { PipelinesLogic } from './pipelines_logic'; export const IngestPipelinesCard: React.FC = () => { const { indexName } = useValues(IndexViewLogic); - const { canSetPipeline, pipelineState, showModal } = useValues(PipelinesLogic); + const { canSetPipeline, index, pipelineState, showModal } = useValues(PipelinesLogic); const { closeModal, openModal, setPipelineState, savePipeline } = useActions(PipelinesLogic); const { makeRequest: fetchCustomPipeline } = useActions(FetchCustomPipelineApiLogic); const { makeRequest: createCustomPipeline } = useActions(CreateCustomPipelineApiLogic); @@ -97,22 +98,24 @@ export const IngestPipelinesCard: React.FC = () => { - - - - - - + + {isApiIndex(index) && ( + + + + + + )} {i18n.translate( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_model_health.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_model_health.test.tsx new file mode 100644 index 0000000000000..0eb88abb317e5 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_model_health.test.tsx @@ -0,0 +1,81 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { setMockValues } from '../../../../__mocks__/kea_logic'; + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { EuiHealth } from '@elastic/eui'; + +import { InferencePipeline, TrainedModelState } from '../../../../../../common/types/pipelines'; + +import { TrainedModelHealth } from './ml_model_health'; + +describe('TrainedModelHealth', () => { + beforeEach(() => { + jest.clearAllMocks(); + setMockValues({}); + }); + + const commonModelData: InferencePipeline = { + modelState: TrainedModelState.NotDeployed, + pipelineName: 'Sample Processor', + types: ['pytorch'], + }; + it('renders model started', () => { + const pipeline: InferencePipeline = { + ...commonModelData, + modelState: TrainedModelState.Started, + }; + const wrapper = shallow(); + const health = wrapper.find(EuiHealth); + expect(health.prop('children')).toEqual('Started'); + expect(health.prop('color')).toEqual('success'); + }); + it('renders model not deployed', () => { + const pipeline: InferencePipeline = { + ...commonModelData, + }; + const wrapper = shallow(); + const health = wrapper.find(EuiHealth); + expect(health.prop('children')).toEqual('Not deployed'); + expect(health.prop('color')).toEqual('danger'); + }); + it('renders model stopping', () => { + const pipeline: InferencePipeline = { + ...commonModelData, + modelState: TrainedModelState.Stopping, + }; + const wrapper = shallow(); + const health = wrapper.find(EuiHealth); + expect(health.prop('children')).toEqual('Stopping'); + expect(health.prop('color')).toEqual('warning'); + }); + it('renders model starting', () => { + const pipeline: InferencePipeline = { + ...commonModelData, + modelState: TrainedModelState.Starting, + }; + const wrapper = shallow(); + const health = wrapper.find(EuiHealth); + expect(health.prop('children')).toEqual('Starting'); + expect(health.prop('color')).toEqual('warning'); + }); + it('renders model failed', () => { + const pipeline: InferencePipeline = { + ...commonModelData, + modelState: TrainedModelState.Failed, + modelStateReason: 'Model start boom.', + }; + const wrapper = shallow(); + const health = wrapper.find(EuiHealth); + expect(health.prop('children')).toEqual('Deployment failed'); + expect(health.prop('color')).toEqual('danger'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_model_health.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_model_health.tsx new file mode 100644 index 0000000000000..0d47c7018d4fe --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_model_health.tsx @@ -0,0 +1,144 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiHealth, EuiToolTip } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { InferencePipeline, TrainedModelState } from '../../../../../../common/types/pipelines'; + +const modelStartedText = i18n.translate( + 'xpack.enterpriseSearch.inferencePipelineCard.modelState.started', + { + defaultMessage: 'Started', + } +); +const modelStartedTooltip = i18n.translate( + 'xpack.enterpriseSearch.inferencePipelineCard.modelState.started.tooltip', + { + defaultMessage: 'This trained model is running and fully available', + } +); +const modelStartingText = i18n.translate( + 'xpack.enterpriseSearch.inferencePipelineCard.modelState.starting', + { + defaultMessage: 'Starting', + } +); +const modelStartingTooltip = i18n.translate( + 'xpack.enterpriseSearch.inferencePipelineCard.modelState.starting.tooltip', + { + defaultMessage: + 'This trained model is in the process of starting up and will be available shortly', + } +); +const modelStoppingText = i18n.translate( + 'xpack.enterpriseSearch.inferencePipelineCard.modelState.stopping', + { + defaultMessage: 'Stopping', + } +); +const modelStoppingTooltip = i18n.translate( + 'xpack.enterpriseSearch.inferencePipelineCard.modelState.stopping.tooltip', + { + defaultMessage: + 'This trained model is in the process of shutting down and is currently unavailable', + } +); +const modelDeploymentFailedText = i18n.translate( + 'xpack.enterpriseSearch.inferencePipelineCard.modelState.deploymentFailed', + { + defaultMessage: 'Deployment failed', + } +); +const modelNotDeployedText = i18n.translate( + 'xpack.enterpriseSearch.inferencePipelineCard.modelState.notDeployed', + { + defaultMessage: 'Not deployed', + } +); +const modelNotDeployedTooltip = i18n.translate( + 'xpack.enterpriseSearch.inferencePipelineCard.modelState.notDeployed.tooltip', + { + defaultMessage: + 'This trained model is not currently deployed. Visit the trained models page to make changes', + } +); + +export const TrainedModelHealth: React.FC = ({ + modelState, + modelStateReason, +}) => { + let modelHealth: { + healthColor: string; + healthText: React.ReactNode; + tooltipText: React.ReactNode; + }; + switch (modelState) { + case TrainedModelState.Started: + modelHealth = { + healthColor: 'success', + healthText: modelStartedText, + tooltipText: modelStartedTooltip, + }; + break; + case TrainedModelState.Stopping: + modelHealth = { + healthColor: 'warning', + healthText: modelStoppingText, + tooltipText: modelStoppingTooltip, + }; + break; + case TrainedModelState.Starting: + modelHealth = { + healthColor: 'warning', + healthText: modelStartingText, + tooltipText: modelStartingTooltip, + }; + break; + case TrainedModelState.Failed: + modelHealth = { + healthColor: 'danger', + healthText: modelDeploymentFailedText, + tooltipText: ( + + ), + }; + break; + case TrainedModelState.NotDeployed: + modelHealth = { + healthColor: 'danger', + healthText: modelNotDeployedText, + tooltipText: modelNotDeployedTooltip, + }; + break; + } + return ( + + {modelHealth.healthText} + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts index 60260dcaa5377..a980402119062 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts @@ -21,3 +21,5 @@ export const SEARCH_INDEX_PATH = `${SEARCH_INDICES_PATH}/:indexName`; export const SEARCH_INDEX_TAB_PATH = `${SEARCH_INDEX_PATH}/:tabId`; export const SEARCH_INDEX_CRAWLER_DOMAIN_DETAIL_PATH = `${SEARCH_INDEX_PATH}/crawler/domains/:domainId`; export const SEARCH_INDEX_SELECT_CONNECTOR_PATH = `${SEARCH_INDEX_PATH}/select_connector`; + +export const ML_MANAGE_TRAINED_MODELS_PATH = '/app/ml/trained_models'; diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.test.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.test.ts index 9a34bb42ec876..79d4600bb31e4 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.test.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.test.ts @@ -9,7 +9,7 @@ import { MlTrainedModelConfig } from '@elastic/elasticsearch/lib/api/typesWithBo import { ElasticsearchClient } from '@kbn/core/server'; import { BUILT_IN_MODEL_TAG } from '@kbn/ml-plugin/common/constants/data_frame_analytics'; -import { InferencePipeline } from '../../../common/types/pipelines'; +import { InferencePipeline, TrainedModelState } from '../../../common/types/pipelines'; import { fetchAndAddTrainedModelData, @@ -169,35 +169,74 @@ const mockGetTrainedModelsData = { model_type: 'pytorch', tags: [], }, + { + inference_config: { text_classification: {} }, + model_id: 'trained-model-id-3', + model_type: 'pytorch', + tags: [], + }, + { + inference_config: { fill_mask: {} }, + model_id: 'trained-model-id-4', + model_type: 'pytorch', + tags: [], + }, ], }; const mockGetTrainedModelStats = { - count: 1, + count: 4, trained_model_stats: [ { model_id: 'trained-model-id-1', }, { deployment_stats: { + allocation_status: { + allocation_count: 1, + }, state: 'started', }, model_id: 'trained-model-id-2', }, + { + deployment_stats: { + allocation_status: { + allocation_count: 1, + }, + state: 'failed', + reason: 'something is wrong, boom', + }, + model_id: 'trained-model-id-3', + }, + { + deployment_stats: { + allocation_status: { + allocation_count: 1, + }, + state: 'starting', + }, + model_id: 'trained-model-id-4', + }, ], }; -const trainedModelDataObject = { +const trainedModelDataObject: Record = { 'trained-model-id-1': { - isDeployed: false, + modelState: TrainedModelState.NotDeployed, pipelineName: 'ml-inference-pipeline-1', types: ['lang_ident', 'ner'], }, 'trained-model-id-2': { - isDeployed: true, + modelState: TrainedModelState.Started, pipelineName: 'ml-inference-pipeline-2', types: ['pytorch', 'ner'], }, + 'ml-inference-pipeline-3': { + modelState: TrainedModelState.NotDeployed, + pipelineName: 'ml-inference-pipeline-3', + types: ['lang_ident', 'ner'], + }, }; describe('fetchMlInferencePipelineProcessorNames lib function', () => { @@ -254,15 +293,15 @@ describe('fetchPipelineProcessorInferenceData lib function', () => { it('should return the inference processor data for the pipelines', async () => { mockClient.ingest.getPipeline.mockImplementation(() => Promise.resolve(mockGetPipeline2)); - const expected = [ + const expected: InferencePipelineData[] = [ { - isDeployed: false, + modelState: TrainedModelState.NotDeployed, pipelineName: 'ml-inference-pipeline-1', trainedModelName: 'trained-model-id-1', types: [], }, { - isDeployed: false, + modelState: TrainedModelState.NotDeployed, pipelineName: 'ml-inference-pipeline-2', trainedModelName: 'trained-model-id-2', types: [], @@ -338,20 +377,20 @@ describe('getMlModelConfigsForModelIds lib function', () => { Promise.resolve(mockGetTrainedModelStats) ); - const input = { + const input: Record = { 'trained-model-id-1': { - isDeployed: true, + modelState: TrainedModelState.Started, pipelineName: '', trainedModelName: 'trained-model-id-1', types: ['pytorch', 'ner'], }, 'trained-model-id-2': { - isDeployed: true, + modelState: TrainedModelState.Started, pipelineName: '', trainedModelName: 'trained-model-id-2', types: ['pytorch', 'ner'], }, - } as Record; + }; const expected = { 'trained-model-id-2': input['trained-model-id-2'], @@ -392,32 +431,57 @@ describe('fetchAndAddTrainedModelData lib function', () => { const pipelines: InferencePipelineData[] = [ { - isDeployed: false, + modelState: TrainedModelState.NotDeployed, pipelineName: 'ml-inference-pipeline-1', trainedModelName: 'trained-model-id-1', types: [], }, { - isDeployed: false, + modelState: TrainedModelState.NotDeployed, pipelineName: 'ml-inference-pipeline-2', trainedModelName: 'trained-model-id-2', types: [], }, + { + modelState: TrainedModelState.NotDeployed, + pipelineName: 'ml-inference-pipeline-3', + trainedModelName: 'trained-model-id-3', + types: [], + }, + { + modelState: TrainedModelState.NotDeployed, + pipelineName: 'ml-inference-pipeline-4', + trainedModelName: 'trained-model-id-4', + types: [], + }, ]; const expected: InferencePipelineData[] = [ { - isDeployed: false, + modelState: TrainedModelState.NotDeployed, pipelineName: 'ml-inference-pipeline-1', trainedModelName: 'trained-model-id-1', types: ['lang_ident', 'ner'], }, { - isDeployed: true, + modelState: TrainedModelState.Started, pipelineName: 'ml-inference-pipeline-2', trainedModelName: 'trained-model-id-2', types: ['pytorch', 'ner'], }, + { + modelState: TrainedModelState.Failed, + modelStateReason: 'something is wrong, boom', + pipelineName: 'ml-inference-pipeline-3', + trainedModelName: 'trained-model-id-3', + types: ['pytorch', 'text_classification'], + }, + { + modelState: TrainedModelState.Starting, + pipelineName: 'ml-inference-pipeline-4', + trainedModelName: 'trained-model-id-4', + types: ['pytorch', 'fill_mask'], + }, ]; const response = await fetchAndAddTrainedModelData( @@ -426,10 +490,10 @@ describe('fetchAndAddTrainedModelData lib function', () => { ); expect(mockClient.ml.getTrainedModels).toHaveBeenCalledWith({ - model_id: 'trained-model-id-1,trained-model-id-2', + model_id: 'trained-model-id-1,trained-model-id-2,trained-model-id-3,trained-model-id-4', }); expect(mockClient.ml.getTrainedModelsStats).toHaveBeenCalledWith({ - model_id: 'trained-model-id-1,trained-model-id-2', + model_id: 'trained-model-id-1,trained-model-id-2,trained-model-id-3,trained-model-id-4', }); expect(response).toEqual(expected); }); @@ -551,11 +615,7 @@ describe('fetchMlInferencePipelineProcessors lib function', () => { const expected: InferencePipeline[] = [ trainedModelDataObject['trained-model-id-1'], - { - isDeployed: false, - pipelineName: 'ml-inference-pipeline-3', - types: ['lang_ident', 'ner'], - }, + trainedModelDataObject['ml-inference-pipeline-3'], ]; const response = await fetchMlInferencePipelineProcessors( diff --git a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.ts b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.ts index 3b695d53ba9ab..95839a9b6ac20 100644 --- a/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.ts +++ b/x-pack/plugins/enterprise_search/server/lib/indices/fetch_ml_inference_pipeline_processors.ts @@ -9,7 +9,7 @@ import { MlTrainedModelConfig } from '@elastic/elasticsearch/lib/api/typesWithBo import { ElasticsearchClient } from '@kbn/core/server'; import { BUILT_IN_MODEL_TAG } from '@kbn/ml-plugin/common/constants/data_frame_analytics'; -import { InferencePipeline } from '../../../common/types/pipelines'; +import { InferencePipeline, TrainedModelState } from '../../../common/types/pipelines'; import { getInferencePipelineNameFromIndexName } from '../../utils/ml_inference_pipeline_utils'; export type InferencePipelineData = InferencePipeline & { @@ -58,7 +58,7 @@ export const fetchPipelineProcessorInferenceData = async ( const trainedModelName = inferenceProcessor?.inference?.model_id; if (trainedModelName) pipelineProcessorData.push({ - isDeployed: false, + modelState: TrainedModelState.NotDeployed, pipelineName: pipelineProcessorName, trainedModelName, types: [], @@ -98,7 +98,7 @@ export const getMlModelConfigsForModelIds = async ( if (trainedModelNames.includes(trainedModelName)) { modelConfigs[trainedModelName] = { - isDeployed: false, + modelState: TrainedModelState.NotDeployed, pipelineName: '', trainedModelName, types: getMlModelTypesForModelConfig(trainedModelData), @@ -109,8 +109,27 @@ export const getMlModelConfigsForModelIds = async ( trainedModelsStats.trained_model_stats.forEach((trainedModelStats) => { const trainedModelName = trainedModelStats.model_id; if (modelConfigs.hasOwnProperty(trainedModelName)) { - const isDeployed = trainedModelStats.deployment_stats?.state === 'started'; - modelConfigs[trainedModelName].isDeployed = isDeployed; + let modelState: TrainedModelState; + switch (trainedModelStats.deployment_stats?.state) { + case 'started': + modelState = TrainedModelState.Started; + break; + case 'starting': + modelState = TrainedModelState.Starting; + break; + case 'stopping': + modelState = TrainedModelState.Stopping; + break; + // @ts-ignore: type is wrong, "failed" is a possible state + case 'failed': + modelState = TrainedModelState.Failed; + break; + default: + modelState = TrainedModelState.NotDeployed; + break; + } + modelConfigs[trainedModelName].modelState = modelState; + modelConfigs[trainedModelName].modelStateReason = trainedModelStats.deployment_stats?.reason; } }); @@ -131,11 +150,12 @@ export const fetchAndAddTrainedModelData = async ( if (!model) { return data; } - const { types, isDeployed } = model; + const { types, modelState, modelStateReason } = model; return { ...data, types, - isDeployed, + modelState, + modelStateReason, }; }); }; diff --git a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts index c0dcc2dbdb0a9..0aaf30ef126d4 100644 --- a/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts +++ b/x-pack/plugins/enterprise_search/server/routes/enterprise_search/connectors.ts @@ -114,7 +114,7 @@ export function registerConnectorRoutes({ router, log }: RouteDependencies) { connectorId: schema.string(), }), body: schema.object({ - nextSyncConfig: schema.string(), + nextSyncConfig: schema.maybe(schema.string()), }), }, }, diff --git a/x-pack/plugins/event_log/README.md b/x-pack/plugins/event_log/README.md index c1d5869e7ed48..05b05946b652d 100644 --- a/x-pack/plugins/event_log/README.md +++ b/x-pack/plugins/event_log/README.md @@ -159,6 +159,7 @@ Below is a document in the expected structure, with descriptions of the fields: es_search_duration_ms: "total time spent performing ES searches as measured by Elasticsearch", total_search_duration_ms: "total time spent performing ES searches as measured by Kibana; includes network latency and time spent serializing/deserializing request/response", total_indexing_duration_ms: "total time spent indexing documents during current rule execution cycle", + total_enrichment_duration_ms: "total time spent enriching documents during current rule execution cycle", execution_gap_duration_s: "duration in seconds of execution gap" } } diff --git a/x-pack/plugins/event_log/generated/mappings.json b/x-pack/plugins/event_log/generated/mappings.json index db6719fed996a..4756b4f2e5534 100644 --- a/x-pack/plugins/event_log/generated/mappings.json +++ b/x-pack/plugins/event_log/generated/mappings.json @@ -347,6 +347,9 @@ }, "total_run_duration_ms": { "type": "long" + }, + "total_enrichment_duration_ms": { + "type": "long" } } } diff --git a/x-pack/plugins/event_log/generated/schemas.ts b/x-pack/plugins/event_log/generated/schemas.ts index b5557f64e9ac7..523ad683eabf2 100644 --- a/x-pack/plugins/event_log/generated/schemas.ts +++ b/x-pack/plugins/event_log/generated/schemas.ts @@ -150,6 +150,7 @@ export const EventSchema = schema.maybe( claim_to_start_duration_ms: ecsStringOrNumber(), prepare_rule_duration_ms: ecsStringOrNumber(), total_run_duration_ms: ecsStringOrNumber(), + total_enrichment_duration_ms: ecsStringOrNumber(), }) ), }) diff --git a/x-pack/plugins/event_log/scripts/mappings.js b/x-pack/plugins/event_log/scripts/mappings.js index 98050b6557210..65c9220fb5355 100644 --- a/x-pack/plugins/event_log/scripts/mappings.js +++ b/x-pack/plugins/event_log/scripts/mappings.js @@ -130,6 +130,9 @@ exports.EcsCustomPropertyMappings = { total_run_duration_ms: { type: 'long', }, + total_enrichment_duration_ms: { + type: 'long', + }, }, }, }, diff --git a/x-pack/plugins/fleet/common/authz.test.ts b/x-pack/plugins/fleet/common/authz.test.ts index ced783c6d4adb..cadb90651b01c 100644 --- a/x-pack/plugins/fleet/common/authz.test.ts +++ b/x-pack/plugins/fleet/common/authz.test.ts @@ -15,7 +15,10 @@ import { ENDPOINT_PRIVILEGES } from './constants'; const SECURITY_SOLUTION_ID = DEFAULT_APP_CATEGORIES.security.id; -function generateActions(privileges: string[] = [], overrides: Record = {}) { +function generateActions( + privileges: typeof ENDPOINT_PRIVILEGES, + overrides: Record = {} +) { return privileges.reduce((acc, privilege) => { const executePackageAction = overrides[privilege] || false; diff --git a/x-pack/plugins/fleet/common/constants/authz.ts b/x-pack/plugins/fleet/common/constants/authz.ts index 3bf1aeb46adc8..d7a0ca4ade2eb 100644 --- a/x-pack/plugins/fleet/common/constants/authz.ts +++ b/x-pack/plugins/fleet/common/constants/authz.ts @@ -23,4 +23,4 @@ export const ENDPOINT_PRIVILEGES = [ 'writeHostIsolation', 'writeProcessOperations', 'writeFileOperations', -]; +] as const; diff --git a/x-pack/plugins/fleet/common/mocks.ts b/x-pack/plugins/fleet/common/mocks.ts index bc8880ed385af..d5aca8398abd8 100644 --- a/x-pack/plugins/fleet/common/mocks.ts +++ b/x-pack/plugins/fleet/common/mocks.ts @@ -7,6 +7,7 @@ import type { DeletePackagePoliciesResponse, NewPackagePolicy, PackagePolicy } from './types'; import type { FleetAuthz } from './authz'; +import { ENDPOINT_PRIVILEGES } from './constants'; export const createNewPackagePolicyMock = (): NewPackagePolicy => { return { @@ -61,6 +62,15 @@ export const deletePackagePolicyMock = (): DeletePackagePoliciesResponse => { * Creates mock `authz` object */ export const createFleetAuthzMock = (): FleetAuthz => { + const endpointActions = ENDPOINT_PRIVILEGES.reduce((acc, privilege) => { + return { + ...acc, + [privilege]: { + executePackageAction: true, + }, + }; + }, {}); + return { fleet: { all: true, @@ -80,5 +90,10 @@ export const createFleetAuthzMock = (): FleetAuthz => { readIntegrationPolicies: true, writeIntegrationPolicies: true, }, + packagePrivileges: { + endpoint: { + actions: endpointActions, + }, + }, }; }; diff --git a/x-pack/plugins/fleet/common/services/agent_status.ts b/x-pack/plugins/fleet/common/services/agent_status.ts index 72b912e573af3..55f93fca48d6f 100644 --- a/x-pack/plugins/fleet/common/services/agent_status.ts +++ b/x-pack/plugins/fleet/common/services/agent_status.ts @@ -47,7 +47,7 @@ export function getAgentStatus(agent: Agent | FleetServerAgent): AgentStatus { ? agent.policy_revision_idx : undefined; - if (!policyRevision || (agent.upgrade_started_at && agent.upgrade_status !== 'completed')) { + if (!policyRevision || (agent.upgrade_started_at && !agent.upgraded_at)) { return 'updating'; } @@ -75,7 +75,7 @@ export function getPreviousAgentStatusForOfflineAgents( ? agent.policy_revision_idx : undefined; - if (!policyRevision || (agent.upgrade_started_at && agent.upgrade_status !== 'completed')) { + if (!policyRevision || (agent.upgrade_started_at && !agent.upgraded_at)) { return 'updating'; } } @@ -109,7 +109,7 @@ export function buildKueryForOfflineAgents(path: string = ''): string { } export function buildKueryForUpgradingAgents(path: string = ''): string { - return `(${path}upgrade_started_at:*) and not (${path}upgrade_status:completed)`; + return `(${path}upgrade_started_at:*) and not (${path}upgraded_at:*)`; } export function buildKueryForUpdatingAgents(path: string = ''): string { diff --git a/x-pack/plugins/fleet/common/services/is_agent_upgradeable.ts b/x-pack/plugins/fleet/common/services/is_agent_upgradeable.ts index c4c9fa7e75a69..2a523d1a2eabb 100644 --- a/x-pack/plugins/fleet/common/services/is_agent_upgradeable.ts +++ b/x-pack/plugins/fleet/common/services/is_agent_upgradeable.ts @@ -25,7 +25,7 @@ export function isAgentUpgradeable(agent: Agent, kibanaVersion: string, versionT return false; } // check that the agent is not already in the process of updating - if (agent.upgrade_started_at && agent.upgrade_status !== 'completed') { + if (agent.upgrade_started_at && !agent.upgraded_at) { return false; } if (versionToUpgrade !== undefined) { diff --git a/x-pack/plugins/fleet/common/types/models/agent.ts b/x-pack/plugins/fleet/common/types/models/agent.ts index 9ca69b5100625..5def12287b4fd 100644 --- a/x-pack/plugins/fleet/common/types/models/agent.ts +++ b/x-pack/plugins/fleet/common/types/models/agent.ts @@ -75,9 +75,8 @@ interface AgentBase { enrolled_at: string; unenrolled_at?: string; unenrollment_started_at?: string; - upgraded_at?: string; + upgraded_at?: string | null; upgrade_started_at?: string | null; - upgrade_status?: 'started' | 'completed'; access_api_key_id?: string; default_api_key?: string; default_api_key_id?: string; @@ -188,15 +187,11 @@ export interface FleetServerAgent { /** * Date/time the Elastic Agent was last upgraded */ - upgraded_at?: string; + upgraded_at?: string | null; /** * Date/time the Elastic Agent started the current upgrade */ upgrade_started_at?: string | null; - /** - * Upgrade status - */ - upgrade_status?: 'started' | 'completed'; /** * ID of the API key the Elastic Agent must used to contact Fleet Server */ diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/confirm_incoming_data_with_preview.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/confirm_incoming_data_with_preview.tsx index af0e3c882ea50..011134151cbd7 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/confirm_incoming_data_with_preview.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/multi_page_layout/components/confirm_incoming_data_with_preview.tsx @@ -75,7 +75,8 @@ const HitPreview: React.FC<{ hit: SearchHit }> = ({ hit }) => { ); const listItems = Object.entries(hitForDisplay).map(([key, value]) => ({ title: `${key}:`, - description: value, + // Ensures arrays and collections of nested objects are displayed correctly + description: JSON.stringify(value), })); return ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx index bb0ec90f2b883..10ced1a5c0323 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/bulk_actions.tsx @@ -228,6 +228,7 @@ export const AgentBulkActions: React.FunctionComponent = ({ }} onClosePopover={() => { setIsTagAddVisible(false); + closeMenu(); }} /> )} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.test.tsx index 8c4f9f3003c82..465db5236338c 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.test.tsx @@ -270,6 +270,59 @@ describe('TagsAddRemove', () => { ); }); + it('should add new tag twice quickly when not found in search and button clicked - bulk selection', () => { + mockBulkUpdateTags.mockImplementation((agents, tagsToAdd, tagsToRemove, onSuccess) => + onSuccess(false) + ); + + const result = renderComponent(undefined, 'query'); + const searchInput = result.getByRole('combobox'); + + fireEvent.input(searchInput, { + target: { value: 'newTag' }, + }); + + fireEvent.click(result.getAllByText('Create a new tag "newTag"')[0].closest('button')!); + + fireEvent.input(searchInput, { + target: { value: 'newTag2' }, + }); + + fireEvent.click(result.getAllByText('Create a new tag "newTag2"')[0].closest('button')!); + + expect(mockBulkUpdateTags).toHaveBeenCalledWith( + 'query', + ['newTag2', 'newTag'], + [], + expect.anything(), + 'Tag created', + 'Tag creation failed' + ); + }); + + it('should remove tags twice quickly on bulk selection', () => { + selectedTags = ['tag1', 'tag2']; + mockBulkUpdateTags.mockImplementation((agents, tagsToAdd, tagsToRemove, onSuccess) => + onSuccess(false) + ); + + const result = renderComponent(undefined, ''); + const getTag = (name: string) => result.getByText(name); + + fireEvent.click(getTag('tag1')); + + fireEvent.click(getTag('tag2')); + + expect(mockBulkUpdateTags).toHaveBeenCalledWith( + '', + [], + ['tag2', 'tag1'], + expect.anything(), + undefined, + undefined + ); + }); + it('should make tag options button visible on mouse enter', async () => { const result = renderComponent('agent1'); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.tsx index a03ec3808e9ab..70b4da44dad68 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/tags_add_remove.tsx @@ -6,7 +6,7 @@ */ import React, { Fragment, useEffect, useState, useMemo, useCallback } from 'react'; -import { difference } from 'lodash'; +import { difference, uniq } from 'lodash'; import styled from 'styled-components'; import type { EuiSelectableOption } from '@elastic/eui'; import { @@ -95,8 +95,9 @@ export const TagsAddRemove: React.FC = ({ if (hasCompleted) { return onTagsUpdated(); } - const newSelectedTags = difference(selectedTags, tagsToRemove).concat(tagsToAdd); - const allTagsWithNew = allTags.includes(tagsToAdd[0]) ? allTags : allTags.concat(tagsToAdd); + const selected = labels.filter((tag) => tag.checked === 'on').map((tag) => tag.label); + const newSelectedTags = difference(selected, tagsToRemove).concat(tagsToAdd); + const allTagsWithNew = uniq(allTags.concat(newSelectedTags)); const allTagsWithRemove = isRenameOrDelete ? difference(allTagsWithNew, tagsToRemove) : allTagsWithNew; @@ -109,8 +110,8 @@ export const TagsAddRemove: React.FC = ({ successMessage?: string, errorMessage?: string ) => { - const newSelectedTags = difference(selectedTags, tagsToRemove).concat(tagsToAdd); if (agentId) { + const newSelectedTags = difference(selectedTags, tagsToRemove).concat(tagsToAdd); updateTagsHook.updateTags( agentId, newSelectedTags, @@ -119,10 +120,22 @@ export const TagsAddRemove: React.FC = ({ errorMessage ); } else { + // sending updated tags to add/remove, in case multiple actions are done quickly and the first one is not yet propagated + const updatedTagsToAdd = tagsToAdd.concat( + labels + .filter((tag) => tag.checked === 'on' && !selectedTags.includes(tag.label)) + .map((tag) => tag.label) + ); + const updatedTagsToRemove = tagsToRemove.concat( + labels + .filter((tag) => tag.checked !== 'on' && selectedTags.includes(tag.label)) + .map((tag) => tag.label) + ); + updateTagsHook.bulkUpdateTags( agents!, - tagsToAdd, - tagsToRemove, + updatedTagsToAdd, + updatedTagsToRemove, (hasCompleted) => handleTagsUpdated(tagsToAdd, tagsToRemove, hasCompleted), successMessage, errorMessage diff --git a/x-pack/plugins/fleet/server/services/agents/actions.ts b/x-pack/plugins/fleet/server/services/agents/actions.ts index 20cb2fb94e51d..17c745bfd285f 100644 --- a/x-pack/plugins/fleet/server/services/agents/actions.ts +++ b/x-pack/plugins/fleet/server/services/agents/actions.ts @@ -134,6 +134,7 @@ export async function bulkCreateAgentActionResults( await esClient.bulk({ index: AGENT_ACTIONS_RESULTS_INDEX, body: bulkBody, + refresh: 'wait_for', }); } @@ -242,8 +243,8 @@ export async function cancelAgentAction(esClient: ElasticsearchClient, actionId: hit._source.agents.map((agentId) => ({ agentId, data: { + upgraded_at: null, upgrade_started_at: null, - upgrade_status: 'completed', }, })) ); diff --git a/x-pack/plugins/fleet/server/services/agents/upgrade.test.ts b/x-pack/plugins/fleet/server/services/agents/upgrade.test.ts index 9692f05822879..db880f56ef474 100644 --- a/x-pack/plugins/fleet/server/services/agents/upgrade.test.ts +++ b/x-pack/plugins/fleet/server/services/agents/upgrade.test.ts @@ -38,7 +38,7 @@ describe('sendUpgradeAgentsActions (plural)', () => { expect(ids).toEqual(idsToAction); for (const doc of docs!) { expect(doc).toHaveProperty('upgrade_started_at'); - expect(doc.upgrade_status).toEqual('started'); + expect(doc.upgraded_at).toEqual(null); } }); it('cannot upgrade from a hosted agent policy by default', async () => { @@ -60,7 +60,7 @@ describe('sendUpgradeAgentsActions (plural)', () => { expect(ids).toEqual(onlyRegular); for (const doc of docs!) { expect(doc).toHaveProperty('upgrade_started_at'); - expect(doc.upgrade_status).toEqual('started'); + expect(doc.upgraded_at).toEqual(null); } // hosted policy is updated in action results with error @@ -98,7 +98,7 @@ describe('sendUpgradeAgentsActions (plural)', () => { expect(ids).toEqual(idsToAction); for (const doc of docs!) { expect(doc).toHaveProperty('upgrade_started_at'); - expect(doc.upgrade_status).toEqual('started'); + expect(doc.upgraded_at).toEqual(null); } }); }); diff --git a/x-pack/plugins/fleet/server/services/agents/upgrade.ts b/x-pack/plugins/fleet/server/services/agents/upgrade.ts index cf298ecb5997d..605aa896de59a 100644 --- a/x-pack/plugins/fleet/server/services/agents/upgrade.ts +++ b/x-pack/plugins/fleet/server/services/agents/upgrade.ts @@ -57,8 +57,8 @@ export async function sendUpgradeAgentAction({ type: 'UPGRADE', }); await updateAgent(esClient, agentId, { + upgraded_at: null, upgrade_started_at: now, - upgrade_status: 'started', }); } diff --git a/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts b/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts index c757a9f1b5482..a34f189871a39 100644 --- a/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts +++ b/x-pack/plugins/fleet/server/services/agents/upgrade_action_runner.ts @@ -146,8 +146,8 @@ export async function upgradeBatch( agentsToUpdate.map((agent) => ({ agentId: agent.id, data: { + upgraded_at: null, upgrade_started_at: now, - upgrade_status: 'started', }, })) ); diff --git a/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts b/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts index 6504b6548f078..bf5fe89574b8a 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/index.test.ts @@ -35,6 +35,7 @@ jest.mock('../..', () => ({ getKibanaBranch: () => 'main', getKibanaVersion: () => '99.0.0', getConfig: () => ({}), + getIsProductionMode: () => false, }, })); diff --git a/x-pack/plugins/fleet/server/services/epm/registry/registry_url.ts b/x-pack/plugins/fleet/server/services/epm/registry/registry_url.ts index 407a61ad7a912..31bb776ee1d69 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/registry_url.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/registry_url.ts @@ -21,7 +21,8 @@ const SNAPSHOT_REGISTRY_URL_CDN = 'https://epr-snapshot.elastic.co'; const getDefaultRegistryUrl = (): string => { const branch = appContextService.getKibanaBranch(); - if (branch === 'main') { + const isProduction = appContextService.getIsProductionMode(); + if (!isProduction || branch === 'main') { return SNAPSHOT_REGISTRY_URL_CDN; } else if (appContextService.getKibanaVersion().includes('-SNAPSHOT')) { return STAGING_REGISTRY_URL_CDN; diff --git a/x-pack/plugins/index_lifecycle_management/README.md b/x-pack/plugins/index_lifecycle_management/README.md index 35c2aa063ec23..912b19295790f 100644 --- a/x-pack/plugins/index_lifecycle_management/README.md +++ b/x-pack/plugins/index_lifecycle_management/README.md @@ -115,4 +115,8 @@ this by running: ```bash yarn es snapshot --license=trial -``` \ No newline at end of file +``` + +## Integration tests + +See `./integration_tests/README.md` \ No newline at end of file diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx index ecefe8132c499..246de6e8ed25b 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/extend_index_management.test.tsx @@ -7,7 +7,7 @@ import moment from 'moment-timezone'; -import { init } from './client_integration/helpers/http_requests'; +import { init } from '../integration_tests/helpers/http_requests'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { usageCollectionPluginMock } from '@kbn/usage-collection-plugin/public/mocks'; import { Index } from '../common/types'; diff --git a/x-pack/plugins/index_lifecycle_management/integration_tests/README.md b/x-pack/plugins/index_lifecycle_management/integration_tests/README.md new file mode 100644 index 0000000000000..5e4bf4360cb72 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/README.md @@ -0,0 +1,14 @@ +Most plugins of the deployment management team follow +the similar testing infrastructure where integration tests are located in `__jest__` and run as unit tests. + +The `index_lifecycle_management` tests [were refactored](https://github.com/elastic/kibana/pull/141750) to be run as integration tests because they [became flaky hitting the 5 seconds timeout](https://github.com/elastic/kibana/issues/115307#issuecomment-1238417474) for a jest unit test. + +Jest integration tests are just sit in a different directory and have two main differences: +- They never use parallelism, this allows them to access file system resources, launch services, etc. without needing to worry about conflicts with other tests +- They are allowed to take their sweet time, the default timeout is currently 10 minutes. + +To run these tests use: + +``` +node scripts/jest_integration x-pack/plugins/index_lifecycle_management/ +``` \ No newline at end of file diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/app/app.helpers.ts similarity index 97% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/app/app.helpers.ts index df64fbce3fa1d..66810ebb1e546 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/app/app.helpers.ts @@ -8,7 +8,7 @@ import { act } from 'react-dom/test-utils'; import { HttpSetup } from '@kbn/core/public'; import { registerTestBed, TestBed, TestBedConfig } from '@kbn/test-jest-helpers'; -import { App } from '../../../public/application/app'; +import { App } from '../../public/application/app'; import { WithAppDependencies } from '../helpers'; const getTestBedConfig = (initialEntries: string[]): TestBedConfig => ({ diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/app/app.test.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/app/app.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/constants.ts similarity index 97% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/constants.ts index 620cb9d6f8dde..a41bea1cb8415 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/constants.ts @@ -7,9 +7,9 @@ import moment from 'moment-timezone'; -import { PolicyFromES } from '../../../common/types'; +import { PolicyFromES } from '../../common/types'; -import { defaultRolloverAction } from '../../../public/application/constants'; +import { defaultRolloverAction } from '../../public/application/constants'; export const POLICY_NAME = 'my_policy'; export const SNAPSHOT_POLICY_NAME = 'my_snapshot_policy'; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/delete_phase.helpers.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/delete_phase.helpers.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/delete_phase.test.ts similarity index 98% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/delete_phase.test.ts index d877f05d06ae1..df6dd516c8a58 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/delete_phase.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/delete_phase.test.ts @@ -6,7 +6,7 @@ */ import { act } from 'react-dom/test-utils'; -import { API_BASE_PATH } from '../../../../common/constants'; +import { API_BASE_PATH } from '../../../common/constants'; import { setupEnvironment } from '../../helpers'; import { DELETE_PHASE_POLICY, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/downsample.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/downsample.helpers.ts similarity index 95% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/downsample.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/downsample.helpers.ts index be96aaabe4a71..1e6ed336a5f03 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/downsample.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/downsample.helpers.ts @@ -14,7 +14,7 @@ import { createTogglePhaseAction, } from '../../helpers'; import { initTestBed } from '../init_test_bed'; -import { AppServicesContext } from '../../../../public/types'; +import { AppServicesContext } from '../../../public/types'; type SetupReturn = ReturnType; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/downsample.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/downsample.test.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/downsample.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/downsample.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/edit_warning.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/edit_warning.test.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/edit_warning.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/edit_warning.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/frozen_phase.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/frozen_phase.test.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/frozen_phase.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/frozen_phase.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts similarity index 94% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts index 7092d52289de9..b41075c6b6b68 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cloud_aware_behavior.helpers.ts @@ -8,7 +8,7 @@ import { HttpSetup } from '@kbn/core/public'; import { TestBedConfig } from '@kbn/test-jest-helpers'; -import { AppServicesContext } from '../../../../../public/types'; +import { AppServicesContext } from '../../../../public/types'; import { createTogglePhaseAction, createNodeAllocationActions } from '../../../helpers'; import { initTestBed } from '../../init_test_bed'; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cloud_aware_behavior.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cold_phase.helpers.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cold_phase.helpers.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cold_phase.test.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/cold_phase.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/cold_phase.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/general_behavior.helpers.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/general_behavior.helpers.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/general_behavior.test.ts similarity index 98% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/general_behavior.test.ts index 1eecd5207664f..4830cee8ee237 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/general_behavior.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/general_behavior.test.ts @@ -17,7 +17,7 @@ import { POLICY_WITH_NODE_ATTR_AND_OFF_ALLOCATION, POLICY_WITH_NODE_ROLE_ALLOCATION, } from '../../constants'; -import { API_BASE_PATH } from '../../../../../common/constants'; +import { API_BASE_PATH } from '../../../../common/constants'; describe(' node allocation general behavior', () => { let testBed: GeneralNodeAllocationTestBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/warm_phase.helpers.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/warm_phase.helpers.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/warm_phase.test.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/node_allocation/warm_phase.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/node_allocation/warm_phase.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/request_flyout.helpers.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/request_flyout.helpers.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/request_flyout.test.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/request_flyout.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/request_flyout.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/rollover.helpers.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/rollover.helpers.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/rollover.test.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/rollover.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/rollover.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/searchable_snapshots.helpers.ts similarity index 97% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/searchable_snapshots.helpers.ts index e70f721a48075..d3b68ffc6a13e 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/searchable_snapshots.helpers.ts @@ -18,7 +18,7 @@ import { createTogglePhaseAction, } from '../../helpers'; import { initTestBed } from '../init_test_bed'; -import { AppServicesContext } from '../../../../public/types'; +import { AppServicesContext } from '../../../public/types'; type SetupReturn = ReturnType; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/searchable_snapshots.test.ts similarity index 99% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/searchable_snapshots.test.ts index 03b7670c1eac5..68e74e23a781c 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/searchable_snapshots.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/searchable_snapshots.test.ts @@ -10,7 +10,7 @@ import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; import { HttpFetchOptionsWithPath } from '@kbn/core/public'; import { setupEnvironment } from '../../helpers'; import { getDefaultHotPhasePolicy } from '../constants'; -import { API_BASE_PATH } from '../../../../common/constants'; +import { API_BASE_PATH } from '../../../common/constants'; import { SearchableSnapshotsTestBed, setupSearchableSnapshotsTestBed, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/timeline.helpers.ts similarity index 94% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/timeline.helpers.ts index 496b27330c931..202388a844464 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/timeline.helpers.ts @@ -8,7 +8,7 @@ import { HttpSetup } from '@kbn/core/public'; import { createTogglePhaseAction } from '../../helpers'; import { initTestBed } from '../init_test_bed'; -import { Phase } from '../../../../common/types'; +import { Phase } from '../../../common/types'; type SetupReturn = ReturnType; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/timeline.test.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timeline.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/timeline.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/timing.helpers.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/timing.helpers.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/timing.test.ts similarity index 95% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/timing.test.ts index 0aee8eb5f0be1..72c6a2a4e789c 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/features/timing.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/features/timing.test.ts @@ -8,7 +8,7 @@ import { act } from 'react-dom/test-utils'; import { setupEnvironment } from '../../helpers'; import { setupTimingTestBed, TimingTestBed } from './timing.helpers'; -import { PhaseWithTiming } from '../../../../common/types'; +import { PhaseWithTiming } from '../../../common/types'; describe(' timing', () => { let testBed: TimingTestBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/cold_phase_validation.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/cold_phase_validation.test.ts similarity index 91% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/cold_phase_validation.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/cold_phase_validation.test.ts index ef2fc67002c14..e75d2cb72ab28 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/cold_phase_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/cold_phase_validation.test.ts @@ -6,12 +6,11 @@ */ import { act } from 'react-dom/test-utils'; -import { i18nTexts } from '../../../../public/application/sections/edit_policy/i18n_texts'; +import { i18nTexts } from '../../../public/application/sections/edit_policy/i18n_texts'; import { setupEnvironment } from '../../helpers'; import { setupValidationTestBed, ValidationTestBed } from './validation.helpers'; -// FLAKY: https://github.com/elastic/kibana/issues/141645 -describe.skip(' cold phase validation', () => { +describe(' cold phase validation', () => { let testBed: ValidationTestBed; const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/downsample_interval.test.ts similarity index 93% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/downsample_interval.test.ts index 79f5fdc6e2840..d2f9943eba68a 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/downsample_interval.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/downsample_interval.test.ts @@ -6,14 +6,13 @@ */ import { act } from 'react-dom/test-utils'; -import { i18nTexts } from '../../../../public/application/sections/edit_policy/i18n_texts'; +import { i18nTexts } from '../../../public/application/sections/edit_policy/i18n_texts'; -import { PhaseWithDownsample } from '../../../../common/types'; +import { PhaseWithDownsample } from '../../../common/types'; import { setupEnvironment } from '../../helpers'; import { setupValidationTestBed, ValidationTestBed } from './validation.helpers'; -// FLAKY: https://github.com/elastic/kibana/issues/141160 -describe.skip(' downsample interval validation', () => { +describe(' downsample interval validation', () => { let testBed: ValidationTestBed; let actions: ValidationTestBed['actions']; const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/error_indicators.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/error_indicators.test.ts similarity index 97% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/error_indicators.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/error_indicators.test.ts index 349f98766620d..bd4a2caec0be5 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/error_indicators.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/error_indicators.test.ts @@ -9,8 +9,7 @@ import { act } from 'react-dom/test-utils'; import { setupEnvironment } from '../../helpers'; import { setupValidationTestBed, ValidationTestBed } from './validation.helpers'; -// FLAKY: https://github.com/elastic/kibana/issues/141645 -describe.skip(' error indicators', () => { +describe(' error indicators', () => { let testBed: ValidationTestBed; const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/hot_phase_validation.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/hot_phase_validation.test.ts similarity index 97% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/hot_phase_validation.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/hot_phase_validation.test.ts index 82b3568d39ce7..71f83a59360d6 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/hot_phase_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/hot_phase_validation.test.ts @@ -6,12 +6,11 @@ */ import { act } from 'react-dom/test-utils'; -import { i18nTexts } from '../../../../public/application/sections/edit_policy/i18n_texts'; +import { i18nTexts } from '../../../public/application/sections/edit_policy/i18n_texts'; import { setupEnvironment } from '../../helpers'; import { setupValidationTestBed, ValidationTestBed } from './validation.helpers'; -// FLAKY: https://github.com/elastic/kibana/issues/141645 -describe.skip(' hot phase validation', () => { +describe(' hot phase validation', () => { let testBed: ValidationTestBed; let actions: ValidationTestBed['actions']; const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/policy_name_validation.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/policy_name_validation.test.ts similarity index 93% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/policy_name_validation.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/policy_name_validation.test.ts index 928380e3d1eac..c530f73a66c11 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/policy_name_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/policy_name_validation.test.ts @@ -6,13 +6,12 @@ */ import { act } from 'react-dom/test-utils'; -import { i18nTexts } from '../../../../public/application/sections/edit_policy/i18n_texts'; +import { i18nTexts } from '../../../public/application/sections/edit_policy/i18n_texts'; import { setupEnvironment } from '../../helpers'; import { getGeneratedPolicies } from '../constants'; import { setupValidationTestBed, ValidationTestBed } from './validation.helpers'; -// FLAKY: https://github.com/elastic/kibana/issues/141645 -describe.skip(' policy name validation', () => { +describe(' policy name validation', () => { let testBed: ValidationTestBed; let actions: ValidationTestBed['actions']; const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/timing.test.ts similarity index 93% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/timing.test.ts index 7db483d6d0ef2..5838f04ba70e9 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/timing.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/timing.test.ts @@ -6,14 +6,13 @@ */ import { act } from 'react-dom/test-utils'; -import { i18nTexts } from '../../../../public/application/sections/edit_policy/i18n_texts'; +import { i18nTexts } from '../../../public/application/sections/edit_policy/i18n_texts'; -import { PhaseWithTiming } from '../../../../common/types'; +import { PhaseWithTiming } from '../../../common/types'; import { setupEnvironment } from '../../helpers'; import { setupValidationTestBed, ValidationTestBed } from './validation.helpers'; -// FLAKY: https://github.com/elastic/kibana/issues/115307 -describe.skip(' timing validation', () => { +describe(' timing validation', () => { let testBed: ValidationTestBed; let actions: ValidationTestBed['actions']; const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/validation.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/validation.helpers.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/validation.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/validation.helpers.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/warm_phase_validation.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/warm_phase_validation.test.ts similarity index 95% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/warm_phase_validation.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/warm_phase_validation.test.ts index df0607a0a0e65..47917b1f8e3d7 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/form_validation/warm_phase_validation.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/form_validation/warm_phase_validation.test.ts @@ -6,12 +6,11 @@ */ import { act } from 'react-dom/test-utils'; -import { i18nTexts } from '../../../../public/application/sections/edit_policy/i18n_texts'; +import { i18nTexts } from '../../../public/application/sections/edit_policy/i18n_texts'; import { setupEnvironment } from '../../helpers'; import { setupValidationTestBed, ValidationTestBed } from './validation.helpers'; -// FLAKY: https://github.com/elastic/kibana/issues/141645 -describe.skip(' warm phase validation', () => { +describe(' warm phase validation', () => { let testBed: ValidationTestBed; const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/init_test_bed.ts similarity index 89% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/init_test_bed.ts index 875bf9db36264..56bed7a6e50aa 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/init_test_bed.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/init_test_bed.ts @@ -5,12 +5,12 @@ * 2.0. */ +import { HttpSetup } from '@kbn/core/public'; import { registerTestBed, TestBedConfig } from '@kbn/test-jest-helpers'; -import { HttpSetup } from '@kbn/core/public'; import { WithAppDependencies } from '../helpers'; -import { EditPolicy } from '../../../public/application/sections/edit_policy'; -import { AppServicesContext } from '../../../public/types'; +import { EditPolicy } from '../../public/application/sections/edit_policy'; +import { AppServicesContext } from '../../public/types'; import { POLICY_NAME } from './constants'; const getTestBedConfig = (testBedConfig?: Partial): TestBedConfig => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.helpers.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/serialization/policy_serialization.helpers.ts similarity index 95% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.helpers.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/serialization/policy_serialization.helpers.ts index 417f53c63a20c..e439fca0de512 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.helpers.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/serialization/policy_serialization.helpers.ts @@ -6,7 +6,7 @@ */ import { HttpSetup } from '@kbn/core/public'; -import { AppServicesContext } from '../../../../public/types'; +import { AppServicesContext } from '../../../public/types'; import { createColdPhaseActions, createDeletePhaseActions, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.test.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/serialization/policy_serialization.test.ts similarity index 99% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.test.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/serialization/policy_serialization.test.ts index 983cfbadfa017..05aa66fcc5f25 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/serialization/policy_serialization.test.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/edit_policy/serialization/policy_serialization.test.ts @@ -9,7 +9,7 @@ import { act } from 'react-dom/test-utils'; import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; import { HttpFetchOptionsWithPath } from '@kbn/core/public'; import { setupEnvironment } from '../../helpers'; -import { API_BASE_PATH } from '../../../../common/constants'; +import { API_BASE_PATH } from '../../../common/constants'; import { getDefaultHotPhasePolicy, POLICY_WITH_INCLUDE_EXCLUDE, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/downsample_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/downsample_actions.ts similarity index 96% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/downsample_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/downsample_actions.ts index 315ed3d58520a..a389a9deebe32 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/downsample_actions.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/downsample_actions.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { TestBed } from '@kbn/test-jest-helpers'; import { act } from 'react-dom/test-utils'; -import { Phase } from '../../../../common/types'; +import { TestBed } from '@kbn/test-jest-helpers'; +import { Phase } from '../../../common/types'; import { createFormToggleAction } from '..'; const createSetDownsampleIntervalAction = diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/errors_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/errors_actions.ts similarity index 96% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/errors_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/errors_actions.ts index 4b863071e191c..18f07734fadee 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/errors_actions.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/errors_actions.ts @@ -7,7 +7,7 @@ import { act } from 'react-dom/test-utils'; import { TestBed } from '@kbn/test-jest-helpers'; -import { Phase } from '../../../../common/types'; +import { Phase } from '../../../common/types'; const createWaitForValidationAction = (testBed: TestBed) => () => { const { component } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/forcemerge_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/forcemerge_actions.ts similarity index 96% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/forcemerge_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/forcemerge_actions.ts index b6ed40de36ca9..619d6bd8be85f 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/forcemerge_actions.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/forcemerge_actions.ts @@ -7,7 +7,7 @@ import { act } from 'react-dom/test-utils'; import { TestBed } from '@kbn/test-jest-helpers'; -import { Phase } from '../../../../common/types'; +import { Phase } from '../../../common/types'; import { createFormToggleAction } from './form_toggle_action'; import { createFormSetValueAction } from './form_set_value_action'; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/form_set_value_action.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/form_set_value_action.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/form_set_value_action.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/form_set_value_action.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/form_toggle_action.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/form_toggle_action.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/form_toggle_action.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/form_toggle_action.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/form_toggle_and_set_value_action.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/form_toggle_and_set_value_action.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/form_toggle_and_set_value_action.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/form_toggle_and_set_value_action.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/index.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/index.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/index.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/index.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/index_priority_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/index_priority_actions.ts similarity index 94% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/index_priority_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/index_priority_actions.ts index 79fb77e53cc59..4c6e4604be7d4 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/index_priority_actions.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/index_priority_actions.ts @@ -6,7 +6,7 @@ */ import { TestBed } from '@kbn/test-jest-helpers'; -import { Phase } from '../../../../common/types'; +import { Phase } from '../../../common/types'; import { createFormToggleAction } from './form_toggle_action'; import { createFormToggleAndSetValueAction } from './form_toggle_and_set_value_action'; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/min_age_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/min_age_actions.ts similarity index 94% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/min_age_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/min_age_actions.ts index ef00fdc8d7757..8b4fa2e5f6179 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/min_age_actions.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/min_age_actions.ts @@ -6,7 +6,7 @@ */ import { TestBed } from '@kbn/test-jest-helpers'; -import { Phase } from '../../../../common/types'; +import { Phase } from '../../../common/types'; import { createFormSetValueAction } from './form_set_value_action'; export const createMinAgeActions = (testBed: TestBed, phase: Phase) => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/node_allocation_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/node_allocation_actions.ts similarity index 95% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/node_allocation_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/node_allocation_actions.ts index 2a680590654a8..a3cb607b60f99 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/node_allocation_actions.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/node_allocation_actions.ts @@ -8,8 +8,8 @@ import { act } from 'react-dom/test-utils'; import { TestBed } from '@kbn/test-jest-helpers'; -import { DataTierAllocationType } from '../../../../public/application/sections/edit_policy/types'; -import { Phase } from '../../../../common/types'; +import { DataTierAllocationType } from '../../../public/application/sections/edit_policy/types'; +import { Phase } from '../../../common/types'; import { createFormSetValueAction } from './form_set_value_action'; export const createNodeAllocationActions = (testBed: TestBed, phase: Phase) => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/phases.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/phases.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/phases.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/phases.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/readonly_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/readonly_actions.ts similarity index 92% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/readonly_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/readonly_actions.ts index 1a7ec56815b00..fe4c71d76265a 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/readonly_actions.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/readonly_actions.ts @@ -6,7 +6,7 @@ */ import { TestBed } from '@kbn/test-jest-helpers'; -import { Phase } from '../../../../common/types'; +import { Phase } from '../../../common/types'; import { createFormToggleAction } from './form_toggle_action'; export const createReadonlyActions = (testBed: TestBed, phase: Phase) => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/replicas_action.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/replicas_action.ts similarity index 92% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/replicas_action.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/replicas_action.ts index 43eca26a4e1ce..35c3afc607513 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/replicas_action.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/replicas_action.ts @@ -6,7 +6,7 @@ */ import { TestBed } from '@kbn/test-jest-helpers'; -import { Phase } from '../../../../common/types'; +import { Phase } from '../../../common/types'; import { createFormToggleAndSetValueAction } from './form_toggle_and_set_value_action'; export const createReplicasAction = (testBed: TestBed, phase: Phase) => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/request_flyout_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/request_flyout_actions.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/request_flyout_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/request_flyout_actions.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/rollover_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/rollover_actions.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/rollover_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/rollover_actions.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/save_policy_action.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/save_policy_action.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/save_policy_action.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/save_policy_action.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/searchable_snapshot_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/searchable_snapshot_actions.ts similarity index 96% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/searchable_snapshot_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/searchable_snapshot_actions.ts index 3efffcddbece6..c9a019c2bc842 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/searchable_snapshot_actions.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/searchable_snapshot_actions.ts @@ -7,7 +7,7 @@ import { act } from 'react-dom/test-utils'; import { TestBed } from '@kbn/test-jest-helpers'; -import { Phase } from '../../../../common/types'; +import { Phase } from '../../../common/types'; import { createFormToggleAction } from './form_toggle_action'; export const createSearchableSnapshotActions = (testBed: TestBed, phase: Phase) => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/shrink_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/shrink_actions.ts similarity index 97% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/shrink_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/shrink_actions.ts index def20f73b82fe..4bf39185b8c03 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/shrink_actions.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/shrink_actions.ts @@ -7,7 +7,7 @@ import { TestBed } from '@kbn/test-jest-helpers'; import { act } from 'react-dom/test-utils'; -import { Phase } from '../../../../common/types'; +import { Phase } from '../../../common/types'; import { createFormSetValueAction } from './form_set_value_action'; export const createShrinkActions = (testBed: TestBed, phase: Phase) => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/snapshot_policy_actions.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/snapshot_policy_actions.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/snapshot_policy_actions.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/snapshot_policy_actions.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/toggle_phase_action.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/toggle_phase_action.ts similarity index 96% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/toggle_phase_action.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/toggle_phase_action.ts index c22efae87d5ac..fc89332e47a67 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/actions/toggle_phase_action.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/actions/toggle_phase_action.ts @@ -8,7 +8,7 @@ import { TestBed } from '@kbn/test-jest-helpers'; import { act } from 'react-dom/test-utils'; -import { Phase } from '../../../../common/types'; +import { Phase } from '../../../common/types'; const toggleDeletePhase = async (testBed: TestBed) => { const { find, component } = testBed; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/global_mocks.tsx b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/global_mocks.tsx similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/global_mocks.tsx rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/global_mocks.tsx diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/http_requests.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/http_requests.ts similarity index 97% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/http_requests.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/http_requests.ts index 7ddcd5358404f..70e85c8bc5df4 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/http_requests.ts +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/http_requests.ts @@ -6,12 +6,12 @@ */ import { httpServiceMock } from '@kbn/core/public/mocks'; -import { API_BASE_PATH } from '../../../common/constants'; +import { API_BASE_PATH } from '../../common/constants'; import { ListNodesRouteResponse, ListSnapshotReposResponse, NodesDetailsResponse, -} from '../../../common/types'; +} from '../../common/types'; import { getDefaultHotPhasePolicy } from '../edit_policy/constants'; type HttpMethod = 'GET' | 'PUT' | 'DELETE' | 'POST'; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/index.ts similarity index 100% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/index.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.tsx b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/setup_environment.tsx similarity index 80% rename from x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.tsx rename to x-pack/plugins/index_lifecycle_management/integration_tests/helpers/setup_environment.tsx index 055097c883e94..91aebb485ea7f 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/setup_environment.tsx +++ b/x-pack/plugins/index_lifecycle_management/integration_tests/helpers/setup_environment.tsx @@ -19,12 +19,12 @@ import { executionContextServiceMock, } from '@kbn/core/public/mocks'; import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; -import { init as initHttp } from '../../../public/application/services/http'; +import { init as initHttp } from '../../public/application/services/http'; import { init as initHttpRequests } from './http_requests'; -import { init as initUiMetric } from '../../../public/application/services/ui_metric'; -import { init as initNotification } from '../../../public/application/services/notification'; -import { KibanaContextProvider } from '../../../public/shared_imports'; -import { createBreadcrumbsMock } from '../../../public/application/services/breadcrumbs.mock'; +import { init as initUiMetric } from '../../public/application/services/ui_metric'; +import { init as initNotification } from '../../public/application/services/notification'; +import { KibanaContextProvider } from '../../public/shared_imports'; +import { createBreadcrumbsMock } from '../../public/application/services/breadcrumbs.mock'; const breadcrumbService = createBreadcrumbsMock(); const appContextMock = { diff --git a/x-pack/plugins/index_lifecycle_management/jest.integration.config.js b/x-pack/plugins/index_lifecycle_management/jest.integration.config.js new file mode 100644 index 0000000000000..6d1ac5ec2fd8a --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/jest.integration.config.js @@ -0,0 +1,19 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test/jest_integration', + rootDir: '../../..', + roots: ['/x-pack/plugins/index_lifecycle_management'], + testMatch: ['/**/integration_tests/**/*.test.{js,mjs,ts,tsx}'], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/index_lifecycle_management', + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/index_lifecycle_management/{common,public,server}/**/*.{ts,tsx}', + ], +}; diff --git a/x-pack/plugins/index_lifecycle_management/tsconfig.json b/x-pack/plugins/index_lifecycle_management/tsconfig.json index d3a342e110211..4b5d7657ed9f6 100644 --- a/x-pack/plugins/index_lifecycle_management/tsconfig.json +++ b/x-pack/plugins/index_lifecycle_management/tsconfig.json @@ -8,6 +8,7 @@ }, "include": [ "__jest__/**/*", + "integration_tests/**/*", "common/**/*", "public/**/*", "server/**/*", diff --git a/x-pack/plugins/infra/public/apps/metrics_app.tsx b/x-pack/plugins/infra/public/apps/metrics_app.tsx index fdeb7173d5cee..ce8123b5f2223 100644 --- a/x-pack/plugins/infra/public/apps/metrics_app.tsx +++ b/x-pack/plugins/infra/public/apps/metrics_app.tsx @@ -45,6 +45,7 @@ export const renderApp = ( ); return () => { + core.chrome.docTitle.reset(); ReactDOM.unmountComponentAtNode(element); plugins.data.search.session.clear(); }; diff --git a/x-pack/plugins/infra/public/components/document_title.tsx b/x-pack/plugins/infra/public/components/document_title.tsx deleted file mode 100644 index 20e482d9df5b5..0000000000000 --- a/x-pack/plugins/infra/public/components/document_title.tsx +++ /dev/null @@ -1,72 +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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; - -type TitleProp = string | ((previousTitle: string) => string); - -interface DocumentTitleProps { - title: TitleProp; -} - -interface DocumentTitleState { - index: number; -} - -const wrapWithSharedState = () => { - const titles: string[] = []; - const TITLE_SUFFIX = ' - Kibana'; - - return class extends React.Component { - public componentDidMount() { - this.setState( - () => { - return { index: titles.push('') - 1 }; - }, - () => { - this.pushTitle(this.getTitle(this.props.title)); - this.updateDocumentTitle(); - } - ); - } - - public componentDidUpdate() { - this.pushTitle(this.getTitle(this.props.title)); - this.updateDocumentTitle(); - } - - public componentWillUnmount() { - this.removeTitle(); - this.updateDocumentTitle(); - } - - public render() { - return null; - } - - public getTitle(title: TitleProp) { - return typeof title === 'function' ? title(titles[this.state.index - 1]) : title; - } - - public pushTitle(title: string) { - titles[this.state.index] = title; - } - - public removeTitle() { - titles.pop(); - } - - public updateDocumentTitle() { - const title = (titles[titles.length - 1] || '') + TITLE_SUFFIX; - if (title !== document.title) { - document.title = title; - } - } - }; -}; - -export const DocumentTitle = wrapWithSharedState(); diff --git a/x-pack/plugins/infra/public/hooks/use_breadcrumbs.ts b/x-pack/plugins/infra/public/hooks/use_breadcrumbs.ts index 37801c16bcf1f..97f737380022d 100644 --- a/x-pack/plugins/infra/public/hooks/use_breadcrumbs.ts +++ b/x-pack/plugins/infra/public/hooks/use_breadcrumbs.ts @@ -22,7 +22,7 @@ export const useBreadcrumbs = (app: AppId, appTitle: string, extraCrumbs: Chrome const appLinkProps = useLinkProps({ app }); useEffect(() => { - chrome?.setBreadcrumbs?.([ + const breadcrumbs = [ { ...observabilityLinkProps, text: observabilityTitle, @@ -32,6 +32,11 @@ export const useBreadcrumbs = (app: AppId, appTitle: string, extraCrumbs: Chrome text: appTitle, }, ...extraCrumbs, - ]); + ]; + + const docTitle = [...breadcrumbs].reverse().map((breadcrumb) => breadcrumb.text as string); + + chrome.docTitle.change(docTitle); + chrome.setBreadcrumbs(breadcrumbs); }, [appLinkProps, appTitle, chrome, extraCrumbs, observabilityLinkProps]); }; diff --git a/x-pack/plugins/infra/public/hooks/use_document_title.tsx b/x-pack/plugins/infra/public/hooks/use_document_title.tsx new file mode 100644 index 0000000000000..82fb5a669eb91 --- /dev/null +++ b/x-pack/plugins/infra/public/hooks/use_document_title.tsx @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ChromeBreadcrumb } from '@kbn/core/public'; +import { useEffect } from 'react'; +import { observabilityTitle } from '../translations'; +import { useKibanaContextForPlugin } from './use_kibana'; + +export const useDocumentTitle = (extraTitles: ChromeBreadcrumb[]) => { + const { + services: { chrome }, + } = useKibanaContextForPlugin(); + + useEffect(() => { + const docTitle = [{ text: observabilityTitle }, ...extraTitles] + .reverse() + .map((breadcrumb) => breadcrumb.text as string); + + chrome.docTitle.change(docTitle); + }, [chrome, extraTitles]); +}; diff --git a/x-pack/plugins/infra/public/pages/logs/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/page_content.tsx index e42cfc2d7c54a..8acd4004603e9 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_content.tsx @@ -12,7 +12,6 @@ import { Route, Switch } from 'react-router-dom'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { HeaderMenuPortal, useLinkProps } from '@kbn/observability-plugin/public'; import { AlertDropdown } from '../../alerting/log_threshold'; -import { DocumentTitle } from '../../components/document_title'; import { HelpCenterContent } from '../../components/help_center_content'; import { useReadOnlyBadge } from '../../hooks/use_readonly_badge'; import { HeaderActionMenuContext } from '../../utils/header_action_menu_provider'; @@ -62,8 +61,6 @@ export const LogsPageContent: React.FunctionComponent = () => { return ( <> - - {setHeaderActionMenu && theme$ && ( diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page.tsx index bb8e4307fe3b9..19f098a6721bc 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page.tsx @@ -10,7 +10,6 @@ import React from 'react'; import { useTrackPageview } from '@kbn/observability-plugin/public'; import { useLogsBreadcrumbs } from '../../../hooks/use_logs_breadcrumbs'; import { StreamPageContent } from './page_content'; -import { StreamPageHeader } from './page_header'; import { LogsPageProviders } from './page_providers'; import { streamTitle } from '../../../translations'; @@ -26,7 +25,6 @@ export const StreamPage = () => { return ( - diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_header.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_header.tsx deleted file mode 100644 index f6c4ad8c8c139..0000000000000 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_header.tsx +++ /dev/null @@ -1,28 +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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import React from 'react'; - -import { DocumentTitle } from '../../../components/document_title'; - -export const StreamPageHeader = () => { - return ( - <> - - i18n.translate('xpack.infra.logs.streamPage.documentTitle', { - defaultMessage: '{previousTitle} | Stream', - values: { - previousTitle, - }, - }) - } - /> - - ); -}; diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx index 5c2fed9753b80..a5dfd7f2ddd0f 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx @@ -6,13 +6,10 @@ */ import { EuiErrorBoundary } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; import React from 'react'; import { useTrackPageview } from '@kbn/observability-plugin/public'; import { APP_WRAPPER_CLASS } from '@kbn/core/public'; -import { DocumentTitle } from '../../../components/document_title'; - import { SourceErrorPage } from '../../../components/source_error_page'; import { SourceLoadingPage } from '../../../components/source_loading_page'; import { useSourceContext } from '../../../containers/metrics_source'; @@ -42,16 +39,6 @@ export const HostsPage = () => { ]); return ( - - i18n.translate('xpack.infra.infrastructureHostsPage.documentTitle', { - defaultMessage: '{previousTitle} | Hosts', - values: { - previousTitle, - }, - }) - } - /> {isLoading && !source ? ( ) : metricIndicesExist && source ? ( diff --git a/x-pack/plugins/infra/public/pages/metrics/index.tsx b/x-pack/plugins/infra/public/pages/metrics/index.tsx index 9c02424aac949..691069a978e83 100644 --- a/x-pack/plugins/infra/public/pages/metrics/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/index.tsx @@ -15,7 +15,6 @@ import { useKibana } from '@kbn/kibana-react-plugin/public'; import { HeaderMenuPortal } from '@kbn/observability-plugin/public'; import { useLinkProps } from '@kbn/observability-plugin/public'; import { MetricsSourceConfigurationProperties } from '../../../common/metrics_sources'; -import { DocumentTitle } from '../../components/document_title'; import { HelpCenterContent } from '../../components/help_center_content'; import { useReadOnlyBadge } from '../../hooks/use_readonly_badge'; import { @@ -73,12 +72,6 @@ export const InfrastructurePage = ({ match }: RouteComponentProps) => { - - { return ( - - i18n.translate('xpack.infra.infrastructureSnapshotPage.documentTitle', { - defaultMessage: '{previousTitle} | Inventory', - values: { - previousTitle, - }, - }) - } - /> {isLoading && !source ? ( ) : metricIndicesExist ? ( diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_error.test.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_error.test.tsx new file mode 100644 index 0000000000000..25ae3b3717bd6 --- /dev/null +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_error.test.tsx @@ -0,0 +1,47 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render } from '@testing-library/react'; + +import { PageError } from './page_error'; +import { errorTitle } from '../../../../translations'; +import { InfraHttpError } from '../../../../types'; +import { useDocumentTitle } from '../../../../hooks/use_document_title'; +import { I18nProvider } from '@kbn/i18n-react'; + +jest.mock('../../../../hooks/use_document_title', () => ({ + useDocumentTitle: jest.fn(), +})); + +const renderErrorPage = () => + render( + + + + ); + +describe('PageError component', () => { + it('renders correctly and set title', () => { + const { getByText } = renderErrorPage(); + expect(useDocumentTitle).toHaveBeenCalledWith([{ text: `${errorTitle}` }]); + + expect(getByText('Error Message')).toBeInTheDocument(); + expect(getByText('Please click the back button and try again.')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_error.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_error.tsx index a6665e0d244f2..b4cdb47399e98 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_error.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/page_error.tsx @@ -6,11 +6,11 @@ */ import React from 'react'; -import { i18n } from '@kbn/i18n'; +import { useDocumentTitle } from '../../../../hooks/use_document_title'; import { InvalidNodeError } from './invalid_node'; -import { DocumentTitle } from '../../../../components/document_title'; import { ErrorPageBody } from '../../../error'; import { InfraHttpError } from '../../../../types'; +import { errorTitle } from '../../../../translations'; interface Props { name: string; @@ -18,18 +18,10 @@ interface Props { } export const PageError = ({ error, name }: Props) => { + useDocumentTitle([{ text: errorTitle }]); + return ( <> - - i18n.translate('xpack.infra.metricDetailPage.documentTitleError', { - defaultMessage: '{previousTitle} | Uh oh', - values: { - previousTitle, - }, - }) - } - /> {error.body?.statusCode === 404 ? ( ) : ( diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx index 823b9d703f502..9b92901976bff 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx @@ -9,7 +9,6 @@ import { i18n } from '@kbn/i18n'; import React, { useState } from 'react'; import { EuiTheme, withTheme } from '@kbn/kibana-react-plugin/common'; import { useLinkProps } from '@kbn/observability-plugin/public'; -import { DocumentTitle } from '../../../components/document_title'; import { withMetricPageProviders } from './page_providers'; import { useMetadata } from './hooks/use_metadata'; import { useMetricsBreadcrumbs } from '../../../hooks/use_metrics_breadcrumbs'; @@ -100,14 +99,6 @@ export const MetricDetail = withMetricPageProviders( return ( <> - {metadata ? ( - - i18n.translate('xpack.infra.infrastructureMetricsExplorerPage.documentTitle', { - defaultMessage: '{previousTitle} | Metrics Explorer', - values: { - previousTitle, - }, - }) - } - /> { ...metricColumn, columnId: 'metric-column2', }, + { + ...metricColumn, + columnId: 'metric-column3', + }, ], changeType: 'unchanged', }, @@ -99,6 +103,10 @@ describe('metric suggestions', () => { ...metricColumn, columnId: 'metric-column2', }, + { + ...metricColumn, + columnId: 'metric-column3', + }, ], changeType: 'unchanged', }, diff --git a/x-pack/plugins/lens/public/visualizations/metric/suggestions.ts b/x-pack/plugins/lens/public/visualizations/metric/suggestions.ts index ae40bf83574f4..c0354d4db65e0 100644 --- a/x-pack/plugins/lens/public/visualizations/metric/suggestions.ts +++ b/x-pack/plugins/lens/public/visualizations/metric/suggestions.ts @@ -11,7 +11,7 @@ import { layerTypes } from '../../../common'; import { metricLabel, MetricVisualizationState, supportedDataTypes } from './visualization'; const MAX_BUCKETED_COLUMNS = 1; -const MAX_METRIC_COLUMNS = 1; +const MAX_METRIC_COLUMNS = 2; // primary and secondary metric const hasLayerMismatch = (keptLayerIds: string[], table: TableSuggestion) => keptLayerIds.length > 1 || (keptLayerIds.length && table.layerId !== keptLayerIds[0]); diff --git a/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx b/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx index ed1efa900cf24..b58068b3ec202 100644 --- a/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/metric/visualization.tsx @@ -19,13 +19,20 @@ import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { IconChartMetric } from '@kbn/chart-icons'; import { LayerType } from '../../../common'; import { getSuggestions } from './suggestions'; -import { Visualization, OperationMetadata, DatasourceLayers, AccessorConfig } from '../../types'; +import { + Visualization, + OperationMetadata, + DatasourceLayers, + AccessorConfig, + Suggestion, +} from '../../types'; import { layerTypes } from '../../../common'; import { GROUP_ID, LENS_METRIC_ID } from './constants'; import { DimensionEditor } from './dimension_editor'; import { Toolbar } from './toolbar'; import { generateId } from '../../id_generator'; import { FormatSelectorOptions } from '../../indexpattern_datasource/dimension_panel/format_selector'; +import { IndexPatternLayer } from '../../indexpattern_datasource/types'; export const DEFAULT_MAX_COLUMNS = 3; @@ -50,6 +57,16 @@ export interface MetricVisualizationState { maxCols?: number; } +interface MetricDatasourceState { + [prop: string]: unknown; + layers: IndexPatternLayer[]; +} + +export interface MetricSuggestion extends Suggestion { + datasourceState: MetricDatasourceState; + visualizationState: MetricVisualizationState; +} + export const supportedDataTypes = new Set(['number']); // TODO - deduplicate with gauges? @@ -484,4 +501,25 @@ export const getMetricVisualization = ({ noPadding: true, }; }, + + getSuggestionFromConvertToLensContext({ suggestions, context }) { + const allSuggestions = suggestions as MetricSuggestion[]; + return { + ...allSuggestions[0], + datasourceState: { + ...allSuggestions[0].datasourceState, + layers: allSuggestions.reduce( + (acc, s) => ({ + ...acc, + ...s.datasourceState.layers, + }), + {} + ), + }, + visualizationState: { + ...allSuggestions[0].visualizationState, + ...context.configuration, + }, + }; + }, }); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/decimal_degrees_form.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/decimal_degrees_form.tsx new file mode 100644 index 0000000000000..03b23e409b770 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/decimal_degrees_form.tsx @@ -0,0 +1,149 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { ChangeEvent, Component } from 'react'; +import { + EuiForm, + EuiFormRow, + EuiButton, + EuiFieldNumber, + EuiTextAlign, + EuiSpacer, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { MapCenter, MapSettings } from '../../../../common/descriptor_types'; +import { withinRange } from './utils'; + +interface Props { + settings: MapSettings; + zoom: number; + center: MapCenter; + onSubmit: (lat: number, lon: number, zoom: number) => void; +} + +interface State { + lat: number | string; + lon: number | string; + zoom: number | string; +} + +export class DecimalDegreesForm extends Component { + state: State = { + lat: this.props.center.lat, + lon: this.props.center.lon, + zoom: this.props.zoom, + }; + + _onLatChange = (evt: ChangeEvent) => { + const sanitizedValue = parseFloat(evt.target.value); + this.setState({ + lat: isNaN(sanitizedValue) ? '' : sanitizedValue, + }); + }; + + _onLonChange = (evt: ChangeEvent) => { + const sanitizedValue = parseFloat(evt.target.value); + this.setState({ + lon: isNaN(sanitizedValue) ? '' : sanitizedValue, + }); + }; + + _onZoomChange = (evt: ChangeEvent) => { + const sanitizedValue = parseFloat(evt.target.value); + this.setState({ + zoom: isNaN(sanitizedValue) ? '' : sanitizedValue, + }); + }; + + _onSubmit = () => { + const { lat, lon, zoom } = this.state; + this.props.onSubmit(lat as number, lon as number, zoom as number); + }; + + render() { + const { isInvalid: isLatInvalid, error: latError } = withinRange(this.state.lat, -90, 90); + const { isInvalid: isLonInvalid, error: lonError } = withinRange(this.state.lon, -180, 180); + const { isInvalid: isZoomInvalid, error: zoomError } = withinRange( + this.state.zoom, + this.props.settings.minZoom, + this.props.settings.maxZoom + ); + + return ( + + + + + + + + + + + + + + + + + + + + + + ); + } +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/mgrs_form.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/mgrs_form.tsx new file mode 100644 index 0000000000000..48455f89b7464 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/mgrs_form.tsx @@ -0,0 +1,149 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import _ from 'lodash'; +import React, { ChangeEvent, Component } from 'react'; +import { + EuiForm, + EuiFormRow, + EuiButton, + EuiFieldNumber, + EuiFieldText, + EuiTextAlign, + EuiSpacer, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { MapCenter, MapSettings } from '../../../../common/descriptor_types'; +import { ddToMGRS, mgrsToDD, withinRange } from './utils'; + +interface Props { + settings: MapSettings; + zoom: number; + center: MapCenter; + onSubmit: (lat: number, lon: number, zoom: number) => void; +} + +interface State { + mgrs: string; + zoom: number | string; +} + +export class MgrsForm extends Component { + state: State = { + mgrs: ddToMGRS(this.props.center.lat, this.props.center.lon), + zoom: this.props.zoom, + }; + + _toPoint() { + return this.state.mgrs === '' ? undefined : mgrsToDD(this.state.mgrs); + } + + _isMgrsInvalid() { + const point = this._toPoint(); + return ( + point === undefined || + !point.north || + _.isNaN(point.north) || + !point.south || + _.isNaN(point.south) || + !point.east || + _.isNaN(point.east) || + !point.west || + _.isNaN(point.west) + ); + } + + _onMGRSChange = (evt: ChangeEvent) => { + this.setState({ + mgrs: _.isNull(evt.target.value) ? '' : evt.target.value, + }); + }; + + _onZoomChange = (evt: ChangeEvent) => { + const sanitizedValue = parseFloat(evt.target.value); + this.setState({ + zoom: isNaN(sanitizedValue) ? '' : sanitizedValue, + }); + }; + + _onSubmit = () => { + const point = this._toPoint(); + if (point) { + this.props.onSubmit(point.north, point.east, this.state.zoom as number); + } + }; + + render() { + const isMgrsInvalid = this._isMgrsInvalid(); + const mgrsError = isMgrsInvalid + ? i18n.translate('xpack.maps.setViewControl.mgrsInvalid', { + defaultMessage: 'MGRS is invalid', + }) + : null; + const { isInvalid: isZoomInvalid, error: zoomError } = withinRange( + this.state.zoom, + this.props.settings.minZoom, + this.props.settings.maxZoom + ); + + return ( + + + + + + + + + + + + + + + + + + ); + } +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/number_form_row.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/number_form_row.tsx new file mode 100644 index 0000000000000..1fec1c76430eb --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/number_form_row.tsx @@ -0,0 +1,6 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.tsx index eb0b1cfc1ddaf..906cbb8a0bb00 100644 --- a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_control.tsx @@ -5,50 +5,11 @@ * 2.0. */ -import React, { ChangeEvent, Component, Fragment } from 'react'; -import { - EuiForm, - EuiFormRow, - EuiButton, - EuiFieldNumber, - EuiFieldText, - EuiButtonIcon, - EuiPopover, - EuiTextAlign, - EuiSpacer, - EuiPanel, -} from '@elastic/eui'; -import { EuiButtonEmpty } from '@elastic/eui'; -import { EuiRadioGroup } from '@elastic/eui'; +import React, { Component } from 'react'; +import { EuiButtonIcon, EuiPopover, EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import * as usng from 'usng.js'; -import { isNaN, isNull } from 'lodash'; import { MapCenter, MapSettings } from '../../../../common/descriptor_types'; - -export const COORDINATE_SYSTEM_DEGREES_DECIMAL = 'dd'; -export const COORDINATE_SYSTEM_MGRS = 'mgrs'; -export const COORDINATE_SYSTEM_UTM = 'utm'; - -export const DEFAULT_SET_VIEW_COORDINATE_SYSTEM = COORDINATE_SYSTEM_DEGREES_DECIMAL; - -// @ts-ignore -const converter = new usng.Converter(); - -const COORDINATE_SYSTEMS = [ - { - id: COORDINATE_SYSTEM_DEGREES_DECIMAL, - label: 'Degrees Decimal', - }, - { - id: COORDINATE_SYSTEM_UTM, - label: 'UTM', - }, - { - id: COORDINATE_SYSTEM_MGRS, - label: 'MGRS', - }, -]; +import { SetViewForm } from './set_view_form'; export interface Props { settings: MapSettings; @@ -59,73 +20,17 @@ export interface Props { interface State { isPopoverOpen: boolean; - lat: number | string; - lon: number | string; - zoom: number | string; - coord: string; - mgrs: string; - utm: { - northing: string; - easting: string; - zoneNumber: string; - zoneLetter: string | undefined; - zone: string; - }; - isCoordPopoverOpen: boolean; - prevView: string | undefined; } export class SetViewControl extends Component { state: State = { isPopoverOpen: false, - lat: 0, - lon: 0, - zoom: 0, - coord: DEFAULT_SET_VIEW_COORDINATE_SYSTEM, - mgrs: '', - utm: { - northing: '', - easting: '', - zoneNumber: '', - zoneLetter: '', - zone: '', - }, - isCoordPopoverOpen: false, - prevView: '', }; - static getDerivedStateFromProps(nextProps: Props, prevState: State) { - const nextView = getViewString(nextProps.center.lat, nextProps.center.lon, nextProps.zoom); - - const utm = convertLatLonToUTM(nextProps.center.lat, nextProps.center.lon); - const mgrs = convertLatLonToMGRS(nextProps.center.lat, nextProps.center.lon); - - if (nextView !== prevState.prevView) { - return { - lat: nextProps.center.lat, - lon: nextProps.center.lon, - zoom: nextProps.zoom, - utm, - mgrs, - prevView: nextView, - }; - } - - return null; - } - _togglePopover = () => { - if (this.state.isPopoverOpen) { - this._closePopover(); - return; - } - - this.setState({ - lat: this.props.center.lat, - lon: this.props.center.lon, - zoom: this.props.zoom, - isPopoverOpen: true, - }); + this.setState((prevState) => ({ + isPopoverOpen: !prevState.isPopoverOpen, + })); }; _closePopover = () => { @@ -134,567 +39,11 @@ export class SetViewControl extends Component { }); }; - _onCoordinateSystemChange = (coordId: string) => { - this.setState({ - coord: coordId, - }); - }; - - _onLatChange = (evt: ChangeEvent) => { - this._onChange('lat', evt); - }; - - _onLonChange = (evt: ChangeEvent) => { - this._onChange('lon', evt); - }; - - _onZoomChange = (evt: ChangeEvent) => { - const sanitizedValue = parseFloat(evt.target.value); - this.setState({ - ['zoom']: isNaN(sanitizedValue) ? '' : sanitizedValue, - }); - }; - - _onUTMZoneChange = (evt: ChangeEvent) => { - this._onUTMChange('zone', evt); - }; - - _onUTMEastingChange = (evt: ChangeEvent) => { - this._onUTMChange('easting', evt); - }; - - _onUTMNorthingChange = (evt: ChangeEvent) => { - this._onUTMChange('northing', evt); - }; - - _onMGRSChange = (evt: ChangeEvent) => { - this.setState( - { - ['mgrs']: isNull(evt.target.value) ? '' : evt.target.value, - }, - this._syncToMGRS - ); - }; - - _onUTMChange = (name: 'easting' | 'northing' | 'zone', evt: ChangeEvent) => { - const value = evt.target.value; - const updateObj = { ...this.state.utm }; - updateObj[name] = isNull(value) ? '' : value; - if (name === 'zone' && value.length > 0) { - const zoneLetter = value.substring(value.length - 1); - const zoneNumber = value.substring(0, value.length - 1); - updateObj.zoneLetter = isNaN(zoneLetter) ? zoneLetter : ''; - updateObj.zoneNumber = isNaN(zoneNumber) ? '' : zoneNumber; - } - this.setState( - { - // @ts-ignore - ['utm']: updateObj, - }, - this._syncToUTM - ); - }; - - _onChange = (name: 'lat' | 'lon', evt: ChangeEvent) => { - const sanitizedValue = parseFloat(evt.target.value); - - this.setState( - // @ts-ignore - { - [name]: isNaN(sanitizedValue) ? '' : sanitizedValue, - }, - this._syncToLatLon - ); - }; - - /** - * Sync all coordinates to the lat/lon that is set - */ - _syncToLatLon = () => { - if (this.state.lat !== '' && this.state.lon !== '') { - const utm = convertLatLonToUTM(this.state.lat, this.state.lon); - const mgrs = convertLatLonToMGRS(this.state.lat, this.state.lon); - - this.setState({ mgrs, utm }); - } else { - this.setState({ - mgrs: '', - utm: { northing: '', easting: '', zoneNumber: '', zoneLetter: '', zone: '' }, - }); - } - }; - - /** - * Sync the current lat/lon to MGRS that is set - */ - _syncToMGRS = () => { - if (this.state.mgrs !== '') { - let lon; - let lat; - - try { - const { north, east } = convertMGRStoLL(this.state.mgrs); - lat = north; - lon = east; - } catch (err) { - return; - } - - const utm = convertLatLonToUTM(lat, lon); - - this.setState({ - lat: isNaN(lat) ? '' : lat, - lon: isNaN(lon) ? '' : lon, - utm, - }); - } else { - this.setState({ - lat: '', - lon: '', - utm: { northing: '', easting: '', zoneNumber: '', zoneLetter: '', zone: '' }, - }); - } - }; - - /** - * Sync the current lat/lon to UTM that is set - */ - _syncToUTM = () => { - if (this.state.utm) { - let lat; - let lon; - try { - ({ lat, lon } = converter.UTMtoLL( - this.state.utm.northing, - this.state.utm.easting, - this.state.utm.zoneNumber - )); - } catch (err) { - return; - } - - const mgrs = convertLatLonToMGRS(lat, lon); - - this.setState({ - lat: isNaN(lat) ? '' : lat, - lon: isNaN(lon) ? '' : lon, - mgrs, - }); - } else { - this.setState({ - lat: '', - lon: '', - mgrs: '', - }); - } - }; - - _renderNumberFormRow = ({ - value, - min, - max, - onChange, - label, - dataTestSubj, - }: { - value: string | number; - min: number; - max: number; - onChange: (evt: ChangeEvent) => void; - label: string; - dataTestSubj: string; - }) => { - const isInvalid = value === '' || value > max || value < min; - const error = isInvalid ? `Must be between ${min} and ${max}` : null; - return { - isInvalid, - component: ( - - - - ), - }; - }; - - _renderMGRSFormRow = ({ - value, - onChange, - label, - dataTestSubj, - }: { - value: string; - onChange: (evt: ChangeEvent) => void; - label: string; - dataTestSubj: string; - }) => { - let point; - try { - point = convertMGRStoLL(value); - } catch (err) { - point = undefined; - } - - const isInvalid = - value === '' || - point === undefined || - !point.north || - isNaN(point.north) || - !point.south || - isNaN(point.south) || - !point.east || - isNaN(point.east) || - !point.west || - isNaN(point.west); - const error = isInvalid - ? i18n.translate('xpack.maps.setViewControl.mgrsInvalid', { - defaultMessage: 'MGRS is invalid', - }) - : null; - return { - isInvalid, - component: ( - - - - ), - }; - }; - - _renderUTMZoneRow = ({ - value, - onChange, - label, - dataTestSubj, - }: { - value: string | number; - onChange: (evt: ChangeEvent) => void; - label: string; - dataTestSubj: string; - }) => { - let point; - try { - point = converter.UTMtoLL( - this.state.utm.northing, - this.state.utm.easting, - this.state.utm.zoneNumber - ); - } catch { - point = undefined; - } - - const isInvalid = value === '' || point === undefined; - const error = isInvalid - ? i18n.translate('xpack.maps.setViewControl.utmInvalidZone', { - defaultMessage: 'UTM Zone is invalid', - }) - : null; - return { - isInvalid, - component: ( - - - - ), - }; - }; - - _renderUTMEastingRow = ({ - value, - onChange, - label, - dataTestSubj, - }: { - value: string | number; - onChange: (evt: ChangeEvent) => void; - label: string; - dataTestSubj: string; - }) => { - let point; - try { - point = converter.UTMtoLL(this.state.utm.northing, value, this.state.utm.zoneNumber); - } catch { - point = undefined; - } - const isInvalid = value === '' || point === undefined; - const error = isInvalid - ? i18n.translate('xpack.maps.setViewControl.utmInvalidEasting', { - defaultMessage: 'UTM Easting is invalid', - }) - : null; - return { - isInvalid, - component: ( - - - - ), - }; - }; - - _renderUTMNorthingRow = ({ - value, - onChange, - label, - dataTestSubj, - }: { - value: string | number; - onChange: (evt: ChangeEvent) => void; - label: string; - dataTestSubj: string; - }) => { - let point; - try { - point = converter.UTMtoLL(value, this.state.utm.easting, this.state.utm.zoneNumber); - } catch { - point = undefined; - } - const isInvalid = value === '' || point === undefined; - const error = isInvalid - ? i18n.translate('xpack.maps.setViewControl.utmInvalidNorthing', { - defaultMessage: 'UTM Northing is invalid', - }) - : null; - return { - isInvalid, - component: ( - - - - ), - }; - }; - - _onSubmit = () => { - const { lat, lon, zoom } = this.state; + _onSubmit = (lat: number, lon: number, zoom: number) => { this._closePopover(); - this.props.onSubmit({ lat: lat as number, lon: lon as number, zoom: zoom as number }); + this.props.onSubmit({ lat, lon, zoom }); }; - _renderSetViewForm() { - let isLatInvalid; - let latFormRow; - let isLonInvalid; - let lonFormRow; - let isMGRSInvalid; - let mgrsFormRow; - let isUtmZoneInvalid; - let utmZoneRow; - let isUtmEastingInvalid; - let utmEastingRow; - let isUtmNorthingInvalid; - let utmNorthingRow; - - if (this.state.coord === COORDINATE_SYSTEM_DEGREES_DECIMAL) { - const latRenderObject = this._renderNumberFormRow({ - value: this.state.lat, - min: -90, - max: 90, - onChange: this._onLatChange, - label: i18n.translate('xpack.maps.setViewControl.latitudeLabel', { - defaultMessage: 'Latitude', - }), - dataTestSubj: 'latitudeInput', - }); - - isLatInvalid = latRenderObject.isInvalid; - latFormRow = latRenderObject.component; - - const lonRenderObject = this._renderNumberFormRow({ - value: this.state.lon, - min: -180, - max: 180, - onChange: this._onLonChange, - label: i18n.translate('xpack.maps.setViewControl.longitudeLabel', { - defaultMessage: 'Longitude', - }), - dataTestSubj: 'longitudeInput', - }); - - isLonInvalid = lonRenderObject.isInvalid; - lonFormRow = lonRenderObject.component; - } else if (this.state.coord === COORDINATE_SYSTEM_MGRS) { - const mgrsRenderObject = this._renderMGRSFormRow({ - value: this.state.mgrs, - onChange: this._onMGRSChange, - label: i18n.translate('xpack.maps.setViewControl.mgrsLabel', { - defaultMessage: 'MGRS', - }), - dataTestSubj: 'mgrsInput', - }); - - isMGRSInvalid = mgrsRenderObject.isInvalid; - mgrsFormRow = mgrsRenderObject.component; - } else if (this.state.coord === COORDINATE_SYSTEM_UTM) { - const utmZoneRenderObject = this._renderUTMZoneRow({ - value: this.state.utm !== undefined ? this.state.utm.zone : '', - onChange: this._onUTMZoneChange, - label: i18n.translate('xpack.maps.setViewControl.utmZoneLabel', { - defaultMessage: 'UTM Zone', - }), - dataTestSubj: 'utmZoneInput', - }); - - isUtmZoneInvalid = utmZoneRenderObject.isInvalid; - utmZoneRow = utmZoneRenderObject.component; - - const utmEastingRenderObject = this._renderUTMEastingRow({ - value: this.state.utm !== undefined ? this.state.utm.easting : '', - onChange: this._onUTMEastingChange, - label: i18n.translate('xpack.maps.setViewControl.utmEastingLabel', { - defaultMessage: 'UTM Easting', - }), - dataTestSubj: 'utmEastingInput', - }); - - isUtmEastingInvalid = utmEastingRenderObject.isInvalid; - utmEastingRow = utmEastingRenderObject.component; - - const utmNorthingRenderObject = this._renderUTMNorthingRow({ - value: this.state.utm !== undefined ? this.state.utm.northing : '', - onChange: this._onUTMNorthingChange, - label: i18n.translate('xpack.maps.setViewControl.utmNorthingLabel', { - defaultMessage: 'UTM Northing', - }), - dataTestSubj: 'utmNorthingInput', - }); - - isUtmNorthingInvalid = utmNorthingRenderObject.isInvalid; - utmNorthingRow = utmNorthingRenderObject.component; - } - - const { isInvalid: isZoomInvalid, component: zoomFormRow } = this._renderNumberFormRow({ - value: this.state.zoom, - min: this.props.settings.minZoom, - max: this.props.settings.maxZoom, - onChange: this._onZoomChange, - label: i18n.translate('xpack.maps.setViewControl.zoomLabel', { - defaultMessage: 'Zoom', - }), - dataTestSubj: 'zoomInput', - }); - - let coordinateInputs; - if (this.state.coord === 'dd') { - coordinateInputs = ( - - {latFormRow} - {lonFormRow} - {zoomFormRow} - - ); - } else if (this.state.coord === 'dms') { - coordinateInputs = ( - - {latFormRow} - {lonFormRow} - {zoomFormRow} - - ); - } else if (this.state.coord === 'utm') { - coordinateInputs = ( - - {utmZoneRow} - {utmEastingRow} - {utmNorthingRow} - {zoomFormRow} - - ); - } else if (this.state.coord === 'mgrs') { - coordinateInputs = ( - - {mgrsFormRow} - {zoomFormRow} - - ); - } - - return ( - - { - this.setState({ isCoordPopoverOpen: false }); - }} - button={ - { - this.setState({ isCoordPopoverOpen: !this.state.isCoordPopoverOpen }); - }} - > - Coordinate System - - } - > - - - - {coordinateInputs} - - - - - - - - - - ); - } - render() { return ( { isOpen={this.state.isPopoverOpen} closePopover={this._closePopover} > - {this._renderSetViewForm()} + ); } } - -function convertLatLonToUTM(lat: string | number, lon: string | number) { - const utmCoord = converter.LLtoUTM(lat, lon); - - let eastwest = 'E'; - if (utmCoord.easting < 0) { - eastwest = 'W'; - } - let norwest = 'N'; - if (utmCoord.northing < 0) { - norwest = 'S'; - } - - if (utmCoord !== 'undefined') { - utmCoord.zoneLetter = isNaN(lat) ? '' : converter.UTMLetterDesignator(lat); - utmCoord.zone = `${utmCoord.zoneNumber}${utmCoord.zoneLetter}`; - utmCoord.easting = Math.round(utmCoord.easting); - utmCoord.northing = Math.round(utmCoord.northing); - utmCoord.str = `${utmCoord.zoneNumber}${utmCoord.zoneLetter} ${utmCoord.easting}${eastwest} ${utmCoord.northing}${norwest}`; - } - - return utmCoord; -} - -function convertLatLonToMGRS(lat: string | number, lon: string | number) { - const mgrsCoord = converter.LLtoMGRS(lat, lon, 5); - return mgrsCoord; -} - -function getViewString(lat: number, lon: number, zoom: number) { - return `${lat},${lon},${zoom}`; -} - -function convertMGRStoUSNG(mgrs: string) { - let squareIdEastSpace = 0; - for (let i = mgrs.length - 1; i > -1; i--) { - // check if we have hit letters yet - if (isNaN(mgrs.substr(i, 1))) { - squareIdEastSpace = i + 1; - break; - } - } - const gridZoneSquareIdSpace = squareIdEastSpace ? squareIdEastSpace - 2 : -1; - const numPartLength = mgrs.substr(squareIdEastSpace).length / 2; - // add the number split space - const eastNorthSpace = squareIdEastSpace ? squareIdEastSpace + numPartLength : -1; - const stringArray = mgrs.split(''); - - stringArray.splice(eastNorthSpace, 0, ' '); - stringArray.splice(squareIdEastSpace, 0, ' '); - stringArray.splice(gridZoneSquareIdSpace, 0, ' '); - - const rejoinedArray = stringArray.join(''); - return rejoinedArray; -} - -function convertMGRStoLL(mgrs: string) { - return mgrs ? converter.USNGtoLL(convertMGRStoUSNG(mgrs)) : ''; -} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_form.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_form.tsx new file mode 100644 index 0000000000000..28fe6073d7646 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/set_view_form.tsx @@ -0,0 +1,134 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { Component } from 'react'; +import { EuiButtonEmpty, EuiPopover, EuiRadioGroup } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { MapCenter, MapSettings } from '../../../../common/descriptor_types'; +import { DecimalDegreesForm } from './decimal_degrees_form'; +import { MgrsForm } from './mgrs_form'; +import { UtmForm } from './utm_form'; + +const DEGREES_DECIMAL = 'dd'; +const MGRS = 'mgrs'; +const UTM = 'utm'; + +const COORDINATE_SYSTEM_OPTIONS = [ + { + id: DEGREES_DECIMAL, + label: i18n.translate('xpack.maps.setViewControl.decimalDegreesLabel', { + defaultMessage: 'Decimal degrees', + }), + }, + { + id: UTM, + label: 'UTM', + }, + { + id: MGRS, + label: 'MGRS', + }, +]; + +interface Props { + settings: MapSettings; + zoom: number; + center: MapCenter; + onSubmit: (lat: number, lon: number, zoom: number) => void; +} + +interface State { + isPopoverOpen: boolean; + coordinateSystem: string; +} + +export class SetViewForm extends Component { + state: State = { + coordinateSystem: DEGREES_DECIMAL, + isPopoverOpen: false, + }; + + _togglePopover = () => { + this.setState((prevState) => ({ + isPopoverOpen: !prevState.isPopoverOpen, + })); + }; + + _closePopover = () => { + this.setState({ + isPopoverOpen: false, + }); + }; + + _onCoordinateSystemChange = (optionId: string) => { + this._closePopover(); + this.setState({ + coordinateSystem: optionId, + }); + }; + + _renderForm() { + if (this.state.coordinateSystem === MGRS) { + return ( + + ); + } + + if (this.state.coordinateSystem === UTM) { + return ( + + ); + } + + return ( + + ); + } + + render() { + return ( +
+ + + + } + > + + + {this._renderForm()} +
+ ); + } +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/utils.test.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/utils.test.ts new file mode 100644 index 0000000000000..e6a6819687d10 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/utils.test.ts @@ -0,0 +1,52 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ddToMGRS, mgrsToDD, ddToUTM, utmToDD } from './utils'; + +describe('MGRS', () => { + test('ddToMGRS should convert lat lon to MGRS', () => { + expect(ddToMGRS(29.29926, 32.05495)).toEqual('36RVT08214151'); + }); + + test('ddToMGRS should return empty string for lat lon that does not translate to MGRS grid', () => { + expect(ddToMGRS(90, 32.05495)).toEqual(''); + }); + + test('mgrsToDD should convert MGRS to lat lon', () => { + expect(mgrsToDD('36RVT08214151')).toEqual({ + east: 32.05498649594143, + north: 29.299330195900975, + south: 29.299239224067065, + west: 32.054884373627345, + }); + }); +}); + +describe('UTM', () => { + test('ddToUTM should convert lat lon to UTM', () => { + expect(ddToUTM(29.29926, 32.05495)).toEqual({ + easting: '408216', + northing: '3241512', + zone: '36R', + }); + }); + + test('ddToUTM should return empty strings for lat lon that does not translate to UTM grid', () => { + expect(ddToUTM(90, 32.05495)).toEqual({ + northing: '', + easting: '', + zone: '', + }); + }); + + test('utmToDD should convert UTM to lat lon', () => { + expect(utmToDD('3241512', '408216', '36R')).toEqual({ + lat: 29.29925770984472, + lon: 32.05494597943409, + }); + }); +}); diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/utils.ts b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/utils.ts new file mode 100644 index 0000000000000..7edf1428d9312 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/utils.ts @@ -0,0 +1,91 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import * as usng from 'usng.js'; + +// @ts-ignore +const converter = new usng.Converter(); + +export function withinRange(value: string | number, min: number, max: number) { + const isInvalid = value === '' || value > max || value < min; + const error = isInvalid + ? i18n.translate('xpack.maps.setViewControl.outOfRangeErrorMsg', { + defaultMessage: `Must be between {min} and {max}`, + values: { min, max }, + }) + : null; + return { isInvalid, error }; +} + +export function ddToUTM(lat: number, lon: number) { + try { + const utm = converter.LLtoUTM(lat, lon); + return { + northing: utm === converter.UNDEFINED_STR ? '' : String(Math.round(utm.northing)), + easting: utm === converter.UNDEFINED_STR ? '' : String(Math.round(utm.easting)), + zone: + utm === converter.UNDEFINED_STR + ? '' + : `${utm.zoneNumber}${converter.UTMLetterDesignator(lat)}`, + }; + } catch (e) { + return { + northing: '', + easting: '', + zone: '', + }; + } +} + +export function utmToDD(northing: string, easting: string, zoneNumber: string) { + try { + return converter.UTMtoLL(northing, easting, zoneNumber); + } catch (e) { + return undefined; + } +} + +export function ddToMGRS(lat: number, lon: number) { + try { + const mgrsCoord = converter.LLtoMGRS(lat, lon, 5); + return mgrsCoord; + } catch (e) { + return ''; + } +} + +function mgrstoUSNG(mgrs: string) { + let squareIdEastSpace = 0; + for (let i = mgrs.length - 1; i > -1; i--) { + // check if we have hit letters yet + if (isNaN(parseInt(mgrs.substr(i, 1), 10))) { + squareIdEastSpace = i + 1; + break; + } + } + const gridZoneSquareIdSpace = squareIdEastSpace ? squareIdEastSpace - 2 : -1; + const numPartLength = mgrs.substr(squareIdEastSpace).length / 2; + // add the number split space + const eastNorthSpace = squareIdEastSpace ? squareIdEastSpace + numPartLength : -1; + const stringArray = mgrs.split(''); + + stringArray.splice(eastNorthSpace, 0, ' '); + stringArray.splice(squareIdEastSpace, 0, ' '); + stringArray.splice(gridZoneSquareIdSpace, 0, ' '); + + const rejoinedArray = stringArray.join(''); + return rejoinedArray; +} + +export function mgrsToDD(mgrs: string) { + try { + return converter.USNGtoLL(mgrstoUSNG(mgrs)); + } catch (e) { + return undefined; + } +} diff --git a/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/utm_form.tsx b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/utm_form.tsx new file mode 100644 index 0000000000000..76a3628217056 --- /dev/null +++ b/x-pack/plugins/maps/public/connected_components/toolbar_overlay/set_view_control/utm_form.tsx @@ -0,0 +1,209 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import _ from 'lodash'; +import React, { ChangeEvent, Component } from 'react'; +import { + EuiForm, + EuiFormRow, + EuiButton, + EuiFieldNumber, + EuiFieldText, + EuiTextAlign, + EuiSpacer, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { MapCenter, MapSettings } from '../../../../common/descriptor_types'; +import { ddToUTM, utmToDD, withinRange } from './utils'; + +interface Props { + settings: MapSettings; + zoom: number; + center: MapCenter; + onSubmit: (lat: number, lon: number, zoom: number) => void; +} + +interface State { + northing: string; + easting: string; + zone: string; + zoom: number | string; +} + +export class UtmForm extends Component { + constructor(props: Props) { + super(props); + const utm = ddToUTM(this.props.center.lat, this.props.center.lon); + this.state = { + northing: utm.northing, + easting: utm.easting, + zone: utm.zone, + zoom: this.props.zoom, + }; + } + + _toPoint() { + const { northing, easting, zone } = this.state; + return northing === '' || easting === '' || zone.length < 2 + ? undefined + : utmToDD(northing, easting, zone.substring(0, zone.length - 1)); + } + + _isUtmInvalid() { + const point = this._toPoint(); + return point === undefined; + } + + _onZoneChange = (evt: ChangeEvent) => { + this.setState({ + zone: _.isNull(evt.target.value) ? '' : evt.target.value, + }); + }; + + _onEastingChange = (evt: ChangeEvent) => { + this.setState({ + easting: _.isNull(evt.target.value) ? '' : evt.target.value, + }); + }; + + _onNorthingChange = (evt: ChangeEvent) => { + this.setState({ + northing: _.isNull(evt.target.value) ? '' : evt.target.value, + }); + }; + + _onZoomChange = (evt: ChangeEvent) => { + const sanitizedValue = parseFloat(evt.target.value); + this.setState({ + zoom: isNaN(sanitizedValue) ? '' : sanitizedValue, + }); + }; + + _onSubmit = () => { + const point = this._toPoint(); + if (point) { + this.props.onSubmit(point.lat, point.lon, this.state.zoom as number); + } + }; + + render() { + const isUtmInvalid = this._isUtmInvalid(); + const northingError = + isUtmInvalid || this.state.northing === '' + ? i18n.translate('xpack.maps.setViewControl.utmInvalidNorthing', { + defaultMessage: 'UTM Northing is invalid', + }) + : null; + const eastingError = + isUtmInvalid || this.state.northing === '' + ? i18n.translate('xpack.maps.setViewControl.utmInvalidEasting', { + defaultMessage: 'UTM Easting is invalid', + }) + : null; + const zoneError = + isUtmInvalid || this.state.northing === '' + ? i18n.translate('xpack.maps.setViewControl.utmInvalidZone', { + defaultMessage: 'UTM Zone is invalid', + }) + : null; + const { isInvalid: isZoomInvalid, error: zoomError } = withinRange( + this.state.zoom, + this.props.settings.minZoom, + this.props.settings.maxZoom + ); + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + ); + } +} diff --git a/x-pack/plugins/ml/public/application/aiops/log_categorization.tsx b/x-pack/plugins/ml/public/application/aiops/log_categorization.tsx index e1d816d61357a..899006b5918dd 100644 --- a/x-pack/plugins/ml/public/application/aiops/log_categorization.tsx +++ b/x-pack/plugins/ml/public/application/aiops/log_categorization.tsx @@ -34,7 +34,7 @@ export const LogCategorizationPage: FC = () => { diff --git a/x-pack/plugins/ml/public/application/components/ml_page/notifications_indicator.tsx b/x-pack/plugins/ml/public/application/components/ml_page/notifications_indicator.tsx index 20d771f5654d4..d0e3516af3db0 100644 --- a/x-pack/plugins/ml/public/application/components/ml_page/notifications_indicator.tsx +++ b/x-pack/plugins/ml/public/application/components/ml_page/notifications_indicator.tsx @@ -16,7 +16,10 @@ import { EuiToolTip, } from '@elastic/eui'; import { combineLatest, of, timer } from 'rxjs'; -import { catchError, filter, switchMap } from 'rxjs/operators'; +import { catchError, switchMap } from 'rxjs/operators'; +import moment from 'moment'; +import { FIELD_FORMAT_IDS } from '@kbn/field-formats-plugin/common'; +import { useFieldFormatter } from '../../contexts/kibana/use_field_formatter'; import { useAsObservable } from '../../hooks'; import { NotificationsCountResponse } from '../../../../common/types/notifications'; import { useMlKibana } from '../../contexts/kibana'; @@ -31,21 +34,26 @@ export const NotificationsIndicator: FC = () => { mlServices: { mlApiServices }, }, } = useMlKibana(); - const [lastCheckedAt] = useStorage(ML_NOTIFICATIONS_LAST_CHECKED_AT); + const dateFormatter = useFieldFormatter(FIELD_FORMAT_IDS.DATE); + const [lastCheckedAt] = useStorage(ML_NOTIFICATIONS_LAST_CHECKED_AT); const lastCheckedAt$ = useAsObservable(lastCheckedAt); + /** Holds the value used for the actual request */ + const [lastCheckRequested, setLastCheckRequested] = useState(); const [notificationsCounts, setNotificationsCounts] = useState(); useEffect(function startPollingNotifications() { - const subscription = combineLatest([ - lastCheckedAt$.pipe(filter((v): v is number => !!v)), - timer(0, NOTIFICATIONS_CHECK_INTERVAL), - ]) + const subscription = combineLatest([lastCheckedAt$, timer(0, NOTIFICATIONS_CHECK_INTERVAL)]) .pipe( - switchMap(([lastChecked]) => - mlApiServices.notifications.countMessages$({ lastCheckedAt: lastChecked }) - ), + switchMap(([lastChecked]) => { + const lastCheckedAtQuery = lastChecked ?? moment().subtract(7, 'd').valueOf(); + setLastCheckRequested(lastCheckedAtQuery); + // Use the latest check time or 7 days ago by default. + return mlApiServices.notifications.countMessages$({ + lastCheckedAt: lastCheckedAtQuery, + }); + }), catchError((error) => { // Fail silently for now return of({} as NotificationsCountResponse); @@ -80,12 +88,22 @@ export const NotificationsIndicator: FC = () => { content={ } > - {errorsAndWarningCount} + + {errorsAndWarningCount} + ) : null} @@ -96,7 +114,8 @@ export const NotificationsIndicator: FC = () => { content={ } > @@ -106,6 +125,7 @@ export const NotificationsIndicator: FC = () => { aria-label={i18n.translate('xpack.ml.notificationsIndicator.unreadIcon', { defaultMessage: 'Unread notifications indicator.', })} + data-test-subj={'mlNotificationsIndicator'} />
diff --git a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx index 811b1c43bce37..9ea6aa1b70f00 100644 --- a/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx +++ b/x-pack/plugins/ml/public/application/notifications/components/notifications_list.tsx @@ -162,6 +162,7 @@ export const NotificationsList: FC = () => { const columns: Array> = [ { + id: 'timestamp', field: 'timestamp', name: , sortable: true, @@ -175,7 +176,7 @@ export const NotificationsList: FC = () => { name: , sortable: true, truncateText: false, - 'data-test-subj': 'mlNotificationLabel', + 'data-test-subj': 'mlNotificationLevel', render: (value: MlNotificationMessageLevel) => { return {value}; }, @@ -194,7 +195,7 @@ export const NotificationsList: FC = () => { }, { field: 'job_id', - name: , + name: , sortable: true, truncateText: false, 'data-test-subj': 'mlNotificationEntity', @@ -320,6 +321,7 @@ export const NotificationsList: FC = () => { }, }, }, + 'data-test-subj': 'mlNotificationsSearchBarInput', }} filters={filters} onChange={(e) => { diff --git a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/allocated_models.tsx b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/allocated_models.tsx index 0da7778c6e2bc..d1808c2c82135 100644 --- a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/allocated_models.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/allocated_models.tsx @@ -190,6 +190,7 @@ export const AllocatedModels: FC = ({ })} onTableChange={() => {}} data-test-subj={'mlNodesAllocatedModels'} + css={{ overflow: 'auto' }} /> ); }; diff --git a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/expanded_row.tsx b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/expanded_row.tsx index 4c96904862786..a6b6adc4fbc20 100644 --- a/x-pack/plugins/ml/public/application/trained_models/nodes_overview/expanded_row.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/nodes_overview/expanded_row.tsx @@ -17,6 +17,7 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import { cloneDeep } from 'lodash'; import { FIELD_FORMAT_IDS } from '@kbn/field-formats-plugin/common'; +import { css } from '@emotion/react'; import { NodeItem } from './nodes_list'; import { useListItemsFormatter } from '../models_management/expanded_row'; import { AllocatedModels } from './allocated_models'; @@ -44,10 +45,12 @@ export const ExpandedRow: FC = ({ item }) => { attributes['ml.max_jvm_size'] = bytesFormatter(attributes['ml.max_jvm_size']); return ( - <> - - - +
+ @@ -85,25 +88,26 @@ export const ExpandedRow: FC = ({ item }) => { /> + - {allocatedModels.length > 0 ? ( - - - -
- -
-
- + {allocatedModels.length > 0 ? ( + <> + + + +
+ +
+
+ - -
-
- ) : null} - - + + + + ) : null} +
); }; diff --git a/x-pack/plugins/ml/server/routes/schemas/notifications_schema.ts b/x-pack/plugins/ml/server/routes/schemas/notifications_schema.ts index a82691ee52813..153ffd0aeea87 100644 --- a/x-pack/plugins/ml/server/routes/schemas/notifications_schema.ts +++ b/x-pack/plugins/ml/server/routes/schemas/notifications_schema.ts @@ -8,26 +8,10 @@ import { schema, TypeOf } from '@kbn/config-schema'; export const getNotificationsQuerySchema = schema.object({ - /** - * Message level, e.g. info, error - */ - level: schema.maybe(schema.string()), - /** - * Message type, e.g. anomaly_detector - */ - type: schema.maybe(schema.string()), /** * Search string for the message content */ queryString: schema.maybe(schema.string()), - /** - * Page numer, zero-indexed - */ - from: schema.number({ defaultValue: 0 }), - /** - * Number of messages to return - */ - size: schema.number({ defaultValue: 10 }), /** * Sort field */ diff --git a/x-pack/plugins/observability/server/ui_settings.ts b/x-pack/plugins/observability/server/ui_settings.ts index 69e7f0ba51af6..a5b111569e311 100644 --- a/x-pack/plugins/observability/server/ui_settings.ts +++ b/x-pack/plugins/observability/server/ui_settings.ts @@ -29,11 +29,16 @@ import { const technicalPreviewLabel = i18n.translate( 'xpack.observability.uiSettings.technicalPreviewLabel', - { - defaultMessage: 'technical preview', - } + { defaultMessage: 'technical preview' } ); +function feedbackLink({ href }: { href: string }) { + return `${i18n.translate( + 'xpack.observability.uiSettings.giveFeedBackLabel', + { defaultMessage: 'Give feedback' } + )}`; +} + type UiSettings = UiSettingsParams & { showInLabs?: boolean }; /** @@ -167,12 +172,7 @@ export const uiSettings: Record = { '{technicalPreviewLabel} Enable the Service groups feature on APM UI. {feedbackLink}.', values: { technicalPreviewLabel: `[${technicalPreviewLabel}]`, - feedbackLink: - '' + - i18n.translate('xpack.observability.enableServiceGroups.feedbackLinkText', { - defaultMessage: 'Give feedback', - }) + - '', + feedbackLink: feedbackLink({ href: 'https://ela.st/feedback-service-groups' }), }, }), schema: schema.boolean(), @@ -206,15 +206,7 @@ export const uiSettings: Record = { '{technicalPreviewLabel} Default APM Service Inventory page sort (for Services without Machine Learning applied) to sort by Service Name. {feedbackLink}.', values: { technicalPreviewLabel: `[${technicalPreviewLabel}]`, - feedbackLink: - '' + - i18n.translate( - 'xpack.observability.apmServiceInventoryOptimizedSorting.feedbackLinkText', - { - defaultMessage: 'Give feedback', - } - ) + - '', + feedbackLink: feedbackLink({ href: 'https://ela.st/feedback-apm-page-performance' }), }, } ), @@ -245,12 +237,7 @@ export const uiSettings: Record = { '{technicalPreviewLabel} Enable the APM Trace Explorer feature, that allows you to search and inspect traces with KQL or EQL. {feedbackLink}.', values: { technicalPreviewLabel: `[${technicalPreviewLabel}]`, - feedbackLink: - '' + - i18n.translate('xpack.observability.apmTraceExplorerTabDescription.feedbackLinkText', { - defaultMessage: 'Give feedback', - }) + - '', + feedbackLink: feedbackLink({ href: 'https://ela.st/feedback-trace-explorer' }), }, }), schema: schema.boolean(), @@ -269,12 +256,7 @@ export const uiSettings: Record = { '{technicalPreviewLabel} Enable the APM Operations Breakdown feature, that displays aggregates for backend operations. {feedbackLink}.', values: { technicalPreviewLabel: `[${technicalPreviewLabel}]`, - feedbackLink: - '' + - i18n.translate('xpack.observability.apmOperationsBreakdownDescription.feedbackLinkText', { - defaultMessage: 'Give feedback', - }) + - '', + feedbackLink: feedbackLink({ href: 'https://ela.st/feedback-operations-breakdown' }), }, }), schema: schema.boolean(), @@ -318,12 +300,7 @@ export const uiSettings: Record = { '{technicalPreviewLabel} Display Amazon Lambda metrics in the service metrics tab. {feedbackLink}', values: { technicalPreviewLabel: `[${technicalPreviewLabel}]`, - feedbackLink: - '' + - i18n.translate('xpack.observability.awsLambdaDescription', { - defaultMessage: 'Send feedback', - }) + - '', + feedbackLink: feedbackLink({ href: 'https://ela.st/feedback-aws-lambda' }), }, }), schema: schema.boolean(), diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_metrics.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_metrics.ts index c6bb71970e599..b15c76119e441 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_metrics.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/model/execution_metrics.ts @@ -12,8 +12,17 @@ export type DurationMetric = t.TypeOf; export const DurationMetric = PositiveInteger; export type RuleExecutionMetrics = t.TypeOf; + +/** + @property total_search_duration_ms - "total time spent performing ES searches as measured by Kibana; + includes network latency and time spent serializing/deserializing request/response", + @property total_indexing_duration_ms - "total time spent indexing documents during current rule execution cycle", + @property total_enrichment_duration_ms - total time spent enriching documents during current rule execution cycle + @property execution_gap_duration_s - "duration in seconds of execution gap" +*/ export const RuleExecutionMetrics = t.partial({ total_search_duration_ms: DurationMetric, total_indexing_duration_ms: DurationMetric, + total_enrichment_duration_ms: DurationMetric, execution_gap_duration_s: DurationMetric, }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.ts index a74845721a022..0140e5f8d9262 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.ts @@ -9,7 +9,6 @@ import * as t from 'io-ts'; import { NonEmptyArray, TimeDuration, enumeration } from '@kbn/securitysolution-io-ts-types'; import { - throttle, action_group as actionGroup, action_params as actionParams, action_id as actionId, @@ -41,6 +40,18 @@ export enum BulkActionEditType { 'set_schedule' = 'set_schedule', } +export const throttleForBulkActions = t.union([ + t.literal('rule'), + TimeDuration({ + allowedDurations: [ + [1, 'h'], + [1, 'd'], + [7, 'd'], + ], + }), +]); +export type ThrottleForBulkActions = t.TypeOf; + const bulkActionEditPayloadTags = t.type({ type: t.union([ t.literal(BulkActionEditType.add_tags), @@ -96,7 +107,7 @@ const bulkActionEditPayloadRuleActions = t.type({ t.literal(BulkActionEditType.set_rule_actions), ]), value: t.type({ - throttle, + throttle: throttleForBulkActions, actions: t.array(normalizedRuleAction), }), }); @@ -106,8 +117,8 @@ export type BulkActionEditPayloadRuleActions = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/endpoint/schema/actions.ts b/x-pack/plugins/security_solution/common/endpoint/schema/actions.ts index 08adac7c9ede0..8b982e6e6f463 100644 --- a/x-pack/plugins/security_solution/common/endpoint/schema/actions.ts +++ b/x-pack/plugins/security_solution/common/endpoint/schema/actions.ts @@ -28,6 +28,8 @@ export const NoParametersRequestSchema = { body: schema.object({ ...BaseActionRequestSchema }), }; +export type BaseActionRequestBody = TypeOf; + export const KillOrSuspendProcessRequestSchema = { body: schema.object({ ...BaseActionRequestSchema, diff --git a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts index 3434e95f29b4b..b9c0dcff2054a 100644 --- a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts +++ b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.test.ts @@ -107,6 +107,40 @@ describe('Endpoint Authz service', () => { ); }); }); + + describe('endpoint rbac is enabled', () => { + describe('canIsolateHost', () => { + it('should be true if packagePrivilege.writeHostIsolation is true', () => { + fleetAuthz.packagePrivileges!.endpoint.actions.writeHostIsolation.executePackageAction = + true; + const authz = calculateEndpointAuthz(licenseService, fleetAuthz, userRoles, true); + expect(authz.canIsolateHost).toBe(true); + }); + + it('should be false if packagePrivilege.writeHostIsolation is false', () => { + fleetAuthz.packagePrivileges!.endpoint.actions.writeHostIsolation.executePackageAction = + false; + const authz = calculateEndpointAuthz(licenseService, fleetAuthz, userRoles, true); + expect(authz.canIsolateHost).toBe(false); + }); + }); + + describe('canUnIsolateHost', () => { + it('should be true if packagePrivilege.writeHostIsolation is true', () => { + fleetAuthz.packagePrivileges!.endpoint.actions.writeHostIsolation.executePackageAction = + true; + const authz = calculateEndpointAuthz(licenseService, fleetAuthz, userRoles, true); + expect(authz.canUnIsolateHost).toBe(true); + }); + + it('should be false if packagePrivilege.writeHostIsolation is false', () => { + fleetAuthz.packagePrivileges!.endpoint.actions.writeHostIsolation.executePackageAction = + false; + const authz = calculateEndpointAuthz(licenseService, fleetAuthz, userRoles, true); + expect(authz.canUnIsolateHost).toBe(false); + }); + }); + }); }); describe('getEndpointAuthzInitialState()', () => { diff --git a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts index 6f578ec24d856..bc40bd11f5d79 100644 --- a/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts +++ b/x-pack/plugins/security_solution/common/endpoint/service/authz/authz.ts @@ -28,14 +28,18 @@ export const calculateEndpointAuthz = ( const isPlatinumPlusLicense = licenseService.isPlatinumPlus(); const isEnterpriseLicense = licenseService.isEnterprise(); const hasEndpointManagementAccess = userRoles.includes('superuser'); + const canIsolateHost = isEndpointRbacEnabled + ? fleetAuthz.packagePrivileges?.endpoint?.actions?.writeHostIsolation?.executePackageAction || + false + : hasEndpointManagementAccess; return { canAccessFleet: fleetAuthz?.fleet.all ?? userRoles.includes('superuser'), canAccessEndpointManagement: hasEndpointManagementAccess, canCreateArtifactsByPolicy: hasEndpointManagementAccess && isPlatinumPlusLicense, // Response Actions - canIsolateHost: isPlatinumPlusLicense && hasEndpointManagementAccess, - canUnIsolateHost: hasEndpointManagementAccess, + canIsolateHost: isPlatinumPlusLicense && canIsolateHost, + canUnIsolateHost: canIsolateHost, canKillProcess: hasEndpointManagementAccess && isEnterpriseLicense, canSuspendProcess: hasEndpointManagementAccess && isEnterpriseLicense, canGetRunningProcesses: hasEndpointManagementAccess && isEnterpriseLicense, diff --git a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts index bcbdcfb3b66b8..91eb10c5f45a2 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts @@ -253,6 +253,7 @@ export interface PendingActionsResponse { } export type PendingActionsRequestQuery = TypeOf; + export interface ActionDetails { /** The action id */ id: string; diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/custom_saved_query_rule.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/custom_saved_query_rule.cy.ts index 9b1d5c71a6fa9..5027fe09a8d3e 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/custom_saved_query_rule.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/custom_saved_query_rule.cy.ts @@ -25,8 +25,8 @@ import { import { goToRuleDetails, editFirstRule } from '../../tasks/alerts_detection_rules'; import { createTimeline } from '../../tasks/api_calls/timelines'; -import { createSavedQuery } from '../../tasks/api_calls/saved_queries'; -import { cleanKibana, deleteAlertsAndRules, deleteSavedQueries } from '../../tasks/common'; +import { createSavedQuery, deleteSavedQueries } from '../../tasks/api_calls/saved_queries'; +import { cleanKibana, deleteAlertsAndRules } from '../../tasks/common'; import { createAndEnableRule, fillAboutRuleAndContinue, diff --git a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/related_integrations.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/related_integrations.cy.ts index b5c6b5cd341ec..02ccff0c265dd 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/detection_rules/related_integrations.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/detection_rules/related_integrations.cy.ts @@ -122,14 +122,14 @@ describe('Related integrations', () => { visit(DETECTIONS_RULE_MANAGEMENT_URL); }); - it('should display a badge with the installed integrations on the rule management page', () => { + it.skip('should display a badge with the installed integrations on the rule management page', () => { cy.get(INTEGRATIONS_POPOVER).should( 'have.text', `${rule.enabledIntegrations}/${rule.integrations.length} integrations` ); }); - it('should display a popover when clicking the badge with the installed integrations on the rule management page', () => { + it.skip('should display a popover when clicking the badge with the installed integrations on the rule management page', () => { openIntegrationsPopover(); cy.get(INTEGRATIONS_POPOVER_TITLE).should( @@ -148,7 +148,7 @@ describe('Related integrations', () => { }); }); - it('should display the integrations on the definition section', () => { + it.skip('should display the integrations on the definition section', () => { goToTheRuleDetailsOf(rule.name); cy.get(INTEGRATIONS).should('have.length', rule.integrations.length); diff --git a/x-pack/plugins/security_solution/cypress/tasks/api_calls/saved_queries.ts b/x-pack/plugins/security_solution/cypress/tasks/api_calls/saved_queries.ts index 8c4aea51ec045..08867cf55d4c0 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/api_calls/saved_queries.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/api_calls/saved_queries.ts @@ -33,3 +33,20 @@ export const createSavedQuery = ( }, headers: { 'kbn-xsrf': 'cypress-creds' }, }); + +export const deleteSavedQueries = () => { + const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; + cy.request('POST', `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed`, { + query: { + bool: { + filter: [ + { + match: { + type: 'query', + }, + }, + ], + }, + }, + }); +}; diff --git a/x-pack/plugins/security_solution/cypress/tasks/common.ts b/x-pack/plugins/security_solution/cypress/tasks/common.ts index 23f04d0fd3c2b..cd9525e95b0b2 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/common.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/common.ts @@ -179,23 +179,6 @@ export const deleteCases = () => { }); }; -export const deleteSavedQueries = () => { - const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; - cy.request('POST', `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed`, { - query: { - bool: { - filter: [ - { - match: { - type: 'query', - }, - }, - ], - }, - }, - }); -}; - export const postDataView = (dataSource: string) => { cy.request({ method: 'POST', diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx index c12643a30f943..b6a3995534d1f 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.test.tsx @@ -5,16 +5,24 @@ * 2.0. */ +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { shallow } from 'enzyme'; import React from 'react'; import type { DraggableStateSnapshot, DraggingStyle } from 'react-beautiful-dnd'; -import { waitFor } from '@testing-library/react'; + import '../../mock/match_media'; +import { TimelineId } from '../../../../common/types'; import { mockBrowserFields } from '../../containers/source/mock'; import { TestProviders } from '../../mock'; import { mockDataProviders } from '../../../timelines/components/timeline/data_providers/mock/mock_data_providers'; +import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../../../timelines/components/row_renderers_browser/constants'; import { DragDropContextWrapper } from './drag_drop_context_wrapper'; -import { ConditionalPortal, DraggableWrapper, getStyle } from './draggable_wrapper'; +import { + ConditionalPortal, + disableHoverActions, + DraggableWrapper, + getStyle, +} from './draggable_wrapper'; import { useMountAppended } from '../../utils/use_mount_appended'; jest.mock('../../lib/kibana'); @@ -27,6 +35,26 @@ jest.mock('@elastic/eui', () => { }; }); +const timelineIdsWithHoverActions = [ + undefined, + TimelineId.active, + TimelineId.alternateTest, + TimelineId.casePage, + TimelineId.detectionsPage, + TimelineId.detectionsRulesDetailsPage, + TimelineId.hostsPageEvents, + TimelineId.hostsPageSessions, + TimelineId.kubernetesPageSessions, + TimelineId.networkPageEvents, + TimelineId.test, + TimelineId.usersPageEvents, +]; + +const timelineIdsNoHoverActions = [ + TimelineId.rulePreview, + ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID, +]; + describe('DraggableWrapper', () => { const dataProvider = mockDataProviders[0]; const message = 'draggable wrapper content'; @@ -36,6 +64,15 @@ describe('DraggableWrapper', () => { jest.useFakeTimers(); }); + afterEach(() => { + const portal = document.querySelector('[data-euiportal="true"]'); + if (portal != null) { + portal.innerHTML = ''; + } + + jest.useRealTimers(); + }); + describe('rendering', () => { test('it renders against the snapshot', () => { const wrapper = shallow( @@ -103,6 +140,56 @@ describe('DraggableWrapper', () => { expect(wrapper.find('[data-test-subj="hover-actions-copy-button"]').exists()).toBe(true); }); }); + + timelineIdsWithHoverActions.forEach((timelineId) => { + test(`it renders hover actions (by default) when 'isDraggable' is false and timelineId is '${timelineId}'`, async () => { + const isDraggable = false; + + const { container } = render( + + + message} + timelineId={timelineId} + /> + + + ); + + fireEvent.mouseEnter(container.querySelector('[data-test-subj="withHoverActionsButton"]')!); + + await waitFor(() => { + expect(screen.getByTestId('hover-actions-copy-button')).toBeInTheDocument(); + }); + }); + }); + + timelineIdsNoHoverActions.forEach((timelineId) => { + test(`it does NOT render hover actions when 'isDraggable' is false and timelineId is '${timelineId}'`, async () => { + const isDraggable = false; + + const { container } = render( + + + message} + timelineId={timelineId} + /> + + + ); + + fireEvent.mouseEnter(container.querySelector('[data-test-subj="withHoverActionsButton"]')!); + + await waitFor(() => { + expect(screen.queryByTestId('hover-actions-copy-button')).not.toBeInTheDocument(); + }); + }); + }); }); describe('text truncation styling', () => { @@ -192,4 +279,18 @@ describe('ConditionalPortal', () => { expect(getStyle(style, snapshot)).toHaveProperty('transitionDuration', '0.00000001s'); }); }); + + describe('disableHoverActions', () => { + timelineIdsNoHoverActions.forEach((timelineId) => + test(`it returns true when timelineId is ${timelineId}`, () => { + expect(disableHoverActions(timelineId)).toBe(true); + }) + ); + + timelineIdsWithHoverActions.forEach((timelineId) => + test(`it returns false when timelineId is ${timelineId}`, () => { + expect(disableHoverActions(timelineId)).toBe(false); + }) + ); + }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx index f972bcf463b5b..887f1635c08c6 100644 --- a/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/common/components/drag_and_drop/draggable_wrapper.tsx @@ -18,6 +18,7 @@ import { Draggable, Droppable } from 'react-beautiful-dnd'; import { useDispatch } from 'react-redux'; import styled from 'styled-components'; +import { TimelineId } from '../../../../common/types'; import { dragAndDropActions } from '../../store/drag_and_drop'; import type { DataProvider } from '../../../timelines/components/timeline/data_providers/data_provider'; import { ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID } from '../../../timelines/components/row_renderers_browser/constants'; @@ -108,6 +109,9 @@ interface Props { onFilterAdded?: () => void; } +export const disableHoverActions = (timelineId: string | undefined): boolean => + [TimelineId.rulePreview, ROW_RENDERER_BROWSER_EXAMPLE_TIMELINE_ID].includes(timelineId ?? ''); + /** * Wraps a draggable component to handle registration / unregistration of the * data provider associated with the item being dropped @@ -370,7 +374,7 @@ const DraggableWrapperComponent: React.FC = ({ diff --git a/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.test.ts b/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.test.ts index 29da5688357b0..a0d23820025b8 100644 --- a/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/user_privileges/endpoint/use_endpoint_privileges.test.ts @@ -7,15 +7,19 @@ import type { RenderHookResult, RenderResult } from '@testing-library/react-hooks'; import { act, renderHook } from '@testing-library/react-hooks'; -import { useCurrentUser, useKibana } from '../../../lib/kibana'; -import { useEndpointPrivileges } from './use_endpoint_privileges'; + import { securityMock } from '@kbn/security-plugin/public/mocks'; import type { AuthenticatedUser } from '@kbn/security-plugin/common'; +import { createFleetAuthzMock } from '@kbn/fleet-plugin/common'; + +import type { EndpointPrivileges } from '../../../../../common/endpoint/types'; +import { useCurrentUser, useKibana } from '../../../lib/kibana'; import { licenseService } from '../../../hooks/use_license'; +import { useEndpointPrivileges } from './use_endpoint_privileges'; import { getEndpointPrivilegesInitialStateMock } from './mocks'; -import type { EndpointPrivileges } from '../../../../../common/endpoint/types'; import { getEndpointPrivilegesInitialState } from './utils'; +const useKibanaMock = useKibana as jest.Mocked; jest.mock('../../../lib/kibana'); jest.mock('../../../hooks/use_license', () => { const licenseServiceInstance = { @@ -47,6 +51,7 @@ describe('When using useEndpointPrivileges hook', () => { }); (useCurrentUser as jest.Mock).mockReturnValue(authenticatedUser); + useKibanaMock().services.fleet!.authz = createFleetAuthzMock(); licenseServiceMock.isPlatinumPlus.mockReturnValue(true); diff --git a/x-pack/plugins/security_solution/public/common/hooks/translations.ts b/x-pack/plugins/security_solution/public/common/hooks/translations.ts index 1f939282b5c72..54ed3a79d017f 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/translations.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/translations.ts @@ -39,10 +39,3 @@ export const EQL_TIME_INTERVAL_NOT_DEFINED = i18n.translate( defaultMessage: 'Time intervals are not defined.', } ); - -export const SAVED_QUERY_LOAD_ERROR_TOAST = i18n.translate( - 'xpack.securitySolution.hooks.useGetSavedQuery.errorToastMessage', - { - defaultMessage: 'Failed to load the saved query', - } -); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/throttle_description.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/throttle_description.tsx index 69110b2e53602..c0b6780ea8bc5 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/throttle_description.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/throttle_description.tsx @@ -6,10 +6,13 @@ */ import { find } from 'lodash/fp'; -import { THROTTLE_OPTIONS, DEFAULT_THROTTLE_OPTION } from '../throttle_select_field'; +import { + THROTTLE_OPTIONS_FOR_RULE_CREATION_AND_EDITING, + DEFAULT_THROTTLE_OPTION, +} from '../throttle_select_field'; export const buildThrottleDescription = (value = DEFAULT_THROTTLE_OPTION.value, title: string) => { - const throttleOption = find(['value', value], THROTTLE_OPTIONS); + const throttleOption = find(['value', value], THROTTLE_OPTIONS_FOR_RULE_CREATION_AND_EDITING); return { title, diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/query_bar/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/query_bar/index.tsx index a5316eabb11f9..7d7c9534c1688 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/query_bar/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/query_bar/index.tsx @@ -70,6 +70,7 @@ const savedQueryToFieldValue = (savedQuery: SavedQuery): FieldValueQueryBar => ( filters: savedQuery.attributes.filters ?? [], query: savedQuery.attributes.query, saved_id: savedQuery.id, + title: savedQuery.attributes.title, }); export const QueryBarDefineRule = ({ diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx index 23042cd1165ec..21bf8125540b4 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx @@ -739,8 +739,8 @@ const StepDefineRuleComponent: FC = ({ <> = ({ 'data-test-subj': 'detectionEngineStepDefineRuleShouldLoadQueryDynamically', euiFieldProps: { disabled: isLoading, + label: formQuery?.title + ? i18n.getSavedQueryCheckboxLabel(formQuery.title) + : undefined, }, }} /> diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx index bc3937013b6ae..b23b496eae82e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/schema.tsx @@ -629,12 +629,6 @@ export const schema: FormSchema = { }, shouldLoadQueryDynamically: { type: FIELD_TYPES.CHECKBOX, - label: i18n.translate( - 'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldShouldLoadQueryDynamicallyLabel', - { - defaultMessage: 'Load the saved query dynamically on each rule execution', - } - ), defaultValue: false, }, }; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/translations.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/translations.tsx index b28d06777fd3c..4650da2ce603a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/translations.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/translations.tsx @@ -78,13 +78,22 @@ export const EQL_QUERY_BAR_LABEL = i18n.translate( } ); -export const SAVED_QUERY_CHECKBOX_LABEL = i18n.translate( - 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.SavedQueryCheckboxLabel', +export const SAVED_QUERY_FORM_ROW_LABEL = i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.SavedQueryFormRowLabel', { defaultMessage: 'Saved query', } ); +export const getSavedQueryCheckboxLabel = (savedQueryName: string) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.fieldShouldLoadQueryDynamicallyLabel', + { + defaultMessage: 'Load saved query "{savedQueryName}" dynamically on each rule execution', + values: { savedQueryName }, + } + ); + export const THREAT_MATCH_INDEX_HELPER_TEXT = i18n.translate( 'xpack.securitySolution.detectionEngine.createRule.stepDefineRule.threatMatchingIcesHelperDescription', { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx index 5cdf89df572cf..fe2c5d8fa4ee0 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx @@ -33,7 +33,7 @@ import { Form, UseField, useForm, useFormData } from '../../../../shared_imports import { StepContentWrapper } from '../step_content_wrapper'; import { ThrottleSelectField, - THROTTLE_OPTIONS, + THROTTLE_OPTIONS_FOR_RULE_CREATION_AND_EDITING, DEFAULT_THROTTLE_OPTION, } from '../throttle_select_field'; import { RuleActionsField } from '../rule_actions_field'; @@ -62,11 +62,14 @@ const GhostFormField = () => <>; const getThrottleOptions = (throttle?: string | null) => { // Add support for throttle options set by the API - if (throttle && findIndex(['value', throttle], THROTTLE_OPTIONS) < 0) { - return [...THROTTLE_OPTIONS, { value: throttle, text: throttle }]; + if ( + throttle && + findIndex(['value', throttle], THROTTLE_OPTIONS_FOR_RULE_CREATION_AND_EDITING) < 0 + ) { + return [...THROTTLE_OPTIONS_FOR_RULE_CREATION_AND_EDITING, { value: throttle, text: throttle }]; } - return THROTTLE_OPTIONS; + return THROTTLE_OPTIONS_FOR_RULE_CREATION_AND_EDITING; }; const DisplayActionsHeader = () => { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/throttle_select_field/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/throttle_select_field/index.tsx index 4bc15d418a38b..264e72fafb60c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/throttle_select_field/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/throttle_select_field/index.tsx @@ -13,15 +13,19 @@ import { } from '../../../../../common/constants'; import { SelectField } from '../../../../shared_imports'; -export const THROTTLE_OPTIONS = [ - { value: NOTIFICATION_THROTTLE_NO_ACTIONS, text: 'Perform no actions' }, +export const THROTTLE_OPTIONS_FOR_BULK_RULE_ACTIONS = [ { value: NOTIFICATION_THROTTLE_RULE, text: 'On each rule execution' }, { value: '1h', text: 'Hourly' }, { value: '1d', text: 'Daily' }, { value: '7d', text: 'Weekly' }, ]; -export const DEFAULT_THROTTLE_OPTION = THROTTLE_OPTIONS[0]; +export const THROTTLE_OPTIONS_FOR_RULE_CREATION_AND_EDITING = [ + { value: NOTIFICATION_THROTTLE_NO_ACTIONS, text: 'Perform no actions' }, + ...THROTTLE_OPTIONS_FOR_BULK_RULE_ACTIONS, +]; + +export const DEFAULT_THROTTLE_OPTION = THROTTLE_OPTIONS_FOR_RULE_CREATION_AND_EDITING[0]; type ThrottleSelectField = typeof SelectField; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/rule_actions_form.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/rule_actions_form.tsx index 8a9e52c9d5528..0ec448a1ab1fb 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/rule_actions_form.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/rule_actions_form.tsx @@ -12,6 +12,7 @@ import type { RuleAction, ActionTypeRegistryContract, } from '@kbn/triggers-actions-ui-plugin/public'; + import type { FormSchema } from '../../../../../../../shared_imports'; import { useForm, @@ -21,9 +22,12 @@ import { getUseField, Field, } from '../../../../../../../shared_imports'; -import type { BulkActionEditPayload } from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; import { BulkActionEditType } from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { NOTIFICATION_THROTTLE_NO_ACTIONS } from '../../../../../../../../common/constants'; +import type { + BulkActionEditPayload, + ThrottleForBulkActions, +} from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { NOTIFICATION_THROTTLE_RULE } from '../../../../../../../../common/constants'; import { BulkEditFormWrapper } from './bulk_edit_form_wrapper'; import { bulkAddRuleActions as i18n } from '../translations'; @@ -32,7 +36,7 @@ import { useKibana } from '../../../../../../../common/lib/kibana'; import { ThrottleSelectField, - THROTTLE_OPTIONS, + THROTTLE_OPTIONS_FOR_BULK_RULE_ACTIONS, } from '../../../../../../components/rules/throttle_select_field'; import { getAllActionMessageParams } from '../../../helpers'; @@ -42,7 +46,7 @@ import { validateRuleActionsField } from '../../../../../../containers/detection const CommonUseField = getUseField({ component: Field }); export interface RuleActionsFormData { - throttle: string; + throttle: ThrottleForBulkActions; actions: RuleAction[]; overwrite: boolean; } @@ -68,7 +72,7 @@ const getFormSchema = ( }); const defaultFormData: RuleActionsFormData = { - throttle: NOTIFICATION_THROTTLE_NO_ACTIONS, + throttle: NOTIFICATION_THROTTLE_RULE, actions: [], overwrite: false, }; @@ -93,7 +97,7 @@ const RuleActionsFormComponent = ({ rulesCount, onClose, onConfirm }: RuleAction defaultValue: defaultFormData, }); - const [{ overwrite, throttle }] = useFormData({ form, watch: ['overwrite', 'throttle'] }); + const [{ overwrite }] = useFormData({ form, watch: ['overwrite', 'throttle'] }); const handleSubmit = useCallback(async () => { const { data, isValid } = await form.submit(); @@ -121,7 +125,7 @@ const RuleActionsFormComponent = ({ rulesCount, onClose, onConfirm }: RuleAction dataTestSubj: 'bulkEditRulesRuleActionThrottle', hasNoInitialSelection: false, euiFieldProps: { - options: THROTTLE_OPTIONS, + options: THROTTLE_OPTIONS_FOR_BULK_RULE_ACTIONS, }, }), [] @@ -129,8 +133,6 @@ const RuleActionsFormComponent = ({ rulesCount, onClose, onConfirm }: RuleAction const messageVariables = useMemo(() => getAllActionMessageParams(), []); - const showActionsSelect = throttle !== NOTIFICATION_THROTTLE_NO_ACTIONS; - return ( -
  • - - - - ), - overwriteActionsCheckbox: ( - - - - ), - }} - /> -
  • {i18n.RULE_VARIABLES_DETAIL}
  • @@ -193,18 +171,14 @@ const RuleActionsFormComponent = ({ rulesCount, onClose, onConfirm }: RuleAction /> - {showActionsSelect && ( - <> - - - - )} + + = ({ const [dataViewOptions, setDataViewOptions] = useState<{ [x: string]: DataViewListItem }>({}); // load saved query only if rule type === 'saved_query', as other rule types still can have saved_id property that is not used + // Rule schema allows to save any rule with saved_id property, but it only used for saved_query rule type + // In future we might look in possibility to restrict rule schema (breaking change!) and remove saved_id from the rest of rules through migration const savedQueryId = rule?.type === 'saved_query' ? rule?.saved_id : undefined; const { isSavedQueryLoading, savedQueryBar } = useGetSavedQuery(savedQueryId); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/translations.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/translations.ts index 1a50d570ea179..b1c7e0033f5f4 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/translations.ts @@ -69,3 +69,10 @@ export const DELETED_RULE = i18n.translate( defaultMessage: 'Deleted rule', } ); + +export const SAVED_QUERY_LOAD_ERROR_TOAST = i18n.translate( + 'xpack.securitySolution.hooks.useGetSavedQuery.errorToastMessage', + { + defaultMessage: 'Failed to load the saved query', + } +); diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_get_saved_query.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/use_get_saved_query.ts similarity index 81% rename from x-pack/plugins/security_solution/public/common/hooks/use_get_saved_query.ts rename to x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/use_get_saved_query.ts index 932fe61e2ce47..4c3c4c6c42fe0 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_get_saved_query.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/use_get_saved_query.ts @@ -7,12 +7,13 @@ import { useEffect, useMemo } from 'react'; -import { useSavedQueryServices } from '../utils/saved_query_services'; -import type { DefineStepRule } from '../../detections/pages/detection_engine/rules/types'; +import { useSavedQueryServices } from '../../../../../common/utils/saved_query_services'; +import type { DefineStepRule } from '../types'; + +import { useFetch, REQUEST_NAMES } from '../../../../../common/hooks/use_fetch'; +import { useAppToasts } from '../../../../../common/hooks/use_app_toasts'; -import { useFetch, REQUEST_NAMES } from './use_fetch'; import { SAVED_QUERY_LOAD_ERROR_TOAST } from './translations'; -import { useAppToasts } from './use_app_toasts'; export const useGetSavedQuery = (savedQueryId: string | undefined) => { const savedQueryServices = useSavedQueryServices(); diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/artifact_list_page.test.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/artifact_list_page.test.tsx index 9160732e32b3e..6780335312251 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/artifact_list_page.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/artifact_list_page.test.tsx @@ -12,7 +12,7 @@ import { act, fireEvent, waitFor, waitForElementToBeRemoved } from '@testing-lib import userEvent from '@testing-library/user-event'; import type { ArtifactListPageRenderingSetup } from './mocks'; import { getArtifactListPageRenderingSetup } from './mocks'; -import { getDeferred } from '../mocks'; +import { getDeferred } from '../../mocks/utils'; jest.mock('../../../common/components/user_privileges'); diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/artifact_list_page.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/artifact_list_page.tsx index fc687282cccac..0586034d15550 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/artifact_list_page.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/artifact_list_page.tsx @@ -11,6 +11,7 @@ import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-t import { EuiButton, EuiSpacer, EuiText } from '@elastic/eui'; import type { EuiFlyoutSize } from '@elastic/eui/src/components/flyout/flyout'; import { useLocation } from 'react-router-dom'; +import { useIsMounted } from '@kbn/securitysolution-hook-utils'; import type { ServerApiError } from '../../../common/types'; import { AdministrationListPage } from '../administration_list_page'; @@ -45,7 +46,6 @@ import { useToasts } from '../../../common/lib/kibana'; import { useMemoizedRouteState } from '../../common/hooks'; import { BackToExternalAppSecondaryButton } from '../back_to_external_app_secondary_button'; import { BackToExternalAppButton } from '../back_to_external_app_button'; -import { useIsMounted } from '../../hooks/use_is_mounted'; type ArtifactEntryCardType = typeof ArtifactEntryCard; @@ -221,7 +221,7 @@ export const ArtifactListPage = memo( ); const handleArtifactDeleteModalOnSuccess = useCallback(() => { - if (isMounted) { + if (isMounted()) { setSelectedItemForDelete(undefined); refetchListData(); } diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_delete_modal.test.ts b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_delete_modal.test.ts index d0fb3e3c59dfa..57ea165f0b85f 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_delete_modal.test.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_delete_modal.test.ts @@ -11,7 +11,7 @@ import type { ArtifactListPageRenderingSetup } from '../mocks'; import { getArtifactListPageRenderingSetup } from '../mocks'; import { act, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { getDeferred } from '../../mocks'; +import { getDeferred } from '../../../mocks/utils'; describe('When displaying the Delete artifact modal in the Artifact List Page', () => { let renderResult: ReturnType; diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx index ee3ac4a907ee4..5179bb7b76be6 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.test.tsx @@ -19,7 +19,7 @@ import type { trustedAppsAllHttpMocks } from '../../../mocks'; import { useUserPrivileges as _useUserPrivileges } from '../../../../common/components/user_privileges'; import { entriesToConditionEntries } from '../../../../common/utils/exception_list_items/mappers'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; -import { getDeferred } from '../../mocks'; +import { getDeferred } from '../../../mocks/utils'; jest.mock('../../../../common/components/user_privileges'); const useUserPrivileges = _useUserPrivileges as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx index 4d9f53c73341e..1261d01c7af44 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/components/artifact_flyout.tsx @@ -24,6 +24,7 @@ import { import type { EuiFlyoutSize } from '@elastic/eui/src/components/flyout/flyout'; import type { IHttpFetchError } from '@kbn/core-http-browser'; +import { useIsMounted } from '@kbn/securitysolution-hook-utils'; import { useUrlParams } from '../../../hooks/use_url_params'; import { useIsFlyoutOpened } from '../hooks/use_is_flyout_opened'; import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; @@ -39,7 +40,6 @@ import { useKibana, useToasts } from '../../../../common/lib/kibana'; import { createExceptionListItemForCreate } from '../../../../../common/endpoint/service/artifacts/utils'; import { useWithArtifactSubmitData } from '../hooks/use_with_artifact_submit_data'; import { useIsArtifactAllowedPerPolicyUsage } from '../hooks/use_is_artifact_allowed_per_policy_usage'; -import { useIsMounted } from '../../../hooks/use_is_mounted'; import { useGetArtifact } from '../../../hooks/artifacts'; import type { PolicyData } from '../../../../../common/endpoint/types'; @@ -271,7 +271,7 @@ export const ArtifactFlyout = memo( const handleFormComponentOnChange: ArtifactFormComponentProps['onChange'] = useCallback( ({ item: updatedItem, isValid }) => { - if (isMounted) { + if (isMounted()) { setFormState({ item: updatedItem, isValid, @@ -289,7 +289,7 @@ export const ArtifactFlyout = memo( : labels.flyoutCreateSubmitSuccess(result) ); - if (isMounted) { + if (isMounted()) { // Close the flyout // `undefined` will cause params to be dropped from url setUrlParams({ ...urlParams, itemId: undefined, show: undefined }, true); @@ -307,12 +307,12 @@ export const ArtifactFlyout = memo( submitHandler(formState.item, formMode) .then(handleSuccess) .catch((submitHandlerError) => { - if (isMounted) { + if (isMounted()) { setExternalSubmitHandlerError(submitHandlerError); } }) .finally(() => { - if (isMounted) { + if (isMounted()) { setExternalIsSubmittingData(false); } }); @@ -326,7 +326,7 @@ export const ArtifactFlyout = memo( useEffect(() => { if (isEditFlow && !hasItemDataForEdit && !error && isInitializing && !isLoadingItemForEdit) { fetchItemForEdit().then(({ data: editItemData }) => { - if (editItemData && isMounted) { + if (editItemData && isMounted()) { setFormState(createFormInitialState(apiClient.listId, editItemData)); } }); diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_with_artifact_list_data.ts b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_with_artifact_list_data.ts index 813e205b64c9a..ddae258fef895 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_with_artifact_list_data.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_list_page/hooks/use_with_artifact_list_data.ts @@ -8,8 +8,8 @@ import { useEffect, useMemo, useState } from 'react'; import type { Pagination } from '@elastic/eui'; import { useQuery } from '@tanstack/react-query'; +import { useIsMounted } from '@kbn/securitysolution-hook-utils'; import type { ServerApiError } from '../../../../common/types'; -import { useIsMounted } from '../../../hooks/use_is_mounted'; import { MANAGEMENT_PAGE_SIZE_OPTIONS } from '../../../common/constants'; import { useUrlParams } from '../../../hooks/use_url_params'; import type { ExceptionsListApiClient } from '../../../services/exceptions_list/exceptions_list_api_client'; @@ -98,7 +98,7 @@ export const useWithArtifactListData = ( // Once we know if data exists, update the page initializing state. // This should only ever happen at most once; useEffect(() => { - if (isMounted) { + if (isMounted()) { if (isPageInitializing && !isLoadingDataExists) { setIsPageInitializing(false); } @@ -107,7 +107,7 @@ export const useWithArtifactListData = ( // Update the uiPagination once the query succeeds useEffect(() => { - if (isMounted && listData && !isLoadingListData && isSuccessListData) { + if (isMounted() && listData && !isLoadingListData && isSuccessListData) { setUiPagination((prevState) => { return { ...prevState, @@ -134,7 +134,7 @@ export const useWithArtifactListData = ( // >> Check if data exists again (which should return true useEffect(() => { if ( - isMounted && + isMounted() && !isLoadingListData && !isLoadingDataExists && !listDataError && diff --git a/x-pack/plugins/security_solution/public/management/components/console/types.ts b/x-pack/plugins/security_solution/public/management/components/console/types.ts index 2d863e7878be2..5b90a18f27ce1 100644 --- a/x-pack/plugins/security_solution/public/management/components/console/types.ts +++ b/x-pack/plugins/security_solution/public/management/components/console/types.ts @@ -168,7 +168,7 @@ export type CommandExecutionComponent< /** The arguments that could have been entered by the user */ TArgs extends SupportedArguments = any, /** Internal store for the Command execution */ - TStore extends object = Record, + TStore extends object = any, /** The metadata defined on the Command Definition */ TMeta = any > = ComponentType>; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.test.tsx index 29b6fd0446577..97689a790afa1 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.test.tsx @@ -129,7 +129,7 @@ describe('When using processes action from response actions console', () => { enterConsoleCommand(renderResult, 'processes'); await waitFor(() => { - expect(renderResult.getByTestId('getProcessesErrorCallout').textContent).toMatch( + expect(renderResult.getByTestId('getProcesses-actionFailure').textContent).toMatch( /error one \| error two/ ); }); @@ -145,7 +145,7 @@ describe('When using processes action from response actions console', () => { enterConsoleCommand(renderResult, 'processes'); await waitFor(() => { - expect(renderResult.getByTestId('performGetProcessesErrorCallout').textContent).toMatch( + expect(renderResult.getByTestId('getProcesses-apiFailure').textContent).toMatch( /this is an error/ ); }); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.tsx index c778f03fcb5f5..d7b05ae721abd 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/get_processes_action.tsx @@ -5,21 +5,17 @@ * 2.0. */ -import React, { memo, useEffect, useMemo } from 'react'; +import React, { memo, useMemo } from 'react'; import styled from 'styled-components'; import { EuiBasicTable } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import type { IHttpFetchError } from '@kbn/core-http-browser'; -import { FormattedMessage } from '@kbn/i18n-react'; +import { useConsoleActionSubmitter } from './hooks/use_console_action_submitter'; import type { - ActionDetails, GetProcessesActionOutputContent, + ProcessesRequestBody, } from '../../../../common/endpoint/types'; -import { useGetActionDetails } from '../../hooks/endpoint/use_get_action_details'; -import type { EndpointCommandDefinitionMeta } from './types'; -import type { CommandExecutionComponentProps } from '../console/types'; import { useSendGetEndpointProcessesRequest } from '../../hooks/endpoint/use_send_get_endpoint_processes_request'; -import { ActionError } from './action_error'; +import type { ActionRequestComponentProps } from './types'; // @ts-expect-error TS2769 const StyledEuiBasicTable = styled(EuiBasicTable)` @@ -43,181 +39,90 @@ const StyledEuiBasicTable = styled(EuiBasicTable)` } `; -export const GetProcessesActionResult = memo< - CommandExecutionComponentProps< - { comment?: string }, - { - actionId?: string; - actionRequestSent?: boolean; - completedActionDetails?: ActionDetails; - apiError?: IHttpFetchError; - }, - EndpointCommandDefinitionMeta - > ->(({ command, setStore, store, status, setStatus, ResultComponent }) => { - const endpointId = command.commandDefinition?.meta?.endpointId; - const { actionId, completedActionDetails, apiError } = store; - - const isPending = status === 'pending'; - const isError = status === 'error'; - const actionRequestSent = Boolean(store.actionRequestSent); - - const { - mutate: getProcesses, - data: getProcessesData, - isSuccess: isGetProcessesSuccess, - error: processesActionRequestError, - } = useSendGetEndpointProcessesRequest(); - - const { data: actionDetails } = useGetActionDetails( - actionId ?? '-', - { - enabled: Boolean(actionId) && isPending, - refetchInterval: isPending ? 3000 : false, - } - ); - - // Send get processes request if not yet done - useEffect(() => { - if (!actionRequestSent && endpointId) { - getProcesses({ - endpoint_ids: [endpointId], - comment: command.args.args?.comment?.[0], - }); - - setStore((prevState) => { - return { ...prevState, actionRequestSent: true }; - }); - } - }, [actionRequestSent, command.args.args?.comment, endpointId, getProcesses, setStore]); +export const GetProcessesActionResult = memo( + ({ command, setStore, store, status, setStatus, ResultComponent }) => { + const endpointId = command.commandDefinition?.meta?.endpointId; + const actionCreator = useSendGetEndpointProcessesRequest(); + + const actionRequestBody = useMemo(() => { + return endpointId + ? { + endpoint_ids: [endpointId], + comment: command.args.args?.comment?.[0], + } + : undefined; + }, [command.args.args?.comment, endpointId]); + + const { result, actionDetails: completedActionDetails } = useConsoleActionSubmitter< + ProcessesRequestBody, + GetProcessesActionOutputContent + >({ + ResultComponent, + setStore, + store, + status, + setStatus, + actionCreator, + actionRequestBody, + dataTestSubj: 'getProcesses', + }); + + const columns = useMemo( + () => [ + { + field: 'user', + name: i18n.translate( + 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.user', + { defaultMessage: 'USER' } + ), + width: '10%', + }, + { + field: 'pid', + name: i18n.translate( + 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.pid', + { defaultMessage: 'PID' } + ), + width: '5%', + }, + { + field: 'entity_id', + name: i18n.translate( + 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.enityId', + { defaultMessage: 'ENTITY ID' } + ), + width: '30%', + }, + + { + field: 'command', + name: i18n.translate( + 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.command', + { defaultMessage: 'COMMAND' } + ), + width: '55%', + }, + ], + [] + ); - // If get processes request was created, store the action id if necessary - useEffect(() => { - if (isPending) { - if (isGetProcessesSuccess && actionId !== getProcessesData?.data.id) { - setStore((prevState) => { - return { ...prevState, actionId: getProcessesData?.data.id }; - }); - } else if (processesActionRequestError) { - setStatus('error'); - setStore((prevState) => { - return { ...prevState, apiError: processesActionRequestError }; - }); + const tableEntries = useMemo(() => { + if (endpointId) { + return completedActionDetails?.outputs?.[endpointId]?.content.entries ?? []; } - } - }, [ - actionId, - getProcessesData?.data.id, - processesActionRequestError, - isGetProcessesSuccess, - setStatus, - setStore, - isPending, - ]); - - useEffect(() => { - if (actionDetails?.data.isCompleted && isPending) { - setStatus('success'); - setStore((prevState) => { - return { - ...prevState, - completedActionDetails: actionDetails?.data, - }; - }); - } - }, [actionDetails?.data, setStatus, setStore, isPending]); - - const columns = useMemo( - () => [ - { - field: 'user', - name: i18n.translate( - 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.user', - { defaultMessage: 'USER' } - ), - width: '10%', - }, - { - field: 'pid', - name: i18n.translate( - 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.pid', - { defaultMessage: 'PID' } - ), - width: '5%', - }, - { - field: 'entity_id', - name: i18n.translate( - 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.enityId', - { defaultMessage: 'ENTITY ID' } - ), - width: '30%', - }, - - { - field: 'command', - name: i18n.translate( - 'xpack.securitySolution.endpointResponseActions.getProcesses.table.header.command', - { defaultMessage: 'COMMAND' } - ), - width: '55%', - }, - ], - [] - ); + return []; + }, [completedActionDetails?.outputs, endpointId]); - const tableEntries = useMemo(() => { - if (endpointId) { - return completedActionDetails?.outputs?.[endpointId]?.content.entries ?? []; + if (!completedActionDetails || !completedActionDetails.wasSuccessful) { + return result; } - return []; - }, [completedActionDetails?.outputs, endpointId]); - - // Show nothing if still pending - if (isPending) { - return ; - } - // Show errors if perform action fails - if (isError && apiError) { + // Show results return ( - - + + ); } - - // Show errors - if (completedActionDetails?.errors) { - return ( - - ); - } - - // Show results - return ( - - - - ); -}); +); GetProcessesActionResult.displayName = 'GetProcessesActionResult'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/hooks.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/hooks.tsx deleted file mode 100644 index bbc390bb2ba53..0000000000000 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/hooks.tsx +++ /dev/null @@ -1,100 +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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useEffect, useRef } from 'react'; -import { useIsMounted } from '../../hooks/use_is_mounted'; -import { useGetActionDetails } from '../../hooks/endpoint/use_get_action_details'; -import { ACTION_DETAILS_REFRESH_INTERVAL } from './constants'; -import type { ActionRequestState, ActionRequestComponentProps } from './types'; -import type { useSendIsolateEndpointRequest } from '../../hooks/endpoint/use_send_isolate_endpoint_request'; -import type { useSendReleaseEndpointRequest } from '../../hooks/endpoint/use_send_release_endpoint_request'; - -export const useUpdateActionState = ({ - actionRequestApi, - actionRequest, - command, - endpointId, - setStatus, - setStore, - isPending, -}: Pick & { - actionRequestApi: ReturnType< - typeof useSendIsolateEndpointRequest | typeof useSendReleaseEndpointRequest - >; - actionRequest?: ActionRequestState; - endpointId?: string; - isPending: boolean; -}) => { - const isMounted = useIsMounted(); - const actionRequestSent = Boolean(actionRequest?.requestSent); - const { data: actionDetails } = useGetActionDetails(actionRequest?.actionId ?? '-', { - enabled: Boolean(actionRequest?.actionId) && isPending, - refetchInterval: isPending ? ACTION_DETAILS_REFRESH_INTERVAL : false, - }); - - // keep a reference to track the console's mounted state - // in order to update the store and cause a re-render on action request API response - const latestIsMounted = useRef(false); - latestIsMounted.current = isMounted; - - // Create action request - useEffect(() => { - if (!actionRequestSent && endpointId && isMounted) { - const request: ActionRequestState = { - requestSent: true, - actionId: undefined, - }; - - actionRequestApi - .mutateAsync({ - endpoint_ids: [endpointId], - comment: command.args.args?.comment?.[0], - }) - .then((response) => { - request.actionId = response.data.id; - - if (latestIsMounted.current) { - setStore((prevState) => { - return { ...prevState, actionRequest: { ...request } }; - }); - } - }); - - setStore((prevState) => { - return { ...prevState, actionRequest: request }; - }); - } - }, [ - actionRequestApi, - actionRequestSent, - command.args.args?.comment, - endpointId, - isMounted, - setStore, - ]); - - useEffect(() => { - // update the console's mounted state ref - latestIsMounted.current = isMounted; - // set to false when unmounted/console is hidden - return () => { - latestIsMounted.current = false; - }; - }, [isMounted]); - - useEffect(() => { - if (actionDetails?.data.isCompleted && isPending) { - setStatus('success'); - setStore((prevState) => { - return { - ...prevState, - completedActionDetails: actionDetails.data, - }; - }); - } - }, [actionDetails?.data, actionDetails?.data.isCompleted, setStatus, setStore, isPending]); -}; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/hooks/use_console_action_submitter.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/hooks/use_console_action_submitter.test.tsx new file mode 100644 index 0000000000000..7ef506ea30f32 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/hooks/use_console_action_submitter.test.tsx @@ -0,0 +1,275 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { + UseConsoleActionSubmitterOptions, + ConsoleActionSubmitter, + CommandResponseActionApiState, +} from './use_console_action_submitter'; +import { useConsoleActionSubmitter } from './use_console_action_submitter'; +import type { AppContextTestRender } from '../../../../common/mock/endpoint'; +import { createAppRootMockRenderer } from '../../../../common/mock/endpoint'; +import { EndpointActionGenerator } from '../../../../../common/endpoint/data_generators/endpoint_action_generator'; +import React, { useState } from 'react'; +import type { CommandExecutionResultProps } from '../../console'; +import type { DeferredInterface } from '../../../mocks/utils'; +import { getDeferred } from '../../../mocks/utils'; +import type { ActionDetails } from '../../../../../common/endpoint/types'; +import { act, waitFor } from '@testing-library/react'; +import { responseActionsHttpMocks } from '../../../mocks/response_actions_http_mocks'; + +describe('When using `useConsoleActionSubmitter()` hook', () => { + let render: () => ReturnType; + let renderResult: ReturnType; + let renderArgs: UseConsoleActionSubmitterOptions; + let updateHookRenderArgs: () => void; + let hookRenderResultStorage: jest.Mock<(args: ConsoleActionSubmitter) => void>; + let releaseSuccessActionRequestApiResponse: DeferredInterface['resolve']; + let releaseFailedActionRequestApiResponse: DeferredInterface['reject']; + let apiMocks: ReturnType; + + const ActionSubmitterTestComponent = () => { + const [hookOptions, setHookOptions] = useState(renderArgs); + + updateHookRenderArgs = () => { + new Promise((r) => { + setTimeout(r, 1); + }).then(() => { + setHookOptions({ + ...renderArgs, + }); + }); + }; + + const { result, actionDetails } = useConsoleActionSubmitter(hookOptions); + + hookRenderResultStorage({ result, actionDetails }); + + return
    {result}
    ; + }; + + const getOutputTextContent = (): string => { + return renderResult.getByTestId('testContainer').textContent ?? ''; + }; + + beforeEach(() => { + const { render: renderComponent, coreStart } = createAppRootMockRenderer(); + const actionGenerator = new EndpointActionGenerator(); + const deferred = getDeferred(); + + apiMocks = responseActionsHttpMocks(coreStart.http); + + hookRenderResultStorage = jest.fn(); + releaseSuccessActionRequestApiResponse = () => + deferred.resolve(actionGenerator.generateActionDetails({ id: '123' })); + releaseFailedActionRequestApiResponse = deferred.reject; + + let status: UseConsoleActionSubmitterOptions['status'] = 'pending'; + let commandStore: CommandResponseActionApiState = {}; + + renderArgs = { + dataTestSubj: 'test', + actionRequestBody: { + endpoint_ids: ['123'], + }, + actionCreator: { + mutateAsync: jest.fn(async () => { + return { + data: await deferred.promise, + }; + }), + } as unknown as UseConsoleActionSubmitterOptions['actionCreator'], + get status() { + return status; + }, + setStatus: jest.fn((newStatus) => { + status = newStatus; + updateHookRenderArgs(); + }), + get store() { + return commandStore; + }, + setStore: jest.fn((newStoreOrCallback: object | ((prevStore: object) => object)) => { + if (typeof newStoreOrCallback === 'function') { + commandStore = newStoreOrCallback(commandStore); + } else { + commandStore = newStoreOrCallback; + } + + updateHookRenderArgs(); + }), + ResultComponent: jest.fn( + ({ children, showAs, 'data-test-subj': dataTestSubj }: CommandExecutionResultProps) => { + return ( +
    + {children} +
    + ); + } + ), + }; + + render = () => { + renderResult = renderComponent(); + return renderResult; + }; + }); + + afterEach(() => { + renderResult.unmount(); + }); + + it('should return expected interface while its still pending', () => { + render(); + + expect(hookRenderResultStorage).toHaveBeenLastCalledWith({ + result: expect.anything(), + action: undefined, + }); + + expect(renderResult.getByTestId('test-pending')).not.toBeNull(); + }); + + it('should update command state when request is sent', () => { + render(); + + expect(renderArgs.store?.actionApiState?.request.sent).toBe(true); + expect(renderArgs.store?.actionApiState?.request.actionId).toBe(undefined); + }); + + it('should store the action id when action request api is successful', async () => { + render(); + + releaseSuccessActionRequestApiResponse(); + + await waitFor(() => { + expect(renderArgs.store?.actionApiState?.request.actionId).toBe('123'); + }); + }); + + it('should store action request api error', async () => { + render(); + const error = new Error('oh oh. request failed'); + + act(() => { + releaseFailedActionRequestApiResponse(error); + }); + + await waitFor(() => { + expect(renderArgs.store?.actionApiState?.request.actionId).toBe(undefined); + expect(renderArgs.store?.actionApiState?.request.error).toBe(error); + }); + + await waitFor(() => { + expect(getOutputTextContent()).toEqual( + 'The following error was encountered:oh oh. request failed' + ); + }); + }); + + it('should still store the action id if component is unmounted while action request API is in flight', async () => { + render(); + renderResult.unmount(); + + expect(renderArgs.store.actionApiState?.request.sent).toBe(true); + + const requestState = renderArgs.store.actionApiState?.request; + releaseSuccessActionRequestApiResponse(); + + await waitFor(() => { + // this check just ensure that we mutated the state when the api returned success instead of + // dispatching a `setStore()`. + expect(renderArgs.store.actionApiState?.request === requestState).toBe(true); + + expect(renderArgs.store.actionApiState?.request.actionId).toEqual('123'); + }); + }); + + it('should call action details api once we have an action id', async () => { + render(); + + expect(apiMocks.responseProvider.actionDetails).not.toHaveBeenCalled(); + + releaseSuccessActionRequestApiResponse(); + + await waitFor(() => { + expect(apiMocks.responseProvider.actionDetails).toHaveBeenCalledWith({ + path: '/api/endpoint/action/123', + }); + }); + }); + + it('should continue to show pending message until action completes', async () => { + apiMocks.responseProvider.actionDetails.mockImplementation(() => { + return { + data: new EndpointActionGenerator().generateActionDetails({ + id: '123', + isCompleted: false, + }), + }; + }); + render(); + releaseSuccessActionRequestApiResponse(); + + await waitFor(() => { + expect(apiMocks.responseProvider.actionDetails).toHaveBeenCalledWith({ + path: '/api/endpoint/action/123', + }); + }); + + expect(renderResult.getByTestId('test-pending')).not.toBeNull(); + + expect(hookRenderResultStorage).toHaveBeenLastCalledWith({ + result: expect.anything(), + actionDetails: undefined, + }); + }); + + it('should store action details api error', async () => { + const error = new Error('on oh. getting action details failed'); + apiMocks.responseProvider.actionDetails.mockImplementation(() => { + throw error; + }); + + render(); + releaseSuccessActionRequestApiResponse(); + + await waitFor(() => { + expect(apiMocks.responseProvider.actionDetails).toHaveBeenCalledWith({ + path: '/api/endpoint/action/123', + }); + }); + + expect(renderArgs.store.actionApiState?.actionDetailsError).toBe(error); + + expect(renderResult.getByTestId('test-apiFailure').textContent).toEqual( + 'The following error was encountered:on oh. getting action details failed' + ); + }); + + it('should store action details once action completes', async () => { + const actionDetails = new EndpointActionGenerator().generateActionDetails({ id: '123' }); + apiMocks.responseProvider.actionDetails.mockReturnValue({ data: actionDetails }); + + render(); + releaseSuccessActionRequestApiResponse(); + + await waitFor(() => { + expect(apiMocks.responseProvider.actionDetails).toHaveBeenCalledWith({ + path: '/api/endpoint/action/123', + }); + }); + + expect(renderArgs.store.actionApiState?.actionDetails).toBe(actionDetails); + expect(hookRenderResultStorage).toHaveBeenLastCalledWith({ + result: expect.anything(), + actionDetails, + }); + + expect(renderResult.getByTestId('test-success').textContent).toEqual(''); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/hooks/use_console_action_submitter.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/hooks/use_console_action_submitter.tsx new file mode 100644 index 0000000000000..7183b5cc61ef7 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/hooks/use_console_action_submitter.tsx @@ -0,0 +1,292 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect, useMemo } from 'react'; +import type { UseMutationResult } from '@tanstack/react-query'; +import type { IHttpFetchError } from '@kbn/core-http-browser'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useIsMounted } from '@kbn/securitysolution-hook-utils'; +import { useTestIdGenerator } from '../../../hooks/use_test_id_generator'; +import type { BaseActionRequestBody } from '../../../../../common/endpoint/schema/actions'; +import { ActionSuccess } from '../action_success'; +import { ActionError } from '../action_error'; +import { FormattedError } from '../../formatted_error'; +import { useGetActionDetails } from '../../../hooks/endpoint/use_get_action_details'; +import { ACTION_DETAILS_REFRESH_INTERVAL } from '../constants'; +import type { + ActionDetails, + Immutable, + ResponseActionApiResponse, +} from '../../../../../common/endpoint/types'; +import type { CommandExecutionComponentProps } from '../../console'; + +export interface ConsoleActionSubmitter { + /** + * The ui to be returned to the console. This UI will display different states of the action, + * including pending, error conditions and generic success messages. + */ + result: JSX.Element; + actionDetails: Immutable> | undefined; +} + +/** + * Command store state for response action api state. + */ +export interface CommandResponseActionApiState { + actionApiState?: { + request: { + sent: boolean; + actionId: string | undefined; + error: IHttpFetchError | undefined; + }; + actionDetails: ActionDetails | undefined; + actionDetailsError: IHttpFetchError | undefined; + }; +} + +export interface UseConsoleActionSubmitterOptions< + TReqBody extends BaseActionRequestBody = BaseActionRequestBody, + TActionOutputContent extends object = object +> extends Pick< + // eslint-disable-next-line @typescript-eslint/no-explicit-any + CommandExecutionComponentProps>, + 'ResultComponent' | 'setStore' | 'store' | 'status' | 'setStatus' + > { + actionCreator: UseMutationResult; + /** + * The API request body. If `undefined`, then API will not be called. + */ + actionRequestBody: TReqBody | undefined; + + dataTestSubj?: string; +} + +/** + * generic hook for use with Response Action commands. It will create the action, store its ID and + * continuously pull the Action's Details until it completes. It handles all aspects of UI display + * for the different states of the command (pending -> success/failure) + * + * @param actionCreator + * @param actionRequestBody + * @param setStatus + * @param status + * @param setStore + * @param store + * @param ResultComponent + * @param dataTestSubj + */ +export const useConsoleActionSubmitter = < + TReqBody extends BaseActionRequestBody = BaseActionRequestBody, + TActionOutputContent extends object = object +>({ + actionCreator, + actionRequestBody, + setStatus, + status, + setStore, + store, + ResultComponent, + dataTestSubj, +}: UseConsoleActionSubmitterOptions< + TReqBody, + TActionOutputContent +>): ConsoleActionSubmitter => { + const isMounted = useIsMounted(); + const getTestId = useTestIdGenerator(dataTestSubj); + const isPending = status === 'pending'; + + const currentActionState = useMemo< + Immutable>['actionApiState']> + >( + () => + store.actionApiState ?? { + request: { + sent: false, + error: undefined, + actionId: undefined, + }, + actionDetails: undefined, + actionDetailsError: undefined, + }, + [store.actionApiState] + ); + + const { actionDetails, actionDetailsError } = currentActionState; + const { + actionId, + sent: actionRequestSent, + error: actionRequestError, + } = currentActionState.request; + + const { data: apiActionDetailsResponse, error: apiActionDetailsError } = + useGetActionDetails(actionId ?? '-', { + enabled: Boolean(actionId) && isPending, + refetchInterval: isPending ? ACTION_DETAILS_REFRESH_INTERVAL : false, + }); + + // Create the action request if not yet done + useEffect(() => { + if (!actionRequestSent && actionRequestBody && isMounted()) { + const updatedRequestState: Required< + CommandResponseActionApiState + >['actionApiState']['request'] = { + ...( + currentActionState as Required< + CommandResponseActionApiState + >['actionApiState'] + ).request, + sent: true, + }; + + // The object defined above (`updatedRequestState`) is saved to the command state right away. + // the creation of the Action request (below) will mutate this object to store the Action ID + // once the API response is received. We do this to ensure that the action is not created more + // than once if the user happens to close the console prior to the response being returned. + // Once a response is received, we check if the component is mounted, and if so, then we send + // another update to the command store which will cause it to re-render and start checking for + // action completion. + actionCreator + .mutateAsync(actionRequestBody) + .then((response) => { + updatedRequestState.actionId = response.data.id; + }) + .catch((err) => { + updatedRequestState.error = err; + }) + .finally(() => { + // If the component is mounted, then set the store with the updated data (causes a rerender) + if (isMounted()) { + setStore((prevState) => { + return { + ...prevState, + actionApiState: { + ...(prevState.actionApiState ?? currentActionState), + request: { ...updatedRequestState }, + }, + }; + }); + } + }); + + setStore((prevState) => { + return { + ...prevState, + actionApiState: { + ...(prevState.actionApiState ?? currentActionState), + request: updatedRequestState, + }, + }; + }); + } + }, [ + actionCreator, + actionRequestBody, + actionRequestSent, + currentActionState, + isMounted, + setStore, + ]); + + // If an error was returned while attempting to create the action request, + // then set command status to error + useEffect(() => { + if (actionRequestError && isPending) { + setStatus('error'); + } + }, [actionRequestError, isPending, setStatus]); + + // If an error was return by the Action Details API, then store it and set the status to error + useEffect(() => { + if (apiActionDetailsError && isPending) { + setStatus('error'); + setStore((prevState) => { + return { + ...prevState, + actionApiState: { + ...(prevState.actionApiState ?? currentActionState), + actionDetails: undefined, + actionDetailsError: apiActionDetailsError, + }, + }; + }); + } + }, [apiActionDetailsError, currentActionState, isPending, setStatus, setStore]); + + // If the action details indicates complete, then update the action's console state and set the status to success + useEffect(() => { + if (apiActionDetailsResponse?.data.isCompleted && isPending) { + setStatus(apiActionDetailsResponse?.data.wasSuccessful ? 'success' : 'error'); + setStore((prevState) => { + return { + ...prevState, + actionApiState: { + ...(prevState.actionApiState ?? currentActionState), + actionDetails: apiActionDetailsResponse.data, + }, + // Unclear why I needed to cast this here. For some reason the `ActionDetails['outputs']` is + // reporting a type error for the `content` property, although the types seem to line up. + } as typeof prevState; + }); + } + }, [apiActionDetailsResponse, currentActionState, isPending, setStatus, setStore]); + + // Calculate the action's UI result based on the different API responses + const result = useMemo(() => { + if (isPending) { + return ; + } + + const apiError = actionRequestError || actionDetailsError; + + if (apiError) { + return ( + + + + + ); + } + + if (actionDetails) { + // Response action failures + if (actionDetails.errors) { + return ( + + ); + } + + return ( + + ); + } + + return <>; + }, [ + isPending, + actionRequestError, + actionDetailsError, + actionDetails, + ResultComponent, + getTestId, + ]); + + return { + result, + actionDetails: currentActionState.actionDetails, + }; +}; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.test.tsx index 63e05d420deaf..110ddbb53b1b0 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.test.tsx @@ -16,9 +16,9 @@ import { getEndpointResponseActionsConsoleCommands } from './endpoint_response_a import { responseActionsHttpMocks } from '../../mocks/response_actions_http_mocks'; import { enterConsoleCommand } from '../console/mocks'; import { waitFor } from '@testing-library/react'; -import { getDeferred } from '../mocks'; import type { ResponderCapabilities } from '../../../../common/endpoint/constants'; import { RESPONDER_CAPABILITIES } from '../../../../common/endpoint/constants'; +import { getDeferred } from '../../mocks/utils'; describe('When using isolate action from response actions console', () => { let render: ( @@ -115,7 +115,7 @@ describe('When using isolate action from response actions console', () => { enterConsoleCommand(renderResult, 'isolate'); await waitFor(() => { - expect(renderResult.getByTestId('isolateSuccessCallout')).toBeTruthy(); + expect(renderResult.getByTestId('isolate-success')).toBeTruthy(); }); }); @@ -130,7 +130,7 @@ describe('When using isolate action from response actions console', () => { enterConsoleCommand(renderResult, 'isolate'); await waitFor(() => { - expect(renderResult.getByTestId('isolateErrorCallout').textContent).toMatch( + expect(renderResult.getByTestId('isolate-actionFailure').textContent).toMatch( /error one \| error two/ ); }); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.tsx index ec11d022650ca..8df7692cf3ac2 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/isolate_action.tsx @@ -5,47 +5,37 @@ * 2.0. */ -import React, { memo } from 'react'; +import { memo, useMemo } from 'react'; +import { useConsoleActionSubmitter } from './hooks/use_console_action_submitter'; import type { ActionRequestComponentProps } from './types'; import { useSendIsolateEndpointRequest } from '../../hooks/endpoint/use_send_isolate_endpoint_request'; -import { ActionError } from './action_error'; -import { useUpdateActionState } from './hooks'; export const IsolateActionResult = memo( ({ command, setStore, store, status, setStatus, ResultComponent }) => { - const endpointId = command.commandDefinition?.meta?.endpointId; - const { completedActionDetails, actionRequest } = store; - const isPending = status === 'pending'; const isolateHostApi = useSendIsolateEndpointRequest(); - useUpdateActionState({ - actionRequestApi: isolateHostApi, - actionRequest, - command, - endpointId, - setStatus, - setStore, - isPending, - }); - - // Show nothing if still pending - if (isPending) { - return ; - } + const actionRequestBody = useMemo(() => { + const endpointId = command.commandDefinition?.meta?.endpointId; + const comment = command.args.args?.comment?.[0]; - // Show errors - if (completedActionDetails?.errors) { - return ( - - ); - } + return endpointId + ? { + endpoint_ids: [endpointId], + comment, + } + : undefined; + }, [command.args.args?.comment, command.commandDefinition?.meta?.endpointId]); - // Show Success - return ; + return useConsoleActionSubmitter({ + ResultComponent, + setStore, + store, + status, + setStatus, + actionCreator: isolateHostApi, + actionRequestBody, + dataTestSubj: 'isolate', + }).result; } ); IsolateActionResult.displayName = 'IsolateActionResult'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.test.tsx index 827a4d6191754..f888df2099b13 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.test.tsx @@ -195,7 +195,7 @@ describe('When using the kill-process action from response actions console', () enterConsoleCommand(renderResult, 'kill-process --pid 123'); await waitFor(() => { - expect(renderResult.getByTestId('killProcessSuccessCallout')).toBeTruthy(); + expect(renderResult.getByTestId('killProcess-success')).toBeTruthy(); }); }); @@ -204,7 +204,7 @@ describe('When using the kill-process action from response actions console', () enterConsoleCommand(renderResult, 'kill-process --entityId 123wer'); await waitFor(() => { - expect(renderResult.getByTestId('killProcessSuccessCallout')).toBeTruthy(); + expect(renderResult.getByTestId('killProcess-success')).toBeTruthy(); }); }); @@ -219,7 +219,7 @@ describe('When using the kill-process action from response actions console', () enterConsoleCommand(renderResult, 'kill-process --pid 123'); await waitFor(() => { - expect(renderResult.getByTestId('killProcessErrorCallout').textContent).toMatch( + expect(renderResult.getByTestId('killProcess-actionFailure').textContent).toMatch( /error one \| error two/ ); }); @@ -234,7 +234,7 @@ describe('When using the kill-process action from response actions console', () enterConsoleCommand(renderResult, 'kill-process --pid 123'); await waitFor(() => { - expect(renderResult.getByTestId('killProcessAPIErrorCallout').textContent).toMatch( + expect(renderResult.getByTestId('killProcess-apiFailure').textContent).toMatch( /this is an error/ ); }); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.tsx index 3e4dcf61d1690..bf501c31b9e85 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/kill_process_action.tsx @@ -5,130 +5,40 @@ * 2.0. */ -import React, { memo, useEffect } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import type { IHttpFetchError } from '@kbn/core-http-browser'; +import { memo, useMemo } from 'react'; +import type { KillOrSuspendProcessRequestBody } from '../../../../common/endpoint/types'; import { parsedPidOrEntityIdParameter } from './utils'; -import { ActionSuccess } from './action_success'; -import type { - ActionDetails, - KillProcessActionOutputContent, -} from '../../../../common/endpoint/types'; -import { useGetActionDetails } from '../../hooks/endpoint/use_get_action_details'; -import type { EndpointCommandDefinitionMeta } from './types'; import { useSendKillProcessRequest } from '../../hooks/endpoint/use_send_kill_process_endpoint_request'; -import type { CommandExecutionComponentProps } from '../console/types'; -import { ActionError } from './action_error'; -import { ACTION_DETAILS_REFRESH_INTERVAL } from './constants'; +import type { ActionRequestComponentProps } from './types'; +import { useConsoleActionSubmitter } from './hooks/use_console_action_submitter'; export const KillProcessActionResult = memo< - CommandExecutionComponentProps< - { comment?: string; pid?: string; entityId?: string }, - { - actionId?: string; - actionRequestSent?: boolean; - completedActionDetails?: ActionDetails; - apiError?: IHttpFetchError; - }, - EndpointCommandDefinitionMeta - > + ActionRequestComponentProps<{ pid?: string[]; entityId?: string[] }> >(({ command, setStore, store, status, setStatus, ResultComponent }) => { - const endpointId = command.commandDefinition?.meta?.endpointId; - const { actionId, completedActionDetails, apiError } = store; - const isPending = status === 'pending'; - const isError = status === 'error'; - const actionRequestSent = Boolean(store.actionRequestSent); + const actionCreator = useSendKillProcessRequest(); - const { mutate, data, isSuccess, error } = useSendKillProcessRequest(); - - const { data: actionDetails } = useGetActionDetails( - actionId ?? '-', - { - enabled: Boolean(actionId) && isPending, - refetchInterval: isPending ? ACTION_DETAILS_REFRESH_INTERVAL : false, - } - ); - - // Send Kill request if not yet done - useEffect(() => { + const actionRequestBody = useMemo(() => { + const endpointId = command.commandDefinition?.meta?.endpointId; const parameters = parsedPidOrEntityIdParameter(command.args.args); - if (!actionRequestSent && endpointId && parameters) { - mutate({ - endpoint_ids: [endpointId], - comment: command.args.args?.comment?.[0], - parameters, - }); - setStore((prevState) => { - return { ...prevState, actionRequestSent: true }; - }); - } - }, [actionRequestSent, command.args.args, endpointId, mutate, setStore]); - - // If kill-process request was created, store the action id if necessary - useEffect(() => { - if (isPending) { - if (isSuccess && actionId !== data.data.id) { - setStore((prevState) => { - return { ...prevState, actionId: data.data.id }; - }); - } else if (error) { - setStatus('error'); - setStore((prevState) => { - return { ...prevState, apiError: error }; - }); - } - } - }, [actionId, data?.data.id, isSuccess, error, setStore, setStatus, isPending]); - - useEffect(() => { - if (actionDetails?.data.isCompleted && isPending) { - setStatus('success'); - setStore((prevState) => { - return { - ...prevState, - completedActionDetails: actionDetails.data, - }; - }); - } - }, [actionDetails?.data, setStatus, setStore, isPending]); - - // Show API errors if perform action fails - if (isError && apiError) { - return ( - - - - ); - } - - // Show nothing if still pending - if (isPending || !completedActionDetails) { - return ; - } - - // Show errors - if (completedActionDetails?.errors) { - return ( - - ); - } - - // Show Success - return ( - - ); + return endpointId + ? { + endpoint_ids: [endpointId], + comment: command.args.args?.comment?.[0], + parameters, + } + : undefined; + }, [command.args.args, command.commandDefinition?.meta?.endpointId]); + + return useConsoleActionSubmitter({ + ResultComponent, + setStore, + store, + status, + setStatus, + actionCreator, + actionRequestBody, + dataTestSubj: 'killProcess', + }).result; }); KillProcessActionResult.displayName = 'KillProcessActionResult'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.test.tsx index 19e3be94469eb..d1c1ea264f863 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.test.tsx @@ -16,9 +16,9 @@ import { getEndpointResponseActionsConsoleCommands } from './endpoint_response_a import { enterConsoleCommand } from '../console/mocks'; import { waitFor } from '@testing-library/react'; import { responseActionsHttpMocks } from '../../mocks/response_actions_http_mocks'; -import { getDeferred } from '../mocks'; import type { ResponderCapabilities } from '../../../../common/endpoint/constants'; import { RESPONDER_CAPABILITIES } from '../../../../common/endpoint/constants'; +import { getDeferred } from '../../mocks/utils'; describe('When using the release action from response actions console', () => { let render: ( @@ -116,7 +116,7 @@ describe('When using the release action from response actions console', () => { enterConsoleCommand(renderResult, 'release'); await waitFor(() => { - expect(renderResult.getByTestId('releaseSuccessCallout')).toBeTruthy(); + expect(renderResult.getByTestId('release-success')).toBeTruthy(); }); }); @@ -131,7 +131,7 @@ describe('When using the release action from response actions console', () => { enterConsoleCommand(renderResult, 'release'); await waitFor(() => { - expect(renderResult.getByTestId('releaseErrorCallout').textContent).toMatch( + expect(renderResult.getByTestId('release-actionFailure').textContent).toMatch( /error one \| error two/ ); }); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.tsx index f789b48671324..9b0f371ca003f 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/release_action.tsx @@ -5,48 +5,37 @@ * 2.0. */ -import React, { memo } from 'react'; +import { memo, useMemo } from 'react'; import type { ActionRequestComponentProps } from './types'; import { useSendReleaseEndpointRequest } from '../../hooks/endpoint/use_send_release_endpoint_request'; -import { ActionError } from './action_error'; -import { useUpdateActionState } from './hooks'; +import { useConsoleActionSubmitter } from './hooks/use_console_action_submitter'; export const ReleaseActionResult = memo( ({ command, setStore, store, status, setStatus, ResultComponent }) => { - const endpointId = command.commandDefinition?.meta?.endpointId; - const { completedActionDetails, actionRequest } = store; - const isPending = status === 'pending'; - const releaseHostApi = useSendReleaseEndpointRequest(); - useUpdateActionState({ - actionRequestApi: releaseHostApi, - actionRequest, - command, - endpointId, - setStatus, - setStore, - isPending, - }); - - // Show nothing if still pending - if (isPending) { - return ; - } + const actionRequestBody = useMemo(() => { + const endpointId = command.commandDefinition?.meta?.endpointId; + const comment = command.args.args?.comment?.[0]; - // Show errors - if (completedActionDetails?.errors) { - return ( - - ); - } + return endpointId + ? { + endpoint_ids: [endpointId], + comment, + } + : undefined; + }, [command.args.args?.comment, command.commandDefinition?.meta?.endpointId]); - // Show Success - return ; + return useConsoleActionSubmitter({ + ResultComponent, + setStore, + store, + status, + setStatus, + actionCreator: releaseHostApi, + actionRequestBody, + dataTestSubj: 'release', + }).result; } ); ReleaseActionResult.displayName = 'ReleaseActionResult'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.test.tsx index 9446fb5dcba6a..7479e52edfb07 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.test.tsx @@ -186,7 +186,7 @@ describe('When using the suspend-process action from response actions console', enterConsoleCommand(renderResult, 'suspend-process --pid 123'); await waitFor(() => { - expect(renderResult.getByTestId('suspendProcessSuccessCallout')).toBeTruthy(); + expect(renderResult.getByTestId('suspendProcess-success')).toBeTruthy(); }); }); @@ -195,7 +195,7 @@ describe('When using the suspend-process action from response actions console', enterConsoleCommand(renderResult, 'suspend-process --entityId 123wer'); await waitFor(() => { - expect(renderResult.getByTestId('suspendProcessSuccessCallout')).toBeTruthy(); + expect(renderResult.getByTestId('suspendProcess-success')).toBeTruthy(); }); }); @@ -210,7 +210,7 @@ describe('When using the suspend-process action from response actions console', enterConsoleCommand(renderResult, 'suspend-process --pid 123'); await waitFor(() => { - expect(renderResult.getByTestId('suspendProcessErrorCallout').textContent).toMatch( + expect(renderResult.getByTestId('suspendProcess-actionFailure').textContent).toMatch( /error one \| error two/ ); }); @@ -225,7 +225,7 @@ describe('When using the suspend-process action from response actions console', enterConsoleCommand(renderResult, 'suspend-process --pid 123'); await waitFor(() => { - expect(renderResult.getByTestId('suspendProcessAPIErrorCallout').textContent).toMatch( + expect(renderResult.getByTestId('suspendProcess-apiFailure').textContent).toMatch( /this is an error/ ); }); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.tsx index a60e7eb6bd65b..f8401a81fa114 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/suspend_process_action.tsx @@ -5,130 +5,46 @@ * 2.0. */ -import React, { memo, useEffect } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import type { IHttpFetchError } from '@kbn/core-http-browser'; +import { memo, useMemo } from 'react'; import { parsedPidOrEntityIdParameter } from './utils'; -import { ActionSuccess } from './action_success'; import type { - ActionDetails, SuspendProcessActionOutputContent, + KillOrSuspendProcessRequestBody, } from '../../../../common/endpoint/types'; -import { useGetActionDetails } from '../../hooks/endpoint/use_get_action_details'; -import type { EndpointCommandDefinitionMeta } from './types'; import { useSendSuspendProcessRequest } from '../../hooks/endpoint/use_send_suspend_process_endpoint_request'; -import type { CommandExecutionComponentProps } from '../console/types'; -import { ActionError } from './action_error'; -import { ACTION_DETAILS_REFRESH_INTERVAL } from './constants'; +import type { ActionRequestComponentProps } from './types'; +import { useConsoleActionSubmitter } from './hooks/use_console_action_submitter'; export const SuspendProcessActionResult = memo< - CommandExecutionComponentProps< - { comment?: string; pid?: string; entityId?: string }, - { - actionId?: string; - actionRequestSent?: boolean; - completedActionDetails?: ActionDetails; - apiError?: IHttpFetchError; - }, - EndpointCommandDefinitionMeta - > + ActionRequestComponentProps<{ pid?: string[]; entityId?: string[] }> >(({ command, setStore, store, status, setStatus, ResultComponent }) => { - const endpointId = command.commandDefinition?.meta?.endpointId; - const { actionId, completedActionDetails, apiError } = store; - const isPending = status === 'pending'; - const isError = status === 'error'; - const actionRequestSent = Boolean(store.actionRequestSent); + const actionCreator = useSendSuspendProcessRequest(); - const { mutate, data, isSuccess, error } = useSendSuspendProcessRequest(); - - const { data: actionDetails } = useGetActionDetails( - actionId ?? '-', - { - enabled: Boolean(actionId) && isPending, - refetchInterval: isPending ? ACTION_DETAILS_REFRESH_INTERVAL : false, - } - ); - - // Send Suspend request if not yet done - useEffect(() => { + const actionRequestBody = useMemo(() => { + const endpointId = command.commandDefinition?.meta?.endpointId; const parameters = parsedPidOrEntityIdParameter(command.args.args); - if (!actionRequestSent && endpointId && parameters) { - mutate({ - endpoint_ids: [endpointId], - comment: command.args.args?.comment?.[0], - parameters, - }); - setStore((prevState) => { - return { ...prevState, actionRequestSent: true }; - }); - } - }, [actionRequestSent, command.args.args, endpointId, mutate, setStore]); - - // If suspend-process request was created, store the action id if necessary - useEffect(() => { - if (isPending) { - if (isSuccess && actionId !== data.data.id) { - setStore((prevState) => { - return { ...prevState, actionId: data.data.id }; - }); - } else if (error) { - setStatus('error'); - setStore((prevState) => { - return { ...prevState, apiError: error }; - }); - } - } - }, [actionId, data?.data.id, isSuccess, error, setStore, setStatus, isPending]); - - useEffect(() => { - if (actionDetails?.data.isCompleted && isPending) { - setStatus('success'); - setStore((prevState) => { - return { - ...prevState, - completedActionDetails: actionDetails.data, - }; - }); - } - }, [actionDetails?.data, setStatus, setStore, isPending]); - - // Show API errors if perform action fails - if (isError && apiError) { - return ( - - - - ); - } - - // Show nothing if still pending - if (isPending || !completedActionDetails) { - return ; - } - - // Show errors - if (completedActionDetails?.errors) { - return ( - - ); - } - - // Show Success - return ( - - ); + return endpointId + ? { + endpoint_ids: [endpointId], + comment: command.args.args?.comment?.[0], + parameters, + } + : undefined; + }, [command.args.args, command.commandDefinition?.meta?.endpointId]); + + return useConsoleActionSubmitter< + KillOrSuspendProcessRequestBody, + SuspendProcessActionOutputContent + >({ + ResultComponent, + setStore, + store, + status, + setStatus, + actionCreator, + actionRequestBody, + dataTestSubj: 'suspendProcess', + }).result; }); SuspendProcessActionResult.displayName = 'SuspendProcessActionResult'; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/types.ts b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/types.ts index 34c306ed0a116..92cc3e8c9017a 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/types.ts +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/types.ts @@ -5,8 +5,9 @@ * 2.0. */ +import type { CommandResponseActionApiState } from './hooks/use_console_action_submitter'; import type { ManagedConsoleExtensionComponentProps } from '../console'; -import type { ActionDetails, HostMetadata } from '../../../../common/endpoint/types'; +import type { HostMetadata } from '../../../../common/endpoint/types'; import type { CommandExecutionComponentProps } from '../console/types'; export interface EndpointCommandDefinitionMeta { @@ -17,16 +18,9 @@ export type EndpointResponderExtensionComponentProps = ManagedConsoleExtensionCo endpoint: HostMetadata; }>; -export interface ActionRequestState { - requestSent: boolean; - actionId?: string; -} - -export type ActionRequestComponentProps = CommandExecutionComponentProps< - { comment?: string }, - { - actionRequest?: ActionRequestState; - completedActionDetails?: ActionDetails; - }, - EndpointCommandDefinitionMeta ->; +export type ActionRequestComponentProps = + CommandExecutionComponentProps< + { comment?: string } & TArgs, + CommandResponseActionApiState, + EndpointCommandDefinitionMeta + >; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/utils.test.ts b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/utils.test.ts index ab84e9de959f0..48b6753645c92 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/utils.test.ts +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/utils.test.ts @@ -19,9 +19,9 @@ describe('Endpoint Responder - Utilities', () => { expect(parameters).toEqual({ entity_id: '123qwe' }); }); - it('should return undefined if no params are defined', () => { + it('should return entity id with emtpy string if no params are defined', () => { const parameters = parsedPidOrEntityIdParameter({}); - expect(parameters).toEqual(undefined); + expect(parameters).toEqual({ entity_id: '' }); }); }); }); diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/utils.ts b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/utils.ts index 9ebcd090bd2a0..0b8e59d0353f7 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/utils.ts +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/utils.ts @@ -4,17 +4,17 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { EndpointActionDataParameterTypes } from '../../../../common/endpoint/types'; +import type { ResponseActionParametersWithPidOrEntityId } from '../../../../common/endpoint/types'; export const parsedPidOrEntityIdParameter = (parameters: { pid?: string[]; entityId?: string[]; -}): EndpointActionDataParameterTypes => { +}): ResponseActionParametersWithPidOrEntityId => { if (parameters.pid) { return { pid: Number(parameters.pid[0]) }; - } else if (parameters.entityId) { - return { entity_id: parameters.entityId[0] }; } - return undefined; + return { + entity_id: parameters?.entityId?.[0] ?? '', + }; }; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx index bb2c1b7761d5a..34cc5a3ca0f99 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/components/hooks.tsx @@ -159,7 +159,6 @@ export const getCommandKey = ( } }; -// TODO: add more filter names here export type FilterName = keyof typeof FILTER_NAMES; export const useActionsLogFilter = ({ filterName, diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.test.tsx index 30148c9643baa..556c765296337 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.test.tsx @@ -393,6 +393,26 @@ describe('Response actions history', () => { expect(noTrays).toEqual([]); }); + it('should contain relevant details in each expanded row', async () => { + render(); + const { getAllByTestId } = renderResult; + + const expandButtons = getAllByTestId(`${testPrefix}-expand-button`); + expandButtons.map((button) => userEvent.click(button)); + const trays = getAllByTestId(`${testPrefix}-details-tray`); + expect(trays).toBeTruthy(); + expect(Array.from(trays[0].querySelectorAll('dt')).map((title) => title.textContent)).toEqual( + [ + 'Command placed', + 'Execution started on', + 'Execution completed', + 'Input', + 'Parameters', + 'Output:', + ] + ); + }); + it('should refresh data when autoRefresh is toggled on', async () => { render(); const { getByTestId } = renderResult; diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx index 2a9362830c76d..ac9a0829bb7b8 100644 --- a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/response_actions_log.tsx @@ -5,112 +5,29 @@ * 2.0. */ -import { - EuiAvatar, - EuiBasicTable, - EuiButtonIcon, - EuiDescriptionList, - EuiEmptyPrompt, - EuiFacetButton, - EuiFlexGroup, - EuiFlexItem, - EuiHorizontalRule, - EuiScreenReaderOnly, - EuiI18nNumber, - EuiText, - EuiCodeBlock, - EuiToolTip, - RIGHT_ALIGNMENT, -} from '@elastic/eui'; -import { euiStyled, css } from '@kbn/kibana-react-plugin/common'; +import { EuiBasicTable, EuiEmptyPrompt, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui'; -import type { HorizontalAlignment, CriteriaWithPagination } from '@elastic/eui'; +import type { CriteriaWithPagination } from '@elastic/eui'; import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import type { ResponseActions, ResponseActionStatus, } from '../../../../common/endpoint/service/response_actions/constants'; -import { getEmptyValue } from '../../../common/components/empty_value'; -import { FormattedDate } from '../../../common/components/formatted_date'; + import type { ActionListApiResponse } from '../../../../common/endpoint/types'; import type { EndpointActionListRequestQuery } from '../../../../common/endpoint/schema/actions'; import { ManagementEmptyStateWrapper } from '../management_empty_state_wrapper'; import { useGetEndpointActionList } from '../../hooks'; -import { OUTPUT_MESSAGES, TABLE_COLUMN_NAMES, UX_MESSAGES } from './translations'; -import { MANAGEMENT_PAGE_SIZE_OPTIONS } from '../../common/constants'; +import { UX_MESSAGES } from './translations'; import { useTestIdGenerator } from '../../hooks/use_test_id_generator'; import { ActionsLogFilters } from './components/actions_log_filters'; -import { - getActionStatus, - getUiCommand, - getCommandKey, - useDateRangePicker, -} from './components/hooks'; -import { StatusBadge } from './components/status_badge'; +import { getCommandKey, useDateRangePicker } from './components/hooks'; import { useActionHistoryUrlParams } from './components/use_action_history_url_params'; import { useUrlPagination } from '../../hooks/use_url_pagination'; import { ManagementPageLoader } from '../management_page_loader'; import { ActionsLogEmptyState } from './components/actions_log_empty_state'; - -const emptyValue = getEmptyValue(); - -// Truncated usernames -const StyledFacetButton = euiStyled(EuiFacetButton)` - .euiText { - margin-top: 0.38rem; - overflow-y: visible !important; - } -`; - -const customDescriptionListCss = css` - &.euiDescriptionList { - > .euiDescriptionList__title { - color: ${(props) => props.theme.eui.euiColorDarkShade}; - font-size: ${(props) => props.theme.eui.euiFontSizeXS}; - margin-top: ${(props) => props.theme.eui.euiSizeS}; - } - - > .euiDescriptionList__description { - font-weight: ${(props) => props.theme.eui.euiFontWeightSemiBold}; - margin-top: ${(props) => props.theme.eui.euiSizeS}; - } - } -`; - -const StyledDescriptionList = euiStyled(EuiDescriptionList).attrs({ - compressed: true, - type: 'column', -})` - ${customDescriptionListCss} -`; - -// output section styles -const topSpacingCss = css` - ${(props) => `${props.theme.eui.euiCodeBlockPaddingModifiers.paddingMedium} 0`} -`; -const dashedBorderCss = css` - ${(props) => `1px dashed ${props.theme.eui.euiColorDisabled}`}; -`; -const StyledDescriptionListOutput = euiStyled(EuiDescriptionList).attrs({ compressed: true })` - ${customDescriptionListCss} - dd { - margin: ${topSpacingCss}; - padding: ${topSpacingCss}; - border-top: ${dashedBorderCss}; - border-bottom: ${dashedBorderCss}; - } -`; - -// code block styles -const StyledEuiCodeBlock = euiStyled(EuiCodeBlock).attrs({ - transparentBackground: true, - paddingSize: 'none', -})` - code { - color: ${(props) => props.theme.eui.euiColorDarkShade} !important; - } -`; +import { useResponseActionsLogTable } from './use_response_actions_log_table'; export const ResponseActionsLog = memo< Pick & { @@ -131,9 +48,6 @@ export const ResponseActionsLog = memo< } = useActionHistoryUrlParams(); const getTestId = useTestIdGenerator('response-actions-list'); - const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState<{ - [k: ActionListApiResponse['data'][number]['id']]: React.ReactNode; - }>({}); // Used to decide if display global loader or not (only the fist time tha page loads) const [isFirstAttempt, setIsFirstAttempt] = useState(true); @@ -183,6 +97,19 @@ export const ResponseActionsLog = memo< { retry: false } ); + // total actions + const totalItemCount = useMemo(() => actionList?.total ?? 0, [actionList]); + + // table columns and expanded row state + const { itemIdToExpandedRowMap, recordRangeLabel, responseActionListColumns, tablePagination } = + useResponseActionsLogTable({ + showHostNames, + pageIndex: isFlyout ? (queryParams.page || 1) - 1 : paginationFromUrlParams.page - 1, + pageSize: isFlyout ? queryParams.pageSize || 10 : paginationFromUrlParams.pageSize, + queryParams, + totalItemCount, + }); + // Hide page header when there is no actions index calling the setIsDataInResponse with false value. // Otherwise, it shows the page header calling the setIsDataInResponse with true value and it also keeps track // if the API request was done for the first time. @@ -248,310 +175,6 @@ export const ResponseActionsLog = memo< [setQueryParams] ); - // total actions - const totalItemCount = useMemo(() => actionList?.total ?? 0, [actionList]); - - // expanded tray contents - const toggleDetails = useCallback( - (item: ActionListApiResponse['data'][number]) => { - const itemIdToExpandedRowMapValues = { ...itemIdToExpandedRowMap }; - if (itemIdToExpandedRowMapValues[item.id]) { - delete itemIdToExpandedRowMapValues[item.id]; - } else { - const { - startedAt, - completedAt, - isCompleted, - wasSuccessful, - isExpired, - command: _command, - parameters, - } = item; - - const parametersList = parameters - ? Object.entries(parameters).map(([key, value]) => { - return `${key}:${value}`; - }) - : undefined; - - const command = getUiCommand(_command); - const dataList = [ - { - title: OUTPUT_MESSAGES.expandSection.placedAt, - description: `${startedAt}`, - }, - { - title: OUTPUT_MESSAGES.expandSection.startedAt, - description: `${startedAt}`, - }, - { - title: OUTPUT_MESSAGES.expandSection.completedAt, - description: `${completedAt ?? emptyValue}`, - }, - { - title: OUTPUT_MESSAGES.expandSection.input, - description: `${command}`, - }, - { - title: OUTPUT_MESSAGES.expandSection.parameters, - description: parametersList ? parametersList : emptyValue, - }, - ].map(({ title, description }) => { - return { - title: {title}, - description: {description}, - }; - }); - - const outputList = [ - { - title: ( - {`${OUTPUT_MESSAGES.expandSection.output}:`} - ), - description: ( - // codeblock for output - - {isExpired - ? OUTPUT_MESSAGES.hasExpired(command) - : isCompleted - ? wasSuccessful - ? OUTPUT_MESSAGES.wasSuccessful(command) - : OUTPUT_MESSAGES.hasFailed(command) - : OUTPUT_MESSAGES.isPending(command)} - - ), - }, - ]; - - itemIdToExpandedRowMapValues[item.id] = ( - <> - - - - - - - - - - ); - } - setItemIdToExpandedRowMap(itemIdToExpandedRowMapValues); - }, - [getTestId, itemIdToExpandedRowMap] - ); - // memoized callback for toggleDetails - const onClickCallback = useCallback( - (actionListDataItem: ActionListApiResponse['data'][number]) => () => - toggleDetails(actionListDataItem), - [toggleDetails] - ); - - // table column - const responseActionListColumns = useMemo(() => { - const columns = [ - { - field: 'startedAt', - name: TABLE_COLUMN_NAMES.time, - width: !showHostNames ? '21%' : '15%', - truncateText: true, - render: (startedAt: ActionListApiResponse['data'][number]['startedAt']) => { - return ( - - ); - }, - }, - { - field: 'command', - name: TABLE_COLUMN_NAMES.command, - width: !showHostNames ? '21%' : '10%', - truncateText: true, - render: (_command: ActionListApiResponse['data'][number]['command']) => { - const command = getUiCommand(_command); - return ( - - - {command} - - - ); - }, - }, - { - field: 'createdBy', - name: TABLE_COLUMN_NAMES.user, - width: !showHostNames ? '21%' : '14%', - truncateText: true, - render: (userId: ActionListApiResponse['data'][number]['createdBy']) => { - return ( - - } - > - - - {userId} - - - - ); - }, - }, - // conditional hostnames column - { - field: 'hosts', - name: TABLE_COLUMN_NAMES.hosts, - width: '20%', - truncateText: true, - render: (_hosts: ActionListApiResponse['data'][number]['hosts']) => { - const hosts = _hosts && Object.values(_hosts); - // join hostnames if the action is for multiple agents - // and skip empty strings for names if any - const _hostnames = hosts - .reduce((acc, host) => { - if (host.name.trim()) { - acc.push(host.name); - } - return acc; - }, []) - .join(', '); - - let hostnames = _hostnames; - if (!_hostnames) { - if (hosts.length > 1) { - // when action was for a single agent and no host name - hostnames = UX_MESSAGES.unenrolled.hosts; - } else if (hosts.length === 1) { - // when action was for a multiple agents - // and none of them have a host name - hostnames = UX_MESSAGES.unenrolled.host; - } - } - return ( - - - {hostnames} - - - ); - }, - }, - { - field: 'comment', - name: TABLE_COLUMN_NAMES.comments, - width: !showHostNames ? '21%' : '30%', - truncateText: true, - render: (comment: ActionListApiResponse['data'][number]['comment']) => { - return ( - - - {comment ?? emptyValue} - - - ); - }, - }, - { - field: 'status', - name: TABLE_COLUMN_NAMES.status, - width: !showHostNames ? '15%' : '10%', - render: (_status: ActionListApiResponse['data'][number]['status']) => { - const status = getActionStatus(_status); - - return ( - - - - ); - }, - }, - { - field: '', - align: RIGHT_ALIGNMENT as HorizontalAlignment, - width: '40px', - isExpander: true, - name: ( - - {UX_MESSAGES.screenReaderExpand} - - ), - render: (actionListDataItem: ActionListApiResponse['data'][number]) => { - return ( - - ); - }, - }, - ]; - // filter out the `hosts` column - // if showHostNames is FALSE - if (!showHostNames) { - return columns.filter((column) => column.field !== 'hosts'); - } - return columns; - }, [showHostNames, getTestId, itemIdToExpandedRowMap, onClickCallback]); - - // table pagination - const tablePagination = useMemo(() => { - const pageIndex = isFlyout ? (queryParams.page || 1) - 1 : paginationFromUrlParams.page - 1; - const pageSize = isFlyout ? queryParams.pageSize || 10 : paginationFromUrlParams.pageSize; - return { - // this controls the table UI page - // to match 0-based table paging - pageIndex, - pageSize, - totalItemCount, - pageSizeOptions: MANAGEMENT_PAGE_SIZE_OPTIONS as number[], - }; - }, [ - isFlyout, - paginationFromUrlParams.page, - paginationFromUrlParams.pageSize, - queryParams.page, - queryParams.pageSize, - totalItemCount, - ]); - // handle onChange const handleTableOnChange = useCallback( ({ page: _page }: CriteriaWithPagination) => { @@ -563,16 +186,12 @@ export const ResponseActionsLog = memo< page: index + 1, pageSize: size, }; - if (isFlyout) { - setQueryParams((prevState) => ({ - ...prevState, - ...pagingArgs, - })); - } else { - setQueryParams((prevState) => ({ - ...prevState, - ...pagingArgs, - })); + + setQueryParams((prevState) => ({ + ...prevState, + ...pagingArgs, + })); + if (!isFlyout) { setPaginationOnUrlParams({ ...pagingArgs, }); @@ -582,42 +201,6 @@ export const ResponseActionsLog = memo< [isFlyout, reFetchEndpointActionList, setQueryParams, setPaginationOnUrlParams] ); - // compute record ranges - const pagedResultsCount = useMemo(() => { - const page = queryParams.page ?? 1; - const perPage = queryParams?.pageSize ?? 10; - - const totalPages = Math.ceil(totalItemCount / perPage); - const fromCount = perPage * page - perPage + 1; - const toCount = - page === totalPages || totalPages === 1 ? totalItemCount : fromCount + perPage - 1; - return { fromCount, toCount }; - }, [queryParams.page, queryParams.pageSize, totalItemCount]); - - // create range label to display - const recordRangeLabel = useMemo( - () => ( - - - - {'-'} - - - ), - total: , - recordsLabel: {UX_MESSAGES.recordsLabel(totalItemCount)}, - }} - /> - - ), - [getTestId, pagedResultsCount.fromCount, pagedResultsCount.toCount, totalItemCount] - ); - if (error?.body?.statusCode === 404 && error?.body?.message === 'index_not_found_exception') { return ; } else if (isFetching && isFirstAttempt) { @@ -675,7 +258,7 @@ export const ResponseActionsLog = memo< columns={responseActionListColumns} itemId="id" itemIdToExpandedRowMap={itemIdToExpandedRowMap} - isExpandable={true} + isExpandable pagination={tablePagination} onChange={handleTableOnChange} loading={isFetching} diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/use_response_actions_log_table.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/use_response_actions_log_table.tsx new file mode 100644 index 0000000000000..e4dd30b468127 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/components/endpoint_response_actions_list/use_response_actions_log_table.tsx @@ -0,0 +1,441 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useCallback, useMemo, useState } from 'react'; +import type { HorizontalAlignment } from '@elastic/eui'; + +import { + EuiI18nNumber, + EuiAvatar, + EuiButtonIcon, + EuiCodeBlock, + EuiDescriptionList, + EuiFacetButton, + EuiFlexGroup, + EuiFlexItem, + RIGHT_ALIGNMENT, + EuiScreenReaderOnly, + EuiText, + EuiToolTip, +} from '@elastic/eui'; +import { css, euiStyled } from '@kbn/kibana-react-plugin/common'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import type { ActionListApiResponse } from '../../../../common/endpoint/types'; +import type { EndpointActionListRequestQuery } from '../../../../common/endpoint/schema/actions'; +import { FormattedDate } from '../../../common/components/formatted_date'; +import { OUTPUT_MESSAGES, TABLE_COLUMN_NAMES, UX_MESSAGES } from './translations'; +import { getActionStatus, getUiCommand } from './components/hooks'; +import { getEmptyValue } from '../../../common/components/empty_value'; +import { StatusBadge } from './components/status_badge'; +import { useTestIdGenerator } from '../../hooks/use_test_id_generator'; +import { MANAGEMENT_PAGE_SIZE_OPTIONS } from '../../common/constants'; + +const emptyValue = getEmptyValue(); + +// Truncated usernames +const StyledFacetButton = euiStyled(EuiFacetButton)` + .euiText { + margin-top: 0.38rem; + overflow-y: visible !important; + } +`; + +const customDescriptionListCss = css` + &.euiDescriptionList { + > .euiDescriptionList__title { + color: ${(props) => props.theme.eui.euiColorDarkShade}; + font-size: ${(props) => props.theme.eui.euiFontSizeXS}; + margin-top: ${(props) => props.theme.eui.euiSizeS}; + } + + > .euiDescriptionList__description { + font-weight: ${(props) => props.theme.eui.euiFontWeightSemiBold}; + margin-top: ${(props) => props.theme.eui.euiSizeS}; + } + } +`; + +const StyledDescriptionList = euiStyled(EuiDescriptionList).attrs({ + compressed: true, + type: 'column', +})` + ${customDescriptionListCss} +`; + +// output section styles +const topSpacingCss = css` + ${(props) => `${props.theme.eui.euiCodeBlockPaddingModifiers.paddingMedium} 0`} +`; +const dashedBorderCss = css` + ${(props) => `1px dashed ${props.theme.eui.euiColorDisabled}`}; +`; +const StyledDescriptionListOutput = euiStyled(EuiDescriptionList).attrs({ compressed: true })` + ${customDescriptionListCss} + dd { + margin: ${topSpacingCss}; + padding: ${topSpacingCss}; + border-top: ${dashedBorderCss}; + border-bottom: ${dashedBorderCss}; + } +`; + +// code block styles +const StyledEuiCodeBlock = euiStyled(EuiCodeBlock).attrs({ + transparentBackground: true, + paddingSize: 'none', +})` + code { + color: ${(props) => props.theme.eui.euiColorDarkShade} !important; + } +`; + +export const useResponseActionsLogTable = ({ + pageIndex, + pageSize, + queryParams, + showHostNames, + totalItemCount, +}: { + pageIndex: number; + pageSize: number; + queryParams: EndpointActionListRequestQuery; + showHostNames: boolean; + totalItemCount: number; +}) => { + const getTestId = useTestIdGenerator('response-actions-list'); + + const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState<{ + [k: ActionListApiResponse['data'][number]['id']]: React.ReactNode; + }>({}); + + // expanded tray contents + const toggleDetails = useCallback( + (item: ActionListApiResponse['data'][number]) => { + const itemIdToExpandedRowMapValues = { ...itemIdToExpandedRowMap }; + if (itemIdToExpandedRowMapValues[item.id]) { + delete itemIdToExpandedRowMapValues[item.id]; + } else { + const { + startedAt, + completedAt, + isCompleted, + wasSuccessful, + isExpired, + command: _command, + parameters, + } = item; + + const parametersList = parameters + ? Object.entries(parameters).map(([key, value]) => { + return `${key}:${value}`; + }) + : undefined; + + const command = getUiCommand(_command); + const dataList = [ + { + title: OUTPUT_MESSAGES.expandSection.placedAt, + description: `${startedAt}`, + }, + { + title: OUTPUT_MESSAGES.expandSection.startedAt, + description: `${startedAt}`, + }, + { + title: OUTPUT_MESSAGES.expandSection.completedAt, + description: `${completedAt ?? emptyValue}`, + }, + { + title: OUTPUT_MESSAGES.expandSection.input, + description: `${command}`, + }, + { + title: OUTPUT_MESSAGES.expandSection.parameters, + description: parametersList ? parametersList : emptyValue, + }, + ].map(({ title, description }) => { + return { + title: {title}, + description: {description}, + }; + }); + + const outputList = [ + { + title: ( + {`${OUTPUT_MESSAGES.expandSection.output}:`} + ), + description: ( + // codeblock for output + + {isExpired + ? OUTPUT_MESSAGES.hasExpired(command) + : isCompleted + ? wasSuccessful + ? OUTPUT_MESSAGES.wasSuccessful(command) + : OUTPUT_MESSAGES.hasFailed(command) + : OUTPUT_MESSAGES.isPending(command)} + + ), + }, + ]; + + itemIdToExpandedRowMapValues[item.id] = ( + <> + + + + + + + + + + ); + } + setItemIdToExpandedRowMap(itemIdToExpandedRowMapValues); + }, + [getTestId, itemIdToExpandedRowMap] + ); + // memoized callback for toggleDetails + const onClickCallback = useCallback( + (actionListDataItem: ActionListApiResponse['data'][number]) => () => + toggleDetails(actionListDataItem), + [toggleDetails] + ); + + const responseActionListColumns = useMemo(() => { + const columns = [ + { + field: 'startedAt', + name: TABLE_COLUMN_NAMES.time, + width: !showHostNames ? '21%' : '15%', + truncateText: true, + render: (startedAt: ActionListApiResponse['data'][number]['startedAt']) => { + return ( + + ); + }, + }, + { + field: 'command', + name: TABLE_COLUMN_NAMES.command, + width: !showHostNames ? '21%' : '10%', + truncateText: true, + render: (_command: ActionListApiResponse['data'][number]['command']) => { + const command = getUiCommand(_command); + return ( + + + {command} + + + ); + }, + }, + { + field: 'createdBy', + name: TABLE_COLUMN_NAMES.user, + width: !showHostNames ? '21%' : '14%', + truncateText: true, + render: (userId: ActionListApiResponse['data'][number]['createdBy']) => { + return ( + + } + > + + + {userId} + + + + ); + }, + }, + // conditional hostnames column + { + field: 'hosts', + name: TABLE_COLUMN_NAMES.hosts, + width: '20%', + truncateText: true, + render: (_hosts: ActionListApiResponse['data'][number]['hosts']) => { + const hosts = _hosts && Object.values(_hosts); + // join hostnames if the action is for multiple agents + // and skip empty strings for names if any + const _hostnames = hosts + .reduce((acc, host) => { + if (host.name.trim()) { + acc.push(host.name); + } + return acc; + }, []) + .join(', '); + + let hostnames = _hostnames; + if (!_hostnames) { + if (hosts.length > 1) { + // when action was for a single agent and no host name + hostnames = UX_MESSAGES.unenrolled.hosts; + } else if (hosts.length === 1) { + // when action was for a multiple agents + // and none of them have a host name + hostnames = UX_MESSAGES.unenrolled.host; + } + } + return ( + + + {hostnames} + + + ); + }, + }, + { + field: 'comment', + name: TABLE_COLUMN_NAMES.comments, + width: !showHostNames ? '21%' : '30%', + truncateText: true, + render: (comment: ActionListApiResponse['data'][number]['comment']) => { + return ( + + + {comment ?? emptyValue} + + + ); + }, + }, + { + field: 'status', + name: TABLE_COLUMN_NAMES.status, + width: !showHostNames ? '15%' : '10%', + render: (_status: ActionListApiResponse['data'][number]['status']) => { + const status = getActionStatus(_status); + + return ( + + + + ); + }, + }, + { + field: '', + align: RIGHT_ALIGNMENT as HorizontalAlignment, + width: '40px', + isExpander: true, + name: ( + + {UX_MESSAGES.screenReaderExpand} + + ), + render: (actionListDataItem: ActionListApiResponse['data'][number]) => { + return ( + + ); + }, + }, + ]; + // filter out the `hosts` column + // if showHostNames is FALSE + if (!showHostNames) { + return columns.filter((column) => column.field !== 'hosts'); + } + return columns; + }, [showHostNames, getTestId, itemIdToExpandedRowMap, onClickCallback]); + + // table pagination + const tablePagination = useMemo(() => { + return { + pageIndex, + pageSize, + totalItemCount, + pageSizeOptions: MANAGEMENT_PAGE_SIZE_OPTIONS as number[], + }; + }, [pageIndex, pageSize, totalItemCount]); + + // compute record ranges + const pagedResultsCount = useMemo(() => { + const page = queryParams.page ?? 1; + const perPage = queryParams?.pageSize ?? 10; + + const totalPages = Math.ceil(totalItemCount / perPage); + const fromCount = perPage * page - perPage + 1; + const toCount = + page === totalPages || totalPages === 1 ? totalItemCount : fromCount + perPage - 1; + return { fromCount, toCount }; + }, [queryParams.page, queryParams.pageSize, totalItemCount]); + + // create range label to display + const recordRangeLabel = useMemo( + () => ( + + + + {'-'} + + + ), + total: , + recordsLabel: {UX_MESSAGES.recordsLabel(totalItemCount)}, + }} + /> + + ), + [getTestId, pagedResultsCount.fromCount, pagedResultsCount.toCount, totalItemCount] + ); + + return { itemIdToExpandedRowMap, responseActionListColumns, recordRangeLabel, tablePagination }; +}; diff --git a/x-pack/plugins/security_solution/public/management/components/page_overlay/page_overlay.tsx b/x-pack/plugins/security_solution/public/management/components/page_overlay/page_overlay.tsx index b5c7629b76aa6..2d3a9c9cb7f07 100644 --- a/x-pack/plugins/security_solution/public/management/components/page_overlay/page_overlay.tsx +++ b/x-pack/plugins/security_solution/public/management/components/page_overlay/page_overlay.tsx @@ -13,6 +13,7 @@ import classnames from 'classnames'; import { useLocation } from 'react-router-dom'; import type { EuiPortalProps } from '@elastic/eui/src/components/portal/portal'; import type { EuiTheme } from '@kbn/kibana-react-plugin/common'; +import { useIsMounted } from '@kbn/securitysolution-hook-utils'; import { useHasFullScreenContent } from '../../../common/containers/use_full_screen'; import { FULL_SCREEN_CONTENT_OVERRIDES_CSS_STYLESHEET, @@ -22,7 +23,6 @@ import { SELECTOR_TIMELINE_IS_VISIBLE_CSS_CLASS_NAME, TIMELINE_EUI_THEME_ZINDEX_LEVEL, } from '../../../timelines/components/timeline/styles'; -import { useIsMounted } from '../../hooks/use_is_mounted'; const OverlayRootContainer = styled.div` border: none; @@ -246,7 +246,7 @@ export const PageOverlay = memo( // Capture the URL `pathname` that the overlay was opened for useEffect(() => { - if (isMounted) { + if (isMounted()) { setOpenedOnPathName((prevState) => { if (isHidden) { return null; @@ -270,7 +270,7 @@ export const PageOverlay = memo( // If `hideOnUrlPathNameChange` is true, then determine if the pathname changed and if so, call `onHide()` useEffect(() => { if ( - isMounted && + isMounted() && onHide && hideOnUrlPathnameChange && !isHidden && @@ -283,7 +283,7 @@ export const PageOverlay = memo( // Handle adding class names to the `document.body` DOM element useEffect(() => { - if (isMounted) { + if (isMounted()) { if (isHidden) { unSetDocumentBodyOverlayIsVisible(); unSetDocumentBodyLock(); diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoints_list.test.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoints_list.test.ts index 0804bef55b3e7..cdb1041cda7ed 100644 --- a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoints_list.test.ts +++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_endpoints_list.test.ts @@ -11,6 +11,8 @@ import { useGetEndpointsList } from './use_get_endpoints_list'; import { HOST_METADATA_LIST_ROUTE } from '../../../../common/endpoint/constants'; import { useQuery as _useQuery } from '@tanstack/react-query'; import { endpointMetadataHttpMocks } from '../../pages/endpoint_hosts/mocks'; +import { EndpointStatus, HostStatus } from '../../../../common/endpoint/types'; +import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; const useQueryMock = _useQuery as jest.Mock; @@ -107,4 +109,127 @@ describe('useGetEndpointsList hook', () => { }) ); }); + + it('should also list inactive agents', async () => { + const getApiResponse = apiMocks.responseProvider.metadataList.getMockImplementation(); + + // set a few of the agents as inactive/unenrolled + apiMocks.responseProvider.metadataList.mockImplementation(() => { + if (getApiResponse) { + return { + ...getApiResponse(), + data: getApiResponse().data.map((item, i) => { + const isInactiveIndex = [0, 1, 3].includes(i); + return { + ...item, + host_status: isInactiveIndex ? HostStatus.INACTIVE : item.host_status, + metadata: { + ...item.metadata, + host: { + ...item.metadata.host, + hostname: isInactiveIndex + ? `${item.metadata.host.hostname}-inactive` + : item.metadata.host.hostname, + }, + Endpoint: { + ...item.metadata.Endpoint, + status: isInactiveIndex + ? EndpointStatus.unenrolled + : item.metadata.Endpoint.status, + }, + }, + }; + }), + }; + } + throw new Error('some error'); + }); + + // verify useGetEndpointsList hook returns the same inactive agents + const res = await renderReactQueryHook(() => useGetEndpointsList({ searchString: 'inactive' })); + expect( + res.data?.map((host) => host.name.split('-')[2]).filter((name) => name === 'inactive').length + ).toEqual(3); + }); + + it('should only list 50 agents when more than 50 in the metadata list API', async () => { + const getApiResponse = apiMocks.responseProvider.metadataList.getMockImplementation(); + + apiMocks.responseProvider.metadataList.mockImplementation(() => { + if (getApiResponse) { + const generator = new EndpointDocGenerator('seed'); + const total = 60; + const data = Array.from({ length: total }, () => { + const endpoint = { + metadata: generator.generateHostMetadata(), + host_status: HostStatus.UNHEALTHY, + }; + + generator.updateCommonInfo(); + + return endpoint; + }); + + return { + ...getApiResponse(), + data, + page: 0, + // this page size is not used by the hook (it uses the default of 50) + // this is only for the test + pageSize: 80, + total, + }; + } + throw new Error('some error'); + }); + + // verify useGetEndpointsList hook returns all 50 agents in the list + const res = await renderReactQueryHook(() => useGetEndpointsList({ searchString: '' })); + expect(res.data?.length).toEqual(50); + }); + + it('should only list 10 more agents when 50 or more agents are already selected', async () => { + const getApiResponse = apiMocks.responseProvider.metadataList.getMockImplementation(); + + apiMocks.responseProvider.metadataList.mockImplementation(() => { + if (getApiResponse) { + const generator = new EndpointDocGenerator('seed'); + const total = 61; + const data = Array.from({ length: total }, () => { + const endpoint = { + metadata: generator.generateHostMetadata(), + host_status: HostStatus.UNHEALTHY, + }; + + generator.updateCommonInfo(); + + return endpoint; + }); + + return { + ...getApiResponse(), + data, + page: 0, + // since we're mocking that all 50 agents are selected + // page size is set to max allowed + pageSize: 10000, + total, + }; + } + throw new Error('some error'); + }); + + // get the first 50 agents to select + const agentIdsToSelect = apiMocks.responseProvider + .metadataList() + .data.map((d) => d.metadata.agent.id) + .slice(0, 50); + + // call useGetEndpointsList with all 50 agents selected + const res = await renderReactQueryHook(() => + useGetEndpointsList({ searchString: '', selectedAgentIds: agentIdsToSelect }) + ); + // verify useGetEndpointsList hook returns 60 agents + expect(res.data?.length).toEqual(60); + }); }); diff --git a/x-pack/plugins/security_solution/public/management/hooks/use_is_mounted.ts b/x-pack/plugins/security_solution/public/management/hooks/use_is_mounted.ts deleted file mode 100644 index 0c5a79b2ca2fc..0000000000000 --- a/x-pack/plugins/security_solution/public/management/hooks/use_is_mounted.ts +++ /dev/null @@ -1,26 +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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useEffect, useState } from 'react'; - -/** - * Track when a component is mounted/unmounted. Good for use in async processing that may update - * a component's internal state. - */ -export const useIsMounted = (): boolean => { - const [isMounted, setIsMounted] = useState(false); - - useEffect(() => { - setIsMounted(true); - - return () => { - setIsMounted(false); - }; - }, []); - - return isMounted; -}; diff --git a/x-pack/plugins/security_solution/public/management/components/mocks.tsx b/x-pack/plugins/security_solution/public/management/mocks/utils.ts similarity index 93% rename from x-pack/plugins/security_solution/public/management/components/mocks.tsx rename to x-pack/plugins/security_solution/public/management/mocks/utils.ts index 45c12df818fd8..946d2d50b05d2 100644 --- a/x-pack/plugins/security_solution/public/management/components/mocks.tsx +++ b/x-pack/plugins/security_solution/public/management/mocks/utils.ts @@ -4,7 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -interface DeferredInterface { + +export interface DeferredInterface { promise: Promise; resolve: (data: T) => void; reject: (e: Error) => void; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/actions_menu.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/actions_menu.test.tsx index 6fc8a99ee7320..35fe96d94d91f 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/actions_menu.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/actions_menu.test.tsx @@ -14,6 +14,9 @@ import { act } from '@testing-library/react'; import { endpointPageHttpMock } from '../../../mocks'; import { fireEvent } from '@testing-library/dom'; import { licenseService } from '../../../../../../common/hooks/use_license'; +import { useUserPrivileges } from '../../../../../../common/components/user_privileges'; +import { initialUserPrivilegesState } from '../../../../../../common/components/user_privileges/user_privileges_context'; +import { getUserPrivilegesMockDefaultValue } from '../../../../../../common/components/user_privileges/__mocks__'; jest.mock('../../../../../../common/lib/kibana/kibana_react', () => { const originalModule = jest.requireActual('../../../../../../common/lib/kibana/kibana_react'); @@ -31,6 +34,7 @@ jest.mock('../../../../../../common/lib/kibana/kibana_react', () => { }; }); jest.mock('../../../../../../common/hooks/use_license'); +jest.mock('../../../../../../common/components/user_privileges'); describe('When using the Endpoint Details Actions Menu', () => { let render: () => Promise>; @@ -59,6 +63,8 @@ describe('When using the Endpoint Details Actions Menu', () => { waitForAction = mockedContext.middlewareSpy.waitForAction; httpMocks = endpointPageHttpMock(mockedContext.coreStart.http); + (useUserPrivileges as jest.Mock).mockReturnValue(getUserPrivilegesMockDefaultValue()); + act(() => { mockedContext.history.push( '/administration/endpoints?selected_endpoint=5fe11314-678c-413e-87a2-b4a3461878ee' @@ -80,6 +86,10 @@ describe('When using the Endpoint Details Actions Menu', () => { }; }); + afterEach(() => { + (useUserPrivileges as jest.Mock).mockClear(); + }); + it('should not show the response actions history link', async () => { await render(); expect(renderResult.queryByTestId('actionsLink')).toBeNull(); @@ -121,18 +131,38 @@ describe('When using the Endpoint Details Actions Menu', () => { describe('and endpoint host is isolated', () => { beforeEach(() => setEndpointMetadataResponse(true)); - it('should display Unisolate action', async () => { - await render(); - expect(renderResult.getByTestId('unIsolateLink')).not.toBeNull(); + describe('and user has unisolate privilege', () => { + it('should display Unisolate action', async () => { + await render(); + expect(renderResult.getByTestId('unIsolateLink')).not.toBeNull(); + }); + + it('should navigate via router when unisolate is clicked', async () => { + await render(); + act(() => { + fireEvent.click(renderResult.getByTestId('unIsolateLink')); + }); + + expect(coreStart.application.navigateToApp).toHaveBeenCalled(); + }); }); - it('should navigate via router when unisolate is clicked', async () => { - await render(); - act(() => { - fireEvent.click(renderResult.getByTestId('unIsolateLink')); + describe('and user does not have unisolate privilege', () => { + beforeEach(() => { + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...initialUserPrivilegesState(), + endpointPrivileges: { + ...initialUserPrivilegesState().endpointPrivileges, + canIsolateHost: false, + canUnIsolateHost: false, + }, + }); }); - expect(coreStart.application.navigateToApp).toHaveBeenCalled(); + it('should not display unisolate action', async () => { + await render(); + expect(renderResult.queryByTestId('unIsolateLink')).toBeNull(); + }); }); }); @@ -143,12 +173,6 @@ describe('When using the Endpoint Details Actions Menu', () => { afterEach(() => licenseServiceMock.isPlatinumPlus.mockReturnValue(true)); - it('should not show the `isolate` action', async () => { - setEndpointMetadataResponse(); - await render(); - expect(renderResult.queryByTestId('isolateLink')).toBeNull(); - }); - it('should still show `unisolate` action for endpoints that are currently isolated', async () => { setEndpointMetadataResponse(true); await render(); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx index 40fd81c4ab587..9a9c884a3979a 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx @@ -19,7 +19,6 @@ import { agentPolicies, uiQueryParams } from '../../store/selectors'; import { useAppUrl } from '../../../../../common/lib/kibana/hooks'; import type { ContextMenuItemNavByRouterProps } from '../../../../components/context_menu_with_router_support/context_menu_item_nav_by_router'; import { isEndpointHostIsolated } from '../../../../../common/utils/validators'; -import { useLicense } from '../../../../../common/hooks/use_license'; import { isIsolationSupported } from '../../../../../../common/endpoint/service/host_isolation/utils'; import { useDoesEndpointSupportResponder } from '../../../../../common/hooks/endpoint/use_does_endpoint_support_responder'; import { UPGRADE_ENDPOINT_FOR_RESPONDER } from '../../../../../common/translations'; @@ -36,7 +35,6 @@ export const useEndpointActionItems = ( endpointMetadata: MaybeImmutable | undefined, options?: Options ): ContextMenuItemNavByRouterProps[] => { - const isPlatinumPlus = useLicense().isPlatinumPlus(); const { getAppUrl } = useAppUrl(); const fleetAgentPolicies = useEndpointSelector(agentPolicies); const allCurrentUrlParams = useEndpointSelector(uiQueryParams); @@ -44,7 +42,8 @@ export const useEndpointActionItems = ( const isResponseActionsConsoleEnabled = useIsExperimentalFeatureEnabled( 'responseActionsConsoleEnabled' ); - const canAccessResponseConsole = useUserPrivileges().endpointPrivileges.canAccessResponseConsole; + const { canAccessResponseConsole, canIsolateHost, canUnIsolateHost } = + useUserPrivileges().endpointPrivileges; const isResponderCapabilitiesEnabled = useDoesEndpointSupportResponder(endpointMetadata); return useMemo(() => { @@ -82,8 +81,8 @@ export const useEndpointActionItems = ( const isolationActions = []; - if (isIsolated) { - // Un-isolate is always available to users regardless of license level + if (isIsolated && canUnIsolateHost) { + // Un-isolate is available to users regardless of license level if they have unisolate permissions isolationActions.push({ 'data-test-subj': 'unIsolateLink', icon: 'lockOpen', @@ -100,7 +99,7 @@ export const useEndpointActionItems = ( /> ), }); - } else if (isPlatinumPlus && isolationSupported) { + } else if (isolationSupported && canIsolateHost) { // For Platinum++ licenses, users also have ability to isolate isolationActions.push({ 'data-test-subj': 'isolateLink', @@ -260,10 +259,11 @@ export const useEndpointActionItems = ( endpointMetadata, fleetAgentPolicies, getAppUrl, - isPlatinumPlus, isResponseActionsConsoleEnabled, showEndpointResponseActionsConsole, options?.isEndpointList, isResponderCapabilitiesEnabled, + canIsolateHost, + canUnIsolateHost, ]); }; diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index b85ad2cc7f6a5..7d8d625d97e39 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -1007,6 +1007,7 @@ describe('when on the endpoint list page', () => { let agentId: string; let agentPolicyId: string; let renderResult: ReturnType; + let endpointActionsButton: HTMLElement; // 2nd endpoint only has isolation capabilities const mockEndpointListApi = () => { @@ -1081,13 +1082,7 @@ describe('when on the endpoint list page', () => { beforeEach(async () => { mockEndpointListApi(); - (useUserPrivileges as jest.Mock).mockReturnValue({ - ...mockInitialUserPrivilegesState(), - endpointPrivileges: { - ...mockInitialUserPrivilegesState().endpointPrivileges, - canAccessResponseConsole: true, - }, - }); + (useUserPrivileges as jest.Mock).mockReturnValue(getUserPrivilegesMockDefaultValue()); reactTestingLibrary.act(() => { history.push(`${MANAGEMENT_PATH}/endpoints`); @@ -1097,9 +1092,7 @@ describe('when on the endpoint list page', () => { await middlewareSpy.waitForAction('serverReturnedEndpointList'); await middlewareSpy.waitForAction('serverReturnedEndpointAgentPolicies'); - const endpointActionsButton = ( - await renderResult.findAllByTestId('endpointTableRowActions') - )[0]; + endpointActionsButton = (await renderResult.findAllByTestId('endpointTableRowActions'))[0]; reactTestingLibrary.act(() => { reactTestingLibrary.fireEvent.click(endpointActionsButton); @@ -1108,7 +1101,6 @@ describe('when on the endpoint list page', () => { afterEach(() => { jest.clearAllMocks(); - (useUserPrivileges as jest.Mock).mockReturnValue(getUserPrivilegesMockDefaultValue()); }); it('shows the Responder option when all 3 processes capabilities are present in the endpoint', async () => { @@ -1141,6 +1133,24 @@ describe('when on the endpoint list page', () => { ); }); + it('hides isolate host option if canIsolateHost is false', () => { + (useUserPrivileges as jest.Mock).mockReturnValue({ + ...mockInitialUserPrivilegesState(), + endpointPrivileges: { + ...mockInitialUserPrivilegesState().endpointPrivileges, + canIsolateHost: false, + }, + }); + reactTestingLibrary.act(() => { + reactTestingLibrary.fireEvent.click(endpointActionsButton); + }); + reactTestingLibrary.act(() => { + reactTestingLibrary.fireEvent.click(endpointActionsButton); + }); + const isolateLink = screen.queryByTestId('isolateLink'); + expect(isolateLink).toBeNull(); + }); + it('navigates to the Security Solution Host Details page', async () => { const hostLink = await renderResult.findByTestId('hostLink'); expect(hostLink.getAttribute('href')).toEqual( diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.test.tsx index 37f04ff804c1d..b8f7a8c19fbcd 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/artifacts/delete_modal/policy_artifacts_delete_modal.test.tsx @@ -20,7 +20,7 @@ import { PolicyArtifactsDeleteModal } from './policy_artifacts_delete_modal'; import { exceptionsListAllHttpMocks } from '../../../../../mocks/exceptions_list_http_mocks'; import { ExceptionsListApiClient } from '../../../../../services/exceptions_list/exceptions_list_api_client'; import { POLICY_ARTIFACT_DELETE_MODAL_LABELS } from './translations'; -import { getDeferred } from '../../../../../components/mocks'; +import { getDeferred } from '../../../../../mocks/utils'; const listType: Array = [ 'endpoint_events', diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/endpoint_policy_create_extension.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/endpoint_policy_create_extension.tsx index 9a4dc273740e5..d1223ff14826e 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/endpoint_policy_create_extension.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/endpoint_policy_create_extension.tsx @@ -28,7 +28,7 @@ import { EDR_ESSENTIAL, ENDPOINT, INTERACTIVE_ONLY, - PREVENT_MALICIOUS_BEHAVIOUR, + PREVENT_MALICIOUS_BEHAVIOR, } from './translations'; const PREFIX = 'endpoint_policy_create_extension'; @@ -75,12 +75,12 @@ export const EndpointPolicyCreateExtension = memo('NGAV'); const [behaviorProtectionChecked, setBehaviorProtectionChecked] = useState(false); - const [selectedCloudEvent, setSelectedCloudEvent] = useState('INTERACTIVE_ONLY'); + const [selectedCloudEvent, setSelectedCloudEvent] = useState('ALL_EVENTS'); const [selectedEnvironment, setSelectedEnvironment] = useState('endpoint'); const initialRender = useRef(true); - // Fleet will initialize the create form with a default name for the integratin policy, however, - // for endpoint security, we want the user to explicitely type in a name, so we blank it out + // Fleet will initialize the create form with a default name for the integrating policy, however, + // for endpoint security, we want the user to explicitly type in a name, so we blank it out // only during 1st component render (thus why the eslint disabled rule below). // Default values for config are endpoint + NGAV useEffect(() => { @@ -113,7 +113,7 @@ export const EndpointPolicyCreateExtension = memo { - // Skip trigerring this onChange on the initial render + // Skip triggering this onChange on the initial render if (initialRender.current) { initialRender.current = false; } else { @@ -217,7 +217,7 @@ export const EndpointPolicyCreateExtension = memo ), @@ -251,7 +251,7 @@ export const EndpointPolicyCreateExtension = memo @@ -265,7 +265,7 @@ export const EndpointPolicyCreateExtension = memo @@ -279,7 +279,7 @@ export const EndpointPolicyCreateExtension = memo @@ -305,13 +305,13 @@ export const EndpointPolicyCreateExtension = memo } > - + } > - + {isPlatinumPlus && ( <> @@ -350,8 +350,8 @@ export const EndpointPolicyCreateExtension = memo diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/translations.ts b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/translations.ts index b50835b36995b..66688371b68de 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/translations.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/ingest_manager_integration/endpoint_policy_create_extension/translations.ts @@ -30,13 +30,13 @@ export const EDR_COMPLETE = i18n.translate( export const ENDPOINT = i18n.translate( 'xpack.securitySolution.createPackagePolicy.stepConfigure.endpointDropdownOption', { - defaultMessage: 'Endpoint', + defaultMessage: 'Traditional Endpoints (desktops, laptops, virtual machines)', } ); export const CLOUD_SECURITY = i18n.translate( - 'xpack.securitySolution.createPackagePolicy.stepConfigure.cloudSecurityDropdownOption', + 'xpack.securitySolution.createPackagePolicy.stepConfigure.cloudDropdownOption', { - defaultMessage: 'Cloud Security', + defaultMessage: 'Cloud Workloads (Linux servers or Kubernetes environments)', } ); export const INTERACTIVE_ONLY = i18n.translate( @@ -51,15 +51,9 @@ export const ALL_EVENTS = i18n.translate( defaultMessage: 'All events', } ); -export const PREVENT_MALWARE = i18n.translate( - 'xpack.securitySolution.createPackagePolicy.stepConfigure.cloudEventFiltersPreventionMalware', +export const PREVENT_MALICIOUS_BEHAVIOR = i18n.translate( + 'xpack.securitySolution.createPackagePolicy.stepConfigure.cloudEventFiltersPreventionMaliciousBehavior', { - defaultMessage: 'Prevent Malware', - } -); -export const PREVENT_MALICIOUS_BEHAVIOUR = i18n.translate( - 'xpack.securitySolution.createPackagePolicy.stepConfigure.cloudEventFiltersPreventionMaliciousBehaviour', - { - defaultMessage: 'Prevent Malicious Behaviour', + defaultMessage: 'Prevent Malicious Behavior', } ); diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx index d8f087a7cc884..c1a52364a76f8 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/header/index.tsx @@ -28,7 +28,7 @@ import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml import { useQueryInspector } from '../../../../common/components/page/manage_query'; const StyledEuiTitle = styled(EuiTitle)` - color: ${({ theme: { eui } }) => eui.euiColorVis9}; + color: ${({ theme: { eui } }) => eui.euiColorDanger}; `; const HOST_RISK_QUERY_ID = 'hostRiskScoreKpiQuery'; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/list_handler.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/list_handler.test.ts new file mode 100644 index 0000000000000..51326c8adbd12 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/list_handler.test.ts @@ -0,0 +1,169 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import type { KibanaResponseFactory, RequestHandler, RouteConfig } from '@kbn/core/server'; +import { + coreMock, + elasticsearchServiceMock, + httpServerMock, + httpServiceMock, + loggingSystemMock, + savedObjectsClientMock, +} from '@kbn/core/server/mocks'; +import type { EndpointActionListRequestQuery } from '../../../../common/endpoint/schema/actions'; +import { ENDPOINTS_ACTION_LIST_ROUTE } from '../../../../common/endpoint/constants'; +import { parseExperimentalConfigValue } from '../../../../common/experimental_features'; +import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__'; +import { EndpointAppContextService } from '../../endpoint_app_context_services'; +import { + createMockEndpointAppContextServiceSetupContract, + createMockEndpointAppContextServiceStartContract, + createRouteHandlerContext, +} from '../../mocks'; +import { registerActionListRoutes } from './list'; +import type { SecuritySolutionRequestHandlerContext } from '../../../types'; +import { doesLogsEndpointActionsIndexExist } from '../../utils'; +import { getActionList, getActionListByStatus } from '../../services'; + +jest.mock('../../utils'); +const mockDoesLogsEndpointActionsIndexExist = doesLogsEndpointActionsIndexExist as jest.Mock; + +jest.mock('../../services'); +const mockGetActionList = getActionList as jest.Mock; +const mockGetActionListByStatus = getActionListByStatus as jest.Mock; + +describe(' Action List Handler', () => { + let endpointAppContextService: EndpointAppContextService; + let mockResponse: jest.Mocked; + + let actionListHandler: ( + query?: EndpointActionListRequestQuery + ) => Promise>; + + beforeEach(() => { + const esClientMock = elasticsearchServiceMock.createScopedClusterClient(); + const routerMock = httpServiceMock.createRouter(); + endpointAppContextService = new EndpointAppContextService(); + endpointAppContextService.setup(createMockEndpointAppContextServiceSetupContract()); + endpointAppContextService.start(createMockEndpointAppContextServiceStartContract()); + mockDoesLogsEndpointActionsIndexExist.mockResolvedValue(true); + + registerActionListRoutes(routerMock, { + logFactory: loggingSystemMock.create(), + service: endpointAppContextService, + config: () => Promise.resolve(createMockConfig()), + experimentalFeatures: parseExperimentalConfigValue(createMockConfig().enableExperimental), + }); + + actionListHandler = async ( + query?: EndpointActionListRequestQuery + ): Promise> => { + const req = httpServerMock.createKibanaRequest({ + query, + }); + mockResponse = httpServerMock.createResponseFactory(); + const [, routeHandler]: [ + RouteConfig, + RequestHandler< + unknown, + EndpointActionListRequestQuery, + unknown, + SecuritySolutionRequestHandlerContext + > + ] = routerMock.get.mock.calls.find(([{ path }]) => + path.startsWith(ENDPOINTS_ACTION_LIST_ROUTE) + )!; + await routeHandler( + coreMock.createCustomRequestHandlerContext( + createRouteHandlerContext(esClientMock, savedObjectsClientMock.create()) + ) as SecuritySolutionRequestHandlerContext, + req, + mockResponse + ); + + return mockResponse; + }; + }); + + afterEach(() => { + endpointAppContextService.stop(); + }); + + describe('Internals', () => { + it('should return `notFound` when actions index does not exist', async () => { + mockDoesLogsEndpointActionsIndexExist.mockResolvedValue(false); + await actionListHandler({ pageSize: 10, page: 1 }); + expect(mockResponse.notFound).toHaveBeenCalledWith({ + body: 'index_not_found_exception', + }); + }); + + it('should return `ok` when actions index exists', async () => { + await actionListHandler({ pageSize: 10, page: 1 }); + expect(mockResponse.ok).toHaveBeenCalled(); + }); + + it('should call `getActionListByStatus` when statuses filter values are provided', async () => { + await actionListHandler({ pageSize: 10, page: 1, statuses: ['failed', 'pending'] }); + expect(mockGetActionListByStatus).toBeCalledWith( + expect.objectContaining({ statuses: ['failed', 'pending'] }) + ); + }); + + it('should correctly format the request when calling `getActionListByStatus`', async () => { + await actionListHandler({ + agentIds: 'agentX', + commands: 'running-processes', + statuses: 'failed', + userIds: 'userX', + }); + expect(mockGetActionListByStatus).toBeCalledWith( + expect.objectContaining({ + elasticAgentIds: ['agentX'], + commands: ['running-processes'], + statuses: ['failed'], + userIds: ['userX'], + }) + ); + }); + + it('should call `getActionList` when statuses filter values are not provided', async () => { + await actionListHandler({ + pageSize: 10, + page: 1, + commands: ['isolate', 'kill-process'], + userIds: ['userX', 'userY'], + }); + expect(mockGetActionList).toBeCalledWith( + expect.objectContaining({ + commands: ['isolate', 'kill-process'], + userIds: ['userX', 'userY'], + }) + ); + }); + + it('should correctly format the request when calling `getActionList`', async () => { + await actionListHandler({ + page: 1, + pageSize: 10, + agentIds: 'agentX', + commands: 'isolate', + userIds: 'userX', + }); + + expect(mockGetActionList).toHaveBeenCalledWith( + expect.objectContaining({ + commands: ['isolate'], + elasticAgentIds: ['agentX'], + userIds: ['userX'], + }) + ); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts index 88d0617c18382..d03117225279a 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts @@ -285,9 +285,7 @@ describe('test endpoint routes', () => { bool: { must_not: { bool: { - should: [ - { match: { 'united.agent.upgrade_status': 'completed' } }, - ], + should: [{ exists: { field: 'united.agent.upgraded_at' } }], minimum_should_match: 1, }, }, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.fixtures.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.fixtures.ts index edc5d681b138e..fb01bd994f0d9 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.fixtures.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.fixtures.ts @@ -71,11 +71,7 @@ export const expectedCompleteUnitedIndexQuery = { must_not: { bool: { should: [ - { - match: { - 'united.agent.upgrade_status': 'completed', - }, - }, + { exists: { field: 'united.agent.upgraded_at' } }, ], minimum_should_match: 1, }, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/agent_status.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/agent_status.test.ts index 875f3927ee34c..6a7febe393db3 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/agent_status.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/agent_status.test.ts @@ -93,7 +93,7 @@ describe('test filtering endpoint hosts by agent status', () => { const status = ['healthy']; const kuery = buildStatusesKuery(status); expect(kuery).toMatchInlineSnapshot( - `"(united.agent.last_checkin:* AND not ((united.agent.last_checkin < now-300s) or ((((united.agent.upgrade_started_at:*) and not (united.agent.upgrade_status:completed)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*) or (not united.agent.policy_revision_idx:*)) AND not ((united.agent.last_checkin < now-300s) or ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not ((united.agent.last_checkin < now-300s) or (united.agent.unenrollment_started_at:*))))) or ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not ((united.agent.last_checkin < now-300s) or (united.agent.unenrollment_started_at:*)))))"` + `"(united.agent.last_checkin:* AND not ((united.agent.last_checkin < now-300s) or ((((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*) or (not united.agent.policy_revision_idx:*)) AND not ((united.agent.last_checkin < now-300s) or ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not ((united.agent.last_checkin < now-300s) or (united.agent.unenrollment_started_at:*))))) or ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not ((united.agent.last_checkin < now-300s) or (united.agent.unenrollment_started_at:*)))))"` ); }); @@ -115,7 +115,7 @@ describe('test filtering endpoint hosts by agent status', () => { const status = ['updating']; const kuery = buildStatusesKuery(status); expect(kuery).toMatchInlineSnapshot( - `"((((united.agent.upgrade_started_at:*) and not (united.agent.upgrade_status:completed)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*) or (not united.agent.policy_revision_idx:*)) AND not ((united.agent.last_checkin < now-300s) or ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not ((united.agent.last_checkin < now-300s) or (united.agent.unenrollment_started_at:*)))))"` + `"((((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*) or (not united.agent.policy_revision_idx:*)) AND not ((united.agent.last_checkin < now-300s) or ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not ((united.agent.last_checkin < now-300s) or (united.agent.unenrollment_started_at:*)))))"` ); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/client_for_executors/client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/client_for_executors/client.ts index 4116848b1ffcf..3c712847851fd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/client_for_executors/client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/client_for_executors/client.ts @@ -222,6 +222,7 @@ const normalizeStatusChangeArgs = (args: StatusChangeArgs): NormalizedStatusChan ? { total_search_duration_ms: normalizeDurations(metrics.searchDurations), total_indexing_duration_ms: normalizeDurations(metrics.indexingDurations), + total_enrichment_duration_ms: normalizeDurations(metrics.enrichmentDurations), execution_gap_duration_s: normalizeGap(metrics.executionGap), } : undefined, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/client_for_executors/client_interface.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/client_for_executors/client_interface.ts index 22392e699fcea..5e48a43e949c3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/client_for_executors/client_interface.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/client_for_executors/client_interface.ts @@ -115,5 +115,6 @@ export interface StatusChangeArgs { export interface MetricsArgs { searchDurations?: string[]; indexingDurations?: string[]; + enrichmentDurations?: string[]; executionGap?: Duration; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/execution_saved_object/saved_objects_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/execution_saved_object/saved_objects_type.ts index ac3b28e87e0d9..1e0a2e74cadcd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/execution_saved_object/saved_objects_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/execution_saved_object/saved_objects_type.ts @@ -58,6 +58,9 @@ const ruleExecutionMappings: SavedObjectsType['mappings'] = { total_indexing_duration_ms: { type: 'long', }, + total_enrichment_duration_ms: { + type: 'long', + }, execution_gap_duration_s: { type: 'long', }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts index ae3f310d841c3..05813ed1ee29c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts @@ -343,6 +343,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = const warningMessages = result.warningMessages.concat(runResult.warningMessages); result = { bulkCreateTimes: result.bulkCreateTimes.concat(runResult.bulkCreateTimes), + enrichmentTimes: result.enrichmentTimes.concat(runResult.enrichmentTimes), createdSignals, createdSignalsCount: createdSignals.length, errors: result.errors.concat(runResult.errors), @@ -358,6 +359,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = } else { result = { bulkCreateTimes: [], + enrichmentTimes: [], createdSignals: [], createdSignalsCount: 0, errors: [], @@ -434,6 +436,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = metrics: { searchDurations: result.searchAfterTimes, indexingDurations: result.bulkCreateTimes, + enrichmentDurations: result.enrichmentTimes, }, }); } @@ -452,6 +455,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = metrics: { searchDurations: result.searchAfterTimes, indexingDurations: result.bulkCreateTimes, + enrichmentDurations: result.enrichmentTimes, }, }); } @@ -464,6 +468,7 @@ export const createSecurityRuleTypeWrapper: CreateSecurityRuleTypeWrapper = metrics: { searchDurations: result.searchAfterTimes, indexingDurations: result.bulkCreateTimes, + enrichmentDurations: result.enrichmentTimes, }, }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/bulk_create_factory.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/bulk_create_factory.ts index 81f15364ff128..95bc32571f6ea 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/bulk_create_factory.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/bulk_create_factory.ts @@ -21,6 +21,7 @@ import type { export interface GenericBulkCreateResponse { success: boolean; bulkCreateDuration: string; + enrichmentDuration: string; createdItemsCount: number; createdItems: Array & { _id: string; _index: string }>; errors: string[]; @@ -45,6 +46,7 @@ export const bulkCreateFactory = return { errors: [], success: true, + enrichmentDuration: '0', bulkCreateDuration: '0', createdItemsCount: 0, createdItems: [], @@ -54,6 +56,24 @@ export const bulkCreateFactory = const start = performance.now(); + let enrichmentsTimeStart = 0; + let enrichmentsTimeFinish = 0; + let enrichAlertsWrapper: typeof enrichAlerts; + if (enrichAlerts) { + enrichAlertsWrapper = async (alerts, params) => { + enrichmentsTimeStart = performance.now(); + try { + const enrichedAlerts = await enrichAlerts(alerts, params); + return enrichedAlerts; + } catch (error) { + ruleExecutionLogger.error(`Enrichments failed ${error}`); + throw error; + } finally { + enrichmentsTimeFinish = performance.now(); + } + }; + } + const { createdAlerts, errors, alertsWereTruncated } = await alertWithPersistence( wrappedDocs.map((doc) => ({ _id: doc._id, @@ -62,7 +82,7 @@ export const bulkCreateFactory = })), refreshForBulkCreate, maxAlerts, - enrichAlerts + enrichAlertsWrapper ); const end = performance.now(); @@ -78,6 +98,7 @@ export const bulkCreateFactory = return { errors: Object.keys(errors), success: false, + enrichmentDuration: makeFloatString(enrichmentsTimeFinish - enrichmentsTimeStart), bulkCreateDuration: makeFloatString(end - start), createdItemsCount: createdAlerts.length, createdItems: createdAlerts, @@ -88,6 +109,7 @@ export const bulkCreateFactory = errors: [], success: true, bulkCreateDuration: makeFloatString(end - start), + enrichmentDuration: makeFloatString(enrichmentsTimeFinish - enrichmentsTimeStart), createdItemsCount: createdAlerts.length, createdItems: createdAlerts, alertsWereTruncated, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts index 403d6542f4f0c..e1af3077ec3e3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts @@ -42,6 +42,7 @@ import type { IRuleExecutionLogForExecutors, IRuleExecutionLogService } from '.. export interface SecurityAlertTypeReturnValue { bulkCreateTimes: string[]; + enrichmentTimes: string[]; createdSignalsCount: number; createdSignals: unknown[]; errors: string[]; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/index.ts index 5d2dcd4a4b3d2..8f23da386f5c7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/index.ts @@ -10,6 +10,7 @@ import type { SecurityAlertTypeReturnValue } from '../types'; export const createResultObject = (state: TState) => { const result: SecurityAlertTypeReturnValue = { + enrichmentTimes: [], bulkCreateTimes: [], createdSignalsCount: 0, createdSignals: [], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_edit_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_edit_rules.ts index 273d6697437bd..75c7db48333c3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_edit_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_edit_rules.ts @@ -5,27 +5,27 @@ * 2.0. */ +import type { BulkEditError, RulesClient } from '@kbn/alerting-plugin/server'; import pMap from 'p-map'; -import type { RulesClient, BulkEditError } from '@kbn/alerting-plugin/server'; import type { BulkActionEditPayload, BulkActionEditPayloadRuleActions, } from '../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { BulkActionEditType } from '../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; import { enrichFilterWithRuleTypeMapping } from './enrich_filter_with_rule_type_mappings'; import type { MlAuthz } from '../../machine_learning/authz'; import { ruleParamsModifier } from './bulk_actions/rule_params_modifier'; import { splitBulkEditActions } from './bulk_actions/split_bulk_edit_actions'; import { validateBulkEditRule } from './bulk_actions/validations'; import { bulkEditActionToRulesClientOperation } from './bulk_actions/action_to_rules_client_operation'; + +import type { RuleAlertType } from './types'; import { - NOTIFICATION_THROTTLE_NO_ACTIONS, MAX_RULES_TO_UPDATE_IN_PARALLEL, + NOTIFICATION_THROTTLE_NO_ACTIONS, } from '../../../../common/constants'; -import { BulkActionEditType } from '../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; import { readRules } from './read_rules'; -import type { RuleAlertType } from './types'; - export interface BulkEditRulesArguments { rulesClient: RulesClient; actions: BulkActionEditPayload[]; @@ -67,39 +67,30 @@ export const bulkEditRules = async ({ // rulesClient bulkEdit currently doesn't support bulk mute/unmute. // this is a workaround to mitigate this, // until https://github.com/elastic/kibana/issues/139084 is resolved - // if rule actions has been applied: - // - we go through each rule - // - mute/unmute if needed, refetch rule - // calling mute for rule needed only when rule was unmuted before and throttle value is NOTIFICATION_THROTTLE_NO_ACTIONS + // if rule actions has been applied, we go through each rule, unmute it if necessary and refetch it // calling unmute needed only if rule was muted and throttle value is not NOTIFICATION_THROTTLE_NO_ACTIONS const ruleActions = attributesActions.filter((rule): rule is BulkActionEditPayloadRuleActions => [BulkActionEditType.set_rule_actions, BulkActionEditType.add_rule_actions].includes(rule.type) ); - // bulk edit actions are applying in a historical order. + // bulk edit actions are applied in historical order. // So, we need to find a rule action that will be applied the last, to be able to check if rule should be muted/unmuted const rulesAction = ruleActions.pop(); if (rulesAction) { - const muteOrUnmuteErrors: BulkEditError[] = []; - const rulesToMuteOrUnmute = await pMap( + const unmuteErrors: BulkEditError[] = []; + const rulesToUnmute = await pMap( result.rules, async (rule) => { try { if (rule.muteAll && rulesAction.value.throttle !== NOTIFICATION_THROTTLE_NO_ACTIONS) { await rulesClient.unmuteAll({ id: rule.id }); return (await readRules({ rulesClient, id: rule.id, ruleId: undefined })) ?? rule; - } else if ( - !rule.muteAll && - rulesAction.value.throttle === NOTIFICATION_THROTTLE_NO_ACTIONS - ) { - await rulesClient.muteAll({ id: rule.id }); - return (await readRules({ rulesClient, id: rule.id, ruleId: undefined })) ?? rule; } return rule; } catch (err) { - muteOrUnmuteErrors.push({ + unmuteErrors.push({ message: err.message, rule: { id: rule.id, @@ -115,8 +106,8 @@ export const bulkEditRules = async ({ return { ...result, - rules: rulesToMuteOrUnmute.filter((rule): rule is RuleAlertType => rule != null), - errors: [...result.errors, ...muteOrUnmuteErrors], + rules: rulesToUnmute.filter((rule): rule is RuleAlertType => rule != null), + errors: [...result.errors, ...unmuteErrors], }; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts index bc22ca9ea44d9..521fdf1e5a595 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts @@ -97,13 +97,10 @@ export const getFilter = async ({ index, exceptionFilter, }); - } else if (savedId && index != null) { - // if savedId present and we ending up here, then saved query failed to be fetched - // and we also didn't fall back to saved in rule query - throw Error(`Failed to fetch saved query. "${err.message}"`); } else { // user did not give any additional fall back mechanism for generating a rule // rethrow error for activity monitoring + err.message = `Failed to fetch saved query. "${err.message}"`; throw err; } } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signals.ts index d80e5cba026b0..0ab6ec2a01dda 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/create_threat_signals.ts @@ -65,6 +65,7 @@ export const createThreatSignals = async ({ let results: SearchAfterAndBulkCreateReturnType = { success: true, warning: false, + enrichmentTimes: [], bulkCreateTimes: [], searchAfterTimes: [], lastLookBackDate: null, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/utils.test.ts index 981868589e4a1..0bcdc8450a830 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/utils.test.ts @@ -55,6 +55,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -67,6 +68,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -83,6 +85,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -95,6 +98,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -111,6 +115,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -123,6 +128,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: new Date('2020-09-16T03:34:32.390Z'), createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -139,6 +145,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -151,6 +158,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: new Date('2020-09-16T03:34:32.390Z'), createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -162,6 +170,7 @@ describe('utils', () => { expect.objectContaining({ searchAfterTimes: ['60'], bulkCreateTimes: ['50'], + enrichmentTimes: ['6'], }) ); }); @@ -172,6 +181,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -184,6 +194,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: new Date('2020-09-16T03:34:32.390Z'), createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -296,6 +307,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -307,6 +319,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['30'], // max value from existingResult.searchAfterTimes bulkCreateTimes: ['25'], // max value from existingResult.bulkCreateTimes + enrichmentTimes: ['3'], // max value from existingResult.enrichmentTimes lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -323,6 +336,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -334,6 +348,7 @@ describe('utils', () => { warning: false, searchAfterTimes: [], bulkCreateTimes: [], + enrichmentTimes: [], lastLookBackDate: undefined, createdSignalsCount: 0, createdSignals: [], @@ -345,6 +360,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['30'], // max value from existingResult.searchAfterTimes bulkCreateTimes: ['25'], // max value from existingResult.bulkCreateTimes + enrichmentTimes: ['3'], // max value from existingResult.enrichmentTimes lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -362,6 +378,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], // max is 30 bulkCreateTimes: ['5', '15', '25'], // max is 25 + enrichmentTimes: ['1', '2', '3'], // max is 3 lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -373,6 +390,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: new Date('2020-09-16T03:34:32.390Z'), createdSignalsCount: 5, createdSignals: Array(5).fill(sampleSignalHit()), @@ -384,6 +402,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['40', '5', '15'], bulkCreateTimes: ['50', '5', '15'], + enrichmentTimes: ['4', '2', '3'], lastLookBackDate: new Date('2020-09-16T04:34:32.390Z'), createdSignalsCount: 8, createdSignals: Array(8).fill(sampleSignalHit()), @@ -396,6 +415,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['70'], // max value between newResult1 and newResult2 + max array value of existingResult (40 + 30 = 70) bulkCreateTimes: ['75'], // max value between newResult1 and newResult2 + max array value of existingResult (50 + 25 = 75) + enrichmentTimes: ['7'], // max value between newResult1 and newResult2 + max array value of existingResult (4 + 3 = 7) lastLookBackDate: new Date('2020-09-16T04:34:32.390Z'), // max lastLookBackDate createdSignalsCount: 16, // all the signals counted together (8 + 5 + 3) createdSignals: Array(16).fill(sampleSignalHit()), @@ -413,6 +433,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], // max is 30 bulkCreateTimes: ['5', '15', '25'], // max is 25 + enrichmentTimes: ['1', '2', '3'], // max is 3 lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -424,6 +445,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: new Date('2020-09-16T03:34:32.390Z'), createdSignalsCount: 5, createdSignals: Array(5).fill(sampleSignalHit()), @@ -435,6 +457,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['40', '5', '15'], bulkCreateTimes: ['50', '5', '15'], + enrichmentTimes: ['5', '2', '3'], lastLookBackDate: new Date('2020-09-16T04:34:32.390Z'), createdSignalsCount: 8, createdSignals: Array(8).fill(sampleSignalHit()), @@ -447,6 +470,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['70'], // max value between newResult1 and newResult2 + max array value of existingResult (40 + 30 = 70) bulkCreateTimes: ['75'], // max value between newResult1 and newResult2 + max array value of existingResult (50 + 25 = 75) + enrichmentTimes: ['8'], // max value between newResult1 and newResult2 + max array value of existingResult (50 + 3 = 8) lastLookBackDate: new Date('2020-09-16T04:34:32.390Z'), // max lastLookBackDate createdSignalsCount: 16, // all the signals counted together (8 + 5 + 3) createdSignals: Array(16).fill(sampleSignalHit()), @@ -464,6 +488,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], // max is 30 bulkCreateTimes: ['5', '15', '25'], // max is 25 + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -475,6 +500,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: new Date('2020-09-16T03:34:32.390Z'), createdSignalsCount: 5, createdSignals: Array(5).fill(sampleSignalHit()), @@ -486,6 +512,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['40', '5', '15'], bulkCreateTimes: ['50', '5', '15'], + enrichmentTimes: ['5', '2', '3'], lastLookBackDate: null, createdSignalsCount: 8, createdSignals: Array(8).fill(sampleSignalHit()), @@ -498,6 +525,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['70'], // max value between newResult1 and newResult2 + max array value of existingResult (40 + 30 = 70) bulkCreateTimes: ['75'], // max value between newResult1 and newResult2 + max array value of existingResult (50 + 25 = 75) + enrichmentTimes: ['8'], // max value between newResult1 and newResult2 + max array value of existingResult (5 + 3 = 8) lastLookBackDate: new Date('2020-09-16T03:34:32.390Z'), // max lastLookBackDate createdSignalsCount: 16, // all the signals counted together (8 + 5 + 3) createdSignals: Array(16).fill(sampleSignalHit()), @@ -515,6 +543,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -527,6 +556,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['5', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -543,6 +573,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -555,6 +586,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -571,6 +603,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -583,6 +616,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: new Date('2020-09-16T03:34:32.390Z'), createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -599,6 +633,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -611,6 +646,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: new Date('2020-09-16T03:34:32.390Z'), createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -632,6 +668,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: undefined, createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), @@ -644,6 +681,7 @@ describe('utils', () => { warning: false, searchAfterTimes: ['10', '20', '30'], bulkCreateTimes: ['5', '15', '25'], + enrichmentTimes: ['1', '2', '3'], lastLookBackDate: new Date('2020-09-16T03:34:32.390Z'), createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/utils.ts index bfba9a6fd22a1..a73ead0bf946d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/utils.ts @@ -70,6 +70,7 @@ export const combineResults = ( ): SearchAfterAndBulkCreateReturnType => ({ success: currentResult.success === false ? false : newResult.success, warning: currentResult.warning || newResult.warning, + enrichmentTimes: calculateAdditiveMax(currentResult.enrichmentTimes, newResult.enrichmentTimes), bulkCreateTimes: calculateAdditiveMax(currentResult.bulkCreateTimes, newResult.bulkCreateTimes), searchAfterTimes: calculateAdditiveMax( currentResult.searchAfterTimes, @@ -94,6 +95,7 @@ export const combineConcurrentResults = ( const maxedNewResult = newResult.reduce( (accum, item) => { const maxSearchAfterTime = calculateMax(accum.searchAfterTimes, item.searchAfterTimes); + const maxEnrichmentTimes = calculateMax(accum.enrichmentTimes, item.enrichmentTimes); const maxBulkCreateTimes = calculateMax(accum.bulkCreateTimes, item.bulkCreateTimes); const lastLookBackDate = calculateMaxLookBack(accum.lastLookBackDate, item.lastLookBackDate); return { @@ -101,6 +103,7 @@ export const combineConcurrentResults = ( warning: accum.warning || item.warning, searchAfterTimes: [maxSearchAfterTime], bulkCreateTimes: [maxBulkCreateTimes], + enrichmentTimes: [maxEnrichmentTimes], lastLookBackDate, createdSignalsCount: accum.createdSignalsCount + item.createdSignalsCount, createdSignals: [...accum.createdSignals, ...item.createdSignals], @@ -113,6 +116,7 @@ export const combineConcurrentResults = ( warning: false, searchAfterTimes: [], bulkCreateTimes: [], + enrichmentTimes: [], lastLookBackDate: undefined, createdSignalsCount: 0, createdSignals: [], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts index 93ddadf826d73..f786a28b50044 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts @@ -286,6 +286,7 @@ export interface SearchAfterAndBulkCreateReturnType { success: boolean; warning: boolean; searchAfterTimes: string[]; + enrichmentTimes: string[]; bulkCreateTimes: string[]; lastLookBackDate: Date | null | undefined; createdSignalsCount: number; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts index d5603130400c7..d80ed256a0de0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.test.ts @@ -953,6 +953,7 @@ describe('utils', () => { }); const expected: SearchAfterAndBulkCreateReturnType = { bulkCreateTimes: [], + enrichmentTimes: [], createdSignalsCount: 0, createdSignals: [], errors: [], @@ -973,6 +974,7 @@ describe('utils', () => { }); const expected: SearchAfterAndBulkCreateReturnType = { bulkCreateTimes: [], + enrichmentTimes: [], createdSignalsCount: 0, createdSignals: [], errors: [], @@ -1291,6 +1293,7 @@ describe('utils', () => { const searchAfterReturnType = createSearchAfterReturnType(); const expected: SearchAfterAndBulkCreateReturnType = { bulkCreateTimes: [], + enrichmentTimes: [], createdSignalsCount: 0, createdSignals: [], errors: [], @@ -1306,6 +1309,7 @@ describe('utils', () => { test('createSearchAfterReturnType can override all values', () => { const searchAfterReturnType = createSearchAfterReturnType({ bulkCreateTimes: ['123'], + enrichmentTimes: [], createdSignalsCount: 5, createdSignals: Array(5).fill(sampleSignalHit()), errors: ['error 1'], @@ -1317,6 +1321,7 @@ describe('utils', () => { }); const expected: SearchAfterAndBulkCreateReturnType = { bulkCreateTimes: ['123'], + enrichmentTimes: [], createdSignalsCount: 5, createdSignals: Array(5).fill(sampleSignalHit()), errors: ['error 1'], @@ -1337,6 +1342,7 @@ describe('utils', () => { }); const expected: SearchAfterAndBulkCreateReturnType = { bulkCreateTimes: [], + enrichmentTimes: [], createdSignalsCount: 5, createdSignals: Array(5).fill(sampleSignalHit()), errors: ['error 1'], @@ -1355,6 +1361,7 @@ describe('utils', () => { const merged = mergeReturns([createSearchAfterReturnType(), createSearchAfterReturnType()]); const expected: SearchAfterAndBulkCreateReturnType = { bulkCreateTimes: [], + enrichmentTimes: [], createdSignalsCount: 0, createdSignals: [], errors: [], @@ -1411,6 +1418,7 @@ describe('utils', () => { const merged = mergeReturns([ createSearchAfterReturnType({ bulkCreateTimes: ['123'], + enrichmentTimes: [], createdSignalsCount: 3, createdSignals: Array(3).fill(sampleSignalHit()), errors: ['error 1', 'error 2'], @@ -1421,6 +1429,7 @@ describe('utils', () => { }), createSearchAfterReturnType({ bulkCreateTimes: ['456'], + enrichmentTimes: [], createdSignalsCount: 2, createdSignals: Array(2).fill(sampleSignalHit()), errors: ['error 3'], @@ -1433,6 +1442,7 @@ describe('utils', () => { ]); const expected: SearchAfterAndBulkCreateReturnType = { bulkCreateTimes: ['123', '456'], // concatenates the prev and next together + enrichmentTimes: [], createdSignalsCount: 5, // Adds the 3 and 2 together createdSignals: Array(5).fill(sampleSignalHit()), errors: ['error 1', 'error 2', 'error 3'], // concatenates the prev and next together @@ -1452,6 +1462,7 @@ describe('utils', () => { const next: GenericBulkCreateResponse = { success: false, bulkCreateDuration: '100', + enrichmentDuration: '0', createdItemsCount: 1, createdItems: [], errors: ['new error'], @@ -1469,6 +1480,7 @@ describe('utils', () => { const next: GenericBulkCreateResponse = { success: true, bulkCreateDuration: '0', + enrichmentDuration: '0', createdItemsCount: 0, createdItems: [], errors: ['error 1'], @@ -1484,6 +1496,7 @@ describe('utils', () => { const next: GenericBulkCreateResponse = { success: true, bulkCreateDuration: '0', + enrichmentDuration: '0', createdItemsCount: 0, createdItems: [], errors: ['error 2'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts index 6030400da2b75..24b5b068d5689 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts @@ -649,6 +649,7 @@ export const createSearchAfterReturnType = ({ success, warning, searchAfterTimes, + enrichmentTimes, bulkCreateTimes, lastLookBackDate, createdSignalsCount, @@ -659,6 +660,7 @@ export const createSearchAfterReturnType = ({ success?: boolean | undefined; warning?: boolean; searchAfterTimes?: string[] | undefined; + enrichmentTimes?: string[] | undefined; bulkCreateTimes?: string[] | undefined; lastLookBackDate?: Date | undefined; createdSignalsCount?: number | undefined; @@ -670,6 +672,7 @@ export const createSearchAfterReturnType = ({ success: success ?? true, warning: warning ?? false, searchAfterTimes: searchAfterTimes ?? [], + enrichmentTimes: enrichmentTimes ?? [], bulkCreateTimes: bulkCreateTimes ?? [], lastLookBackDate: lastLookBackDate ?? null, createdSignalsCount: createdSignalsCount ?? 0, @@ -715,6 +718,7 @@ export const addToSearchAfterReturn = ({ current.createdSignalsCount += next.createdItemsCount; current.createdSignals.push(...next.createdItems); current.bulkCreateTimes.push(next.bulkCreateDuration); + current.enrichmentTimes.push(next.enrichmentDuration); current.errors = [...new Set([...current.errors, ...next.errors])]; }; @@ -727,6 +731,7 @@ export const mergeReturns = ( warning: existingWarning, searchAfterTimes: existingSearchAfterTimes, bulkCreateTimes: existingBulkCreateTimes, + enrichmentTimes: existingEnrichmentTimes, lastLookBackDate: existingLastLookBackDate, createdSignalsCount: existingCreatedSignalsCount, createdSignals: existingCreatedSignals, @@ -738,6 +743,7 @@ export const mergeReturns = ( success: newSuccess, warning: newWarning, searchAfterTimes: newSearchAfterTimes, + enrichmentTimes: newEnrichmentTimes, bulkCreateTimes: newBulkCreateTimes, lastLookBackDate: newLastLookBackDate, createdSignalsCount: newCreatedSignalsCount, @@ -750,6 +756,7 @@ export const mergeReturns = ( success: existingSuccess && newSuccess, warning: existingWarning || newWarning, searchAfterTimes: [...existingSearchAfterTimes, ...newSearchAfterTimes], + enrichmentTimes: [...existingEnrichmentTimes, ...newEnrichmentTimes], bulkCreateTimes: [...existingBulkCreateTimes, ...newBulkCreateTimes], lastLookBackDate: newLastLookBackDate ?? existingLastLookBackDate, createdSignalsCount: existingCreatedSignalsCount + newCreatedSignalsCount, diff --git a/x-pack/plugins/security_solution/server/usage/collector.ts b/x-pack/plugins/security_solution/server/usage/collector.ts index e14af8c553736..6f526051f17d1 100644 --- a/x-pack/plugins/security_solution/server/usage/collector.ts +++ b/x-pack/plugins/security_solution/server/usage/collector.ts @@ -414,6 +414,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -500,6 +514,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -586,6 +614,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -672,6 +714,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -758,6 +814,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -844,6 +914,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -946,6 +1030,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1032,6 +1130,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1118,6 +1230,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1204,6 +1330,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1290,6 +1430,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1376,6 +1530,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1478,6 +1646,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1564,6 +1746,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1650,6 +1846,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1736,6 +1946,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1822,6 +2046,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', @@ -1908,6 +2146,20 @@ export const registerCollector: RegisterCollector = ({ _meta: { description: 'The min duration' }, }, }, + enrichment_duration: { + max: { + type: 'float', + _meta: { description: 'The max duration' }, + }, + avg: { + type: 'float', + _meta: { description: 'The avg duration' }, + }, + min: { + type: 'float', + _meta: { description: 'The min duration' }, + }, + }, gap_duration: { max: { type: 'float', diff --git a/x-pack/plugins/security_solution/server/usage/detections/rules/get_initial_usage.ts b/x-pack/plugins/security_solution/server/usage/detections/rules/get_initial_usage.ts index eb32c58bda6cf..3ad6b5740b53e 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/rules/get_initial_usage.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/rules/get_initial_usage.ts @@ -144,6 +144,7 @@ export const getInitialSingleEventMetric = (): SingleEventMetric => ({ succeeded: 0, index_duration: getInitialMaxAvgMin(), search_duration: getInitialMaxAvgMin(), + enrichment_duration: getInitialMaxAvgMin(), gap_duration: getInitialMaxAvgMin(), gap_count: 0, }); diff --git a/x-pack/plugins/security_solution/server/usage/detections/rules/get_metrics.mocks.ts b/x-pack/plugins/security_solution/server/usage/detections/rules/get_metrics.mocks.ts index 129d2b32d0b3d..83eb7df28a026 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/rules/get_metrics.mocks.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/rules/get_metrics.mocks.ts @@ -155,6 +155,15 @@ export const getEventLogAllRules = (): SearchResponse ({ avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, threat_match: { @@ -2506,6 +2835,11 @@ export const getEventLogAllRulesResult = (): SingleEventLogStatusMetric => ({ avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, machine_learning: { @@ -2529,6 +2863,11 @@ export const getEventLogAllRulesResult = (): SingleEventLogStatusMetric => ({ avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, query: { @@ -2594,6 +2933,11 @@ export const getEventLogAllRulesResult = (): SingleEventLogStatusMetric => ({ avg: 4246.375, min: 2811, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 6, }, saved_query: { @@ -2617,6 +2961,11 @@ export const getEventLogAllRulesResult = (): SingleEventLogStatusMetric => ({ avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, threshold: { @@ -2640,6 +2989,11 @@ export const getEventLogAllRulesResult = (): SingleEventLogStatusMetric => ({ avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, total: { @@ -2676,6 +3030,11 @@ export const getEventLogElasticRulesResult = (): SingleEventLogStatusMetric => ( avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, threat_match: { @@ -2699,6 +3058,11 @@ export const getEventLogElasticRulesResult = (): SingleEventLogStatusMetric => ( avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, machine_learning: { @@ -2722,6 +3086,11 @@ export const getEventLogElasticRulesResult = (): SingleEventLogStatusMetric => ( avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, query: { @@ -2772,6 +3141,11 @@ export const getEventLogElasticRulesResult = (): SingleEventLogStatusMetric => ( avg: 4141.75, min: 2811, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 4, }, saved_query: { @@ -2795,6 +3169,11 @@ export const getEventLogElasticRulesResult = (): SingleEventLogStatusMetric => ( avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, threshold: { @@ -2818,6 +3197,11 @@ export const getEventLogElasticRulesResult = (): SingleEventLogStatusMetric => ( avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, total: { @@ -2854,6 +3238,11 @@ export const getEventLogCustomRulesResult = (): SingleEventLogStatusMetric => ({ avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, threat_match: { @@ -2877,6 +3266,11 @@ export const getEventLogCustomRulesResult = (): SingleEventLogStatusMetric => ({ avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, machine_learning: { @@ -2900,6 +3294,11 @@ export const getEventLogCustomRulesResult = (): SingleEventLogStatusMetric => ({ avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, query: { @@ -2940,6 +3339,11 @@ export const getEventLogCustomRulesResult = (): SingleEventLogStatusMetric => ({ avg: 4351, min: 3051, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 2, }, saved_query: { @@ -2963,6 +3367,11 @@ export const getEventLogCustomRulesResult = (): SingleEventLogStatusMetric => ({ avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, threshold: { @@ -2986,6 +3395,11 @@ export const getEventLogCustomRulesResult = (): SingleEventLogStatusMetric => ({ avg: 0, min: 0, }, + enrichment_duration: { + max: 0, + avg: 0, + min: 0, + }, gap_count: 0, }, total: { diff --git a/x-pack/plugins/security_solution/server/usage/detections/rules/types.ts b/x-pack/plugins/security_solution/server/usage/detections/rules/types.ts index 499c79b11fcfa..84fb656f793d4 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/rules/types.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/rules/types.ts @@ -85,6 +85,7 @@ export interface SingleEventMetric { succeeded: number; index_duration: MaxAvgMin; search_duration: MaxAvgMin; + enrichment_duration: MaxAvgMin; gap_duration: MaxAvgMin; gap_count: number; } diff --git a/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_type_metrics.test.ts b/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_type_metrics.test.ts index 09a988fbf02ef..693e3579d7c3a 100644 --- a/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_type_metrics.test.ts +++ b/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_type_metrics.test.ts @@ -68,6 +68,21 @@ describe('get_event_log_agg_by_rule_type_metrics', () => { field: 'kibana.alert.rule.execution.metrics.total_search_duration_ms', }, }, + maxTotalEnrichmentDuration: { + max: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + minTotalEnrichmentDuration: { + min: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + avgTotalEnrichmentDuration: { + avg: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, }, }); }); diff --git a/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_type_metrics.ts b/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_type_metrics.ts index 6fe8103e29a0d..957f56809d64f 100644 --- a/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_type_metrics.ts +++ b/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_type_metrics.ts @@ -74,6 +74,21 @@ export const getEventLogAggByRuleTypeMetrics = ( field: 'kibana.alert.rule.execution.metrics.total_search_duration_ms', }, }, + maxTotalEnrichmentDuration: { + max: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + minTotalEnrichmentDuration: { + min: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + avgTotalEnrichmentDuration: { + avg: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, }, }; }; diff --git a/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_types_metrics.test.ts b/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_types_metrics.test.ts index 22261ac48812c..4673ca1b6bcb8 100644 --- a/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_types_metrics.test.ts +++ b/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_rule_types_metrics.test.ts @@ -74,6 +74,21 @@ describe('get_event_log_agg_by_rule_types_metrics', () => { field: 'kibana.alert.rule.execution.metrics.total_search_duration_ms', }, }, + maxTotalEnrichmentDuration: { + max: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + minTotalEnrichmentDuration: { + min: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + avgTotalEnrichmentDuration: { + avg: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, }, }, }); @@ -139,6 +154,21 @@ describe('get_event_log_agg_by_rule_types_metrics', () => { field: 'kibana.alert.rule.execution.metrics.total_search_duration_ms', }, }, + maxTotalEnrichmentDuration: { + max: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + minTotalEnrichmentDuration: { + min: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + avgTotalEnrichmentDuration: { + avg: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, }, }, }); @@ -204,6 +234,21 @@ describe('get_event_log_agg_by_rule_types_metrics', () => { field: 'kibana.alert.rule.execution.metrics.total_search_duration_ms', }, }, + maxTotalEnrichmentDuration: { + max: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + minTotalEnrichmentDuration: { + min: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + avgTotalEnrichmentDuration: { + avg: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, }, }, 'siem.indicatorRule': { @@ -263,6 +308,21 @@ describe('get_event_log_agg_by_rule_types_metrics', () => { field: 'kibana.alert.rule.execution.metrics.total_search_duration_ms', }, }, + maxTotalEnrichmentDuration: { + max: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + minTotalEnrichmentDuration: { + min: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + avgTotalEnrichmentDuration: { + avg: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, }, }, }); diff --git a/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_statuses.test.ts b/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_statuses.test.ts index 7d474769bd79f..a87046660fe16 100644 --- a/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_statuses.test.ts +++ b/x-pack/plugins/security_solution/server/usage/queries/utils/get_event_log_agg_by_statuses.test.ts @@ -137,6 +137,21 @@ describe('get_event_log_agg_by_statuses', () => { field: 'kibana.alert.rule.execution.metrics.total_search_duration_ms', }, }, + maxTotalEnrichmentDuration: { + max: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + minTotalEnrichmentDuration: { + min: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + avgTotalEnrichmentDuration: { + avg: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, }, }, }, @@ -246,6 +261,21 @@ describe('get_event_log_agg_by_statuses', () => { field: 'kibana.alert.rule.execution.metrics.total_search_duration_ms', }, }, + maxTotalEnrichmentDuration: { + max: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + minTotalEnrichmentDuration: { + min: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + avgTotalEnrichmentDuration: { + avg: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, }, }, }, @@ -418,6 +448,21 @@ describe('get_event_log_agg_by_statuses', () => { field: 'kibana.alert.rule.execution.metrics.total_search_duration_ms', }, }, + maxTotalEnrichmentDuration: { + max: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + minTotalEnrichmentDuration: { + min: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + avgTotalEnrichmentDuration: { + avg: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, }, }, 'siem.thresholdRule': { @@ -477,6 +522,21 @@ describe('get_event_log_agg_by_statuses', () => { field: 'kibana.alert.rule.execution.metrics.total_search_duration_ms', }, }, + maxTotalEnrichmentDuration: { + max: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + minTotalEnrichmentDuration: { + min: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, + avgTotalEnrichmentDuration: { + avg: { + field: 'kibana.alert.rule.execution.metrics.total_enrichment_duration_ms', + }, + }, }, }, }, diff --git a/x-pack/plugins/security_solution/server/usage/queries/utils/transform_single_rule_metric.test.ts b/x-pack/plugins/security_solution/server/usage/queries/utils/transform_single_rule_metric.test.ts index c64f0833fe851..9c5810011a975 100644 --- a/x-pack/plugins/security_solution/server/usage/queries/utils/transform_single_rule_metric.test.ts +++ b/x-pack/plugins/security_solution/server/usage/queries/utils/transform_single_rule_metric.test.ts @@ -85,6 +85,15 @@ describe('transform_single_rule_metric', () => { minTotalSearchDuration: { value: 12, }, + minTotalEnrichmentDuration: { + value: 4, + }, + maxTotalEnrichmentDuration: { + value: 2, + }, + avgTotalEnrichmentDuration: { + value: 12, + }, }, }); @@ -131,6 +140,11 @@ describe('transform_single_rule_metric', () => { avg: 2, min: 9, }, + enrichment_duration: { + max: 2, + avg: 12, + min: 4, + }, gap_count: 4, }); }); diff --git a/x-pack/plugins/security_solution/server/usage/queries/utils/transform_single_rule_metric.ts b/x-pack/plugins/security_solution/server/usage/queries/utils/transform_single_rule_metric.ts index bebd867fb195f..5b3b6f8b7ebb2 100644 --- a/x-pack/plugins/security_solution/server/usage/queries/utils/transform_single_rule_metric.ts +++ b/x-pack/plugins/security_solution/server/usage/queries/utils/transform_single_rule_metric.ts @@ -52,6 +52,11 @@ export const transformSingleRuleMetric = ({ avg: singleMetric.avgTotalSearchDuration.value ?? 0.0, min: singleMetric.minTotalSearchDuration.value ?? 0.0, }, + enrichment_duration: { + max: singleMetric?.maxTotalEnrichmentDuration?.value ?? 0.0, + avg: singleMetric?.avgTotalEnrichmentDuration?.value ?? 0.0, + min: singleMetric?.minTotalEnrichmentDuration?.value ?? 0.0, + }, gap_duration: { max: singleMetric.maxGapDuration.value ?? 0.0, avg: singleMetric.avgGapDuration.value ?? 0.0, diff --git a/x-pack/plugins/security_solution/server/usage/types.ts b/x-pack/plugins/security_solution/server/usage/types.ts index fe7711196303c..a6db2e3d71e91 100644 --- a/x-pack/plugins/security_solution/server/usage/types.ts +++ b/x-pack/plugins/security_solution/server/usage/types.ts @@ -121,6 +121,15 @@ export interface SingleExecutionMetricAgg { minTotalSearchDuration: { value: number | null; }; + maxTotalEnrichmentDuration: { + value: number | null; + }; + avgTotalEnrichmentDuration: { + value: number | null; + }; + minTotalEnrichmentDuration: { + value: number | null; + }; } export interface EventLogTypeStatusAggs { diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index 0c389000f6c80..9a47ad9de093e 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -4644,6 +4644,18 @@ "properties": { "all": { "properties": { + "total": { + "type": "long" + }, + "monthly": { + "type": "long" + }, + "weekly": { + "type": "long" + }, + "daily": { + "type": "long" + }, "assignees": { "properties": { "total": { @@ -4657,18 +4669,6 @@ } } }, - "total": { - "type": "long" - }, - "monthly": { - "type": "long" - }, - "weekly": { - "type": "long" - }, - "daily": { - "type": "long" - }, "status": { "properties": { "open": { @@ -4720,6 +4720,18 @@ }, "sec": { "properties": { + "total": { + "type": "long" + }, + "monthly": { + "type": "long" + }, + "weekly": { + "type": "long" + }, + "daily": { + "type": "long" + }, "assignees": { "properties": { "total": { @@ -4732,7 +4744,11 @@ "type": "long" } } - }, + } + } + }, + "obs": { + "properties": { "total": { "type": "long" }, @@ -4744,11 +4760,7 @@ }, "daily": { "type": "long" - } - } - }, - "obs": { - "properties": { + }, "assignees": { "properties": { "total": { @@ -4761,7 +4773,11 @@ "type": "long" } } - }, + } + } + }, + "main": { + "properties": { "total": { "type": "long" }, @@ -4773,11 +4789,7 @@ }, "daily": { "type": "long" - } - } - }, - "main": { - "properties": { + }, "assignees": { "properties": { "total": { @@ -4790,18 +4802,6 @@ "type": "long" } } - }, - "total": { - "type": "long" - }, - "monthly": { - "type": "long" - }, - "weekly": { - "type": "long" - }, - "daily": { - "type": "long" } } } @@ -10029,6 +10029,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -10161,6 +10183,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -10293,6 +10337,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -10425,6 +10491,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -10557,6 +10645,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -10689,6 +10799,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -10847,6 +10979,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -10979,6 +11133,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -11111,6 +11287,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -11243,6 +11441,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -11375,6 +11595,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -11507,6 +11749,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -11665,6 +11929,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -11797,6 +12083,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -11929,6 +12237,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -12061,6 +12391,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -12193,6 +12545,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { @@ -12325,6 +12699,28 @@ } } }, + "enrichment_duration": { + "properties": { + "max": { + "type": "float", + "_meta": { + "description": "The max duration" + } + }, + "avg": { + "type": "float", + "_meta": { + "description": "The avg duration" + } + }, + "min": { + "type": "float", + "_meta": { + "description": "The min duration" + } + } + } + }, "gap_duration": { "properties": { "max": { diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index b2984037b0302..e0ff0ef2793f7 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -15485,8 +15485,6 @@ "xpack.infra.deprecations.tiebreakerAdjustIndexing": "Ajustez votre indexation pour utiliser \"{field}\" comme moyen de départager.", "xpack.infra.deprecations.timestampAdjustIndexing": "Ajustez votre indexation pour utiliser \"{field}\" comme horodatage.", "xpack.infra.homePage.toolbar.showingLastOneMinuteDataText": "Dernières {duration} de données pour l'heure sélectionnée", - "xpack.infra.infrastructureMetricsExplorerPage.documentTitle": "{previousTitle} | Metrics Explorer", - "xpack.infra.infrastructureSnapshotPage.documentTitle": "{previousTitle} | Inventory", "xpack.infra.inventoryTimeline.header": "{metricLabel} moyen", "xpack.infra.kibanaMetrics.cloudIdMissingErrorMessage": "Le modèle de {metricId} nécessite un cloudId, mais aucun n'a été attribué à {nodeId}.", "xpack.infra.kibanaMetrics.invalidInfraMetricErrorMessage": "{id} n'est pas une valeur inframétrique valide", @@ -15526,7 +15524,6 @@ "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, one {# entrée mise en surbrillance} other {# entrées mises en surbrillance}}", "xpack.infra.logs.showingEntriesFromTimestamp": "Affichage des entrées à partir de {timestamp}", "xpack.infra.logs.showingEntriesUntilTimestamp": "Affichage des entrées jusqu'à {timestamp}", - "xpack.infra.logs.streamPage.documentTitle": "{previousTitle} | Flux", "xpack.infra.logs.viewInContext.logsFromContainerTitle": "Les logs affichés proviennent du conteneur {container}", "xpack.infra.logs.viewInContext.logsFromFileTitle": "Les logs affichés proviennent du fichier {file} et de l'hôte {host}", "xpack.infra.logSourceConfiguration.invalidMessageFieldTypeErrorMessage": "Le champ {messageField} doit être un champ textuel.", @@ -15535,8 +15532,7 @@ "xpack.infra.logSourceConfiguration.missingDataViewsLabel": "Vue de données {indexPatternId} manquante", "xpack.infra.logSourceConfiguration.missingMessageFieldErrorMessage": "La vue de données doit contenir un champ {messageField}.", "xpack.infra.logSourceErrorPage.savedObjectNotFoundErrorMessage": "Impossible de localiser ce {savedObjectType} : {savedObjectId}", - "xpack.infra.metricDetailPage.documentTitle": "Infrastructure | Indicateurs | {name}", - "xpack.infra.metricDetailPage.documentTitleError": "{previousTitle} | Oups", + "xpack.infra.metricDetailPage.documentTitleError": "Oups", "xpack.infra.metrics.alertFlyout.alertPerRedundantFilterError": "Il est possible que cette règle signale {matchedGroups} moins que prévu, car la requête de filtre comporte une correspondance pour {groupCount, plural, one {ce champ} other {ces champs}}. Pour en savoir plus, veuillez consulter {filteringAndGroupingLink}.", "xpack.infra.metrics.alertFlyout.ofExpression.helpTextDetail": "Vous ne trouvez pas d'indicateur ? {documentationLink}.", "xpack.infra.metrics.alerting.anomaly.summaryHigher": "{differential} x plus élevé", @@ -15690,7 +15686,6 @@ "xpack.infra.header.logsTitle": "Logs", "xpack.infra.header.observabilityTitle": "Observability", "xpack.infra.hideHistory": "Masquer l'historique", - "xpack.infra.homePage.documentTitle": "Indicateurs", "xpack.infra.homePage.inventoryTabTitle": "Inventory", "xpack.infra.homePage.metricsExplorerTabTitle": "Metrics Explorer", "xpack.infra.homePage.noMetricsIndicesInstructionsActionLabel": "Voir les instructions de configuration", @@ -25702,9 +25697,6 @@ "xpack.securitySolution.endpoint.resolver.relatedEventLimitTitle": "Cette liste inclut {numberOfEntries} événements de processus.", "xpack.securitySolution.endpointPolicyStatus.revisionNumber": "rév. {revNumber}", "xpack.securitySolution.endpointResponseActions.actionError.errorMessage": "{ errorCount, plural, =1 {Erreur rencontrée} other {Erreurs rencontrées}} :", - "xpack.securitySolution.endpointResponseActions.getProcesses.performApiErrorMessage": "L'erreur suivante a été rencontrée : {error}", - "xpack.securitySolution.endpointResponseActions.killProcess.performApiErrorMessage": "L'erreur suivante a été rencontrée : {error}", - "xpack.securitySolution.endpointResponseActions.suspendProcess.performApiErrorMessage": "L'erreur suivante a été rencontrée : {error}", "xpack.securitySolution.event.reason.reasonRendererTitle": "Outil de rendu d'événement : {eventRendererName} ", "xpack.securitySolution.eventDetails.nestedColumnCheckboxAriaLabel": "Le champ {field} est un objet, et il est composé de champs imbriqués qui peuvent être ajoutés en tant que colonne", "xpack.securitySolution.eventDetails.viewColumnCheckboxAriaLabel": "Afficher la colonne {field}", @@ -28124,8 +28116,6 @@ "xpack.securitySolution.endpointManagement.noPermissionsSubText": "Vous devez disposer du rôle de superutilisateur pour utiliser cette fonctionnalité. Si vous ne disposez pas de ce rôle, ni d'autorisations pour modifier les rôles d'utilisateur, contactez votre administrateur Kibana.", "xpack.securitySolution.endpointManagemnet.noPermissionsText": "Vous ne disposez pas des autorisations Kibana requises pour utiliser Elastic Security Administration", "xpack.securitySolution.endpointPolicyStatus.tooltipTitleLabel": "Politique appliquée", - "xpack.securitySolution.endpointResponseActions.getProcesses.errorMessageTitle": "Échec de l’obtention des processus", - "xpack.securitySolution.endpointResponseActions.getProcesses.performApiErrorMessageTitle": "Échec de l’exécution de l’action d’obtention des processus", "xpack.securitySolution.endpointResponseActions.getProcesses.table.header.command": "COMMANDE", "xpack.securitySolution.endpointResponseActions.getProcesses.table.header.enityId": "ID D’ENTITÉ", "xpack.securitySolution.endpointResponseActions.getProcesses.table.header.pid": "PID", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index a09bdfe578cb5..8715883e4251c 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -15471,8 +15471,6 @@ "xpack.infra.deprecations.tiebreakerAdjustIndexing": "インデックスを調整し、\"{field}\"をタイブレーカーとして使用します。", "xpack.infra.deprecations.timestampAdjustIndexing": "インデックスを調整し、\"{field}\"をタイムスタンプとして使用します。", "xpack.infra.homePage.toolbar.showingLastOneMinuteDataText": "指定期間のデータの最後の{duration}", - "xpack.infra.infrastructureMetricsExplorerPage.documentTitle": "{previousTitle} | メトリックエクスプローラー", - "xpack.infra.infrastructureSnapshotPage.documentTitle": "{previousTitle} | インベントリ", "xpack.infra.inventoryTimeline.header": "平均{metricLabel}", "xpack.infra.kibanaMetrics.cloudIdMissingErrorMessage": "{metricId} のモデルには cloudId が必要ですが、{nodeId} に cloudId が指定されていません。", "xpack.infra.kibanaMetrics.invalidInfraMetricErrorMessage": "{id} は有効な InfraMetric ではありません", @@ -15512,7 +15510,6 @@ "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, other {# 件のハイライトされたエントリー}}", "xpack.infra.logs.showingEntriesFromTimestamp": "{timestamp} 以降のエントリーを表示中", "xpack.infra.logs.showingEntriesUntilTimestamp": "{timestamp} までのエントリーを表示中", - "xpack.infra.logs.streamPage.documentTitle": "{previousTitle} | Stream", "xpack.infra.logs.viewInContext.logsFromContainerTitle": "表示されたログはコンテナー{container}から取得されました", "xpack.infra.logs.viewInContext.logsFromFileTitle": "表示されたログは、ファイル{file}およびホスト{host}から取得されました", "xpack.infra.logSourceConfiguration.invalidMessageFieldTypeErrorMessage": "{messageField}フィールドはテキストフィールドでなければなりません。", @@ -15520,8 +15517,7 @@ "xpack.infra.logSourceConfiguration.missingDataViewsLabel": "データビュー{indexPatternId}が見つかりません", "xpack.infra.logSourceConfiguration.missingMessageFieldErrorMessage": "データビューには{messageField}フィールドが必要です。", "xpack.infra.logSourceErrorPage.savedObjectNotFoundErrorMessage": "{savedObjectType}:{savedObjectId}が見つかりませんでした", - "xpack.infra.metricDetailPage.documentTitle": "インフラストラクチャ | メトリック | {name}", - "xpack.infra.metricDetailPage.documentTitleError": "{previousTitle} | おっと", + "xpack.infra.metricDetailPage.documentTitleError": "おっと", "xpack.infra.metrics.alertFlyout.alertPerRedundantFilterError": "このルールは想定未満の{matchedGroups}に対してアラートを通知できます。フィルタークエリには{groupCount, plural, one {このフィールド} other {これらのフィールド}}の完全一致が含まれるためです。詳細については、{filteringAndGroupingLink}を参照してください。", "xpack.infra.metrics.alertFlyout.ofExpression.helpTextDetail": "メトリックが見つからない場合は、{documentationLink}。", "xpack.infra.metrics.alerting.anomaly.summaryHigher": "{differential}x高い", @@ -15675,7 +15671,6 @@ "xpack.infra.header.logsTitle": "ログ", "xpack.infra.header.observabilityTitle": "Observability", "xpack.infra.hideHistory": "履歴を表示しない", - "xpack.infra.homePage.documentTitle": "メトリック", "xpack.infra.homePage.inventoryTabTitle": "インベントリ", "xpack.infra.homePage.metricsExplorerTabTitle": "メトリックエクスプローラー", "xpack.infra.homePage.noMetricsIndicesInstructionsActionLabel": "セットアップの手順を表示", @@ -25677,9 +25672,6 @@ "xpack.securitySolution.endpoint.resolver.relatedEventLimitTitle": "このリストには、{numberOfEntries} 件のプロセスイベントが含まれています。", "xpack.securitySolution.endpointPolicyStatus.revisionNumber": "rev. {revNumber}", "xpack.securitySolution.endpointResponseActions.actionError.errorMessage": "次の{ errorCount, plural, other {件のエラー}}が発生しました:", - "xpack.securitySolution.endpointResponseActions.getProcesses.performApiErrorMessage": "次のエラーが発生しました:{error}", - "xpack.securitySolution.endpointResponseActions.killProcess.performApiErrorMessage": "次のエラーが発生しました:{error}", - "xpack.securitySolution.endpointResponseActions.suspendProcess.performApiErrorMessage": "次のエラーが発生しました:{error}", "xpack.securitySolution.event.reason.reasonRendererTitle": "イベントレンダラー:{eventRendererName} ", "xpack.securitySolution.eventDetails.nestedColumnCheckboxAriaLabel": "{field}フィールドはオブジェクトであり、列として追加できるネストされたフィールドに分解されます", "xpack.securitySolution.eventDetails.viewColumnCheckboxAriaLabel": "{field} 列を表示", @@ -28099,8 +28091,6 @@ "xpack.securitySolution.endpointManagement.noPermissionsSubText": "この機能を使用するには、スーパーユーザーロールが必要です。スーパーユーザーロールがなく、ユーザーロールを編集する権限もない場合は、Kibana管理者に問い合わせてください。", "xpack.securitySolution.endpointManagemnet.noPermissionsText": "Elastic Security Administrationを使用するために必要なKibana権限がありません。", "xpack.securitySolution.endpointPolicyStatus.tooltipTitleLabel": "ポリシーが適用されました", - "xpack.securitySolution.endpointResponseActions.getProcesses.errorMessageTitle": "プロセスの取得アクションが失敗しました", - "xpack.securitySolution.endpointResponseActions.getProcesses.performApiErrorMessageTitle": "プロセスの取得アクションの実行が失敗しました", "xpack.securitySolution.endpointResponseActions.getProcesses.table.header.command": "コマンド", "xpack.securitySolution.endpointResponseActions.getProcesses.table.header.enityId": "エンティティID", "xpack.securitySolution.endpointResponseActions.getProcesses.table.header.pid": "PID", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 5ade45168ae73..ee88a0ed92217 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -15491,8 +15491,6 @@ "xpack.infra.deprecations.tiebreakerAdjustIndexing": "调整索引以将“{field}”用作决胜属性。", "xpack.infra.deprecations.timestampAdjustIndexing": "调整索引以将“{field}”用作时间戳。", "xpack.infra.homePage.toolbar.showingLastOneMinuteDataText": "选定时间过去 {duration}的数据", - "xpack.infra.infrastructureMetricsExplorerPage.documentTitle": "{previousTitle} | 指标浏览器", - "xpack.infra.infrastructureSnapshotPage.documentTitle": "{previousTitle} | 库存", "xpack.infra.inventoryTimeline.header": "平均值 {metricLabel}", "xpack.infra.kibanaMetrics.cloudIdMissingErrorMessage": "{metricId} 的模型需要云 ID,但没有为 {nodeId} 提供。", "xpack.infra.kibanaMetrics.invalidInfraMetricErrorMessage": "{id} 不是有效的 InfraMetric", @@ -15532,7 +15530,6 @@ "xpack.infra.logs.searchResultTooltip": "{bucketCount, plural, other {# 个高亮条目}}", "xpack.infra.logs.showingEntriesFromTimestamp": "正在显示自 {timestamp} 起的条目", "xpack.infra.logs.showingEntriesUntilTimestamp": "正在显示截止于 {timestamp} 的条目", - "xpack.infra.logs.streamPage.documentTitle": "{previousTitle} | 流式传输", "xpack.infra.logs.viewInContext.logsFromContainerTitle": "显示的日志来自容器 {container}", "xpack.infra.logs.viewInContext.logsFromFileTitle": "显示的日志来自文件 {file} 和主机 {host}", "xpack.infra.logSourceConfiguration.invalidMessageFieldTypeErrorMessage": "{messageField} 字段必须是文本字段。", @@ -15541,8 +15538,7 @@ "xpack.infra.logSourceConfiguration.missingDataViewsLabel": "缺少数据视图 {indexPatternId}", "xpack.infra.logSourceConfiguration.missingMessageFieldErrorMessage": "数据视图必须包含 {messageField} 字段。", "xpack.infra.logSourceErrorPage.savedObjectNotFoundErrorMessage": "无法找到该{savedObjectType}:{savedObjectId}", - "xpack.infra.metricDetailPage.documentTitle": "Infrastructure | 指标 | {name}", - "xpack.infra.metricDetailPage.documentTitleError": "{previousTitle} | 啊哦", + "xpack.infra.metricDetailPage.documentTitleError": "啊哦", "xpack.infra.metrics.alertFlyout.alertPerRedundantFilterError": "此规则可能针对低于预期的 {matchedGroups} 告警,因为筛选查询包含{groupCount, plural, one {此字段} other {这些字段}}的匹配项。有关更多信息,请参阅 {filteringAndGroupingLink}。", "xpack.infra.metrics.alertFlyout.ofExpression.helpTextDetail": "找不到指标?{documentationLink}。", "xpack.infra.metrics.alerting.anomaly.summaryHigher": "高 {differential} 倍", @@ -15696,7 +15692,6 @@ "xpack.infra.header.logsTitle": "日志", "xpack.infra.header.observabilityTitle": "Observability", "xpack.infra.hideHistory": "隐藏历史记录", - "xpack.infra.homePage.documentTitle": "指标", "xpack.infra.homePage.inventoryTabTitle": "库存", "xpack.infra.homePage.metricsExplorerTabTitle": "指标浏览器", "xpack.infra.homePage.noMetricsIndicesInstructionsActionLabel": "查看设置说明", @@ -25711,9 +25706,6 @@ "xpack.securitySolution.endpoint.resolver.relatedEventLimitTitle": "此列表包括 {numberOfEntries} 个进程事件。", "xpack.securitySolution.endpointPolicyStatus.revisionNumber": "修订版 {revNumber}", "xpack.securitySolution.endpointResponseActions.actionError.errorMessage": "遇到以下{ errorCount, plural, other {错误}}:", - "xpack.securitySolution.endpointResponseActions.getProcesses.performApiErrorMessage": "遇到以下错误:{error}", - "xpack.securitySolution.endpointResponseActions.killProcess.performApiErrorMessage": "遇到以下错误:{error}", - "xpack.securitySolution.endpointResponseActions.suspendProcess.performApiErrorMessage": "遇到以下错误:{error}", "xpack.securitySolution.event.reason.reasonRendererTitle": "事件渲染器:{eventRendererName} ", "xpack.securitySolution.eventDetails.nestedColumnCheckboxAriaLabel": "{field} 字段是对象,并分解为可以添加为列的嵌套字段", "xpack.securitySolution.eventDetails.viewColumnCheckboxAriaLabel": "查看 {field} 列", @@ -28133,8 +28125,6 @@ "xpack.securitySolution.endpointManagement.noPermissionsSubText": "您必须具有超级用户角色才能使用此功能。如果您不具有超级用户角色,且无权编辑用户角色,请与 Kibana 管理员联系。", "xpack.securitySolution.endpointManagemnet.noPermissionsText": "您没有所需的 Kibana 权限,无法使用 Elastic Security 管理", "xpack.securitySolution.endpointPolicyStatus.tooltipTitleLabel": "已应用策略", - "xpack.securitySolution.endpointResponseActions.getProcesses.errorMessageTitle": "获取进程操作失败", - "xpack.securitySolution.endpointResponseActions.getProcesses.performApiErrorMessageTitle": "执行获取进程操作失败", "xpack.securitySolution.endpointResponseActions.getProcesses.table.header.command": "命令", "xpack.securitySolution.endpointResponseActions.getProcesses.table.header.enityId": "实体 ID", "xpack.securitySolution.endpointResponseActions.getProcesses.table.header.pid": "PID", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/update_api_key_modal_confirmation.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/update_api_key_modal_confirmation.tsx index 0c6f3edaf3b89..c3072c123ff82 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/update_api_key_modal_confirmation.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/update_api_key_modal_confirmation.tsx @@ -6,6 +6,7 @@ */ import { EuiConfirmModal } from '@elastic/eui'; +import { KueryNode } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import React, { useEffect, useState, useMemo } from 'react'; import { HttpSetup } from '@kbn/core/public'; @@ -25,7 +26,7 @@ export const UpdateApiKeyModalConfirmation = ({ }: { onCancel: () => void; idsToUpdate: string[]; - idsToUpdateFilter?: string; + idsToUpdateFilter?: KueryNode | null | undefined; numberOfSelectedRules?: number; apiUpdateApiKeyCall: ({ ids, @@ -33,7 +34,7 @@ export const UpdateApiKeyModalConfirmation = ({ filter, }: { ids?: string[]; - filter?: string; + filter?: KueryNode | null | undefined; http: HttpSetup; }) => Promise; setIsLoadingState: (isLoading: boolean) => void; @@ -50,7 +51,7 @@ export const UpdateApiKeyModalConfirmation = ({ const { showToast } = useBulkEditResponse({ onSearchPopulate }); useEffect(() => { - if (idsToUpdateFilter) { + if (typeof idsToUpdateFilter !== 'undefined') { setUpdateModalVisibility(true); } else { setUpdateModalVisibility(idsToUpdate.length > 0); @@ -58,7 +59,7 @@ export const UpdateApiKeyModalConfirmation = ({ }, [idsToUpdate, idsToUpdateFilter]); const numberOfIdsToUpdate = useMemo(() => { - if (idsToUpdateFilter) { + if (typeof idsToUpdateFilter !== 'undefined') { return numberOfSelectedRules; } return idsToUpdate.length; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_edit_select.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_edit_select.test.tsx new file mode 100644 index 0000000000000..07bf3516fbdef --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_edit_select.test.tsx @@ -0,0 +1,147 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook, act } from '@testing-library/react-hooks'; +import { useBulkEditSelect } from './use_bulk_edit_select'; +import { RuleTableItem } from '../../types'; + +const items = [ + { + id: '1', + isEditable: true, + }, + { + id: '2', + isEditable: true, + }, + { + id: '3', + isEditable: true, + }, + { + id: '4', + isEditable: true, + }, +] as RuleTableItem[]; + +describe('useBulkEditSelectTest', () => { + it('getFilter should return null when nothing is selected', async () => { + const { result } = renderHook(() => + useBulkEditSelect({ + items, + totalItemCount: 4, + }) + ); + + expect(result.current.getFilter()).toEqual(null); + }); + + it('getFilter should return rule list filter when nothing is selected', async () => { + const { result } = renderHook(() => + useBulkEditSelect({ + items, + totalItemCount: 4, + tagsFilter: ['test: 123'], + searchText: 'rules*', + }) + ); + + expect(result.current.getFilter()?.arguments.length).toEqual(2); + }); + + it('getFilter should return rule list filter when something is selected', async () => { + const { result } = renderHook(() => + useBulkEditSelect({ + items, + totalItemCount: 4, + tagsFilter: ['test: 123'], + searchText: 'rules*', + }) + ); + + act(() => { + result.current.onSelectRow(items[0]); + }); + + expect(result.current.getFilter()?.arguments.length).toEqual(2); + expect([...result.current.selectedIds]).toEqual([items[0].id]); + }); + + it('getFilter should return null when selecting all', async () => { + const { result } = renderHook(() => + useBulkEditSelect({ + items, + totalItemCount: 4, + }) + ); + + act(() => { + result.current.onSelectAll(); + }); + + expect(result.current.getFilter()).toEqual(null); + }); + + it('getFilter should return rule list filter when selecting all with excluded ids', async () => { + const { result } = renderHook(() => + useBulkEditSelect({ + items, + totalItemCount: 4, + }) + ); + + act(() => { + result.current.onSelectAll(); + result.current.onSelectRow(items[0]); + }); + + expect(result.current.getFilter()?.arguments.length).toEqual(1); + }); + + it('getFilter should return rule list filter when selecting all', async () => { + const { result } = renderHook(() => + useBulkEditSelect({ + items, + totalItemCount: 4, + tagsFilter: ['test: 123'], + searchText: 'rules*', + }) + ); + + act(() => { + result.current.onSelectAll(); + }); + + expect(result.current.getFilter()?.arguments.length).toEqual(2); + }); + + it('getFilter should return rule list filter and exclude ids when selecting all with excluded ids', async () => { + const { result } = renderHook(() => + useBulkEditSelect({ + items, + totalItemCount: 4, + tagsFilter: ['test: 123'], + searchText: 'rules*', + }) + ); + + act(() => { + result.current.onSelectAll(); + result.current.onSelectRow(items[0]); + }); + + expect(result.current.getFilter()?.arguments.length).toEqual(2); + expect(result.current.getFilter()?.arguments[1].arguments[0].arguments).toEqual([ + expect.objectContaining({ + value: 'alert.id', + }), + expect.objectContaining({ + value: 'alert:1', + }), + ]); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_edit_select.tsx b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_edit_select.tsx index 20950d35b0264..31c248ae1254e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_edit_select.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_edit_select.tsx @@ -5,7 +5,9 @@ * 2.0. */ import { useReducer, useMemo, useCallback } from 'react'; -import { RuleTableItem } from '../../types'; +import { fromKueryExpression, nodeBuilder } from '@kbn/es-query'; +import { mapFiltersToKueryNode } from '../lib/rule_api/map_filters_to_kuery_node'; +import { RuleTableItem, RuleStatus } from '../../types'; interface BulkEditSelectionState { selectedIds: Set; @@ -71,9 +73,26 @@ const reducer = (state: BulkEditSelectionState, action: Action) => { interface UseBulkEditSelectProps { totalItemCount: number; items: RuleTableItem[]; + typesFilter?: string[]; + actionTypesFilter?: string[]; + tagsFilter?: string[]; + ruleExecutionStatusesFilter?: string[]; + ruleStatusesFilter?: RuleStatus[]; + searchText?: string; } -export function useBulkEditSelect({ totalItemCount = 0, items = [] }: UseBulkEditSelectProps) { +export function useBulkEditSelect(props: UseBulkEditSelectProps) { + const { + totalItemCount = 0, + items = [], + typesFilter, + actionTypesFilter, + tagsFilter, + ruleExecutionStatusesFilter, + ruleStatusesFilter, + searchText, + } = props; + const [state, dispatch] = useReducer(reducer, initialState); const itemIds = useMemo(() => { @@ -161,18 +180,54 @@ export function useBulkEditSelect({ totalItemCount = 0, items = [] }: UseBulkEdi dispatch({ type: ActionTypes.CLEAR_SELECTION }); }, []); + const getFilterKueryNode = useCallback( + (idsToExclude?: string[]) => { + const ruleFilterKueryNode = mapFiltersToKueryNode({ + typesFilter, + actionTypesFilter, + tagsFilter, + ruleExecutionStatusesFilter, + ruleStatusesFilter, + searchText, + }); + + if (idsToExclude && idsToExclude.length) { + const excludeFilter = fromKueryExpression( + `NOT (${idsToExclude.map((id) => `alert.id: "alert:${id}"`).join(' or ')})` + ); + if (ruleFilterKueryNode) { + return nodeBuilder.and([ruleFilterKueryNode, excludeFilter]); + } + return excludeFilter; + } + + return ruleFilterKueryNode; + }, + [ + typesFilter, + actionTypesFilter, + tagsFilter, + ruleExecutionStatusesFilter, + ruleStatusesFilter, + searchText, + ] + ); + const getFilter = useCallback(() => { const { selectedIds, isAllSelected } = state; const idsArray = [...selectedIds]; if (isAllSelected) { + // Select all but nothing is selected to exclude if (idsArray.length === 0) { - return 'alert.id: *'; + return getFilterKueryNode(); } - return `NOT (${idsArray.map((id) => `alert.id: "alert:${id}"`).join(' or ')})`; + // Select all, exclude certain alerts + return getFilterKueryNode(idsArray); } - return ''; - }, [state]); + + return getFilterKueryNode(); + }, [state, getFilterKueryNode]); return useMemo(() => { return { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/snooze.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/snooze.ts index 1f020aff106f5..b82efdb5e09cf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/snooze.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/snooze.ts @@ -5,6 +5,7 @@ * 2.0. */ import { HttpSetup } from '@kbn/core/public'; +import { KueryNode } from '@kbn/es-query'; import { SnoozeSchedule, BulkEditResponse } from '../../../types'; import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants'; @@ -37,7 +38,7 @@ export async function snoozeRule({ export interface BulkSnoozeRulesProps { ids?: string[]; - filter?: string; + filter?: KueryNode | null | undefined; snoozeSchedule: SnoozeSchedule; } @@ -51,7 +52,7 @@ export function bulkSnoozeRules({ try { body = JSON.stringify({ ids: ids?.length ? ids : undefined, - filter, + ...(filter ? { filter: JSON.stringify(filter) } : {}), operations: [ { operation: 'set', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unsnooze.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unsnooze.ts index 7bfadf1e1b824..d055149fdfbd8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unsnooze.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/unsnooze.ts @@ -5,6 +5,7 @@ * 2.0. */ import { HttpSetup } from '@kbn/core/public'; +import { KueryNode } from '@kbn/es-query'; import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants'; import { BulkEditResponse } from '../../../types'; @@ -26,7 +27,7 @@ export async function unsnoozeRule({ export interface BulkUnsnoozeRulesProps { ids?: string[]; - filter?: string; + filter?: KueryNode | null | undefined; scheduleIds?: string[]; } @@ -40,7 +41,7 @@ export function bulkUnsnoozeRules({ try { body = JSON.stringify({ ids: ids?.length ? ids : undefined, - filter, + ...(filter ? { filter: JSON.stringify(filter) } : {}), operations: [ { operation: 'delete', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_api_key.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_api_key.ts index 53327bbdb1e1e..f9a6912c1d43f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_api_key.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update_api_key.ts @@ -5,6 +5,7 @@ * 2.0. */ import { HttpSetup } from '@kbn/core/public'; +import { KueryNode } from '@kbn/es-query'; import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants'; import { BulkEditResponse } from '../../../types'; @@ -16,7 +17,7 @@ export async function updateAPIKey({ id, http }: { id: string; http: HttpSetup } export interface BulkUpdateAPIKeyProps { ids?: string[]; - filter?: string; + filter?: KueryNode | null | undefined; } export function bulkUpdateAPIKey({ @@ -28,7 +29,7 @@ export function bulkUpdateAPIKey({ try { body = JSON.stringify({ ids: ids?.length ? ids : undefined, - filter, + ...(filter ? { filter: JSON.stringify(filter) } : {}), operations: [ { operation: 'set', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.test.tsx index 4e6ae5c7cdb91..fcf1ba99b7af4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.test.tsx @@ -20,9 +20,13 @@ jest.mock('../../../../common/lib/kibana', () => ({ const setRulesToUpdateAPIKey = jest.fn(); const setRulesToSnooze = jest.fn(); +const setRulesToUnsnooze = jest.fn(); const setRulesToSchedule = jest.fn(); +const setRulesToUnschedule = jest.fn(); const setRulesToSnoozeFilter = jest.fn(); +const setRulesToUnsnoozeFilter = jest.fn(); const setRulesToScheduleFilter = jest.fn(); +const setRulesToUnscheduleFilter = jest.fn(); const setRulesToUpdateAPIKeyFilter = jest.fn(); describe('rule_quick_edit_buttons', () => { @@ -39,16 +43,20 @@ describe('rule_quick_edit_buttons', () => { const wrapper = mountWithIntl( ''} + getFilter={() => null} selectedItems={[mockRule]} onPerformingAction={() => {}} onActionPerformed={() => {}} setRulesToDelete={() => {}} setRulesToUpdateAPIKey={() => {}} setRulesToSnooze={() => {}} + setRulesToUnsnooze={() => {}} setRulesToSchedule={() => {}} + setRulesToUnschedule={() => {}} setRulesToSnoozeFilter={() => {}} + setRulesToUnsnoozeFilter={() => {}} setRulesToScheduleFilter={() => {}} + setRulesToUnscheduleFilter={() => {}} setRulesToUpdateAPIKeyFilter={() => {}} /> ); @@ -58,7 +66,9 @@ describe('rule_quick_edit_buttons', () => { expect(wrapper.find('[data-test-subj="updateAPIKeys"]').exists()).toBeTruthy(); expect(wrapper.find('[data-test-subj="deleteAll"]').exists()).toBeTruthy(); expect(wrapper.find('[data-test-subj="bulkSnooze"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="bulkUnsnooze"]').exists()).toBeTruthy(); expect(wrapper.find('[data-test-subj="bulkSnoozeSchedule"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="bulkRemoveSnoozeSchedule"]').exists()).toBeTruthy(); }); it('renders enableAll if rules are all disabled', async () => { @@ -70,16 +80,20 @@ describe('rule_quick_edit_buttons', () => { const wrapper = mountWithIntl( ''} + getFilter={() => null} selectedItems={[mockRule]} onPerformingAction={() => {}} onActionPerformed={() => {}} setRulesToDelete={() => {}} setRulesToUpdateAPIKey={() => {}} setRulesToSnooze={() => {}} + setRulesToUnsnooze={() => {}} setRulesToSchedule={() => {}} + setRulesToUnschedule={() => {}} setRulesToSnoozeFilter={() => {}} + setRulesToUnsnoozeFilter={() => {}} setRulesToScheduleFilter={() => {}} + setRulesToUnscheduleFilter={() => {}} setRulesToUpdateAPIKeyFilter={() => {}} /> ); @@ -97,27 +111,34 @@ describe('rule_quick_edit_buttons', () => { const wrapper = mountWithIntl( ''} + getFilter={() => null} selectedItems={[mockRule]} onPerformingAction={() => {}} onActionPerformed={() => {}} setRulesToDelete={() => {}} setRulesToUpdateAPIKey={() => {}} setRulesToSnooze={() => {}} + setRulesToUnsnooze={() => {}} setRulesToSchedule={() => {}} + setRulesToUnschedule={() => {}} setRulesToSnoozeFilter={() => {}} + setRulesToUnsnoozeFilter={() => {}} setRulesToScheduleFilter={() => {}} + setRulesToUnscheduleFilter={() => {}} setRulesToUpdateAPIKeyFilter={() => {}} /> ); expect(wrapper.find('[data-test-subj="disableAll"]').first().prop('isDisabled')).toBeTruthy(); expect(wrapper.find('[data-test-subj="deleteAll"]').first().prop('isDisabled')).toBeTruthy(); - - expect(wrapper.find('[data-test-subj="updateAPIKeys"]').first().prop('isDiabled')).toBeFalsy(); - expect(wrapper.find('[data-test-subj="bulkSnooze"]').first().prop('isDiabled')).toBeFalsy(); + expect(wrapper.find('[data-test-subj="updateAPIKeys"]').first().prop('isDisabled')).toBeFalsy(); + expect(wrapper.find('[data-test-subj="bulkSnooze"]').first().prop('isDisabled')).toBeFalsy(); + expect(wrapper.find('[data-test-subj="bulkUnsnooze"]').first().prop('isDisabled')).toBeFalsy(); + expect( + wrapper.find('[data-test-subj="bulkSnoozeSchedule"]').first().prop('isDisabled') + ).toBeFalsy(); expect( - wrapper.find('[data-test-subj="bulkSnoozeSchedule"]').first().prop('isDiabled') + wrapper.find('[data-test-subj="bulkRemoveSnoozeSchedule"]').first().prop('isDisabled') ).toBeFalsy(); }); @@ -131,16 +152,20 @@ describe('rule_quick_edit_buttons', () => { const wrapper = mountWithIntl( ''} + getFilter={() => null} selectedItems={[mockRule]} onPerformingAction={() => {}} onActionPerformed={() => {}} setRulesToDelete={() => {}} setRulesToSnooze={setRulesToSnooze} + setRulesToUnsnooze={setRulesToUnsnooze} setRulesToSchedule={setRulesToSchedule} + setRulesToUnschedule={setRulesToUnschedule} setRulesToUpdateAPIKey={setRulesToUpdateAPIKey} setRulesToSnoozeFilter={setRulesToSnoozeFilter} + setRulesToUnsnoozeFilter={setRulesToUnsnoozeFilter} setRulesToScheduleFilter={setRulesToScheduleFilter} + setRulesToUnscheduleFilter={setRulesToUnscheduleFilter} setRulesToUpdateAPIKeyFilter={setRulesToUpdateAPIKeyFilter} /> ); @@ -148,14 +173,22 @@ describe('rule_quick_edit_buttons', () => { wrapper.find('[data-test-subj="bulkSnooze"]').first().simulate('click'); expect(setRulesToSnooze).toHaveBeenCalledTimes(1); + wrapper.find('[data-test-subj="bulkUnsnooze"]').first().simulate('click'); + expect(setRulesToUnsnooze).toHaveBeenCalledTimes(1); + wrapper.find('[data-test-subj="bulkSnoozeSchedule"]').first().simulate('click'); expect(setRulesToSchedule).toHaveBeenCalledTimes(1); + wrapper.find('[data-test-subj="bulkRemoveSnoozeSchedule"]').first().simulate('click'); + expect(setRulesToUnschedule).toHaveBeenCalledTimes(1); + wrapper.find('[data-test-subj="updateAPIKeys"]').first().simulate('click'); expect(setRulesToUpdateAPIKey).toHaveBeenCalledTimes(1); expect(setRulesToSnoozeFilter).not.toHaveBeenCalled(); + expect(setRulesToUnsnoozeFilter).not.toHaveBeenCalled(); expect(setRulesToScheduleFilter).not.toHaveBeenCalled(); + expect(setRulesToUnscheduleFilter).not.toHaveBeenCalled(); expect(setRulesToUpdateAPIKeyFilter).not.toHaveBeenCalled(); }); @@ -169,16 +202,20 @@ describe('rule_quick_edit_buttons', () => { const wrapper = mountWithIntl( ''} + getFilter={() => null} selectedItems={[mockRule]} onPerformingAction={() => {}} onActionPerformed={() => {}} setRulesToDelete={() => {}} setRulesToSnooze={setRulesToSnooze} + setRulesToUnsnooze={setRulesToUnsnooze} setRulesToSchedule={setRulesToSchedule} + setRulesToUnschedule={setRulesToUnschedule} setRulesToUpdateAPIKey={setRulesToUpdateAPIKey} setRulesToSnoozeFilter={setRulesToSnoozeFilter} + setRulesToUnsnoozeFilter={setRulesToUnsnoozeFilter} setRulesToScheduleFilter={setRulesToScheduleFilter} + setRulesToUnscheduleFilter={setRulesToUnscheduleFilter} setRulesToUpdateAPIKeyFilter={setRulesToUpdateAPIKeyFilter} /> ); @@ -186,14 +223,22 @@ describe('rule_quick_edit_buttons', () => { wrapper.find('[data-test-subj="bulkSnooze"]').first().simulate('click'); expect(setRulesToSnoozeFilter).toHaveBeenCalledTimes(1); + wrapper.find('[data-test-subj="bulkUnsnooze"]').first().simulate('click'); + expect(setRulesToUnsnoozeFilter).toHaveBeenCalledTimes(1); + wrapper.find('[data-test-subj="bulkSnoozeSchedule"]').first().simulate('click'); expect(setRulesToScheduleFilter).toHaveBeenCalledTimes(1); + wrapper.find('[data-test-subj="bulkRemoveSnoozeSchedule"]').first().simulate('click'); + expect(setRulesToUnscheduleFilter).toHaveBeenCalledTimes(1); + wrapper.find('[data-test-subj="updateAPIKeys"]').first().simulate('click'); expect(setRulesToUpdateAPIKeyFilter).toHaveBeenCalledTimes(1); - expect(setRulesToSchedule).not.toHaveBeenCalled(); expect(setRulesToSnooze).not.toHaveBeenCalled(); + expect(setRulesToUnsnooze).not.toHaveBeenCalled(); + expect(setRulesToSchedule).not.toHaveBeenCalled(); + expect(setRulesToUnschedule).not.toHaveBeenCalled(); expect(setRulesToUpdateAPIKey).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx index 0b7db1ebeceba..f3cbae535d777 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; +import { KueryNode } from '@kbn/es-query'; import React, { useState, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiButtonEmpty, EuiFlexItem, EuiFlexGroup, EuiIconTip } from '@elastic/eui'; @@ -21,19 +22,25 @@ import { useKibana } from '../../../../common/lib/kibana'; export type ComponentOpts = { selectedItems: RuleTableItem[]; isAllSelected?: boolean; - getFilter: () => string; + getFilter: () => KueryNode | null; onPerformingAction?: () => void; onActionPerformed?: () => void; isSnoozingRules?: boolean; + isUnsnoozingRules?: boolean; isSchedulingRules?: boolean; + isUnschedulingRules?: boolean; isUpdatingRuleAPIKeys?: boolean; setRulesToDelete: React.Dispatch>; setRulesToUpdateAPIKey: React.Dispatch>; setRulesToSnooze: React.Dispatch>; + setRulesToUnsnooze: React.Dispatch>; setRulesToSchedule: React.Dispatch>; - setRulesToSnoozeFilter: React.Dispatch>; - setRulesToScheduleFilter: React.Dispatch>; - setRulesToUpdateAPIKeyFilter: React.Dispatch>; + setRulesToUnschedule: React.Dispatch>; + setRulesToSnoozeFilter: React.Dispatch>; + setRulesToUnsnoozeFilter: React.Dispatch>; + setRulesToScheduleFilter: React.Dispatch>; + setRulesToUnscheduleFilter: React.Dispatch>; + setRulesToUpdateAPIKeyFilter: React.Dispatch>; } & BulkOperationsComponentOpts; const ButtonWithTooltip = ({ @@ -65,16 +72,22 @@ export const RuleQuickEditButtons: React.FunctionComponent = ({ onPerformingAction = noop, onActionPerformed = noop, isSnoozingRules = false, + isUnsnoozingRules = false, isSchedulingRules = false, + isUnschedulingRules = false, isUpdatingRuleAPIKeys = false, enableRules, disableRules, setRulesToDelete, setRulesToUpdateAPIKey, setRulesToSnooze, + setRulesToUnsnooze, setRulesToSchedule, + setRulesToUnschedule, setRulesToSnoozeFilter, + setRulesToUnsnoozeFilter, setRulesToScheduleFilter, + setRulesToUnscheduleFilter, setRulesToUpdateAPIKeyFilter, }: ComponentOpts) => { const { @@ -90,7 +103,9 @@ export const RuleQuickEditButtons: React.FunctionComponent = ({ isDisablingRules || isDeletingRules || isSnoozingRules || + isUnsnoozingRules || isSchedulingRules || + isUnschedulingRules || isUpdatingRuleAPIKeys; const allRulesDisabled = useMemo(() => { @@ -220,6 +235,28 @@ export const RuleQuickEditButtons: React.FunctionComponent = ({ } } + async function onUnsnoozeAllClick() { + onPerformingAction(); + try { + if (isAllSelected) { + setRulesToUnsnoozeFilter(getFilter()); + } else { + setRulesToUnsnooze(selectedItems); + } + } catch (e) { + toasts.addDanger({ + title: i18n.translate( + 'xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.failedToSnoozeRules', + { + defaultMessage: 'Failed to snooze or unsnooze rules', + } + ), + }); + } finally { + onActionPerformed(); + } + } + async function onScheduleAllClick() { onPerformingAction(); try { @@ -242,6 +279,28 @@ export const RuleQuickEditButtons: React.FunctionComponent = ({ } } + async function onUnscheduleAllClick() { + onPerformingAction(); + try { + if (isAllSelected) { + setRulesToUnscheduleFilter(getFilter()); + } else { + setRulesToUnschedule(selectedItems); + } + } catch (e) { + toasts.addDanger({ + title: i18n.translate( + 'xpack.triggersActionsUI.sections.rulesList.bulkActionPopover.failedToSnoozeRules', + { + defaultMessage: 'Failed to snooze or unsnooze rules', + } + ), + }); + } finally { + onActionPerformed(); + } + } + return ( = ({ />
    + + + + + = ({ /> + + + + + void; onSave: () => void; - setIsLoading: (isLoading: boolean) => void; + setIsSnoozingRule: (isLoading: boolean) => void; + setIsUnsnoozingRule: (isLoading: boolean) => void; onSearchPopulate?: (filter: string) => void; } & BulkOperationsComponentOpts; @@ -43,13 +48,29 @@ const failureMessage = i18n.translate( } ); +const deleteConfirmPlural = (total: number) => + i18n.translate('xpack.triggersActionsUI.sections.rulesList.bulkUnsnoozeConfirmationPlural', { + defaultMessage: 'Unsnooze {total, plural, one {# rule} other {# rules}}? ', + values: { total }, + }); + +const deleteConfirmSingle = (ruleName: string) => + i18n.translate('xpack.triggersActionsUI.sections.rulesList.bulkUnsnoozeConfirmationSingle', { + defaultMessage: 'Unsnooze {ruleName}?', + values: { ruleName }, + }); + export const BulkSnoozeModal = (props: BulkSnoozeModalProps) => { const { rulesToSnooze, + rulesToUnsnooze, rulesToSnoozeFilter, + rulesToUnsnoozeFilter, + numberOfSelectedRules = 0, onClose, onSave, - setIsLoading, + setIsSnoozingRule, + setIsUnsnoozingRule, onSearchPopulate, bulkSnoozeRules, bulkUnsnoozeRules, @@ -62,18 +83,18 @@ export const BulkSnoozeModal = (props: BulkSnoozeModalProps) => { const { showToast } = useBulkEditResponse({ onSearchPopulate }); const isSnoozeModalOpen = useMemo(() => { - if (rulesToSnoozeFilter) { + if (typeof rulesToSnoozeFilter !== 'undefined') { return true; } return rulesToSnooze.length > 0; }, [rulesToSnooze, rulesToSnoozeFilter]); - const isSnoozed = useMemo(() => { - if (rulesToSnoozeFilter) { + const isUnsnoozeModalOpen = useMemo(() => { + if (typeof rulesToUnsnoozeFilter !== 'undefined') { return true; } - return rulesToSnooze.some((item) => isRuleSnoozed(item)); - }, [rulesToSnooze, rulesToSnoozeFilter]); + return rulesToUnsnooze.length > 0; + }, [rulesToUnsnooze, rulesToUnsnoozeFilter]); const interval = useMemo(() => { if (rulesToSnoozeFilter) { @@ -87,7 +108,7 @@ export const BulkSnoozeModal = (props: BulkSnoozeModalProps) => { const onSnoozeRule = async (schedule: SnoozeSchedule) => { onClose(); - setIsLoading(true); + setIsSnoozingRule(true); try { const response = await bulkSnoozeRules({ ids: rulesToSnooze.map((item) => item.id), @@ -100,18 +121,17 @@ export const BulkSnoozeModal = (props: BulkSnoozeModalProps) => { title: failureMessage, }); } - setIsLoading(false); + setIsSnoozingRule(false); onSave(); }; - const onUnsnoozeRule = async (scheduleIds?: string[]) => { + const onUnsnoozeRule = async () => { onClose(); - setIsLoading(true); + setIsUnsnoozingRule(true); try { const response = await bulkUnsnoozeRules({ - ids: rulesToSnooze.map((item) => item.id), - filter: rulesToSnoozeFilter, - scheduleIds, + ids: rulesToUnsnooze.map((item) => item.id), + filter: rulesToUnsnoozeFilter, }); showToast(response, 'snooze'); } catch (error) { @@ -119,10 +139,42 @@ export const BulkSnoozeModal = (props: BulkSnoozeModalProps) => { title: failureMessage, }); } - setIsLoading(false); + setIsUnsnoozingRule(false); onSave(); }; + const confirmationTitle = useMemo(() => { + if (!rulesToUnsnoozeFilter && numberOfSelectedRules === 1 && rulesToUnsnooze[0]) { + return deleteConfirmSingle(rulesToUnsnooze[0].name); + } + return deleteConfirmPlural(numberOfSelectedRules); + }, [rulesToUnsnooze, rulesToUnsnoozeFilter, numberOfSelectedRules]); + + if (isUnsnoozeModalOpen) { + return ( + + ); + } + if (isSnoozeModalOpen) { return ( @@ -138,11 +190,11 @@ export const BulkSnoozeModal = (props: BulkSnoozeModalProps) => { @@ -153,6 +205,7 @@ export const BulkSnoozeModal = (props: BulkSnoozeModalProps) => { ); } + return null; }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/bulk_snooze_schedule_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/bulk_snooze_schedule_modal.tsx index 56293c01614de..d5a1fd3d62b78 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/bulk_snooze_schedule_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/bulk_snooze_schedule_modal.tsx @@ -5,18 +5,19 @@ * 2.0. */ -import React, { useMemo, useState } from 'react'; +import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import { KueryNode } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { + EuiConfirmModal, EuiModal, EuiModalHeader, + EuiModalHeaderTitle, EuiModalBody, EuiModalFooter, EuiSpacer, EuiButtonEmpty, - EuiModalHeaderTitle, - EuiConfirmModal, } from '@elastic/eui'; import { withBulkRuleOperations, @@ -49,24 +50,30 @@ const deleteConfirmSingle = (ruleName: string) => export type BulkSnoozeScheduleModalProps = { rulesToSchedule: RuleTableItem[]; - rulesToScheduleFilter?: string; + rulesToUnschedule: RuleTableItem[]; + rulesToScheduleFilter?: KueryNode | null | undefined; + rulesToUnscheduleFilter?: KueryNode | null | undefined; numberOfSelectedRules?: number; onClose: () => void; onSave: () => void; - setIsLoading: (isLoading: boolean) => void; + setIsSchedulingRule: (isLoading: boolean) => void; + setIsUnschedulingRule: (isLoading: boolean) => void; onSearchPopulate?: (filter: string) => void; } & BulkOperationsComponentOpts; export const BulkSnoozeScheduleModal = (props: BulkSnoozeScheduleModalProps) => { const { rulesToSchedule, + rulesToUnschedule, rulesToScheduleFilter, + rulesToUnscheduleFilter, numberOfSelectedRules = 0, onClose, onSave, bulkSnoozeRules, bulkUnsnoozeRules, - setIsLoading, + setIsSchedulingRule, + setIsUnschedulingRule, onSearchPopulate, } = props; @@ -76,18 +83,23 @@ export const BulkSnoozeScheduleModal = (props: BulkSnoozeScheduleModalProps) => const { showToast } = useBulkEditResponse({ onSearchPopulate }); - const [showConfirmation, setShowConfirmation] = useState(false); - const isScheduleModalOpen = useMemo(() => { - if (rulesToScheduleFilter) { + if (typeof rulesToScheduleFilter !== 'undefined') { return true; } return rulesToSchedule.length > 0; }, [rulesToSchedule, rulesToScheduleFilter]); + const isUnscheduleModalOpen = useMemo(() => { + if (typeof rulesToUnscheduleFilter !== 'undefined') { + return true; + } + return rulesToUnschedule.length > 0; + }, [rulesToUnschedule, rulesToUnscheduleFilter]); + const onAddSnoozeSchedule = async (schedule: SnoozeSchedule) => { onClose(); - setIsLoading(true); + setIsSchedulingRule(true); try { const response = await bulkSnoozeRules({ ids: rulesToSchedule.map((item) => item.id), @@ -100,18 +112,17 @@ export const BulkSnoozeScheduleModal = (props: BulkSnoozeScheduleModalProps) => title: failureMessage, }); } - setIsLoading(false); + setIsSchedulingRule(false); onSave(); }; const onRemoveSnoozeSchedule = async () => { - setShowConfirmation(false); onClose(); - setIsLoading(true); + setIsUnschedulingRule(true); try { const response = await bulkUnsnoozeRules({ - ids: rulesToSchedule.map((item) => item.id), - filter: rulesToScheduleFilter, + ids: rulesToUnschedule.map((item) => item.id), + filter: rulesToUnscheduleFilter, scheduleIds: [], }); showToast(response, 'snoozeSchedule'); @@ -120,7 +131,7 @@ export const BulkSnoozeScheduleModal = (props: BulkSnoozeScheduleModalProps) => title: failureMessage, }); } - setIsLoading(false); + setIsUnschedulingRule(false); onSave(); }; @@ -131,14 +142,11 @@ export const BulkSnoozeScheduleModal = (props: BulkSnoozeScheduleModalProps) => return deleteConfirmPlural(numberOfSelectedRules); }, [rulesToSchedule, rulesToScheduleFilter, numberOfSelectedRules]); - if (showConfirmation) { + if (isUnscheduleModalOpen) { return ( { - setShowConfirmation(false); - onClose(); - }} + onCancel={onClose} onConfirm={onRemoveSnoozeSchedule} confirmButtonText={i18n.translate( 'xpack.triggersActionsUI.sections.rulesList.bulkDeleteConfirmButton', @@ -154,6 +162,7 @@ export const BulkSnoozeScheduleModal = (props: BulkSnoozeScheduleModalProps) => )} buttonColor="danger" defaultFocusedButton="confirm" + data-test-subj="bulkRemoveScheduleConfirmationModal" /> ); } @@ -172,13 +181,12 @@ export const BulkSnoozeScheduleModal = (props: BulkSnoozeScheduleModalProps) => setShowConfirmation(true)} + onCancelSchedules={onRemoveSnoozeSchedule} onClose={() => {}} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx index 3bde062935a86..6bfe953e28696 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx @@ -80,8 +80,14 @@ jest.mock('../../../../common/get_experimental_features', () => ({ const ruleTags = ['a', 'b', 'c', 'd']; -const { loadRuleTypes, updateAPIKey, loadRuleTags, bulkSnoozeRules, bulkUpdateAPIKey } = - jest.requireMock('../../../lib/rule_api'); +const { + loadRuleTypes, + updateAPIKey, + loadRuleTags, + bulkSnoozeRules, + bulkUnsnoozeRules, + bulkUpdateAPIKey, +} = jest.requireMock('../../../lib/rule_api'); const { loadRuleAggregationsWithKueryFilter } = jest.requireMock( '../../../lib/rule_api/aggregate_kuery_filter' ); @@ -1994,6 +2000,33 @@ describe.skip('Rules list bulk actions', () => { ); }); + it('can bulk unsnooze', async () => { + await setup(); + wrapper.find('[data-test-subj="checkboxSelectRow-1"]').at(1).simulate('change'); + wrapper.find('[data-test-subj="selectAllRulesButton"]').at(1).simulate('click'); + wrapper.find('[data-test-subj="showBulkActionButton"]').first().simulate('click'); + + // Unselect something to test filtering + wrapper.find('[data-test-subj="checkboxSelectRow-2"]').at(1).simulate('change'); + + wrapper.find('[data-test-subj="bulkUnsnooze"]').first().simulate('click'); + + expect(wrapper.find('[data-test-subj="bulkUnsnoozeConfirmationModal"]').exists()).toBeTruthy(); + wrapper.find('[data-test-subj="confirmModalConfirmButton"]').first().simulate('click'); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(bulkUnsnoozeRules).toHaveBeenCalledWith( + expect.objectContaining({ + ids: [], + filter: 'NOT (alert.id: "alert:2")', + }) + ); + }); + it('can bulk add snooze schedule', async () => { await setup(); wrapper.find('[data-test-subj="checkboxSelectRow-1"]').at(1).simulate('change'); @@ -2020,6 +2053,36 @@ describe.skip('Rules list bulk actions', () => { ); }); + it('can bulk remove snooze schedule', async () => { + await setup(); + wrapper.find('[data-test-subj="checkboxSelectRow-1"]').at(1).simulate('change'); + wrapper.find('[data-test-subj="selectAllRulesButton"]').at(1).simulate('click'); + wrapper.find('[data-test-subj="showBulkActionButton"]').first().simulate('click'); + + // Unselect something to test filtering + wrapper.find('[data-test-subj="checkboxSelectRow-2"]').at(1).simulate('change'); + + wrapper.find('[data-test-subj="bulkRemoveSnoozeSchedule"]').first().simulate('click'); + + expect( + wrapper.find('[data-test-subj="bulkRemoveScheduleConfirmationModal"]').exists() + ).toBeTruthy(); + wrapper.find('[data-test-subj="confirmModalConfirmButton"]').first().simulate('click'); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(bulkUnsnoozeRules).toHaveBeenCalledWith( + expect.objectContaining({ + ids: [], + filter: 'NOT (alert.id: "alert:2")', + scheduleIds: [], + }) + ); + }); + it('can bulk update API key', async () => { await setup(); wrapper.find('[data-test-subj="checkboxSelectRow-1"]').at(1).simulate('change'); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx index a725a0e916c19..a06958fb3072e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import moment from 'moment'; import { capitalize, isEmpty, sortBy } from 'lodash'; +import { KueryNode } from '@kbn/es-query'; import { FormattedMessage } from '@kbn/i18n-react'; import React, { useEffect, useState, ReactNode, useCallback, useMemo } from 'react'; import { @@ -206,17 +207,36 @@ export const RulesList = ({ const [rulesToDelete, setRulesToDelete] = useState([]); + // TODO - tech debt: Right now we're using null and undefined to determine if we should + // render the bulk edit modal. Refactor this to only keep track of 1 set of rules and types + // to determine which modal to show const [rulesToSnooze, setRulesToSnooze] = useState([]); - const [rulesToSnoozeFilter, setRulesToSnoozeFilter] = useState(''); + const [rulesToSnoozeFilter, setRulesToSnoozeFilter] = useState(); + + const [rulesToUnsnooze, setRulesToUnsnooze] = useState([]); + const [rulesToUnsnoozeFilter, setRulesToUnsnoozeFilter] = useState< + KueryNode | null | undefined + >(); const [rulesToSchedule, setRulesToSchedule] = useState([]); - const [rulesToScheduleFilter, setRulesToScheduleFilter] = useState(''); + const [rulesToScheduleFilter, setRulesToScheduleFilter] = useState< + KueryNode | null | undefined + >(); + + const [rulesToUnschedule, setRulesToUnschedule] = useState([]); + const [rulesToUnscheduleFilter, setRulesToUnscheduleFilter] = useState< + KueryNode | null | undefined + >(); const [rulesToUpdateAPIKey, setRulesToUpdateAPIKey] = useState([]); - const [rulesToUpdateAPIKeyFilter, setRulesToUpdateAPIKeyFilter] = useState(''); + const [rulesToUpdateAPIKeyFilter, setRulesToUpdateAPIKeyFilter] = useState< + KueryNode | null | undefined + >(); const [isSnoozingRules, setIsSnoozingRules] = useState(false); const [isSchedulingRules, setIsSchedulingRules] = useState(false); + const [isUnsnoozingRules, setIsUnsnoozingRules] = useState(false); + const [isUnschedulingRules, setIsUnschedulingRules] = useState(false); const [isUpdatingRuleAPIKeys, setIsUpdatingRuleAPIKeys] = useState(false); const hasAnyAuthorizedRuleType = useMemo(() => { @@ -578,6 +598,12 @@ export const RulesList = ({ } = useBulkEditSelect({ totalItemCount: rulesState.totalItemCount, items: tableItems, + searchText, + typesFilter: rulesTypesFilter, + actionTypesFilter, + ruleExecutionStatusesFilter, + ruleStatusesFilter, + tagsFilter, }); const authorizedToModifySelectedRules = useMemo(() => { @@ -594,17 +620,27 @@ export const RulesList = ({ const clearRulesToSnooze = () => { setRulesToSnooze([]); - setRulesToSnoozeFilter(''); + setRulesToSnoozeFilter(undefined); + }; + + const clearRulesToUnsnooze = () => { + setRulesToUnsnooze([]); + setRulesToUnsnoozeFilter(undefined); }; const clearRulesToSchedule = () => { setRulesToSchedule([]); - setRulesToScheduleFilter(''); + setRulesToScheduleFilter(undefined); + }; + + const clearRulesToUnschedule = () => { + setRulesToUnschedule([]); + setRulesToUnscheduleFilter(undefined); }; const clearRulesToUpdateAPIKey = () => { setRulesToUpdateAPIKey([]); - setRulesToUpdateAPIKeyFilter(''); + setRulesToUpdateAPIKeyFilter(undefined); }; const isRulesTableLoading = useMemo(() => { @@ -613,7 +649,9 @@ export const RulesList = ({ ruleTypesState.isLoading || isPerformingAction || isSnoozingRules || + isUnsnoozingRules || isSchedulingRules || + isUnschedulingRules || isUpdatingRuleAPIKeys ); }, [ @@ -621,7 +659,9 @@ export const RulesList = ({ ruleTypesState, isPerformingAction, isSnoozingRules, + isUnsnoozingRules, isSchedulingRules, + isUnschedulingRules, isUpdatingRuleAPIKeys, ]); @@ -903,14 +943,20 @@ export const RulesList = ({ setIsPerformingAction(false); }} isSnoozingRules={isSnoozingRules} + isUnsnoozingRules={isUnsnoozingRules} isSchedulingRules={isSchedulingRules} + isUnschedulingRules={isUnschedulingRules} isUpdatingRuleAPIKeys={isUpdatingRuleAPIKeys} setRulesToDelete={setRulesToDelete} setRulesToUpdateAPIKey={setRulesToUpdateAPIKey} setRulesToSnooze={setRulesToSnooze} + setRulesToUnsnooze={setRulesToUnsnooze} setRulesToSchedule={setRulesToSchedule} + setRulesToUnschedule={setRulesToUnschedule} setRulesToSnoozeFilter={setRulesToSnoozeFilter} + setRulesToUnsnoozeFilter={setRulesToUnsnoozeFilter} setRulesToScheduleFilter={setRulesToScheduleFilter} + setRulesToUnscheduleFilter={setRulesToUnscheduleFilter} setRulesToUpdateAPIKeyFilter={setRulesToUpdateAPIKeyFilter} /> @@ -983,13 +1029,19 @@ export const RulesList = ({ /> { clearRulesToSnooze(); + clearRulesToUnsnooze(); }} onSave={async () => { clearRulesToSnooze(); + clearRulesToUnsnooze(); onClearSelection(); await loadData(); }} @@ -997,14 +1049,19 @@ export const RulesList = ({ /> { clearRulesToSchedule(); + clearRulesToUnschedule(); }} onSave={async () => { clearRulesToSchedule(); + clearRulesToUnschedule(); onClearSelection(); await loadData(); }} diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts index 2d30465401caa..23dcc1abaea44 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts @@ -7,6 +7,7 @@ import expect from '@kbn/expect'; import { SuperTest, Test } from 'supertest'; +import { fromKueryExpression } from '@kbn/es-query'; import { Spaces } from '../../scenarios'; import { getUrlPrefix, getTestRuleData, ObjectRemover } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; @@ -198,6 +199,20 @@ const findTestUtils = ( expect(response.body.data[0].params.strValue).to.eql('my b'); }); + it('should filter on kueryNode parameters', async () => { + const response = await supertest.get( + `${getUrlPrefix(Spaces.space1.id)}/${ + describeType === 'public' ? 'api' : 'internal' + }/alerting/rules/_find?filter=${JSON.stringify( + fromKueryExpression('alert.attributes.params.strValue:"my b"') + )}` + ); + + expect(response.status).to.eql(200); + expect(response.body.total).to.equal(1); + expect(response.body.data[0].params.strValue).to.eql('my b'); + }); + it('should sort by parameters', async () => { const response = await supertest.get( `${getUrlPrefix(Spaces.space1.id)}/${ diff --git a/x-pack/test/api_integration/apis/ml/index.ts b/x-pack/test/api_integration/apis/ml/index.ts index 915d755ca97c0..e76eef8cb82bf 100644 --- a/x-pack/test/api_integration/apis/ml/index.ts +++ b/x-pack/test/api_integration/apis/ml/index.ts @@ -67,5 +67,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./saved_objects')); loadTestFile(require.resolve('./system')); loadTestFile(require.resolve('./trained_models')); + loadTestFile(require.resolve('./notifications')); }); } diff --git a/x-pack/test/api_integration/apis/ml/notifications/count_notifications.ts b/x-pack/test/api_integration/apis/ml/notifications/count_notifications.ts new file mode 100644 index 0000000000000..58932ea199b5d --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/notifications/count_notifications.ts @@ -0,0 +1,55 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import moment from 'moment'; +import type { FtrProviderContext } from '../../../ftr_provider_context'; +import { USER } from '../../../../functional/services/ml/security_common'; +import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; + +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertestWithoutAuth'); + const ml = getService('ml'); + + describe('GET notifications count', () => { + before(async () => { + await ml.api.initSavedObjects(); + await ml.testResources.setKibanaTimeZoneToUTC(); + + const adJobConfig = ml.commonConfig.getADFqSingleMetricJobConfig('fq_job'); + await ml.api.createAnomalyDetectionJob(adJobConfig); + + await ml.api.waitForJobNotificationsToIndex('fq_job'); + }); + + after(async () => { + await ml.api.cleanMlIndices(); + await ml.testResources.cleanMLSavedObjects(); + }); + + it('return notifications count by level', async () => { + const { body, status } = await supertest + .get(`/api/ml/notifications/count`) + .query({ lastCheckedAt: moment().subtract(7, 'd').valueOf() }) + .auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) + .set(COMMON_REQUEST_HEADERS); + ml.api.assertResponseStatusCode(200, status, body); + + expect(body.info).to.eql(1); + expect(body.warning).to.eql(0); + expect(body.error).to.eql(0); + }); + + it('returns an error for unauthorized user', async () => { + const { body, status } = await supertest + .get(`/api/ml/notifications/count`) + .auth(USER.ML_UNAUTHORIZED, ml.securityCommon.getPasswordForUser(USER.ML_UNAUTHORIZED)) + .set(COMMON_REQUEST_HEADERS); + ml.api.assertResponseStatusCode(403, status, body); + }); + }); +}; diff --git a/x-pack/test/api_integration/apis/ml/notifications/get_notifications.ts b/x-pack/test/api_integration/apis/ml/notifications/get_notifications.ts new file mode 100644 index 0000000000000..992065cdae67d --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/notifications/get_notifications.ts @@ -0,0 +1,102 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import type { + NotificationItem, + NotificationsSearchResponse, +} from '@kbn/ml-plugin/common/types/notifications'; +import type { FtrProviderContext } from '../../../ftr_provider_context'; +import { USER } from '../../../../functional/services/ml/security_common'; +import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; + +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertestWithoutAuth'); + const esArchiver = getService('esArchiver'); + const ml = getService('ml'); + + describe('GET notifications', () => { + before(async () => { + await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/bm_classification'); + await ml.api.initSavedObjects(); + await ml.testResources.setKibanaTimeZoneToUTC(); + + const adJobConfig = ml.commonConfig.getADFqSingleMetricJobConfig('fq_job'); + await ml.api.createAnomalyDetectionJob(adJobConfig); + + const dfaJobConfig = ml.commonConfig.getDFABmClassificationJobConfig('df_job'); + await ml.api.createDataFrameAnalyticsJob(dfaJobConfig); + + // wait for notification to index + + await ml.api.waitForJobNotificationsToIndex('fq_job'); + await ml.api.waitForJobNotificationsToIndex('df_job'); + }); + + after(async () => { + await ml.api.cleanMlIndices(); + await ml.testResources.cleanMLSavedObjects(); + }); + + it('return all notifications ', async () => { + const { body, status } = await supertest + .get(`/api/ml/notifications`) + .query({ earliest: 'now-1d', latest: 'now' }) + .auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) + .set(COMMON_REQUEST_HEADERS); + ml.api.assertResponseStatusCode(200, status, body); + + expect((body as NotificationsSearchResponse).total).to.eql(2); + }); + + it('return notifications based on the query string', async () => { + const { body, status } = await supertest + .get(`/api/ml/notifications`) + .query({ earliest: 'now-1d', latest: 'now', queryString: 'job_type:anomaly_detector' }) + .auth(USER.ML_VIEWER, ml.securityCommon.getPasswordForUser(USER.ML_VIEWER)) + .set(COMMON_REQUEST_HEADERS); + ml.api.assertResponseStatusCode(200, status, body); + + expect((body as NotificationsSearchResponse).total).to.eql(1); + expect( + (body as NotificationsSearchResponse).results.filter( + (result: NotificationItem) => result.job_type === 'anomaly_detector' + ) + ).to.length(body.total); + }); + + it('supports sorting asc sorting by field', async () => { + const { body, status } = await supertest + .get(`/api/ml/notifications`) + .query({ earliest: 'now-1d', latest: 'now', sortField: 'job_id', sortDirection: 'asc' }) + .auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) + .set(COMMON_REQUEST_HEADERS); + ml.api.assertResponseStatusCode(200, status, body); + + expect(body.results[0].job_id).to.eql('df_job'); + }); + + it('supports sorting desc sorting by field', async () => { + const { body, status } = await supertest + .get(`/api/ml/notifications`) + .query({ earliest: 'now-1h', latest: 'now', sortField: 'job_id', sortDirection: 'desc' }) + .auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) + .set(COMMON_REQUEST_HEADERS); + ml.api.assertResponseStatusCode(200, status, body); + + expect(body.results[0].job_id).to.eql('fq_job'); + }); + + it('returns an error for unauthorized user', async () => { + const { body, status } = await supertest + .get(`/api/ml/notifications`) + .auth(USER.ML_UNAUTHORIZED, ml.securityCommon.getPasswordForUser(USER.ML_UNAUTHORIZED)) + .set(COMMON_REQUEST_HEADERS); + ml.api.assertResponseStatusCode(403, status, body); + }); + }); +}; diff --git a/x-pack/test/api_integration/apis/ml/notifications/index.ts b/x-pack/test/api_integration/apis/ml/notifications/index.ts new file mode 100644 index 0000000000000..4a09fce5ee51e --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/notifications/index.ts @@ -0,0 +1,15 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('Notifications', function () { + loadTestFile(require.resolve('./get_notifications')); + loadTestFile(require.resolve('./count_notifications')); + }); +} diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts index b60ce575c4cd0..c17e679b6be31 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts @@ -1513,10 +1513,9 @@ export default ({ getService }: FtrProviderContext): void => { }); describe('throttle', () => { + // For bulk editing of rule actions, NOTIFICATION_THROTTLE_NO_ACTIONS + // is not available as payload, because "Perform No Actions" is not a valid option const casesForEmptyActions = [ - { - payloadThrottle: NOTIFICATION_THROTTLE_NO_ACTIONS, - }, { payloadThrottle: NOTIFICATION_THROTTLE_RULE, }, @@ -1561,10 +1560,6 @@ export default ({ getService }: FtrProviderContext): void => { }); const casesForNonEmptyActions = [ - { - payloadThrottle: NOTIFICATION_THROTTLE_NO_ACTIONS, - expectedThrottle: NOTIFICATION_THROTTLE_NO_ACTIONS, - }, { payloadThrottle: NOTIFICATION_THROTTLE_RULE, expectedThrottle: NOTIFICATION_THROTTLE_RULE, @@ -1616,12 +1611,9 @@ export default ({ getService }: FtrProviderContext): void => { }); describe('notifyWhen', () => { + // For bulk editing of rule actions, NOTIFICATION_THROTTLE_NO_ACTIONS + // is not available as payload, because "Perform No Actions" is not a valid option const cases = [ - { - payload: { throttle: NOTIFICATION_THROTTLE_NO_ACTIONS }, - // keeps existing default value which is onActiveAlert - expected: { notifyWhen: 'onActiveAlert' }, - }, { payload: { throttle: '1d' }, expected: { notifyWhen: 'onThrottleInterval' }, diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules.ts index a8dc735376f69..705714ec3ba50 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules.ts @@ -220,7 +220,7 @@ export default ({ getService }: FtrProviderContext) => { updatedRule.rule_id = createRuleBody.rule_id; updatedRule.name = 'some other name'; updatedRule.actions = [action1]; - updatedRule.throttle = '1m'; + updatedRule.throttle = '1d'; delete updatedRule.id; const { body } = await supertest @@ -243,7 +243,7 @@ export default ({ getService }: FtrProviderContext) => { }, }, ]; - outputRule.throttle = '1m'; + outputRule.throttle = '1d'; const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body); expect(bodyToCompare).to.eql(outputRule); }); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules_bulk.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules_bulk.ts index dc7209b9f1c98..2f5fb63382552 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules_bulk.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules_bulk.ts @@ -150,12 +150,12 @@ export default ({ getService }: FtrProviderContext) => { const updatedRule1 = getSimpleRuleUpdate('rule-1'); updatedRule1.name = 'some other name'; updatedRule1.actions = [action1]; - updatedRule1.throttle = '1m'; + updatedRule1.throttle = '1d'; const updatedRule2 = getSimpleRuleUpdate('rule-2'); updatedRule2.name = 'some other name'; updatedRule2.actions = [action1]; - updatedRule2.throttle = '1m'; + updatedRule2.throttle = '1d'; // update both rule names const { body }: { body: FullResponseSchema[] } = await supertest @@ -179,7 +179,7 @@ export default ({ getService }: FtrProviderContext) => { }, }, ]; - outputRule.throttle = '1m'; + outputRule.throttle = '1d'; const bodyToCompare = removeServerGeneratedProperties(response); expect(bodyToCompare).to.eql(outputRule); }); diff --git a/x-pack/test/fleet_api_integration/apis/agents/reassign.ts b/x-pack/test/fleet_api_integration/apis/agents/reassign.ts index 1283c9433ebba..2dd546511dd9a 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/reassign.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/reassign.ts @@ -121,9 +121,18 @@ export default function (providerContext: FtrProviderContext) { ]); expect(agent2data.body.item.policy_id).to.eql('policy2'); expect(agent3data.body.item.policy_id).to.eql('policy2'); + + const { body } = await supertest + .get(`/api/fleet/agents/action_status`) + .set('kbn-xsrf', 'xxx'); + const actionStatus = body.items[0]; + + expect(actionStatus.status).to.eql('FAILED'); + expect(actionStatus.nbAgentsActionCreated).to.eql(2); + expect(actionStatus.nbAgentsFailed).to.eql(3); }); - it('should allow to reassign multiple agents by id -- mixed invalid, hosted, etc', async () => { + it('should return error when none of the agents can be reassigned -- mixed invalid, hosted, etc', async () => { // agent1 is enrolled in policy1. set policy1 to hosted await supertest .put(`/api/fleet/agent_policies/policy1`) @@ -131,13 +140,15 @@ export default function (providerContext: FtrProviderContext) { .send({ name: 'Test policy', namespace: 'default', is_managed: true }) .expect(200); - await supertest + const { body } = await supertest .post(`/api/fleet/agents/bulk_reassign`) .set('kbn-xsrf', 'xxx') .send({ agents: ['agent2', 'INVALID_ID', 'agent3'], policy_id: 'policy2', - }); + }) + .expect(400); + expect(body.message).to.eql('No agents to reassign, already assigned or hosted agents'); const [agent2data, agent3data] = await Promise.all([ supertest.get(`/api/fleet/agents/agent2`), diff --git a/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts b/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts index fe31806038a5c..7f778d77f1a51 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts @@ -140,6 +140,13 @@ export default function (providerContext: FtrProviderContext) { expect(typeof agent3data.body.item.unenrollment_started_at).to.be('undefined'); expect(typeof agent3data.body.item.unenrolled_at).to.be('undefined'); expect(agent2data.body.item.active).to.eql(true); + + const { body } = await supertest + .get(`/api/fleet/agents/action_status`) + .set('kbn-xsrf', 'xxx'); + const actionStatus = body.items[0]; + expect(actionStatus.status).to.eql('FAILED'); + expect(actionStatus.nbAgentsFailed).to.eql(2); }); it('/agents/bulk_unenroll should allow to unenroll multiple agents by id from an regular agent policy', async () => { diff --git a/x-pack/test/fleet_api_integration/apis/agents/update_agent_tags.ts b/x-pack/test/fleet_api_integration/apis/agents/update_agent_tags.ts index 88079ae5e1aff..ff11076addcec 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/update_agent_tags.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/update_agent_tags.ts @@ -88,27 +88,46 @@ export default function (providerContext: FtrProviderContext) { }); it('should bulk update tags of multiple agents by kuery in batches', async () => { - await supertest + const { body: actionBody } = await supertest .post(`/api/fleet/agents/bulk_update_agent_tags`) .set('kbn-xsrf', 'xxx') .send({ agents: 'active: true', tagsToAdd: ['newTag'], tagsToRemove: ['existingTag'], - batchSize: 2, + batchSize: 3, }) .expect(200); + const actionId = actionBody.actionId; + + const verifyActionResult = async () => { + const { body } = await supertest.get(`/api/fleet/agents`).set('kbn-xsrf', 'xxx'); + expect(body.total).to.eql(4); + body.items.forEach((agent: any) => { + expect(agent.tags.includes('newTag')).to.be(true); + expect(agent.tags.includes('existingTag')).to.be(false); + }); + }; + await new Promise((resolve, reject) => { - setTimeout(async () => { - const { body } = await supertest.get(`/api/fleet/agents`).set('kbn-xsrf', 'xxx'); - expect(body.total).to.eql(4); - body.items.forEach((agent: any) => { - expect(agent.tags.includes('newTag')).to.be(true); - expect(agent.tags.includes('existingTag')).to.be(false); - }); - resolve({}); - }, 2000); + let attempts = 0; + const intervalId = setInterval(async () => { + if (attempts > 4) { + clearInterval(intervalId); + reject('action timed out'); + } + ++attempts; + const { + body: { items: actionStatuses }, + } = await supertest.get(`/api/fleet/agents/action_status`).set('kbn-xsrf', 'xxx'); + const action = actionStatuses.find((a: any) => a.actionId === actionId); + if (action && action.nbAgentsAck === 4) { + clearInterval(intervalId); + await verifyActionResult(); + resolve({}); + } + }, 1000); }).catch((e) => { throw e; }); @@ -156,6 +175,13 @@ export default function (providerContext: FtrProviderContext) { expect(agent1data.body.item.tags.includes('newTag')).to.be(false); expect(agent2data.body.item.tags.includes('newTag')).to.be(true); + + const { body } = await supertest + .get(`/api/fleet/agents/action_status`) + .set('kbn-xsrf', 'xxx'); + const actionStatus = body.items[0]; + expect(actionStatus.status).to.eql('FAILED'); + expect(actionStatus.nbAgentsFailed).to.eql(1); }); }); }); diff --git a/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts b/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts index e2762e21f33ad..e8dad8624021f 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts @@ -608,7 +608,7 @@ export default function (providerContext: FtrProviderContext) { .send({ agents: 'active:true', version: fleetServerVersion, - batchSize: 2, + batchSize: 3, }) .expect(200); @@ -626,7 +626,7 @@ export default function (providerContext: FtrProviderContext) { await new Promise((resolve, reject) => { let attempts = 0; const intervalId = setInterval(async () => { - if (attempts > 2) { + if (attempts > 4) { clearInterval(intervalId); reject('action timed out'); } @@ -636,7 +636,7 @@ export default function (providerContext: FtrProviderContext) { } = await supertest.get(`/api/fleet/agents/action_status`).set('kbn-xsrf', 'xxx'); const action = actionStatuses.find((a: any) => a.actionId === actionId); // 2 upgradeable - if (action && action.nbAgentsActionCreated === 2) { + if (action && action.nbAgentsActionCreated === 2 && action.nbAgentsFailed === 3) { clearInterval(intervalId); await verifyActionResult(); resolve({}); @@ -1032,6 +1032,13 @@ export default function (providerContext: FtrProviderContext) { expect(typeof agent1data.body.item.upgrade_started_at).to.be('undefined'); expect(typeof agent2data.body.item.upgrade_started_at).to.be('string'); + + const { body } = await supertest + .get(`/api/fleet/agents/action_status`) + .set('kbn-xsrf', 'xxx'); + const actionStatus = body.items[0]; + expect(actionStatus.status).to.eql('FAILED'); + expect(actionStatus.nbAgentsFailed).to.eql(1); }); it('enrolled in a hosted agent policy bulk upgrade with force flag should respond with 200 and update the agent SOs', async () => { diff --git a/x-pack/test/functional/apps/infra/home_page.ts b/x-pack/test/functional/apps/infra/home_page.ts index 6acaabcd5d207..1c0323808270d 100644 --- a/x-pack/test/functional/apps/infra/home_page.ts +++ b/x-pack/test/functional/apps/infra/home_page.ts @@ -14,8 +14,9 @@ const DATE_WITHOUT_DATA = DATES.metricsAndLogs.hosts.withoutData; export default ({ getPageObjects, getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); + const browser = getService('browser'); const retry = getService('retry'); - const pageObjects = getPageObjects(['common', 'infraHome', 'infraSavedViews']); + const pageObjects = getPageObjects(['common', 'header', 'infraHome', 'infraSavedViews']); const kibanaServer = getService('kibanaServer'); describe('Home page', function () { @@ -34,6 +35,22 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await pageObjects.common.navigateToApp('infraOps'); await pageObjects.infraHome.getNoMetricsIndicesPrompt(); }); + + it('renders the correct error page title', async () => { + await pageObjects.common.navigateToUrlWithBrowserHistory( + 'infraOps', + '/detail/host/test', + '', + { + ensureCurrentUrl: false, + } + ); + await pageObjects.infraHome.waitForLoading(); + await pageObjects.header.waitUntilLoadingHasFinished(); + + const documentTitle = await browser.getTitle(); + expect(documentTitle).to.contain('Uh oh - Observability - Elastic'); + }); }); describe('with metrics present', () => { @@ -47,6 +64,13 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs') ); + it('renders the correct page title', async () => { + await pageObjects.header.waitUntilLoadingHasFinished(); + + const documentTitle = await browser.getTitle(); + expect(documentTitle).to.contain('Inventory - Infrastructure - Observability - Elastic'); + }); + it('renders an empty data prompt for dates with no data', async () => { await pageObjects.infraHome.goToTime(DATE_WITHOUT_DATA); await pageObjects.infraHome.getNoMetricsDataPrompt(); diff --git a/x-pack/test/functional/apps/infra/link_to.ts b/x-pack/test/functional/apps/infra/link_to.ts index ebfcb740961b1..05eccc8e57ebc 100644 --- a/x-pack/test/functional/apps/infra/link_to.ts +++ b/x-pack/test/functional/apps/infra/link_to.ts @@ -42,6 +42,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await retry.tryForTime(5000, async () => { const currentUrl = await browser.getCurrentUrl(); const parsedUrl = new URL(currentUrl); + const documentTitle = await browser.getTitle(); expect(parsedUrl.pathname).to.be('/app/logs/stream'); expect(parsedUrl.searchParams.get('logFilter')).to.be( @@ -51,6 +52,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { `(end:'${endDate}',position:(tiebreaker:0,time:${timestamp}),start:'${startDate}',streamLive:!f)` ); expect(parsedUrl.searchParams.get('sourceId')).to.be('default'); + expect(documentTitle).to.contain('Stream - Logs - Observability - Elastic'); }); }); }); diff --git a/x-pack/test/functional/apps/infra/logs_source_configuration.ts b/x-pack/test/functional/apps/infra/logs_source_configuration.ts index 56eed5ec4b635..38cc795034a22 100644 --- a/x-pack/test/functional/apps/infra/logs_source_configuration.ts +++ b/x-pack/test/functional/apps/infra/logs_source_configuration.ts @@ -16,6 +16,7 @@ const COMMON_REQUEST_HEADERS = { export default ({ getPageObjects, getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); + const browser = getService('browser'); const logsUi = getService('logsUi'); const infraSourceConfigurationForm = getService('infraSourceConfigurationForm'); const pageObjects = getPageObjects(['common', 'header', 'infraLogs']); @@ -49,6 +50,15 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'); }); + it('renders the correct page title', async () => { + await pageObjects.infraLogs.navigateToTab('settings'); + + await pageObjects.header.waitUntilLoadingHasFinished(); + const documentTitle = await browser.getTitle(); + + expect(documentTitle).to.contain('Settings - Logs - Observability - Elastic'); + }); + it('can change the log indices to a pattern that matches nothing', async () => { await pageObjects.infraLogs.navigateToTab('settings'); diff --git a/x-pack/test/functional/apps/infra/metrics_explorer.ts b/x-pack/test/functional/apps/infra/metrics_explorer.ts index fc620d9ba5665..4d6859a4e99e7 100644 --- a/x-pack/test/functional/apps/infra/metrics_explorer.ts +++ b/x-pack/test/functional/apps/infra/metrics_explorer.ts @@ -16,6 +16,7 @@ const timepickerFormat = 'MMM D, YYYY @ HH:mm:ss.SSS'; export default ({ getPageObjects, getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); + const browser = getService('browser'); const pageObjects = getPageObjects([ 'common', 'infraHome', @@ -42,6 +43,13 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); after(() => esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs')); + it('should render the correct page title', async () => { + const documentTitle = await browser.getTitle(); + expect(documentTitle).to.contain( + 'Metrics Explorer - Infrastructure - Observability - Elastic' + ); + }); + it('should have three metrics by default', async () => { const metrics = await pageObjects.infraMetricsExplorer.getMetrics(); expect(metrics.length).to.equal(3); diff --git a/x-pack/test/functional/apps/lens/group3/tsvb_open_in_lens.ts b/x-pack/test/functional/apps/lens/group3/tsvb_open_in_lens.ts index a7acd8bf5ba1c..173ab1c4fdf04 100644 --- a/x-pack/test/functional/apps/lens/group3/tsvb_open_in_lens.ts +++ b/x-pack/test/functional/apps/lens/group3/tsvb_open_in_lens.ts @@ -102,9 +102,18 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await visualBuilder.clickDataTab('metric'); }); - it('should hide the "Edit Visualization in Lens" menu item', async () => { + it('should show the "Edit Visualization in Lens" menu item', async () => { const button = await testSubjects.exists('visualizeEditInLensButton'); - expect(button).to.eql(false); + expect(button).to.eql(true); + }); + + it('should convert to Lens', async () => { + const button = await testSubjects.find('visualizeEditInLensButton'); + await button.click(); + await lens.waitForVisualization('mtrVis'); + + const metricData = await lens.getMetricVisualizationData(); + expect(metricData[0].title).to.eql('Count of records'); }); }); diff --git a/x-pack/test/functional/apps/ml/short_tests/index.ts b/x-pack/test/functional/apps/ml/short_tests/index.ts index f96d2b91ee0ef..d446a35933474 100644 --- a/x-pack/test/functional/apps/ml/short_tests/index.ts +++ b/x-pack/test/functional/apps/ml/short_tests/index.ts @@ -33,5 +33,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./model_management')); loadTestFile(require.resolve('./feature_controls')); loadTestFile(require.resolve('./settings')); + loadTestFile(require.resolve('./notifications')); }); } diff --git a/x-pack/test/functional/apps/ml/short_tests/notifications/index.ts b/x-pack/test/functional/apps/ml/short_tests/notifications/index.ts new file mode 100644 index 0000000000000..e026d44a67af2 --- /dev/null +++ b/x-pack/test/functional/apps/ml/short_tests/notifications/index.ts @@ -0,0 +1,16 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('Notifcations', function () { + this.tags(['ml', 'skipFirefox']); + + loadTestFile(require.resolve('./notification_list')); + }); +} diff --git a/x-pack/test/functional/apps/ml/short_tests/notifications/notification_list.ts b/x-pack/test/functional/apps/ml/short_tests/notifications/notification_list.ts new file mode 100644 index 0000000000000..c9ad8d2423ef8 --- /dev/null +++ b/x-pack/test/functional/apps/ml/short_tests/notifications/notification_list.ts @@ -0,0 +1,96 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['common']); + const esArchiver = getService('esArchiver'); + const ml = getService('ml'); + const browser = getService('browser'); + + describe('Notifications list', function () { + before(async () => { + await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); + await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.setKibanaTimeZoneToUTC(); + + // Prepare jobs to generate notifications + await Promise.all( + [ + { jobId: 'fq_001', spaceId: undefined }, + { jobId: 'fq_002', spaceId: 'space1' }, + ].map(async (v) => { + const datafeedConfig = ml.commonConfig.getADFqDatafeedConfig(v.jobId); + + await ml.api.createAnomalyDetectionJob( + ml.commonConfig.getADFqSingleMetricJobConfig(v.jobId), + v.spaceId + ); + await ml.api.openAnomalyDetectionJob(v.jobId); + await ml.api.createDatafeed(datafeedConfig, v.spaceId); + await ml.api.startDatafeed(datafeedConfig.datafeed_id); + }) + ); + + await ml.securityUI.loginAsMlPowerUser(); + await PageObjects.common.navigateToApp('ml', { + basePath: '', + }); + }); + + after(async () => { + await ml.api.cleanMlIndices(); + await ml.testResources.cleanMLSavedObjects(); + await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + }); + + it('displays a generic notification indicator', async () => { + await ml.notifications.assertNotificationIndicatorExist(); + }); + + it('opens the Notifications page', async () => { + await ml.navigation.navigateToNotifications(); + + await ml.notifications.table.waitForTableToLoad(); + await ml.notifications.table.assertRowsNumberPerPage(25); + }); + + it('does not show notifications from another space', async () => { + await ml.notifications.table.filterWithSearchString('Job created', 1); + }); + + it('display a number of errors in the notification indicator', async () => { + await ml.navigation.navigateToOverview(); + + const jobConfig = ml.commonConfig.getADFqSingleMetricJobConfig('fq_fail'); + jobConfig.analysis_config = { + bucket_span: '15m', + influencers: ['airline'], + detectors: [ + { function: 'mean', field_name: 'responsetime', partition_field_name: 'airline' }, + { function: 'min', field_name: 'responsetime', partition_field_name: 'airline' }, + { function: 'max', field_name: 'responsetime', partition_field_name: 'airline' }, + ], + }; + // Set extremely low memory limit to trigger an error + jobConfig.analysis_limits!.model_memory_limit = '1024kb'; + + const datafeedConfig = ml.commonConfig.getADFqDatafeedConfig(jobConfig.job_id); + + await ml.api.createAnomalyDetectionJob(jobConfig); + await ml.api.openAnomalyDetectionJob(jobConfig.job_id); + await ml.api.createDatafeed(datafeedConfig); + await ml.api.startDatafeed(datafeedConfig.datafeed_id); + await ml.api.waitForJobMemoryStatus(jobConfig.job_id, 'hard_limit'); + + // refresh the page to avoid 1m wait + await browser.refresh(); + await ml.notifications.assertNotificationErrorsCount(0); + }); + }); +} diff --git a/x-pack/test/functional/services/ml/api.ts b/x-pack/test/functional/services/ml/api.ts index 07bd1f346cf25..62d46e644f173 100644 --- a/x-pack/test/functional/services/ml/api.ts +++ b/x-pack/test/functional/services/ml/api.ts @@ -273,6 +273,16 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) { return state; }, + async getJobMemoryStatus(jobId: string): Promise<'hard_limit' | 'soft_limit' | 'ok'> { + const jobStats = await this.getADJobStats(jobId); + + expect(jobStats.jobs).to.have.length( + 1, + `Expected job stats to have exactly one job (got '${jobStats.length}')` + ); + return jobStats.jobs[0].model_size_stats.memory_status; + }, + async getADJobStats(jobId: string): Promise { log.debug(`Fetching anomaly detection job stats for job ${jobId}...`); const { body: jobStats, status } = await esSupertest.get( @@ -299,6 +309,27 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) { }); }, + async waitForJobMemoryStatus( + jobId: string, + expectedMemoryStatus: 'hard_limit' | 'soft_limit' | 'ok', + timeout: number = 2 * 60 * 1000 + ) { + await retry.waitForWithTimeout( + `job memory status to be ${expectedMemoryStatus}`, + timeout, + async () => { + const memoryStatus = await this.getJobMemoryStatus(jobId); + if (memoryStatus === expectedMemoryStatus) { + return true; + } else { + throw new Error( + `expected job memory status to be ${expectedMemoryStatus} but got ${memoryStatus}` + ); + } + } + ); + }, + async getDatafeedState(datafeedId: string): Promise { log.debug(`Fetching datafeed state for datafeed ${datafeedId}`); const { body: datafeedStats, status } = await esSupertest.get( @@ -576,6 +607,18 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) { return response; }, + async hasNotifications(query: object) { + const body = await es.search({ + index: '.ml-notifications*', + body: { + size: 10000, + query, + }, + }); + + return body.hits.hits.length > 0; + }, + async adJobExist(jobId: string) { this.validateJobId(jobId); try { @@ -608,6 +651,24 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) { }); }, + async waitForJobNotificationsToIndex(jobId: string, timeout: number = 60 * 1000) { + await retry.waitForWithTimeout(`Notifications for '${jobId}' to exist`, timeout, async () => { + if ( + await this.hasNotifications({ + term: { + job_id: { + value: jobId, + }, + }, + }) + ) { + return true; + } else { + throw new Error(`expected '${jobId}' notifications to exist`); + } + }); + }, + async createAnomalyDetectionJob(jobConfig: Job, space?: string) { const jobId = jobConfig.job_id; log.debug( diff --git a/x-pack/test/functional/services/ml/common_table_service.ts b/x-pack/test/functional/services/ml/common_table_service.ts new file mode 100644 index 0000000000000..50a40ab43f35a --- /dev/null +++ b/x-pack/test/functional/services/ml/common_table_service.ts @@ -0,0 +1,118 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { WebElementWrapper } from '../../../../../test/functional/services/lib/web_element_wrapper'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export type MlTableService = ReturnType; + +export function MlTableServiceProvider({ getPageObject, getService }: FtrProviderContext) { + const testSubjects = getService('testSubjects'); + const commonPage = getPageObject('common'); + + const TableService = class { + constructor( + public readonly tableTestSubj: string, + public readonly tableRowSubj: string, + public readonly columns: Array<{ id: string; testSubj: string }>, + public readonly searchInputSubj: string + ) {} + + public async assertTableLoaded() { + await testSubjects.existOrFail(`~${this.tableTestSubj} loaded`); + } + + public async assertTableLoading() { + await testSubjects.existOrFail(`~${this.tableTestSubj} loading`); + } + + public async parseTable() { + const table = await testSubjects.find(`~${this.tableTestSubj}`); + const $ = await table.parseDomContent(); + const rows = []; + + for (const tr of $.findTestSubjects(`~${this.tableRowSubj}`).toArray()) { + const $tr = $(tr); + + const rowObject = this.columns.reduce((acc, curr) => { + acc[curr.id] = $tr + .findTestSubject(curr.testSubj) + .find('.euiTableCellContent') + .text() + .trim(); + return acc; + }, {} as Record); + + rows.push(rowObject); + } + + return rows; + } + + public async assertRowsNumberPerPage(rowsNumber: 10 | 25 | 50 | 100) { + const textContent = await testSubjects.getVisibleText( + `~${this.tableTestSubj} > tablePaginationPopoverButton` + ); + expect(textContent).to.be(`Rows per page: ${rowsNumber}`); + } + + public async waitForTableToStartLoading() { + await testSubjects.existOrFail(`~${this.tableTestSubj}`, { timeout: 60 * 1000 }); + await testSubjects.existOrFail(`${this.tableTestSubj} loading`, { timeout: 30 * 1000 }); + } + + public async waitForTableToLoad() { + await testSubjects.existOrFail(`~${this.tableTestSubj}`, { timeout: 60 * 1000 }); + await testSubjects.existOrFail(`${this.tableTestSubj} loaded`, { timeout: 30 * 1000 }); + } + + async getSearchInput(): Promise { + return await testSubjects.find(this.searchInputSubj); + } + + public async assertSearchInputValue(expectedSearchValue: string) { + const searchBarInput = await this.getSearchInput(); + const actualSearchValue = await searchBarInput.getAttribute('value'); + expect(actualSearchValue).to.eql( + expectedSearchValue, + `Search input value should be '${expectedSearchValue}' (got '${actualSearchValue}')` + ); + } + + public async filterWithSearchString(queryString: string, expectedRowCount: number = 1) { + await this.waitForTableToLoad(); + const searchBarInput = await this.getSearchInput(); + await searchBarInput.clearValueWithKeyboard(); + await searchBarInput.type(queryString); + await commonPage.pressEnterKey(); + await this.assertSearchInputValue(queryString); + await this.waitForTableToStartLoading(); + await this.waitForTableToLoad(); + + const rows = await this.parseTable(); + + expect(rows).to.have.length( + expectedRowCount, + `Filtered table should have ${expectedRowCount} row(s) for filter '${queryString}' (got ${rows.length} matching items)` + ); + } + }; + + return { + getServiceInstance( + name: string, + tableTestSubj: string, + tableRowSubj: string, + columns: Array<{ id: string; testSubj: string }>, + searchInputSubj: string + ) { + Object.defineProperty(TableService, 'name', { value: name }); + return new TableService(tableTestSubj, tableRowSubj, columns, searchInputSubj); + }, + }; +} diff --git a/x-pack/test/functional/services/ml/common_ui.ts b/x-pack/test/functional/services/ml/common_ui.ts index 0d8ee7d11a8b1..ef69f909437c1 100644 --- a/x-pack/test/functional/services/ml/common_ui.ts +++ b/x-pack/test/functional/services/ml/common_ui.ts @@ -164,22 +164,27 @@ export function MachineLearningCommonUIProvider({ }, async setMultiSelectFilter(testDataSubj: string, fieldTypes: string[]) { - await testSubjects.clickWhenNotDisabledWithoutRetry(`${testDataSubj}-button`); - await testSubjects.existOrFail(`${testDataSubj}-popover`); - await testSubjects.existOrFail(`${testDataSubj}-searchInput`); - const searchBarInput = await testSubjects.find(`${testDataSubj}-searchInput`); + await retry.tryForTime(60 * 1000, async () => { + // escape popover + await browser.pressKeys(browser.keys.ESCAPE); - for (const fieldType of fieldTypes) { - await retry.tryForTime(5000, async () => { - await searchBarInput.clearValueWithKeyboard(); - await searchBarInput.type(fieldType); - if (!(await testSubjects.exists(`${testDataSubj}-option-${fieldType}-checked`))) { - await testSubjects.existOrFail(`${testDataSubj}-option-${fieldType}`); - await testSubjects.click(`${testDataSubj}-option-${fieldType}`); - await testSubjects.existOrFail(`${testDataSubj}-option-${fieldType}-checked`); - } - }); - } + await testSubjects.clickWhenNotDisabledWithoutRetry(`${testDataSubj}-button`); + await testSubjects.existOrFail(`${testDataSubj}-popover`); + await testSubjects.existOrFail(`${testDataSubj}-searchInput`); + const searchBarInput = await testSubjects.find(`${testDataSubj}-searchInput`); + + for (const fieldType of fieldTypes) { + await retry.tryForTime(5000, async () => { + await searchBarInput.clearValueWithKeyboard(); + await searchBarInput.type(fieldType); + if (!(await testSubjects.exists(`${testDataSubj}-option-${fieldType}-checked`))) { + await testSubjects.existOrFail(`${testDataSubj}-option-${fieldType}`); + await testSubjects.click(`${testDataSubj}-option-${fieldType}`); + await testSubjects.existOrFail(`${testDataSubj}-option-${fieldType}-checked`); + } + }); + } + }); // escape popover await browser.pressKeys(browser.keys.ESCAPE); diff --git a/x-pack/test/functional/services/ml/index.ts b/x-pack/test/functional/services/ml/index.ts index d8c6924ec4cfd..9452baa324898 100644 --- a/x-pack/test/functional/services/ml/index.ts +++ b/x-pack/test/functional/services/ml/index.ts @@ -59,6 +59,8 @@ import { MachineLearningJobAnnotationsProvider } from './job_annotations_table'; import { MlNodesPanelProvider } from './ml_nodes_list'; import { MachineLearningCasesProvider } from './cases'; import { AnomalyChartsProvider } from './anomaly_charts'; +import { NotificationsProvider } from './notifications'; +import { MlTableServiceProvider } from './common_table_service'; export function MachineLearningProvider(context: FtrProviderContext) { const commonAPI = MachineLearningCommonAPIProvider(context); @@ -123,6 +125,7 @@ export function MachineLearningProvider(context: FtrProviderContext) { const settingsFilterList = MachineLearningSettingsFilterListProvider(context, commonUI); const singleMetricViewer = MachineLearningSingleMetricViewerProvider(context, commonUI); const stackManagementJobs = MachineLearningStackManagementJobsProvider(context); + const tableService = MlTableServiceProvider(context); const testExecution = MachineLearningTestExecutionProvider(context); const testResources = MachineLearningTestResourcesProvider(context, api); const alerting = MachineLearningAlertingProvider(context, api, commonUI); @@ -130,6 +133,7 @@ export function MachineLearningProvider(context: FtrProviderContext) { const trainedModels = TrainedModelsProvider(context, commonUI); const trainedModelsTable = TrainedModelsTableProvider(context, commonUI); const mlNodesPanel = MlNodesPanelProvider(context); + const notifications = NotificationsProvider(context, commonUI, tableService); const cases = MachineLearningCasesProvider(context, swimLane, anomalyCharts); @@ -171,7 +175,9 @@ export function MachineLearningProvider(context: FtrProviderContext) { jobWizardMultiMetric, jobWizardPopulation, lensVisualizations, + mlNodesPanel, navigation, + notifications, overviewPage, securityCommon, securityUI, @@ -181,10 +187,10 @@ export function MachineLearningProvider(context: FtrProviderContext) { singleMetricViewer, stackManagementJobs, swimLane, + tableService, testExecution, testResources, trainedModels, trainedModelsTable, - mlNodesPanel, }; } diff --git a/x-pack/test/functional/services/ml/notifications.ts b/x-pack/test/functional/services/ml/notifications.ts new file mode 100644 index 0000000000000..2365717d7226b --- /dev/null +++ b/x-pack/test/functional/services/ml/notifications.ts @@ -0,0 +1,48 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; +import { MlCommonUI } from './common_ui'; +import { MlTableService } from './common_table_service'; + +export function NotificationsProvider( + { getService }: FtrProviderContext, + mlCommonUI: MlCommonUI, + tableService: MlTableService +) { + const testSubjects = getService('testSubjects'); + + return { + async assertNotificationIndicatorExist(expectExist = true) { + if (expectExist) { + await testSubjects.existOrFail('mlNotificationsIndicator'); + } else { + await testSubjects.missingOrFail('mlNotificationsIndicator'); + } + }, + + async assertNotificationErrorsCount(expectedCount: number) { + const actualCount = await testSubjects.getVisibleText('mlNotificationErrorsIndicator'); + expect(actualCount).to.greaterThan(expectedCount); + }, + + table: tableService.getServiceInstance( + 'NotificationsTable', + 'mlNotificationsTable', + 'mlNotificationsTableRow', + [ + { id: 'timestamp', testSubj: 'mlNotificationTime' }, + { id: 'level', testSubj: 'mlNotificationLevel' }, + { id: 'job_type', testSubj: 'mlNotificationType' }, + { id: 'job_id', testSubj: 'mlNotificationEntity' }, + { id: 'message', testSubj: 'mlNotificationMessage' }, + ], + 'mlNotificationsSearchBarInput' + ), + }; +} diff --git a/x-pack/test/functional/services/ml/test_resources.ts b/x-pack/test/functional/services/ml/test_resources.ts index 4fccde6712e62..d1a7557caf2b1 100644 --- a/x-pack/test/functional/services/ml/test_resources.ts +++ b/x-pack/test/functional/services/ml/test_resources.ts @@ -46,6 +46,14 @@ export function MachineLearningTestResourcesProvider( await kibanaServer.uiSettings.unset('dateFormat:tz'); }, + async disableKibanaAnnouncements() { + await kibanaServer.uiSettings.update({ hideAnnouncements: true }); + }, + + async resetKibanaAnnouncements() { + await kibanaServer.uiSettings.unset('hideAnnouncements'); + }, + async savedObjectExistsById(id: string, objectType: SavedObjectType): Promise { const response = await supertest.get(`/api/saved_objects/${objectType}/${id}`); return response.status === 200; diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/upgrade.ts b/x-pack/test/functional_with_es_ssl/apps/cases/upgrade.ts index cbbbb90c05abc..c1e2979d313bb 100644 --- a/x-pack/test/functional_with_es_ssl/apps/cases/upgrade.ts +++ b/x-pack/test/functional_with_es_ssl/apps/cases/upgrade.ts @@ -18,6 +18,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const supertest = getService('supertest'); const testSubjects = getService('testSubjects'); const find = getService('find'); + const toasts = getService('toasts'); const updateConnector = async (id: string, req: Record) => { const { body: connector } = await supertest @@ -74,6 +75,10 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); describe('Case view page', function () { + it('does not show any error toasters', async () => { + expect(await toasts.getToastCount()).to.be(0); + }); + it('shows the title correctly', async () => { const title = await testSubjects.find('header-page-title'); expect(await title.getVisibleText()).equal('Upgrade test in Kibana'); @@ -275,6 +280,10 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { it('shows the add comment button', async () => { await testSubjects.exists('submit-comment'); }); + + it('shows the assignees section', async () => { + await testSubjects.exists('case-view-assignees'); + }); }); }); }; diff --git a/x-pack/test/screenshot_creation/apps/ml_docs/index.ts b/x-pack/test/screenshot_creation/apps/ml_docs/index.ts index 1c12efc89caf7..806414939cd84 100644 --- a/x-pack/test/screenshot_creation/apps/ml_docs/index.ts +++ b/x-pack/test/screenshot_creation/apps/ml_docs/index.ts @@ -22,6 +22,7 @@ export default function ({ getPageObject, getService, loadTestFile }: FtrProvide before(async () => { await ml.testResources.installAllKibanaSampleData(); await ml.testResources.setKibanaTimeZoneToUTC(); + await ml.testResources.disableKibanaAnnouncements(); await browser.setWindowSize(1920, 1080); }); @@ -29,6 +30,7 @@ export default function ({ getPageObject, getService, loadTestFile }: FtrProvide await securityPage.forceLogout(); await ml.testResources.removeAllKibanaSampleData(); await ml.testResources.resetKibanaTimeZone(); + await ml.testResources.resetKibanaAnnouncements(); }); loadTestFile(require.resolve('./anomaly_detection')); diff --git a/x-pack/test/screenshot_creation/apps/response_ops_docs/index.ts b/x-pack/test/screenshot_creation/apps/response_ops_docs/index.ts index 64ed2599d65b4..e836e3e63c9b7 100644 --- a/x-pack/test/screenshot_creation/apps/response_ops_docs/index.ts +++ b/x-pack/test/screenshot_creation/apps/response_ops_docs/index.ts @@ -23,6 +23,7 @@ export default function ({ getPageObject, getService, loadTestFile }: FtrProvide before(async () => { await ml.testResources.installAllKibanaSampleData(); await ml.testResources.setKibanaTimeZoneToUTC(); + await ml.testResources.disableKibanaAnnouncements(); await browser.setWindowSize(1920, 1080); await securityPage.login( esTestConfig.getUrlParts().username, @@ -34,6 +35,7 @@ export default function ({ getPageObject, getService, loadTestFile }: FtrProvide await securityPage.forceLogout(); await ml.testResources.removeAllKibanaSampleData(); await ml.testResources.resetKibanaTimeZone(); + await ml.testResources.resetKibanaAnnouncements(); }); loadTestFile(require.resolve('./stack_cases')); diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/metadata.fixtures.ts b/x-pack/test/security_solution_endpoint_api_int/apis/metadata.fixtures.ts index 281ba95d8e0cb..3a81ad1c71dcb 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/metadata.fixtures.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/metadata.fixtures.ts @@ -247,8 +247,8 @@ export function generateMetadataDocs(timestamp: number) { dataset: 'endpoint.metadata', }, host: { - hostname: 'rezzani-7.example.com', - name: 'rezzani-7.example.com', + hostname: 'Example-host-name-XYZ', + name: 'Example-host-name-XYZ', id: 'fc0ff548-feba-41b6-8367-65e8790d0eaf', ip: ['10.101.149.26', '2606:a000:ffc0:39:11ef:37b9:3371:578c'], mac: ['e2-6d-f9-0-46-2e'], @@ -399,8 +399,8 @@ export function generateMetadataDocs(timestamp: number) { }, host: { architecture: 'x86', - hostname: 'rezzani-7.example.com', - name: 'rezzani-7.example.com', + hostname: 'Example-host-name-XYZ', + name: 'Example-host-name-XYZ', id: 'fc0ff548-feba-41b6-8367-65e8790d0eaf', ip: ['10.101.149.26', '2606:a000:ffc0:39:11ef:37b9:3371:578c'], mac: ['e2-6d-f9-0-46-2e'], @@ -550,8 +550,8 @@ export function generateMetadataDocs(timestamp: number) { }, host: { architecture: 'x86', - hostname: 'rezzani-7.example.com', - name: 'rezzani-7.example.com', + hostname: 'Example-host-name-XYZ', + name: 'Example-host-name-XYZ', id: 'fc0ff548-feba-41b6-8367-65e8790d0eaf', ip: ['10.101.149.26', '2606:a000:ffc0:39:11ef:37b9:3371:578c'], mac: ['e2-6d-f9-0-46-2e'], diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts b/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts index 508aa8884fcfe..0ee6b44952577 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts @@ -259,6 +259,26 @@ export default function ({ getService }: FtrProviderContext) { expect(body.pageSize).to.eql(10); }); + it('metadata api should return the endpoint based on the agent hostname', async () => { + const targetEndpointId = 'fc0ff548-feba-41b6-8367-65e8790d0eaf'; + const targetAgentHostname = 'Example-host-name-XYZ'; + const { body } = await supertest + .get(HOST_METADATA_LIST_ROUTE) + .set('kbn-xsrf', 'xxx') + .query({ + kuery: `united.endpoint.host.hostname:${targetAgentHostname}`, + }) + .expect(200); + expect(body.total).to.eql(1); + const resultHostId: string = body.data[0].metadata.host.id; + const resultElasticAgentName: string = body.data[0].metadata.host.hostname; + expect(resultHostId).to.eql(targetEndpointId); + expect(resultElasticAgentName).to.eql(targetAgentHostname); + expect(body.data.length).to.eql(1); + expect(body.page).to.eql(0); + expect(body.pageSize).to.eql(10); + }); + it('metadata api should return all hosts when filter is empty string', async () => { const { body } = await supertest .get(HOST_METADATA_LIST_ROUTE) diff --git a/yarn.lock b/yarn.lock index f809bc0cac463..085f55146d4ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2954,6 +2954,14 @@ version "0.0.0" uid "" +"@kbn/core-http-request-handler-context-server-internal@link:bazel-bin/packages/core/http/core-http-request-handler-context-server-internal": + version "0.0.0" + uid "" + +"@kbn/core-http-request-handler-context-server@link:bazel-bin/packages/core/http/core-http-request-handler-context-server": + version "0.0.0" + uid "" + "@kbn/core-http-router-server-internal@link:bazel-bin/packages/core/http/core-http-router-server-internal": version "0.0.0" uid "" @@ -7075,6 +7083,14 @@ version "0.0.0" uid "" +"@types/kbn__core-http-request-handler-context-server-internal@link:bazel-bin/packages/core/http/core-http-request-handler-context-server-internal/npm_module_types": + version "0.0.0" + uid "" + +"@types/kbn__core-http-request-handler-context-server@link:bazel-bin/packages/core/http/core-http-request-handler-context-server/npm_module_types": + version "0.0.0" + uid "" + "@types/kbn__core-http-router-server-internal@link:bazel-bin/packages/core/http/core-http-router-server-internal/npm_module_types": version "0.0.0" uid ""