diff --git a/.eslintignore b/.eslintignore index 66684fbcd52e6..4c6618779bbda 100644 --- a/.eslintignore +++ b/.eslintignore @@ -21,8 +21,6 @@ snapshots.js # plugin overrides /src/core/lib/kbn_internal_native_observable /src/plugins/data/common/es_query/kuery/ast/_generated_/** -/src/plugins/vis_type_timelion/common/_generated_/** -/x-pack/plugins/apm/e2e/tmp/* /x-pack/plugins/canvas/canvas_plugin /x-pack/plugins/canvas/shareable_runtime/build /x-pack/plugins/canvas/storybook/build diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a2d95405dcb82..48674bc5444ff 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -27,9 +27,9 @@ /src/plugins/kibana_legacy/ @elastic/kibana-vis-editors /src/plugins/vis_default_editor/ @elastic/kibana-vis-editors /src/plugins/vis_types/metric/ @elastic/kibana-vis-editors -/src/plugins/vis_type_table/ @elastic/kibana-vis-editors +/src/plugins/vis_types/table/ @elastic/kibana-vis-editors /src/plugins/vis_types/tagcloud/ @elastic/kibana-vis-editors -/src/plugins/vis_type_timelion/ @elastic/kibana-vis-editors +/src/plugins/vis_types/timelion/ @elastic/kibana-vis-editors /src/plugins/vis_type_timeseries/ @elastic/kibana-vis-editors /src/plugins/vis_types/vega/ @elastic/kibana-vis-editors /src/plugins/vis_types/vislib/ @elastic/kibana-vis-editors @@ -125,8 +125,6 @@ /x-pack/test/api_integration/apis/uptime @elastic/uptime # Client Side Monitoring / Uptime (lives in APM directories but owned by Uptime) -/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm @elastic/uptime -/x-pack/plugins/apm/e2e/cypress/integration/csm_dashboard.feature @elastic/uptime /x-pack/plugins/apm/public/application/uxApp.tsx @elastic/uptime /x-pack/plugins/apm/public/components/app/RumDashboard @elastic/uptime /x-pack/plugins/apm/server/lib/rum_client @elastic/uptime diff --git a/.github/paths-labeller.yml b/.github/paths-labeller.yml index 81d57be9b2d95..37414be6973ad 100644 --- a/.github/paths-labeller.yml +++ b/.github/paths-labeller.yml @@ -15,7 +15,6 @@ - "x-pack/test/fleet_api_integration/**/*.*" - "Team:uptime": - "x-pack/plugins/uptime/**/*.*" - - "x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/*.*" - "x-pack/plugins/apm/public/application/csmApp.tsx" - "x-pack/plugins/apm/public/components/app/RumDashboard/**/*.*" - "x-pack/plugins/apm/public/components/app/RumDashboard/*.*" diff --git a/.i18nrc.json b/.i18nrc.json index 11d31be8f891c..08783349ec64e 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -56,12 +56,12 @@ "server": "src/legacy/server", "statusPage": "src/legacy/core_plugins/status_page", "telemetry": ["src/plugins/telemetry", "src/plugins/telemetry_management_section"], - "timelion": ["src/plugins/vis_type_timelion"], + "timelion": ["src/plugins/vis_types/timelion"], "uiActions": "src/plugins/ui_actions", "visDefaultEditor": "src/plugins/vis_default_editor", "visTypeMarkdown": "src/plugins/vis_type_markdown", "visTypeMetric": "src/plugins/vis_types/metric", - "visTypeTable": "src/plugins/vis_type_table", + "visTypeTable": "src/plugins/vis_types/table", "visTypeTagCloud": "src/plugins/vis_types/tagcloud", "visTypeTimeseries": "src/plugins/vis_type_timeseries", "visTypeVega": "src/plugins/vis_types/vega", diff --git a/api_docs/core.json b/api_docs/core.json index 2e9e92cced3e9..6f429f3ee38e8 100644 --- a/api_docs/core.json +++ b/api_docs/core.json @@ -753,19 +753,19 @@ "references": [ { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/public/plugin.ts" + "path": "src/plugins/vis_types/table/public/plugin.ts" }, { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/public/plugin.ts" + "path": "src/plugins/vis_types/table/public/plugin.ts" }, { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/target/types/public/plugin.d.ts" + "path": "src/plugins/vis_types/table/target/types/public/plugin.d.ts" }, { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/target/types/public/plugin.d.ts" + "path": "src/plugins/vis_types/table/target/types/public/plugin.d.ts" } ], "children": [ diff --git a/api_docs/data.json b/api_docs/data.json index d6442b90246a9..e62ddb5e30f12 100644 --- a/api_docs/data.json +++ b/api_docs/data.json @@ -5004,11 +5004,11 @@ }, { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts" + "path": "src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts" }, { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts" + "path": "src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts" }, { "plugin": "visTypeVega", @@ -16631,11 +16631,11 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts" }, { "plugin": "visualize", @@ -16671,11 +16671,11 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/timelion_vis_fn.ts" + "path": "src/plugins/vis_types/timelion/public/timelion_vis_fn.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/timelion_vis_fn.ts" + "path": "src/plugins/vis_types/timelion/public/timelion_vis_fn.ts" }, { "plugin": "dashboard", @@ -18119,11 +18119,11 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/plugin_services.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/plugin_services.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/plugin_services.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/plugin_services.ts" }, { "plugin": "indexPatternManagement", @@ -18135,11 +18135,11 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.test.ts" + "path": "src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.test.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.test.ts" + "path": "src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.test.ts" }, { "plugin": "discover", @@ -19008,27 +19008,27 @@ "references": [ { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx" + "path": "src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx" + "path": "src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx" + "path": "src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx" + "path": "src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx" + "path": "src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx" + "path": "src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx" } ], "initialIsOpen": false @@ -21706,15 +21706,15 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts" }, { "plugin": "visTypeVega", @@ -24261,7 +24261,7 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/plugin.ts" + "path": "src/plugins/vis_types/timelion/public/plugin.ts" }, { "plugin": "visTypeTimeseries", @@ -24479,7 +24479,7 @@ }, { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/public/plugin.ts" + "path": "src/plugins/vis_types/table/public/plugin.ts" }, { "plugin": "visTypeTimeseries", @@ -27306,11 +27306,11 @@ }, { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts" + "path": "src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts" }, { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts" + "path": "src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts" }, { "plugin": "visTypeVega", @@ -32208,11 +32208,11 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts" }, { "plugin": "visualize", @@ -32248,11 +32248,11 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/timelion_vis_fn.ts" + "path": "src/plugins/vis_types/timelion/public/timelion_vis_fn.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/timelion_vis_fn.ts" + "path": "src/plugins/vis_types/timelion/public/timelion_vis_fn.ts" }, { "plugin": "dashboard", @@ -38924,11 +38924,11 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts" }, { "plugin": "visualize", @@ -38964,11 +38964,11 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/timelion_vis_fn.ts" + "path": "src/plugins/vis_types/timelion/public/timelion_vis_fn.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/timelion_vis_fn.ts" + "path": "src/plugins/vis_types/timelion/public/timelion_vis_fn.ts" }, { "plugin": "dashboard", @@ -39892,27 +39892,27 @@ "references": [ { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx" + "path": "src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx" + "path": "src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx" + "path": "src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx" + "path": "src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx" + "path": "src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx" + "path": "src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx" } ], "initialIsOpen": false diff --git a/api_docs/data_index_patterns.json b/api_docs/data_index_patterns.json index dc87175ac6d1b..cf621b2413975 100644 --- a/api_docs/data_index_patterns.json +++ b/api_docs/data_index_patterns.json @@ -5927,11 +5927,11 @@ }, { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts" + "path": "src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts" }, { "plugin": "visTypeTable", - "path": "src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts" + "path": "src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts" }, { "plugin": "visTypeVega", @@ -13270,11 +13270,11 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/plugin_services.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/plugin_services.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/helpers/plugin_services.ts" + "path": "src/plugins/vis_types/timelion/public/helpers/plugin_services.ts" }, { "plugin": "indexPatternManagement", @@ -13286,11 +13286,11 @@ }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.test.ts" + "path": "src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.test.ts" }, { "plugin": "visTypeTimelion", - "path": "src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.test.ts" + "path": "src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.test.ts" }, { "plugin": "discover", diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 75eac66df04a1..99f241e81384d 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -898,11 +898,11 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern), [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern) | - | -| | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/public/plugin.ts#:~:text=fieldFormats) | - | -| | [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern), [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern) | - | -| | [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern), [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern) | - | -| | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/public/plugin.ts#:~:text=AsyncPlugin), [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/public/plugin.ts#:~:text=AsyncPlugin), [plugin.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/target/types/public/plugin.d.ts#:~:text=AsyncPlugin), [plugin.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_table/target/types/public/plugin.d.ts#:~:text=AsyncPlugin) | - | +| | [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern), [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern) | - | +| | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/public/plugin.ts#:~:text=fieldFormats) | - | +| | [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern), [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern) | - | +| | [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern), [table_vis_controller.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/public/legacy/table_vis_controller.test.ts#:~:text=IndexPattern) | - | +| | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/public/plugin.ts#:~:text=AsyncPlugin), [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/public/plugin.ts#:~:text=AsyncPlugin), [plugin.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/target/types/public/plugin.d.ts#:~:text=AsyncPlugin), [plugin.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/table/target/types/public/plugin.d.ts#:~:text=AsyncPlugin) | - | @@ -910,15 +910,15 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [plugin_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/plugin_services.ts#:~:text=IndexPatternsContract), [plugin_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/plugin_services.ts#:~:text=IndexPatternsContract), [timelion_expression_input_helpers.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.test.ts#:~:text=IndexPatternsContract), [timelion_expression_input_helpers.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.test.ts#:~:text=IndexPatternsContract) | - | -| | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/plugin.ts#:~:text=indexPatterns) | - | -| | [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_renderer.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx#:~:text=RangeFilterParams), [timelion_vis_renderer.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx#:~:text=RangeFilterParams) | 8.1 | -| | [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts#:~:text=esQuery), [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts#:~:text=esQuery), [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts#:~:text=esQuery) | 8.1 | -| | [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts#:~:text=Filter) | 8.1 | -| | [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts#:~:text=Filter) | 8.1 | -| | [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_renderer.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx#:~:text=RangeFilterParams), [timelion_vis_renderer.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx#:~:text=RangeFilterParams) | 8.1 | -| | [plugin_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/plugin_services.ts#:~:text=IndexPatternsContract), [plugin_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/plugin_services.ts#:~:text=IndexPatternsContract), [timelion_expression_input_helpers.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.test.ts#:~:text=IndexPatternsContract), [timelion_expression_input_helpers.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.test.ts#:~:text=IndexPatternsContract) | - | -| | [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts#:~:text=Filter) | 8.1 | +| | [plugin_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/plugin_services.ts#:~:text=IndexPatternsContract), [plugin_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/plugin_services.ts#:~:text=IndexPatternsContract), [timelion_expression_input_helpers.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.test.ts#:~:text=IndexPatternsContract), [timelion_expression_input_helpers.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.test.ts#:~:text=IndexPatternsContract) | - | +| | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/plugin.ts#:~:text=indexPatterns) | - | +| | [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_renderer.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx#:~:text=RangeFilterParams), [timelion_vis_renderer.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx#:~:text=RangeFilterParams) | 8.1 | +| | [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts#:~:text=esQuery), [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts#:~:text=esQuery), [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts#:~:text=esQuery) | 8.1 | +| | [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/timelion_vis_fn.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/timelion_vis_fn.ts#:~:text=Filter) | 8.1 | +| | [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/timelion_vis_fn.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/timelion_vis_fn.ts#:~:text=Filter) | 8.1 | +| | [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_renderer.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx#:~:text=RangeFilterParams), [timelion_vis_renderer.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx#:~:text=RangeFilterParams), [timelion_vis_component.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx#:~:text=RangeFilterParams) | 8.1 | +| | [plugin_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/plugin_services.ts#:~:text=IndexPatternsContract), [plugin_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/plugin_services.ts#:~:text=IndexPatternsContract), [timelion_expression_input_helpers.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.test.ts#:~:text=IndexPatternsContract), [timelion_expression_input_helpers.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.test.ts#:~:text=IndexPatternsContract) | - | +| | [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_request_handler.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/timelion_vis_fn.ts#:~:text=Filter), [timelion_vis_fn.ts](https://github.com/elastic/kibana/tree/master/src/plugins/vis_types/timelion/public/timelion_vis_fn.ts#:~:text=Filter) | 8.1 | diff --git a/api_docs/vis_type_table.json b/api_docs/vis_type_table.json index bb75ded4e7b63..3b649cd9b0d09 100644 --- a/api_docs/vis_type_table.json +++ b/api_docs/vis_type_table.json @@ -27,7 +27,7 @@ "tags": [], "label": "TableVisParams", "description": [], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false, "children": [ { @@ -40,7 +40,7 @@ "signature": [ "number | \"\"" ], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false }, { @@ -50,7 +50,7 @@ "tags": [], "label": "showPartialRows", "description": [], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false }, { @@ -60,7 +60,7 @@ "tags": [], "label": "showMetricsAtAllLevels", "description": [], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false }, { @@ -70,7 +70,7 @@ "tags": [], "label": "showToolbar", "description": [], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false }, { @@ -80,7 +80,7 @@ "tags": [], "label": "showTotal", "description": [], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false }, { @@ -99,7 +99,7 @@ "text": "AggTypes" } ], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false }, { @@ -109,7 +109,7 @@ "tags": [], "label": "percentageCol", "description": [], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false }, { @@ -122,7 +122,7 @@ "signature": [ "boolean | undefined" ], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false } ], @@ -137,7 +137,7 @@ "tags": [], "label": "AggTypes", "description": [], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false, "initialIsOpen": false } @@ -153,7 +153,7 @@ "signature": [ "\"table\"" ], - "path": "src/plugins/vis_type_table/common/types.ts", + "path": "src/plugins/vis_types/table/common/types.ts", "deprecated": false, "initialIsOpen": false } diff --git a/api_docs/vis_type_timelion.json b/api_docs/vis_type_timelion.json index b8ee00ea01a07..decb94234c64d 100644 --- a/api_docs/vis_type_timelion.json +++ b/api_docs/vis_type_timelion.json @@ -14,7 +14,7 @@ "tags": [], "label": "_LEGACY_", "description": [], - "path": "src/plugins/vis_type_timelion/public/index.ts", + "path": "src/plugins/vis_types/timelion/public/index.ts", "deprecated": false, "children": [ { @@ -24,7 +24,7 @@ "tags": [], "label": "DEFAULT_TIME_FORMAT", "description": [], - "path": "src/plugins/vis_type_timelion/public/index.ts", + "path": "src/plugins/vis_types/timelion/public/index.ts", "deprecated": false }, { @@ -37,7 +37,7 @@ "signature": [ "(from: number, to: number, size: number, interval: string, min: string) => string" ], - "path": "src/plugins/vis_type_timelion/public/index.ts", + "path": "src/plugins/vis_types/timelion/public/index.ts", "deprecated": false, "returnComment": [], "children": [ @@ -48,7 +48,7 @@ "tags": [], "label": "from", "description": [], - "path": "src/plugins/vis_type_timelion/common/lib/calculate_interval.ts", + "path": "src/plugins/vis_types/timelion/common/lib/calculate_interval.ts", "deprecated": false }, { @@ -58,7 +58,7 @@ "tags": [], "label": "to", "description": [], - "path": "src/plugins/vis_type_timelion/common/lib/calculate_interval.ts", + "path": "src/plugins/vis_types/timelion/common/lib/calculate_interval.ts", "deprecated": false }, { @@ -68,7 +68,7 @@ "tags": [], "label": "size", "description": [], - "path": "src/plugins/vis_type_timelion/common/lib/calculate_interval.ts", + "path": "src/plugins/vis_types/timelion/common/lib/calculate_interval.ts", "deprecated": false }, { @@ -78,7 +78,7 @@ "tags": [], "label": "interval", "description": [], - "path": "src/plugins/vis_type_timelion/common/lib/calculate_interval.ts", + "path": "src/plugins/vis_types/timelion/common/lib/calculate_interval.ts", "deprecated": false }, { @@ -88,7 +88,7 @@ "tags": [], "label": "min", "description": [], - "path": "src/plugins/vis_type_timelion/common/lib/calculate_interval.ts", + "path": "src/plugins/vis_types/timelion/common/lib/calculate_interval.ts", "deprecated": false } ] @@ -105,7 +105,7 @@ "ParsedExpression", ">" ], - "path": "src/plugins/vis_type_timelion/public/index.ts", + "path": "src/plugins/vis_types/timelion/public/index.ts", "deprecated": false, "returnComment": [], "children": [ @@ -116,7 +116,7 @@ "tags": [], "label": "input", "description": [], - "path": "src/plugins/vis_type_timelion/common/parser_async.ts", + "path": "src/plugins/vis_types/timelion/common/parser_async.ts", "deprecated": false } ] @@ -137,7 +137,7 @@ "LegacyAxis", "): string; }" ], - "path": "src/plugins/vis_type_timelion/public/index.ts", + "path": "src/plugins/vis_types/timelion/public/index.ts", "deprecated": false, "returnComment": [], "children": [] @@ -160,7 +160,7 @@ }, ") => string" ], - "path": "src/plugins/vis_type_timelion/public/index.ts", + "path": "src/plugins/vis_types/timelion/public/index.ts", "deprecated": false, "returnComment": [], "children": [ @@ -180,7 +180,7 @@ "text": "IUiSettingsClient" } ], - "path": "src/plugins/vis_type_timelion/public/helpers/get_timezone.ts", + "path": "src/plugins/vis_types/timelion/public/helpers/get_timezone.ts", "deprecated": false } ] @@ -203,7 +203,7 @@ }, ") => (esInterval: any) => any" ], - "path": "src/plugins/vis_type_timelion/public/index.ts", + "path": "src/plugins/vis_types/timelion/public/index.ts", "deprecated": false, "returnComment": [], "children": [ @@ -223,7 +223,7 @@ "text": "IUiSettingsClient" } ], - "path": "src/plugins/vis_type_timelion/public/helpers/xaxis_formatter.ts", + "path": "src/plugins/vis_types/timelion/public/helpers/xaxis_formatter.ts", "deprecated": false } ] @@ -240,7 +240,7 @@ "IAxis", ") => number[]" ], - "path": "src/plugins/vis_type_timelion/public/index.ts", + "path": "src/plugins/vis_types/timelion/public/index.ts", "deprecated": false, "returnComment": [], "children": [] @@ -256,7 +256,7 @@ "tags": [], "label": "VisTypeTimelionPluginStart", "description": [], - "path": "src/plugins/vis_type_timelion/public/plugin.ts", + "path": "src/plugins/vis_types/timelion/public/plugin.ts", "deprecated": false, "children": [ { @@ -275,7 +275,7 @@ "TimelionFunctionArgsSuggestion", "[]; }" ], - "path": "src/plugins/vis_type_timelion/public/plugin.ts", + "path": "src/plugins/vis_types/timelion/public/plugin.ts", "deprecated": false, "returnComment": [], "children": [] @@ -291,7 +291,7 @@ "tags": [], "label": "VisTypeTimelionPluginSetup", "description": [], - "path": "src/plugins/vis_type_timelion/public/plugin.ts", + "path": "src/plugins/vis_types/timelion/public/plugin.ts", "deprecated": false, "children": [ { @@ -301,7 +301,7 @@ "tags": [], "label": "isUiEnabled", "description": [], - "path": "src/plugins/vis_type_timelion/public/plugin.ts", + "path": "src/plugins/vis_types/timelion/public/plugin.ts", "deprecated": false } ], @@ -322,7 +322,7 @@ "description": [ "\nDescribes public Timelion plugin contract returned at the `setup` stage." ], - "path": "src/plugins/vis_type_timelion/server/plugin.ts", + "path": "src/plugins/vis_types/timelion/server/plugin.ts", "deprecated": false, "children": [ { @@ -332,7 +332,7 @@ "tags": [], "label": "uiEnabled", "description": [], - "path": "src/plugins/vis_type_timelion/server/plugin.ts", + "path": "src/plugins/vis_types/timelion/server/plugin.ts", "deprecated": false } ], diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 84e6668830edc..55c53129ba499 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -285,7 +285,7 @@ The plugin exposes the static DefaultEditorController class to consume. |WARNING: Missing README. -|{kib-repo}blob/{branch}/src/plugins/vis_type_table/README.md[visTypeTable] +|{kib-repo}blob/{branch}/src/plugins/vis_types/table/README.md[visTypeTable] |Contains the data table visualization, that allows presenting data in a simple table format. @@ -293,7 +293,7 @@ The plugin exposes the static DefaultEditorController class to consume. |WARNING: Missing README. -|{kib-repo}blob/{branch}/src/plugins/vis_type_timelion/README.md[visTypeTimelion] +|{kib-repo}blob/{branch}/src/plugins/vis_types/timelion/README.md[visTypeTimelion] |Contains the timelion visualization and the timelion backend. @@ -391,7 +391,7 @@ security and spaces filtering as well as performing audit logging. |{kib-repo}blob/{branch}/x-pack/plugins/enterprise_search/README.md[enterpriseSearch] -|This plugin provides beta Kibana user interfaces for managing the Enterprise Search solution and its products, App Search and Workplace Search. +|This plugin provides Kibana user interfaces for managing the Enterprise Search solution and its products, App Search and Workplace Search. |{kib-repo}blob/{branch}/x-pack/plugins/event_log/README.md[eventLog] diff --git a/docs/user/dashboard/aggregation-based.asciidoc b/docs/user/dashboard/aggregation-based.asciidoc index d901ab8deccb8..351e1f5d0825a 100644 --- a/docs/user/dashboard/aggregation-based.asciidoc +++ b/docs/user/dashboard/aggregation-based.asciidoc @@ -187,8 +187,33 @@ TIP: Aggregation-based panels support a maximum of three *Split series*. [role="screenshot"] image:images/bar-chart-tutorial-2.png[Bar chart with sample logs data] +[float] +[[save-the-aggregation-based-panel]] +===== Save and add the panel + +Save the panel to the *Visualize Library* and add it to the dashboard, or add it to the dashboard without saving. + +To save the panel to the *Visualize Library*: + +. Click *Save to library*. + +. Enter the *Title* and add any applicable <>. + +. Make sure that *Add to Dashboard after saving* is selected. + . Click *Save and return*. +To save the panel to the dashboard: + +. Click *Save and return*. + +. Add an optional title to the panel. + +.. In the panel header, click *No Title*. + +.. On the *Customize panel* window, select *Show panel title*. + +.. Enter the *Panel title*, then click *Save*. diff --git a/docs/user/dashboard/aggregation-reference.asciidoc b/docs/user/dashboard/aggregation-reference.asciidoc deleted file mode 100644 index 17bfc19c2e0c9..0000000000000 --- a/docs/user/dashboard/aggregation-reference.asciidoc +++ /dev/null @@ -1,467 +0,0 @@ -[[aggregation-reference]] -== Supported features by panel type - -Each panel type in {kib} supports different features and {ref}/search-aggregations.html[{es} aggregations]. -This reference can help simplify the comparison if you need a specific feature. - - -[float] -[[chart-types]] -=== Supported panel types by editor - -[options="header"] -|=== - -| Type | Lens | TSVB | Agg-based | Vega | Timelion - -| Table -| ✓ -| ✓ -| ✓ -| -| - -| Bar, line, and area -| ✓ -| ✓ -| ✓ -| ✓ -| ✓ - -| Split chart/small multiples -| -| ✓ -| ✓ -| ✓ -| - -| Pie and donut -| ✓ -| -| ✓ -| ✓ -| - -| Sunburst -| ✓ -| -| ✓ -| ✓ -| - -| Treemap -| ✓ -| -| -| ✓ -| - -| Heat map -| ✓ -| ✓ -| ✓ -| ✓ -| - -| Gauge and Goal -| -| ✓ -| ✓ -| ✓ -| - -| Markdown -| -| ✓ -| -| -| - -| Metric -| ✓ -| ✓ -| ✓ -| ✓ -| - -| Tag cloud -| -| -| ✓ -| ✓ -| - -|=== - -[float] -[[table-features]] -=== Table features - -[options="header"] -|=== - -| Type | Lens | TSVB | Agg-based - -| Summary row -| ✓ -| -| ✓ - -| Pivot table -| ✓ -| -| - -| Calculated column -| Formula -| ✓ -| Percent only - -| Color by value -| ✓ -| ✓ -| - -|=== - -[float] -[[xy-features]] -=== Bar, line, area features - -[options="header"] -|=== - -| Type | Lens | TSVB | Agg-based | Vega | Timelion - -| Dense time series -| Customizable -| ✓ -| Customizable -| ✓ -| ✓ - -| Percentage mode -| ✓ -| ✓ -| ✓ -| ✓ -| - -| Break downs -| 1 -| 1 -| 3 -| ∞ -| 1 - -| Custom color with break downs -| -| Only for Filters -| ✓ -| ✓ -| - -| Fit missing values -| ✓ -| -| ✓ -| ✓ -| ✓ - -| Synchronized tooltips -| -| ✓ -| -| -| - -|=== - -[float] -[[bucket-aggregations]] -=== Bucket aggregations - -Vega supports all bucket aggregations because it allows custom queries. - -For information about {es} bucket aggregations, refer to {ref}/search-aggregations-bucket.html[Bucket aggregations]. - -[options="header"] -|=== - -| Type | Lens | TSVB | Agg-based - -| Histogram -| ✓ -| -| ✓ - -| Date histogram -| ✓ -| ✓ -| ✓ - -| Date range -| Use filters -| -| ✓ - -| Filter -| -| ✓ -| - -| Filters -| ✓ -| ✓ -| ✓ - -| GeoHash grid -| -| -| ✓ - -| IP range -| Use filters -| Use filters -| ✓ - -| Range -| ✓ -| Use filters -| ✓ - -| Terms -| ✓ -| ✓ -| ✓ - -| Significant terms -| -| -| ✓ - -|=== - -[float] -[[metrics-aggregations]] -=== Metrics aggregations - -Vega supports all metric aggregations because it allows custom queries. - -For information about {es} metrics aggregations, refer to {ref}/search-aggregations-metrics.html[Metrics aggregations]. - -[options="header"] -|=== - -| Type | Lens | TSVB | Agg-based - -| Metrics with filters -| ✓ -| -| - -| Average, Sum, Max, Min -| ✓ -| ✓ -| ✓ - -| Unique count (Cardinality) -| ✓ -| ✓ -| ✓ - -| Percentiles and Median -| ✓ -| ✓ -| ✓ - -| Percentiles Rank -| -| ✓ -| ✓ - -| Standard deviation -| -| ✓ -| ✓ - -| Sum of squares -| -| ✓ -| - -| Top hit (Last value) -| ✓ -| ✓ -| ✓ - -| Value count -| -| -| ✓ - -| Variance -| -| ✓ -| - -|=== - -[float] -[[pipeline-aggregations]] -=== Pipeline aggregations - -Vega supports all pipeline aggregations because it allows custom queries. - -For information about {es} pipeline aggregations, refer to {ref}/search-aggregations-pipeline.html[Pipeline aggregations]. - -[options="header"] -|=== - -| Type | Lens | TSVB | Agg-based - -| Avg bucket -| <> -| ✓ -| ✓ - -| Derivative -| ✓ -| ✓ -| ✓ - -| Max bucket -| <> -| ✓ -| ✓ - -| Min bucket -| <> -| ✓ -| ✓ - -| Sum bucket -| <> -| ✓ -| ✓ - -| Moving average -| ✓ -| ✓ -| ✓ - -| Cumulative sum -| ✓ -| ✓ -| ✓ - -| Bucket script -| -| -| ✓ - -| Bucket selector -| -| -| - -| Serial differencing -| -| ✓ -| ✓ - -|=== - -[float] -[[custom-functions]] -=== Additional functions - -[options="header"] -|=== - -| Type | Lens | TSVB | Agg-based - -| Counter rate -| ✓ -| ✓ -| - -| <> -| Use <> -| ✓ -| - -| <> -| -| ✓ -| - -| <> -| -| ✓ -| - -| Static value -| -| ✓ -| - - -|=== - -[float] -[[other-features]] -=== Other features - -This comparison is meant for users who are not sure about which {kib} panel type to -build their advanced visualization. - -[options="header"] -|=== - -| Type | Lens | TSVB | Agg-based | Vega | Timelion - -| Math -| ✓ -| ✓ -| -| ✓ -| ✓ - -| Visualize two indices -| ✓ -| ✓ -| -| ✓ -| ✓ - -| Math across indices -| -| -| -| ✓ -| ✓ - -| Time shifts -| ✓ -| ✓ -| -| ✓ -| ✓ - -| Fully custom {es} queries -| -| -| -| ✓ -| - -| Normalize by time -| ✓ -| ✓ -| -| -| - - -|=== diff --git a/docs/user/dashboard/dashboard-troubleshooting.asciidoc b/docs/user/dashboard/dashboard-troubleshooting.asciidoc new file mode 100644 index 0000000000000..d9bf80a5b1996 --- /dev/null +++ b/docs/user/dashboard/dashboard-troubleshooting.asciidoc @@ -0,0 +1,69 @@ +[[dashboard-troubleshooting]] +== Dashboard and visualizations troubleshooting +++++ +Troubleshooting +++++ + +Find solutions to common dashboard and visualization issues. + +[float] +[[defer-loading-panels-below-the-fold]] +=== Improve dashboard loading time + +To improve the dashboard loading time, enable *Defer loading panels below the fold* *Lab*, which loads dashboard panels as they become visible on the dashboard. + +. In the toolbar, click *Labs*. ++ +To enable *Labs*, contact your administrator, or configure the <>. + +. To specify how you want to enable the lab, use the following actions: + +* *{kib}* — Enables the lab in {kib}. + +* *Browser* — Enables the lab for your browser, and persists after you close the browser. + +* *Session* — Enables the lab for this browser session, then resets after you close the browser. + +. Click *Close*. + +[float] +[[migrate-timelion-app-worksheets]] +=== Migrate Timelion app worksheets + +deprecated::[The *Timelion* app is deprecated in 7.0.0, and will be removed in 7.16.0. To prepare for the removal of *Timelion* app, you must migrate *Timelion* app worksheets to a dashboard. + +. Open the main menu, then click *Dashboard*. + +. On the *Dashboards* page, click *Create dashboard*. + +. For each *Timelion* app worksheet, create a visualization with the *Timelion* editor. + +.. On the dashboard, click *All types > Aggregation based*, then select *Timelion*. + +.. In your browser, open a new tab, the open the *Timelion* app. + +.. Select the chart you want to copy, then copy the chart expression. ++ +[role="screenshot"] +image::images/timelion-copy-expression.png[Timelion app chart] + +.. Go to the *Timelion* editor, paste the chart expression in the *Timelion expression* field, then click *Update*. ++ +[role="screenshot"] +image::images/timelion-vis-paste-expression.png[Timelion advanced editor UI] + +. Save the visualization. + +.. In the toolbar, click *Save to library*. + +.. Enter the *Title* and add any applicable <>. + +.. Make sure that *Add to Dashboard after saving* is selected. + +.. Click *Save and return*. ++ +The Timelion visualization panel appears on the dashboard. ++ +[role="screenshot"] +image::user/dashboard/images/timelion-dashboard.png[Final dashboard with saved Timelion app worksheet] + diff --git a/docs/user/dashboard/dashboard.asciidoc b/docs/user/dashboard/dashboard.asciidoc index 1284c057af2da..1a9a0087becda 100644 --- a/docs/user/dashboard/dashboard.asciidoc +++ b/docs/user/dashboard/dashboard.asciidoc @@ -1,5 +1,5 @@ [[dashboard]] -= Dashboard += Dashboard and visualizations [partintro] -- @@ -11,14 +11,13 @@ that bring clarity to your data, tell a story about your data, and allow you to [role="screenshot"] image:images/Dashboard_example.png[Example dashboard] -Panels display your data in charts, tables, maps, and more, which allow you to compare your data side-by-side to identify patterns and connections. Dashboards support several editors you can use to create panels, and support many types of panels to display your data. +Panels display your data in charts, tables, maps, and more, which allow you to compare your data side-by-side to identify patterns and connections. Dashboards support several types of panels to display your data, and several options to create panels. [cols="2"] |=== | <> -| Use the *Lens*, *TSVB*, *Vega*, and *Timelion* editors to create visualizations of your data, or create *Aggregation based* visualizations using {es} aggregations. -*Lens* is the recommended editor. +| Use one of the editors to create visualizations of your data. Each editor varies in capabilities for all levels of analysts. | <> | Create beautiful displays of your geographical data. @@ -33,7 +32,10 @@ Panels display your data in charts, tables, maps, and more, which allow you to c | Display a table of live streaming logs. | <> -| Add context to your panels with <>, or add dynamic filters with <>. +| Add interactive filters with *Controls* panels. + +| <> +| Add context to your panels with *Text*. |=== @@ -61,71 +63,115 @@ refer to <>. [[open-the-dashboard]] === Open the dashboard -Begin with an empty dashboard, or open an existing dashboard. +Begin with an empty dashboard, or open an existing dashboard. . Open the main menu, then click *Dashboard*. . On the *Dashboards* page, choose one of the following options: * To start with an empty dashboard, click *Create dashboard*. ++ +When you create a dashboard, you are automatically in edit mode and can make changes to the dashboard. * To open an existing dashboard, click the dashboard *Title* you want to open. ++ +When you open an existing dashboard, you are in view mode. To make changes to the dashboard, click *Edit* in the toolbar. [float] [[create-panels-with-lens]] -=== Add panels +=== Create and add panels + +You create panels using the editors, which you can access from the dashboard toolbar or the *Visualize Library*, or add panels that are saved in the *Visualize Library*, or search results from <>. + +To create panels from the dashboard toolbar, use one of the following options: + +* *Create visualization* — Opens the drag-and-drop editor, which is the recommended way to create visualization panels. + +* *All types* — Opens the menu for all of the editors and panel types. + +To create panels from the *Visualize Library*: -Create and add panels of your data to the dashboard, or add existing panels from the library. +. Open the main menu, then click *Visualize Library*. -* *Create visualization* — Opens *Lens*, the recommended editor to create visualizations of your data. +. Click *Create visualization*, then select an editor. -* *All types* — Select the editor to create the panel, or select the panel type you want to add to the dashboard. +To add existing panels from the *Visualize Library*: -* *Add from library* — Add panels from the *Visualize Library*, including search results from <>. The search results from *Discover* are not aggregated. +. In the dashboard toolbar, click *Add from library*. + +. Click the panel you want to add to the dashboard, then click *X*. + When a panel contains a saved query, both queries are applied. ++ +When you add search results from *Discover* to dashboards, the results are not aggregated. [[tsvb]] [float] [[save-panels]] -=== Save panels +=== Save and add panels -Consider where you want to save the panel in {kib}. You can save the panel just on the dashboard you are working on, or save the panel in the *Visualize Library*. +Consider where you want to save and add the panel in {kib}. [float] [[save-to-visualize-library]] ==== Save to the Visualize Library -To use the panel on *Canvas* workpads and other dashboards, save the panel to the *Visualize Library*. +To use the panel on other dashboards and *Canvas* workpads, save the panel to the *Visualize Library*. When panels are saved in the *Visualize Library*, image:dashboard/images/visualize-library-icon.png[Visualize Library icon] appears in the panel header. -. Click *Save to library*. +If you created the panel from the dashboard: + +. In the editor, click *Save to library*. -. Enter the *Title* and add any applicable *Tags*. +. Enter the *Title* and add any applicable <>. . Make sure that *Add to Dashboard after saving* is selected. . Click *Save and return*. -+ -When panels are saved in the *Visualize Library*, image:dashboard/images/visualize-library-icon.png[Visualize Library icon] appears in the panel header. + +If you created the panel from the *Visualize Library*: + +. In the editor, click *Save*. + +. On the *Save* window, enter the *Title*. + +. Choose one of the following options: + +* To save the panel to a dashboard and the *Visualize Library*, select *Add to library*, add any applicable <>, then click *Save and go to Dashboard*. + +* To save the panel only to the *Visualize Library*, select *None*, add any applicable <>, then click *Save and add to library*. [float] [[save-to-the-dashboard]] ==== Save to the dashboard -Quickly add the panel and return to the dashboard without specifying the save options or adding the panel to the *Visualize Library*. +Return to the dashboard and add the panel without specifying the save options or adding the panel to the *Visualize Library*. -. Click *Save and return*. +If you created the panel from the dashboard: -. Add more panels to the dashboard, or specify the panel title. +. In the editor, click *Save and return*. + +. Add an optional title to the panel. .. In the panel header, click *No Title*. -.. Select *Show panel title*. +.. On the *Customize panel* window, select *Show panel title*. + +.. Enter the *Panel title*, then click *Save*. + +If you created the panel from the *Visualize Library*: + +. Click *Save*. -.. Enter the *Panel title*. +. On the *Save* window, enter the *Title*. -If you change your mind and want to add the panel to the *Visualize Library*: +. Choose one of the following options: + +* If you want to add the panel to an existing dashboard, select *Existing*, select the dashboard from the dropdown, then click *Save and go to Dashboard*. + +* If you want to add the panel to a new dashboard, select *New*, then click *Save and go to Dashboard*. + +To add unsaved dashboard panels to the *Visualize Library*: . Open the panel menu, then select *More > Save to library*. @@ -135,72 +181,61 @@ If you change your mind and want to add the panel to the *Visualize Library*: [[add-text]] == Add context to panels -To provide context to your dashboard panels, add *Text* panels that display important information, instructions, images, and more. - -You create *Text* panels using GitHub-flavored Markdown text. For information about GitHub-flavored Markdown text, click *Help*. +To provide context to your dashboard panels, add *Text* panels that display important information, instructions, images, and more. You create *Text* panels using GitHub-flavored Markdown text. -. From the dashboard, click *All types*, then select *Text*. +. On the dashboard, click image:images/dashboard_createNewTextButton_7.15.0.png[Create New Text button in dashboard toolbar]. . In the *Markdown* field, enter the text, then click *Update*. For example, when you enter: [role="screenshot"] -image::images/markdown_example_1.png[] +image::images/markdown_example_1.png[Markdown text with links] The following instructions are displayed: [role="screenshot"] -image::images/markdown_example_2.png[] +image::images/markdown_example_2.png[Panel with markdown link text] Or when you enter: [role="screenshot"] -image::images/markdown_example_3.png[] +image::images/markdown_example_3.png[Markdown text with image file] The following image is displayed: [role="screenshot"] -image::images/markdown_example_4.png[] +image::images/markdown_example_4.png[Panel with markdown image] -[float] -[[edit-panels]] -== Edit panels +For detailed information about writing on GitHub, click *Help*. -To make changes to the panel, use the panel menu options. - -. In the toolbar, click *Edit*. +[float] +[[save-the-markdown-panel]] +=== Save and add the panel -. Open the panel menu, then use the following options: +Save the panel to the *Visualize Library* and add it to the dashboard, or add it to the dashboard without saving. -* *Edit lens* — Opens *Lens* so you can make changes to the visualization. +To save the panel to the *Visualize Library*: -* *Edit visualization* — Opens the editor so you can make changes to the panel. -+ -To make changes without changing the original version, open the panel menu, then click *More > Unlink from library*. +. Click *Save to library*. -* *Edit panel title* — Opens the *Customize panel* window to change the *Panel title*. +. Enter the *Title* and add any applicable <>. -* *More > Replace panel* — Opens the *Visualize Library* so you can select a new panel to replace the existing panel. +. Make sure that *Add to Dashboard after saving* is selected. -* *More > Delete from dashboard* — Removes the panel from the dashboard. -+ -If you want to use the panel later, make sure that you save the panel to the *Visualize Library*. +. Click *Save and return*. -[float] -[[search-or-filter-your-data]] -== Search and filter your data +To save the panel to the dashboard: -{kib} supports several ways to search your data and apply {es} filters. You can combine the filters with any panel -filter to display the data want to you see. +. Click *Save and return*. -For more information about {kib} and {es} filters, refer to <>. +. Add an optional title to the panel. -To apply a panel-level time filter: +.. In the panel header, click *No Title*. -. Open the panel menu, then select *More > Customize time range*. +.. On the *Customize panel* window, select *Show panel title*. -. Enter the time range you want to view, then click *Add to panel*. +.. Enter the *Panel title*, then click *Save*. [float] [[arrange-panels]] @@ -208,7 +243,7 @@ To apply a panel-level time filter: [[resizing-containers]] == Arrange panels -To compare the data side-by-side, move and arrange the panels. +Compare the data in your panels side-by-side, organize panels by priority, resize the panels so they all appear immediately on the dashboard, and more. In the toolbar, click *Edit*, then use the following options: @@ -219,18 +254,28 @@ In the toolbar, click *Edit*, then use the following options: * To maximize to fullscreen, open the panel menu, then click *More > Maximize panel*. [float] -[[apply-design-options]] -== Apply design options +[[edit-panels]] +== Edit panels -Apply a set of design options to the entire dashboard. +To make changes to the panel, use the panel menu options. -In the toolbar, click *Edit > Options*, then use the following options: +. In the toolbar, click *Edit*. + +. Open the panel menu, then use the following options: -* *Use margins between panels* — Specifies a margin of space between each panel. +* *Edit lens* — Opens *Lens* so you can make changes to the visualization. -* *Show panel titles* — Specifies the appearance of titles in the header of each panel. +* *Edit visualization* — Opens the editor so you can make changes to the panel. ++ +To make changes without changing the original version, open the panel menu, then click *More > Unlink from library*. + +* *Edit panel title* — Opens the *Customize panel* window to change the *Panel title*. + +* *More > Replace panel* — Opens the *Visualize Library* so you can select a new panel to replace the existing panel. -* *Sync color pallettes across panels* — Specifies whether the color pallette is applied to all panels. +* *More > Delete from dashboard* — Removes the panel from the dashboard. ++ +If you want to use the panel later, make sure that you save the panel to the *Visualize Library*. [float] [[duplicate-panels]] @@ -262,56 +307,71 @@ Copy panels from one dashboard to another dashboard. . On the *Copy to dashboard* window, select the dashboard, then click *Copy and go to dashboard*. [float] -[[explore-the-underlying-documents]] -== Explore the underlying documents +[[search-or-filter-your-data]] +== Search and filter your data -You can add additional interactions that allow you to open *Discover* from dashboard panels. To use the interactions, the panel must use only one index pattern. +{kib} supports several ways to search your data and apply {es} filters. You can combine the filters with any panel +filter to display the data want to you see. -Panel interaction:: Opens the data in *Discover* with the current dashboard filters, but does not take the filters -saved with the panel. -+ -To enable panel interactions, refer to <>. -+ -NOTE: In {kib} 7.13 and earlier, the panel interaction is enabled by default. +For more information about {kib} and {es} filters, refer to <>. -Series interaction:: -Opens the series data in *Discover* from inside the panel. -+ -To enable series interactions, refer to <>. +To apply a panel-level time filter: + +. Open the panel menu, then select *More > Customize time range*. + +. Enter the time range you want to view, then click *Add to panel*. [float] -[[download-csv]] -== Download panel data +[[apply-design-options]] +== Apply design options -Download panel data in a CSV file. When you download visualization panels with multiple layers, each layer produces a CSV file, and the file names contain the visualization and layer index names. +Apply a set of design options to the entire dashboard. -. Open the panel menu, then select *Inspect*. +. If you're in view mode, click *Edit* in the toolbar. -. Click *Download CSV*, then select the format type from the dropdown: +. In the toolbar, *Options*, then use the following options: -* *Formatted CSV* — Contains human-readable dates and numbers. +* *Use margins between panels* — Adds a margin of space between each panel. -* *Unformatted* — Best used for computer use. +* *Show panel titles* — Displays the titles in the panels headers. + +* *Sync color pallettes across panels* — Applies the same color palette to all panels on the dashboard. [float] -[[defer-loading-panels-below-the-fold]] -== Improve dashboard loading time +[[save-dashboards]] +== Save dashboards -To improve the dashboard loading time, enable the *Defer loading panels below the fold* *Lab*, which loads the dashboard panels as they become visible on the dashboard. +When you've finished making changes to the dashboard, save it. -. In the toolbar, click *Labs*. -+ -To enable *Labs*, contact your administrator, or configure the <>. +If you are saving a new dashboard: + +. In the toolbar, click *Save*. + +. On the *Save dashboard* window, enter the *Title* and an optional *Description*. -. To specify how you want to enable the lab, use the following actions: +. Add any applicable <>. -* *{kib}* — Enables the lab in {kib}. +. To save the time filter to the dashboard, select *Store time with dashboard*. -* *Browser* — Enables the lab for your browser, and persists after you close the browser. +. Click *Save*. -* *Session* — Enables the lab for this browser session, then resets after you close the browser. +If you are saving an existing dashboard, click *Save*. -. Click *Close*. +To exit *Edit* mode, click *Switch to view mode*. + +[float] +[[download-csv]] +== Download panel data + +Download panel data in a CSV file. When you download visualization panels with multiple layers, each layer produces a CSV file, and the file names contain the visualization and layer index names. + +. Open the panel menu, then select *Inspect*. + +. Click *Download CSV*, then select the format type from the dropdown: + +* *Formatted CSV* — Contains human-readable dates and numbers. + +* *Unformatted* — Best used for computer use. [float] [[share-the-dashboard]] @@ -333,3 +393,5 @@ include::lens-advanced.asciidoc[] include::create-panels-with-editors.asciidoc[] include::make-dashboards-interactive.asciidoc[] + +include::dashboard-troubleshooting.asciidoc[] diff --git a/docs/user/dashboard/enhance-dashboards.asciidoc b/docs/user/dashboard/enhance-dashboards.asciidoc deleted file mode 100644 index de8af34e6d32e..0000000000000 --- a/docs/user/dashboard/enhance-dashboards.asciidoc +++ /dev/null @@ -1,69 +0,0 @@ -[[enhance-dashboards]] -== Enhance dashboards - -You can add filter panels to interact with the data in your visualization panels, and Markdown panels to add context to the data. -To make your dashboard look the way you want, use the editing options. - -[float] -[[add-controls]] -=== Add controls - -To filter the data on your dashboard in real-time, add a *Controls* panel or use a map panel to <>. - -{kib} supports two types of *Controls*: - -* *Options list* — Filters content based on one or more specified options. The dropdown menu is dynamically populated with the results of a terms aggregation. -For example, use the options list on the sample flight dashboard when you want to filter the data by origin city and destination city. - -* *Range slider* — Filters data within a specified range of numbers. The minimum and maximum values are dynamically populated with the results of a -min and max aggregation. For example, use the range slider when you want to filter the sample flight dashboard by a specific average ticket price. -+ -[role="screenshot"] -image::images/dashboard-controls.png[] - -. On the dashboard, click *All types*, then select *Controls*. - -. Click *Options*, then configure the following options: - -* *Update {kib} filters on each change* — When selected, all interactive inputs create filters that refresh the dashboard. When unselected, - {kib} filters are created only when you click *Apply changes*. - -* *Use time filter* — When selected, the aggregations that generate the options list and time range are connected to the <>. - -* *Pin filters for all applications* — When selected, all filters created by interacting with the inputs are automatically pinned. - -. Click *Update* - -[float] -[[add-text]] -=== Add text - -Add text panels with *Markdown* when you want to provide context to the other panels on your dashboard, such as important information, instructions, and images. - -*Markdown* is a text entry field that accepts GitHub-flavored Markdown text. For information about GitHub-flavored Markdown text, click *Help*. - -. From the dashboard, click *All types*, then select *Text*. - -. In the *Markdown* field, enter the text, then click *Update*. - -For example, when you enter: - -[role="screenshot"] -image::images/markdown_example_1.png[] - -The following instructions are displayed: - -[role="screenshot"] -image::images/markdown_example_2.png[] - -Or when you enter: - -[role="screenshot"] -image::images/markdown_example_3.png[] - -The following image is displayed: - -[role="screenshot"] -image::images/markdown_example_4.png[] - - diff --git a/docs/user/dashboard/images/dashboard_createNewTextButton_7.15.0.png b/docs/user/dashboard/images/dashboard_createNewTextButton_7.15.0.png new file mode 100644 index 0000000000000..f89f2ef5cf249 Binary files /dev/null and b/docs/user/dashboard/images/dashboard_createNewTextButton_7.15.0.png differ diff --git a/docs/user/dashboard/images/markdown_example_1.png b/docs/user/dashboard/images/markdown_example_1.png index 71dd9b76b8caf..8ade6b83cf742 100644 Binary files a/docs/user/dashboard/images/markdown_example_1.png and b/docs/user/dashboard/images/markdown_example_1.png differ diff --git a/docs/user/dashboard/images/markdown_example_2.png b/docs/user/dashboard/images/markdown_example_2.png index f2094c3cbb3f1..e114d33846fdf 100644 Binary files a/docs/user/dashboard/images/markdown_example_2.png and b/docs/user/dashboard/images/markdown_example_2.png differ diff --git a/docs/user/dashboard/images/markdown_example_3.png b/docs/user/dashboard/images/markdown_example_3.png index eca9735b495d0..09a1858a2a932 100644 Binary files a/docs/user/dashboard/images/markdown_example_3.png and b/docs/user/dashboard/images/markdown_example_3.png differ diff --git a/docs/user/dashboard/images/markdown_example_4.png b/docs/user/dashboard/images/markdown_example_4.png index d4a0829fef64e..f0d133fc3641a 100644 Binary files a/docs/user/dashboard/images/markdown_example_4.png and b/docs/user/dashboard/images/markdown_example_4.png differ diff --git a/docs/user/dashboard/images/timelion-dashboard.png b/docs/user/dashboard/images/timelion-dashboard.png new file mode 100644 index 0000000000000..e217dca98d079 Binary files /dev/null and b/docs/user/dashboard/images/timelion-dashboard.png differ diff --git a/docs/user/dashboard/lens.asciidoc b/docs/user/dashboard/lens.asciidoc index 6b61c9fe6a9a3..0f130f15c8a77 100644 --- a/docs/user/dashboard/lens.asciidoc +++ b/docs/user/dashboard/lens.asciidoc @@ -178,7 +178,39 @@ For a time shift example, refer to <>. [float] [[filter-the-data]] -==== Apply filters with the legend +==== Apply filters + +You can use the <> to focus on a known set of data for the entire visualization, or use the filter options from the layer pane or legend. + +[float] +[[filter-with-the-function]] +===== Apply multiple KQL filters + +With the *Filters* function, you can apply more than one KQL filter, and apply a KQL filter to a single layer so you can visualize filtered and unfiltered data at the same time. + +. In the layer pane, click a field. + +. Click the *Filters* function. + +. Click *Add a filter*, then enter the KQL filter you want to apply. ++ +To try the *Filters* function on your own, refer to <>. + +[float] +[[filter-with-the-advanced-option]] +===== Apply a single KQL filter + +With the *Filter by* advanced option, you can assign a color to each filter group in *Bar* and *Line and area* visualizations, and build complex tables. For example, to display failure rate and the overall data. + +. In the layer pane, click a field. + +. Click *Add advanced options*, then select *Filter by*. + +. Enter the KQL filter you want to apply. + +[float] +[[filter-with-legend-filters]] +===== Apply legend filters Apply filters to visualizations directly from the values in the legend. *Bar*, *Line and area*, and *Proportion* visualizations support legend filters. @@ -205,30 +237,38 @@ The following component menus are available: * *Left axis*, *Bottom axis*, and *Right axis* — Specify how you want to display the chart axes. For example, add axis labels and change the orientation and bounds. [float] -[[lens-faq]] -==== Frequently asked questions +[[save-the-lens-panel]] +===== Save and add the panel -For answers to common *Lens* questions, review the following. +Save the panel to the *Visualize Library* and add it to the dashboard, or add it to the dashboard without saving. -[discrete] -[[kql]] -.*When should I use KQL filters, the Filters function, or the Filter by option?* -[%collapsible] -==== -Use the <> field to focus on a known set of data for the entire visualization. You can combine KQL filters with other filters using AND logic. +To save the panel to the *Visualize Library*: -Use the *Filters* function to apply: +. Click *Save to library*. -* More than one KQL filter. +. Enter the *Title* and add any applicable <>. -* The KQL filter to a single layer, which allows you to visualize filtered and unfiltered data. +. Make sure that *Add to Dashboard after saving* is selected. -Use the *Filter by* advanced option to: +. Click *Save and return*. -* Assign a custom color to each filter group in a bar, line, or area chart. +To save the panel to the dashboard: -* Build a complex table. For example, to display the failure rate and overall data. -==== +. Click *Save and return*. + +. Add an optional title to the panel. + +.. In the panel header, click *No Title*. + +.. On the *Customize panel* window, select *Show panel title*. + +.. Enter the *Panel title*, then click *Save*. + +[float] +[[lens-faq]] +=== Frequently asked questions + +For answers to common *Lens* questions, review the following. [discrete] [[when-should-i-normalize-the-data-by-unit-or-use-a-custom-interval]] @@ -401,4 +441,4 @@ Pagination in a data table is unsupported. To use pagination in data tables, cre [%collapsible] ==== Specifying the color for a single data point, such as a single bar or line, is unsupported. -==== +==== \ No newline at end of file diff --git a/docs/user/dashboard/make-dashboards-interactive.asciidoc b/docs/user/dashboard/make-dashboards-interactive.asciidoc index c3a94f17fc6d9..6e09fd34f508e 100644 --- a/docs/user/dashboard/make-dashboards-interactive.asciidoc +++ b/docs/user/dashboard/make-dashboards-interactive.asciidoc @@ -1,4 +1,4 @@ -[[role="xpack"]] +[role="xpack"] [[drilldowns]] == Make dashboards interactive @@ -7,28 +7,7 @@ you to apply dashboard-level filters, and drilldowns that allow you to navigate to other \ dashboards and external websites. -Add interactive capabilities to your dashboard, such as controls that allow you to apply dashboard-level filters, and drilldowns that allow you to navigate to other dashboards and external websites. - -*Controls* panels allow you to apply dashboard-level filters based on values from a list, or a range of values. - -{kib} supports two types of *Controls*: - -* *Options list* — Filters content based on one or more specified options. The dropdown menu is dynamically populated with the results of a terms aggregation. -For example, use the options list on the sample flight dashboard when you want to filter the data by origin city and destination city. - -* *Range slider* — Filters data within a specified range of numbers. The minimum and maximum values are dynamically populated with the results of a -min and max aggregation. For example, use the range slider when you want to filter the sample flight dashboard by a specific average ticket price. -+ -[role="screenshot"] -image::images/dashboard-controls.png[] - -Panels have built-in interactive capabilities that apply filters to the dashboard data. For example, when you drag a time range or click a pie slice, a filter for the time range or pie slice is applied. Drilldowns let you customize the interactive behavior while keeping the context of the interaction. - -{kib} supports two types of drilldowns: - -* *Dashboard* — Navigates you from one dashboard to another dashboard. For example, when can create a drilldown for a *Lens* panel that navigates you from a summary dashboard to a dashboard with a filter for a specific host name. - -* *URL* — Navigates you from a dashboard to an external website. For example, a website with the specific host name as a parameter. +Add interactive capabilities to your dashboard, such as controls that allow you to apply dashboard-level filters, and drilldowns that allow you to navigate to *Discover*, other dashboards, and external websites. ++++ - -
-++++ +[[kibana-home-page]] +[role="screenshot"] +image::images/analytics-home-page.png[Analytics home page] *{kib} is for administrators, analysts, and business users.* As an admin, your role is to manage the Elastic Stack, from creating your deployment to getting {es} data into {kib}, and then -managing the data. As an analyst, your job is to discover insights +managing the data. As an analyst, you're looking to discover insights in the data, visualize your data on dashboards, and share your findings. As a business user, you want to view existing dashboards and drill down into details. *{kib} works with all types of data.* Your data can be structured or unstructured text, -numerical data, time-series data, geospatial data, logs, metrics, security events, -and more. Kibana is designed to use Elasticsearch as a data store. +numerical data, time series data, geospatial data, logs, metrics, security events, +and more. No matter your data, {kib} can help you uncover patterns and relationships and visualize the results. -[float] -[[kibana-home-page]] -=== Where to start - -Start with the home page, where you’re presented options for adding your data. -You can collect data from an app or service or upload a file that contains your data. -If you’re not ready to use your own data, you can add a sample data set. - -The home page provides access to the *Enterprise Search*, *Observability*, and *Security* solutions, -and everything you need to visualize and analyze your data. - -To access all of {kib} features, use the main menu. -Open this menu by clicking the -menu icon. -For a quick reference of all {kib} features, refer to <> - -[role="screenshot"] -image::images/kibana-main-menu.png[Kibana main menu] - [float] [[extend-your-use-case]] === Search, observe, and protect @@ -82,12 +53,13 @@ that it ran in, trace the transaction, and check the overall service availabilit the events and alerts from your environment. Elastic Security helps you defend your organization from threats before damage and loss occur. + [float] [[visualize-and-analyze]] -=== Visualize and analyze +=== Analyze -Data analysis is a core functionality of {kib}. -You can quickly search through large amounts of data, explore fields and values, +Data analysis is a core functionality of {kib}. Quickly search through large amounts +of data, explore fields and values, and then use {kib}’s drag-and-drop interface to rapidly build charts, tables, metrics, and more. [role="screenshot"] @@ -108,14 +80,17 @@ You can limit your results to the most recent documents added to {es}. | *3* | *Visualize.* {kib} provides many options to create visualizations of your data, from -aggregation-based data to time series data. +aggregation-based data to time series data to geo data. <> is your starting point to create visualizations, and then pulling them together to show your data from multiple perspectives. +Use <>, +to give your data +the “wow” factor for display on a big screen. Use *Graph* to explore patterns and relationships. | *4* -| *Present.* With <>, you can display your data on a visually -compelling, pixel-perfect workpad. **Canvas** can give your data -the “wow” factor needed to impress your CEO and captivate coworkers with a big-screen display. +| *Model data behavior.* +Use <> to model the behavior of your data—forecast unusual behavior and +perform outlier detection, regression, and classification analysis. | *5* | *Share.* Ready to <> your findings with a larger audience? {kib} offers many options—embed @@ -123,50 +98,9 @@ a dashboard, share a link, export to PDF, and more. |=== [float] -==== Plot location data on a map -If you’re looking to better understand the “where’’ in your data, your data -analysis journey will also include <>. This app is the right -choice when you’re looking for a spatial pattern, performing ad-hoc location-driven analysis, -or analyzing metrics with a geographic perspective. With *Maps*, you can build -world country maps, administrative region maps, and point-to-point origin-destination maps. -You can also visualize and track movement over space and through time. - -[float] -==== Model data behavior - -To model the behavior of your data, you'll use -<>. -This app can help you extract insights from your data that you might otherwise miss. -You can forecast unusual behavior in your time series data. -You can also perform outlier detection, regression, and classification analysis -on your data and generate annotated results. - -[float] -==== Graph relationships - -Looking to uncover how items in your data are related? -<> is your app. Graphing relationships is useful in a variety of use cases, -from fraud detection to recommendation engines. For example, graph exploration -can help you uncover website vulnerabilities that hackers are targeting, -so you can harden your website. Or, you might provide graph-based -personalized recommendations to your e-commerce customers. - -[float] -[[manage-all-things-stack]] -=== Manage all things Elastic Stack - -{kib}'s <> UIs takes you under the hood, -so you can twist the levers and turn the knobs. You'll find -guided processes for administering all things Elastic Stack, -including data, indices, clusters, alerts, and security. - -[role="screenshot"] -image::images/stack-management.png[Index Management view in Stack Management] - -[float] -==== Manage your data, indices, and clusters +=== Manage your data -{kib} offers these data management tasks—all from the convenience of a UI: +{kib} helps you perform your data management tasks from the convenience of a UI. You can: * Refresh, flush, and clear the cache of your indices. * Define the lifecycle of an index as it ages. @@ -174,71 +108,64 @@ image::images/stack-management.png[Index Management view in Stack Management] * Roll up data from one or more indices into a new, compact index. * Replicate indices on a remote cluster and copy them to a local cluster. -[float] -==== Alert and take action -Detecting and acting on significant shifts and signals in your data is a need -that exists in almost every use case. For example, you might set a rule to notify you when: +For a full list of data management UIs, refer to <>. + +[role="screenshot"] +image::images/stack-management.png[Index Management view in Stack Management] -* A shift occurs in your business critical KPIs. -* System resources, such as memory, CPU and disk space, take a dip. -* An unusually high number of service requests, suspicious processes, and login attempts occurs. -A rule triggers when a specified condition is met. For example, -you can create a rule when the average or max of one of -your metrics exceeds a threshold within a specified time frame. +[float] +=== Alert and take action -When the rule triggers, you can send a notification to a system that is part of -your daily workflow. {kib} integrates with email, Slack, PagerDuty, and ServiceNow, -to name a few. +Detecting and acting on significant shifts and signals in your data is a need +that exists in almost every use case. Alerting allows you to +detect conditions in different {kib} apps and trigger actions when those conditions are met. +For example, you might trigger an alert when a shift occurs in your business critical KPIs or when +memory, CPU, or disk space take a dip. +When the alert triggers, you can send a notification to a system that is part of your daily workflow: +email, Slack, PagerDuty, ServiceNow, and other third party integrations. -A dedicated view for creating, searching, and editing rules is in <>. +A dedicated view for creating, searching, +and editing rules is in <> [role="screenshot"] image::images/rules-and-connectors.png[Rules and Connectors view] - [float] [[organize-and-secure]] -=== Organize your work in spaces +=== Organize content + +You might be managing tens, hundreds, or even thousands of dashboards, visualizations, and other {kib} assets. +{kib} has several features for keeping your content organized. -Want to share {kib}’s goodness with other people or teams without overwhelming them? You can do so -with <>, built for organizing your visualizations, dashboards, and index patterns. + +[float] +[[organize-in-spaces]] +==== Collect related items in a space + +{kib} +<> is built for organizing your visualizations, dashboards, and {data-sources}. Think of a space as its own mini {kib} installation—it’s isolated from all other spaces, so you can tailor it to your specific needs without impacting others. -[role="screenshot"] -image::images/select-your-space.png[Space selector view] - Most of {kib}’s entities are space-aware, including dashboards, visualizations, index patterns, *Canvas* workpads, graphs, tags, and machine learning jobs. -In addition: - -* **Elastic Security** is space-aware, so the timelines and investigations -you open in one space will not be available to other spaces. - -* **Observability** is currently partially space-aware, but will be enhanced to become fully space-aware. - -* Most of the **Stack Management** features are not space aware because they -are primarily used to manage features of {es}, which serves as a shared data store for all spaces. - -* Alerts are space-aware and work nicely with the {kib} role-based access control -model to allow you secure access to them, depending on the alert type and your user roles. -For example, roles with no access to an app will not have access to its alerts. +[role="screenshot"] +image::images/select-your-space.png[Space selector view] [float] -==== Control feature visibility +==== Organize your content with tags -You can take spaces one step further and control which features are visible -within each space. For example, you might hide **Dev Tools** in your "Marketing" -space or show **Stack Monitoring** only in your "Engineering" space. +Tags are keywords or labels that you assign to {kib} saved objects, +such as dashboards and visualizations, so you can classify them in a way that is meaningful to you. +For example, if you tag objects with “design”, you can search and +filter on the tag to see related objects. +Tags are also good for grouping content into categories within a space. -Controlling feature visibility is not a security feature. To secure access -to specific features on a per-user basis, you must configure -<>. - -[role="screenshot"] -image::spaces/images/edit-space-feature-visibility.png[Features Controls view] +Don’t worry if you have hundreds of dashboards that need to be tagged. Use <> +in *Stack Management* to create your tags, then assign and delete +them in bulk operations. [float] [[intro-kibana-Security]] @@ -291,22 +218,14 @@ users’ behavior. For more information, see <>. - -|Add data -|The Add data page, available from the home page. - -|See the full list of {kib} features -|The https://www.elastic.co/kibana/features[{kib} features page on elastic.co] - -2+|*Build a search experience* - -|Create a search experience for your workplace -|https://www.elastic.co/guide/en/workplace-search/current/workplace-search-getting-started.html[Workplace Search] - -|Build a search experience for your app -|https://www.elastic.co/guide/en/app-search/current/getting-started.html[App Search] - - -2+|*Monitor, analyze, and react to events* - -|Monitor software services and applications in real-time by collecting performance information -|{observability-guide}/apm.html[APM] - -|Monitor the availability of your sites and services -|{observability-guide}/monitor-uptime.html[Uptime] - -|Search, filter, and tail all your logs -|{observability-guide}/monitor-logs.html[Logs] +This example searches for visualizations with the tag `design` . -|Analyze metrics from your infrastructure, apps, and services -|{observability-guide}/analyze-metrics.html[Metrics] - -2+|*Prevent, detect, and respond to threats* - -|Create and manage rules for suspicious source events, and view the alerts these rules create. -|{security-guide}/detection-engine-overview.html[Detections] - -|View all hosts and host-related security events. -|{security-guide}/hosts-overview.html[Hosts] - -|View key network activity metrics via an interactive map. -|{security-guide}/network-page-overview.html[Network] - -|Investigate alerts and complex threats, such as lateral movement of malware across hosts in your network. -|{security-guide}/timelines-ui.html[Timelines] - -|Create and track security issues -|{security-guide}/cases-overview.html[Cases] - -|View and manage hosts that are running Endpoint Security -|{security-guide}/admin-page-ov.html[Administration] - -2+| *Analyze and visualize your data* - -|Know what’s in your data -|<> - -|Create charts and other visualizations -|<> - -|Show your data from different perspectives -|<> - -|Work with location data -|<> - -|Create a presentation of your data -|<> - -|Generate models for your data’s behavior -|<> - -|Explore connections in your data -|<> - -|Share your data -|<>, <>, <> - -2+|*Administer your Kibana instance* - -|Manage your Elasticsearch data -|< Data>> - -|Set up rules -|< Rules and Connectors>> - -|Organize your workspace and users -|< Spaces>> +[role="screenshot"] +image::images/tags-search.png[Example of searching for tags] -|Define user roles and privileges -|< Users>> -|Customize {kib} to suit your needs -|< Advanced Settings>> +[float] +=== View all {kib} has to offer -|=== +To view the full list of {kib} apps and features, go to https://www.elastic.co/kibana/features[{kib} features]. [float] [[try-kibana]] -=== How to get help +=== Get help -Using our in-product guidance can help you get up and running, faster. -Click the help icon image:images/intro-help-icon.png[Help icon in navigation bar] +Click image:images/intro-help-icon.png[Help icon in navigation bar] for help with questions or to provide feedback. To keep up with what’s new and changed in Elastic, click the celebration icon in the global header. diff --git a/package.json b/package.json index 3a910de84a2c7..628fd320ea046 100644 --- a/package.json +++ b/package.json @@ -154,6 +154,7 @@ "@kbn/server-http-tools": "link:bazel-bin/packages/kbn-server-http-tools", "@kbn/server-route-repository": "link:bazel-bin/packages/kbn-server-route-repository", "@kbn/std": "link:bazel-bin/packages/kbn-std", + "@kbn/timelion-grammar": "link:bazel-bin/packages/kbn-timelion-grammar", "@kbn/tinymath": "link:bazel-bin/packages/kbn-tinymath", "@kbn/typed-react-router-config": "link:bazel-bin/packages/kbn-typed-react-router-config", "@kbn/ui-framework": "link:bazel-bin/packages/kbn-ui-framework", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 5c29b4a7eb64b..deec9d6bf5dc0 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -58,6 +58,7 @@ filegroup( "//packages/kbn-telemetry-tools:build", "//packages/kbn-test:build", "//packages/kbn-test-subj-selector:build", + "//packages/kbn-timelion-grammar:build", "//packages/kbn-tinymath:build", "//packages/kbn-typed-react-router-config:build", "//packages/kbn-ui-framework:build", diff --git a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts index f4017df600a48..1a49faabd8da3 100644 --- a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts +++ b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts @@ -67,7 +67,6 @@ it('produces the right watch and ignore list', () => { /x-pack/test/plugin_functional/plugins/resolver_test/docs/**, /x-pack/plugins/reporting/chromium, /x-pack/plugins/security_solution/cypress, - /x-pack/plugins/apm/e2e, /x-pack/plugins/apm/scripts, /x-pack/plugins/canvas/canvas_plugin_src, /x-pack/plugins/cases/server/scripts, diff --git a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts index b0773fd567635..f08e456940808 100644 --- a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts +++ b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts @@ -58,7 +58,6 @@ export function getServerWatchPaths({ pluginPaths, pluginScanDirs }: Options) { ...pluginInternalDirsIgnore, fromRoot('x-pack/plugins/reporting/chromium'), fromRoot('x-pack/plugins/security_solution/cypress'), - fromRoot('x-pack/plugins/apm/e2e'), fromRoot('x-pack/plugins/apm/scripts'), fromRoot('x-pack/plugins/canvas/canvas_plugin_src'), // prevents server from restarting twice for Canvas plugin changes, fromRoot('x-pack/plugins/cases/server/scripts'), diff --git a/packages/kbn-dev-utils/src/vscode_config/managed_config_keys.ts b/packages/kbn-dev-utils/src/vscode_config/managed_config_keys.ts index 288bfad02d7f4..8b941e9e4f71f 100644 --- a/packages/kbn-dev-utils/src/vscode_config/managed_config_keys.ts +++ b/packages/kbn-dev-utils/src/vscode_config/managed_config_keys.ts @@ -8,7 +8,7 @@ export interface ManagedConfigKey { key: string; - value: Record; + value: string | Record; } /** @@ -37,4 +37,9 @@ export const MANAGED_CONFIG_KEYS: ManagedConfigKey[] = [ ['**/packages/kbn-pm/dist/index.js']: true, }, }, + { + key: 'typescript.tsdk', + // we use a relative path here so that it works with remote vscode connections + value: './node_modules/typescript/lib', + }, ]; diff --git a/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.test.ts b/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.test.ts index dd57449c21da3..3573acd59559f 100644 --- a/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.test.ts +++ b/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.test.ts @@ -22,6 +22,10 @@ const TEST_KEYS: ManagedConfigKey[] = [ world: [1, 2, 3], }, }, + { + key: 'stringKey', + value: 'foo', + }, ]; const run = (json?: string) => updateVscodeConfig(TEST_KEYS, '', json); @@ -35,7 +39,9 @@ it('updates the passed JSON with the managed settings', () => { "hello": true, // @managed "world": [1, 2, 3] - } + }, + // @managed + "stringKey": "foo" } `); @@ -50,7 +56,9 @@ it('initialized empty or undefined json values', () => { "hello": true, // @managed "world": [1, 2, 3] - } + }, + // @managed + "stringKey": "foo" } `); @@ -63,14 +71,16 @@ it('initialized empty or undefined json values', () => { "hello": true, // @managed "world": [1, 2, 3] - } + }, + // @managed + "stringKey": "foo" } `); }); -it('replaces conflicting managed keys which do not have object values', () => { - expect(run(`{ "key": false }`)).toMatchInlineSnapshot(` +it('replaces conflicting managed keys which do not have matching value types', () => { + expect(run(`{ "key": false, "stringKey": { "a": "B" } }`)).toMatchInlineSnapshot(` // @managed { "key": { @@ -78,7 +88,9 @@ it('replaces conflicting managed keys which do not have object values', () => { "hello": true, // @managed "world": [1, 2, 3] - } + }, + // @managed + "stringKey": "foo" } `); @@ -122,7 +134,9 @@ it('persists comments in the original file', () => { "hello": true, // @managed "world": [1, 2, 3] - } + }, + // @managed + "stringKey": "foo" } `); @@ -148,7 +162,9 @@ it('overrides old values for managed keys', () => { "hello": true, // @managed "world": [1, 2, 3] - } + }, + // @managed + "stringKey": "foo" } `); @@ -176,7 +192,9 @@ it('does not modify properties with leading `// self managed` comment', () => { // self managed "key": { "world": [5] - } + }, + // self managed + "stringKey": "--" } `); @@ -186,7 +204,9 @@ it('does not modify properties with leading `// self managed` comment', () => { // self managed "key": { "world": [5] - } + }, + // self managed + "stringKey": "--" } `); @@ -210,7 +230,9 @@ it('does not modify child properties with leading `// self managed` comment', () "world": [5], // @managed "hello": true - } + }, + // @managed + "stringKey": "foo" } `); @@ -236,7 +258,9 @@ it('does not modify unknown child properties', () => { "world": [5], // @managed "hello": true - } + }, + // @managed + "stringKey": "foo" } `); @@ -262,7 +286,9 @@ it('removes managed properties which are no longer managed', () => { "world": [5], // @managed "hello": true - } + }, + // @managed + "stringKey": "foo" } `); @@ -286,7 +312,9 @@ it('wipes out child keys which conflict with newly managed child keys', () => { "hello": true, // @managed "world": [1, 2, 3] - } + }, + // @managed + "stringKey": "foo" } `); @@ -308,7 +336,9 @@ it('correctly formats info text when specified', () => { "hello": true, // @managed "world": [1, 2, 3] - } + }, + // @managed + "stringKey": "foo" } `); @@ -321,7 +351,10 @@ it('allows "// self managed" comments conflicting with "// @managed" comments to // @managed // self managed "hello": ["world"] - } + }, + // @managed + // self managed + "stringKey": 12345 } `); @@ -333,7 +366,9 @@ it('allows "// self managed" comments conflicting with "// @managed" comments to "hello": ["world"], // @managed "world": [1, 2, 3] - } + }, + // self managed + "stringKey": 12345 } `); diff --git a/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.ts b/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.ts index ac1b5515252dd..42a642ef1b6c4 100644 --- a/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.ts +++ b/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.ts @@ -25,11 +25,20 @@ const isManaged = (node?: t.Node) => (c) => c.type === 'CommentLine' && c.value.trim().toLocaleLowerCase() === '@managed' ); -const isSelfManaged = (node?: t.Node) => - !!node?.leadingComments?.some( +const isSelfManaged = (node?: t.Node) => { + const result = !!node?.leadingComments?.some( (c) => c.type === 'CommentLine' && c.value.trim().toLocaleLowerCase() === 'self managed' ); + // if we find a node which is both managed and self managed remove the managed comment + if (result && node && isManaged(node)) { + node.leadingComments = + node.leadingComments?.filter((c) => c.value.trim() !== '@managed') ?? null; + } + + return result; +}; + const remove = (arr: T[], value: T) => { const index = arr.indexOf(value); if (index > -1) { @@ -37,16 +46,16 @@ const remove = (arr: T[], value: T) => { } }; -const createManagedChildProp = (key: string, value: any) => { +const createManagedProp = (key: string, value: any) => { const childProp = t.objectProperty(t.stringLiteral(key), parseExpression(JSON.stringify(value))); t.addComment(childProp, 'leading', ' @managed', true); return childProp; }; -const createManagedProp = (key: string, value: Record) => { +const createObjectPropOfManagedValues = (key: string, value: Record) => { return t.objectProperty( t.stringLiteral(key), - t.objectExpression(Object.entries(value).map(([k, v]) => createManagedChildProp(k, v))) + t.objectExpression(Object.entries(value).map(([k, v]) => createManagedProp(k, v))) ); }; @@ -57,8 +66,16 @@ const createManagedProp = (key: string, value: Record) => { * @param key the key name to add * @param value managed value which should be set at `key` */ -const addManagedProp = (ast: t.ObjectExpression, key: string, value: Record) => { - ast.properties.push(createManagedProp(key, value)); +const addManagedProp = ( + ast: t.ObjectExpression, + key: string, + value: string | Record +) => { + ast.properties.push( + typeof value === 'string' + ? createManagedProp(key, value) + : createObjectPropOfManagedValues(key, value) + ); }; /** @@ -72,7 +89,7 @@ const addManagedProp = (ast: t.ObjectExpression, key: string, value: Record + value: string | Record ) => { remove(ast.properties, existing); addManagedProp(ast, existing.key.value, value); @@ -98,15 +115,11 @@ const mergeManagedProperties = ( if (!existing) { // add the new managed prop - properties.push(createManagedChildProp(key, value)); + properties.push(createManagedProp(key, value)); continue; } if (isSelfManaged(existing)) { - // strip "// @managed" comment if conflicting with "// self managed" - existing.leadingComments = (existing.leadingComments ?? []).filter( - (c) => c.value.trim() !== '@managed' - ); continue; } @@ -119,7 +132,7 @@ const mergeManagedProperties = ( // take over the unmanaged child prop by deleting the previous prop and replacing it // with a brand new one remove(properties, existing); - properties.push(createManagedChildProp(key, value)); + properties.push(createManagedProp(key, value)); } // iterate through the props to find "// @managed" props which are no longer in @@ -170,20 +183,29 @@ export function updateVscodeConfig(keys: ManagedConfigKey[], infoText: string, j continue; } - if (existingProp && existingProp.value.type === 'ObjectExpression') { - // setting exists and is an object so merge properties of `value` with it - mergeManagedProperties(existingProp.value.properties, value); + if (typeof value === 'object') { + if (existingProp && existingProp.value.type === 'ObjectExpression') { + // setting exists and is an object so merge properties of `value` with it + mergeManagedProperties(existingProp.value.properties, value); + continue; + } + + if (existingProp) { + // setting exists but its value is not an object expression so replace it + replaceManagedProp(ast, existingProp, value); + continue; + } + + // setting isn't in config file so create it + addManagedProp(ast, key, value); continue; } if (existingProp) { - // setting exists but its value is not an object expression so replace it replaceManagedProp(ast, existingProp, value); - continue; + } else { + addManagedProp(ast, key, value); } - - // setting isn't in config file so create it - addManagedProp(ast, key, value); } ast.leadingComments = [ diff --git a/packages/kbn-timelion-grammar/BUILD.bazel b/packages/kbn-timelion-grammar/BUILD.bazel new file mode 100644 index 0000000000000..9302e650630f3 --- /dev/null +++ b/packages/kbn-timelion-grammar/BUILD.bazel @@ -0,0 +1,46 @@ +load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") +load("@npm//peggy:index.bzl", "peggy") + +PKG_BASE_NAME = "kbn-timelion-grammar" +PKG_REQUIRE_NAME = "@kbn/timelion-grammar" + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +peggy( + name = "grammar", + data = [ + ":grammar/chain.peggy" + ], + output_dir = True, + args = [ + "-o", + "$(@D)/chain.js", + "./%s/grammar/chain.peggy" % package_name() + ], +) + +js_library( + name = PKG_BASE_NAME, + srcs = NPM_MODULE_EXTRA_FILES + [ + ":grammar" + ], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [ + ":%s" % PKG_BASE_NAME, + ] +) + +filegroup( + name = "build", + srcs = [ + ":npm_module", + ], + visibility = ["//visibility:public"], +) diff --git a/src/plugins/vis_type_timelion/common/chain.peg b/packages/kbn-timelion-grammar/grammar/chain.peggy similarity index 100% rename from src/plugins/vis_type_timelion/common/chain.peg rename to packages/kbn-timelion-grammar/grammar/chain.peggy diff --git a/packages/kbn-timelion-grammar/package.json b/packages/kbn-timelion-grammar/package.json new file mode 100644 index 0000000000000..04b88b002fc47 --- /dev/null +++ b/packages/kbn-timelion-grammar/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/timelion-grammar", + "version": "1.0.0", + "license": "SSPL-1.0 OR Elastic License 2.0", + "private": true, + "main": "grammar/chain.js" + } \ No newline at end of file diff --git a/scripts/kibana_verification_code.js b/scripts/kibana_verification_code.js new file mode 100644 index 0000000000000..42e3e54b9d4c8 --- /dev/null +++ b/scripts/kibana_verification_code.js @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +require('../src/cli_verification_code/dev'); diff --git a/src/cli_verification_code/cli_verification_code.js b/src/cli_verification_code/cli_verification_code.js new file mode 100644 index 0000000000000..7ed83e8211c3c --- /dev/null +++ b/src/cli_verification_code/cli_verification_code.js @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { kibanaPackageJson, getDataPath } from '@kbn/utils'; +import path from 'path'; +import fs from 'fs'; +import chalk from 'chalk'; + +import Command from '../cli/command'; + +const program = new Command('bin/kibana-verification-code'); + +program + .version(kibanaPackageJson.version) + .description('Tool to get Kibana verification code') + .action(() => { + const fpath = path.join(getDataPath(), 'verification_code'); + try { + const code = fs.readFileSync(fpath).toString(); + console.log( + `Your verification code is: ${chalk.black.bgCyanBright( + ` ${code.substr(0, 3)} ${code.substr(3)} ` + )}` + ); + } catch (error) { + console.log(`Couldn't find verification code. + +If Kibana hasn't been configured yet, restart Kibana to generate a new code. + +Otherwise, you can safely ignore this message and start using Kibana.`); + } + }); + +program.parse(process.argv); diff --git a/src/cli_verification_code/dev.js b/src/cli_verification_code/dev.js new file mode 100644 index 0000000000000..e424f6b7bec91 --- /dev/null +++ b/src/cli_verification_code/dev.js @@ -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. + */ + +require('../setup_node_env'); +require('./cli_verification_code'); diff --git a/src/cli_verification_code/dist.js b/src/cli_verification_code/dist.js new file mode 100644 index 0000000000000..6f7e63591a96d --- /dev/null +++ b/src/cli_verification_code/dist.js @@ -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. + */ + +require('../setup_node_env/dist'); +require('./cli_verification_code'); diff --git a/src/dev/build/tasks/bin/scripts/kibana-verification-code b/src/dev/build/tasks/bin/scripts/kibana-verification-code new file mode 100755 index 0000000000000..e8214affc23d7 --- /dev/null +++ b/src/dev/build/tasks/bin/scripts/kibana-verification-code @@ -0,0 +1,29 @@ +#!/bin/sh +SCRIPT=$0 + +# SCRIPT may be an arbitrarily deep series of symlinks. Loop until we have the concrete path. +while [ -h "$SCRIPT" ] ; do + ls=$(ls -ld "$SCRIPT") + # Drop everything prior to -> + link=$(expr "$ls" : '.*-> \(.*\)$') + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=$(dirname "$SCRIPT")/"$link" + fi +done + +DIR="$(dirname "${SCRIPT}")/.." +CONFIG_DIR=${KBN_PATH_CONF:-"$DIR/config"} +NODE="${DIR}/node/bin/node" +test -x "$NODE" +if [ ! -x "$NODE" ]; then + echo "unable to find usable node.js executable." + exit 1 +fi + +if [ -f "${CONFIG_DIR}/node.options" ]; then + KBN_NODE_OPTS="$(grep -v ^# < ${CONFIG_DIR}/node.options | xargs)" +fi + +NODE_OPTIONS="$KBN_NODE_OPTS $NODE_OPTIONS" "${NODE}" "${DIR}/src/cli_verification_code/dist" "$@" diff --git a/src/dev/build/tasks/bin/scripts/kibana-verification-code.bat b/src/dev/build/tasks/bin/scripts/kibana-verification-code.bat new file mode 100755 index 0000000000000..9202244e951e4 --- /dev/null +++ b/src/dev/build/tasks/bin/scripts/kibana-verification-code.bat @@ -0,0 +1,35 @@ +@echo off + +SETLOCAL ENABLEDELAYEDEXPANSION + +set SCRIPT_DIR=%~dp0 +for %%I in ("%SCRIPT_DIR%..") do set DIR=%%~dpfI + +set NODE=%DIR%\node\node.exe + +If Not Exist "%NODE%" ( + Echo unable to find usable node.js executable. + Exit /B 1 +) + +set CONFIG_DIR=%KBN_PATH_CONF% +If ["%KBN_PATH_CONF%"] == [] ( + set "CONFIG_DIR=%DIR%\config" +) + +IF EXIST "%CONFIG_DIR%\node.options" ( + for /F "usebackq eol=# tokens=*" %%i in ("%CONFIG_DIR%\node.options") do ( + If [!NODE_OPTIONS!] == [] ( + set "NODE_OPTIONS=%%i" + ) Else ( + set "NODE_OPTIONS=!NODE_OPTIONS! %%i" + ) + ) +) + +TITLE Kibana Verification Code +"%NODE%" "%DIR%\src\cli_verification_code\dist" %* + +:finally + +ENDLOCAL diff --git a/src/dev/build/tasks/package_json/find_used_dependencies.ts b/src/dev/build/tasks/package_json/find_used_dependencies.ts index 8cb8b3c986de7..8072287996368 100644 --- a/src/dev/build/tasks/package_json/find_used_dependencies.ts +++ b/src/dev/build/tasks/package_json/find_used_dependencies.ts @@ -42,7 +42,7 @@ export async function findUsedDependencies(listedPkgDependencies: any, baseDir: // Another way would be to include an index file and import all the functions // using named imports const dynamicRequiredEntries = await globby([ - normalize(Path.resolve(baseDir, 'src/plugins/vis_type_timelion/server/**/*.js')), + normalize(Path.resolve(baseDir, 'src/plugins/vis_types/timelion/server/**/*.js')), ]); // Compose all the needed entries diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index b99d547059d9c..be07c9c68784e 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -60,7 +60,6 @@ export const IGNORE_FILE_GLOBS = [ // TODO fix file names in APM to remove these 'x-pack/plugins/apm/public/**/*', 'x-pack/plugins/apm/scripts/**/*', - 'x-pack/plugins/apm/e2e/**/*', 'x-pack/plugins/maps/server/fonts/**/*', diff --git a/src/dev/typescript/projects.ts b/src/dev/typescript/projects.ts index e3d8185e73e55..a9e1e0da8e97f 100644 --- a/src/dev/typescript/projects.ts +++ b/src/dev/typescript/projects.ts @@ -59,10 +59,6 @@ export const PROJECTS = [ createProject('x-pack/plugins/osquery/cypress/tsconfig.json', { name: 'osquery/cypress', }), - createProject('x-pack/plugins/apm/e2e/tsconfig.json', { - name: 'apm/cypress', - disableTypeCheck: true, - }), createProject('x-pack/plugins/apm/ftr_e2e/tsconfig.json', { name: 'apm/ftr_e2e', disableTypeCheck: true, diff --git a/src/plugins/data/common/mocks.ts b/src/plugins/data/common/mocks.ts new file mode 100644 index 0000000000000..a9fc4c822a66e --- /dev/null +++ b/src/plugins/data/common/mocks.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export * from './index_patterns/fields/fields.mocks'; diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index 158eafb27c898..7a8dfc48e395a 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -41,6 +41,7 @@ export { shouldReadFieldFromDocValues, // used only in logstash_fields fixture FieldDescriptor, getCapabilitiesForRollupIndices, + IndexPatternsServiceStart, } from './index_patterns'; export { diff --git a/src/plugins/discover/public/__mocks__/index_pattern.ts b/src/plugins/discover/public/__mocks__/index_pattern.ts index 67aac96889424..9e7049187f639 100644 --- a/src/plugins/discover/public/__mocks__/index_pattern.ts +++ b/src/plugins/discover/public/__mocks__/index_pattern.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { IIndexPatternFieldList } from '../../../data/common/index_patterns/fields'; +import { IIndexPatternFieldList } from '../../../data/common'; import { IndexPattern } from '../../../data/common'; import { indexPatterns } from '../../../data/public'; diff --git a/src/plugins/discover/public/__mocks__/index_pattern_with_timefield.ts b/src/plugins/discover/public/__mocks__/index_pattern_with_timefield.ts index 0262bb942b8a5..f52ab8fd1c296 100644 --- a/src/plugins/discover/public/__mocks__/index_pattern_with_timefield.ts +++ b/src/plugins/discover/public/__mocks__/index_pattern_with_timefield.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { IIndexPatternFieldList } from '../../../data/common/index_patterns/fields'; +import { IIndexPatternFieldList } from '../../../data/common'; import { IndexPattern } from '../../../data/common'; import { indexPatterns } from '../../../data/public'; diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.scss b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.scss new file mode 100644 index 0000000000000..ede39feed30b6 --- /dev/null +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.scss @@ -0,0 +1,7 @@ +// Special handling for images coming from the image field formatter +// See discover_grid.scss for more explanation on those values +.rowFormatter__value img { + vertical-align: middle; + max-height: lineHeightFromBaseline(2) !important; + max-width: ($euiSizeXXL * 12.5) !important; +} diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx index 3b2d6d1c793ae..14cf1839107e7 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/lib/row_formatter.tsx @@ -11,6 +11,8 @@ import type { IndexPattern } from 'src/plugins/data/common'; import { MAX_DOC_FIELDS_DISPLAYED } from '../../../../../../../common'; import { getServices } from '../../../../../../kibana_services'; +import './row_formatter.scss'; + interface Props { defPairs: Array<[string, unknown]>; } @@ -21,6 +23,7 @@ const TemplateComponent = ({ defPairs }: Props) => {
{pair[0]}:
{' '} diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_search.tsx b/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_search.tsx index 12b19300ce266..4ab19a6ab05ef 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_search.tsx +++ b/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_search.tsx @@ -230,8 +230,8 @@ export function DiscoverFieldSearch({ onChange, value, types }: Props) { return ( ; + fieldCounts?: Record; /** * hits fetched from ES, displayed in the doc table */ - documents: ElasticSearchHit[]; + documents?: ElasticSearchHit[]; } -export function DiscoverSidebar({ +export function DiscoverSidebarComponent({ alwaysShowActionButtons = false, columns, fieldCounts, @@ -109,8 +109,10 @@ export function DiscoverSidebar({ const availableFieldsContainer = useRef(null); useEffect(() => { - const newFields = getIndexPatternFieldList(selectedIndexPattern, fieldCounts); - setFields(newFields); + if (documents) { + const newFields = getIndexPatternFieldList(selectedIndexPattern, fieldCounts); + setFields(newFields); + } }, [selectedIndexPattern, fieldCounts, documents]); const scrollDimensions = useResizeObserver(scrollContainer); @@ -265,7 +267,7 @@ export function DiscoverSidebar({ const filterChanged = useMemo(() => isEqual(fieldFilter, getDefaultFieldFilter()), [fieldFilter]); - if (!selectedIndexPattern || !fields) { + if (!selectedIndexPattern) { return null; } @@ -344,7 +346,7 @@ export function DiscoverSidebar({
{ - if (el && !el.dataset.dynamicScroll) { + if (documents && el && !el.dataset.dynamicScroll) { el.dataset.dynamicScroll = 'true'; setScrollContainer(el); } @@ -352,7 +354,7 @@ export function DiscoverSidebar({ onScroll={throttle(lazyScroll, 100)} className="eui-yScroll" > - {fields.length > 0 && ( + {Array.isArray(fields) && fields.length > 0 && (
{selectedFields && selectedFields.length > 0 && @@ -500,3 +502,5 @@ export function DiscoverSidebar({ ); } + +export const DiscoverSidebar = memo(DiscoverSidebarComponent); diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx b/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx index 7533a54ade405..90a3d33ddbe67 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx +++ b/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx @@ -114,6 +114,7 @@ export interface DiscoverSidebarResponsiveProps { * Mobile: Index pattern selector is visible and a button to trigger a flyout with all elements */ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) { + const { selectedIndexPattern, onEditRuntimeField, useNewFieldsApi, onChangeIndexPattern } = props; const [fieldFilter, setFieldFilter] = useState(getDefaultFieldFilter()); const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); /** @@ -125,7 +126,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) fieldCounts.current = calcFieldCounts( {}, props.documents$.getValue().result, - props.selectedIndexPattern + selectedIndexPattern ); } @@ -137,20 +138,20 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) fieldCounts.current = calcFieldCounts( next.result.length && fieldCounts.current ? fieldCounts.current : {}, next.result, - props.selectedIndexPattern! + selectedIndexPattern! ); } setDocumentState({ ...documentState, ...next }); } }); return () => subscription.unsubscribe(); - }, [props.documents$, props.selectedIndexPattern, documentState, setDocumentState]); + }, [props.documents$, selectedIndexPattern, documentState, setDocumentState]); useEffect(() => { // when index pattern changes fieldCounts needs to be cleaned up to prevent displaying // fields of the previous index pattern fieldCounts.current = {}; - }, [props.selectedIndexPattern]); + }, [selectedIndexPattern]); const closeFieldEditor = useRef<() => void | undefined>(); @@ -174,34 +175,44 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) setIsFlyoutVisible(false); }, []); - if (!props.selectedIndexPattern) { - return null; - } - const { indexPatternFieldEditor } = props.services; - const indexPatternFieldEditPermission = indexPatternFieldEditor?.userPermissions.editIndexPattern(); - const canEditIndexPatternField = !!indexPatternFieldEditPermission && props.useNewFieldsApi; - const editField = (fieldName?: string) => { - if (!canEditIndexPatternField || !props.selectedIndexPattern) { - return; - } - const ref = indexPatternFieldEditor.openEditor({ - ctx: { - indexPattern: props.selectedIndexPattern, - }, - fieldName, - onSave: async () => { - props.onEditRuntimeField(); - }, - }); - if (setFieldEditorRef) { - setFieldEditorRef(ref); - } - if (closeFlyout) { - closeFlyout(); - } - }; + const editField = useCallback( + (fieldName?: string) => { + const indexPatternFieldEditPermission = indexPatternFieldEditor?.userPermissions.editIndexPattern(); + const canEditIndexPatternField = !!indexPatternFieldEditPermission && useNewFieldsApi; + if (!canEditIndexPatternField || !selectedIndexPattern) { + return; + } + const ref = indexPatternFieldEditor.openEditor({ + ctx: { + indexPattern: selectedIndexPattern, + }, + fieldName, + onSave: async () => { + onEditRuntimeField(); + }, + }); + if (setFieldEditorRef) { + setFieldEditorRef(ref); + } + if (closeFlyout) { + closeFlyout(); + } + }, + [ + closeFlyout, + indexPatternFieldEditor, + selectedIndexPattern, + setFieldEditorRef, + onEditRuntimeField, + useNewFieldsApi, + ] + ); + + if (!selectedIndexPattern) { + return null; + } return ( <> @@ -209,7 +220,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) o.attributes.title)} /> @@ -296,7 +307,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps)
, + fieldCounts: Record | undefined, fieldFilterState: FieldFilterState, useNewFieldsApi: boolean ): GroupedFields { diff --git a/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx b/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx index c3d1df096c32f..c68b1ab7b844c 100644 --- a/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx +++ b/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { SavedObjectSaveModal, showSaveModal } from '../../../../../../../saved_objects/public'; import { SavedSearch } from '../../../../../saved_searches'; -import { IndexPattern } from '../../../../../../../data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../data/common'; import { DiscoverServices } from '../../../../../build_services'; import { GetStateReturn } from '../../services/discover_state'; import { setBreadcrumbsTitle } from '../../../../helpers/breadcrumbs'; diff --git a/src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts b/src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts index 9f9071ed403ce..83107d6c57ab8 100644 --- a/src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts +++ b/src/plugins/discover/public/application/apps/main/utils/get_switch_index_pattern_app_state.test.ts @@ -7,7 +7,7 @@ */ import { getSwitchIndexPatternAppState } from './get_switch_index_pattern_app_state'; -import { IndexPattern } from '../../../../../../data/common/index_patterns'; +import { IndexPattern } from '../../../../../../data/common'; /** * Helper function returning an index pattern diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid.scss b/src/plugins/discover/public/application/components/discover_grid/discover_grid.scss index 48b99458377ad..0204433a5ba1c 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid.scss +++ b/src/plugins/discover/public/application/components/discover_grid/discover_grid.scss @@ -86,6 +86,21 @@ .dscDiscoverGrid__descriptionListDescription { word-break: normal !important; + + // Special handling for images coming from the image field formatter + img { + // Align the images vertically centered with the text + vertical-align: middle; + // Set the maximum height to the line-height. The used function is the same + // function used to calculate the line-height for the EuiDescriptionList Description. + // !important is required to overwrite the max-height on the element from the field formatter + max-height: lineHeightFromBaseline(2) !important; + // An arbitrary amount of width we don't want to go over, to not have very wide images. + // For most width-height-ratios that will never be hit, because we'd usually limit + // it by the way smaller height. But images with very large width and very small height + // might be limited by that. + max-width: ($euiSizeXXL * 12.5) !important; + } } @include euiBreakpoint('xs', 's', 'm') { diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx b/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx index ab80cd3e7b461..b1823eb3d668c 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx +++ b/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx @@ -9,7 +9,7 @@ import React, { useContext } from 'react'; import { EuiDataGridColumnCellActionProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { IndexPatternField } from '../../../../../data/common/index_patterns/fields'; +import { IndexPatternField } from '../../../../../data/common'; import { DiscoverGridContext } from './discover_grid_context'; export const FilterInBtn = ({ diff --git a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx b/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx index f62b8b411e2bf..ecef98915ff65 100644 --- a/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx +++ b/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx @@ -110,6 +110,9 @@ export const getRenderCellValueFn = ( }); return ( + // If you change the styling of this list (specifically something that will change the line-height) + // make sure to adjust the img overwrites attached to dscDiscoverGrid__descriptionListDescription + // in discover_grid.scss {[...highlightPairs, ...sourcePairs].slice(0, maxDocFieldsDisplayed).map(([key, value]) => ( diff --git a/src/plugins/interactive_setup/public/single_chars_field.tsx b/src/plugins/interactive_setup/public/single_chars_field.tsx index 8d5cd2854c0aa..18ecd38e6483a 100644 --- a/src/plugins/interactive_setup/public/single_chars_field.tsx +++ b/src/plugins/interactive_setup/public/single_chars_field.tsx @@ -12,6 +12,7 @@ import React, { useEffect, useRef } from 'react'; import useList from 'react-use/lib/useList'; import useUpdateEffect from 'react-use/lib/useUpdateEffect'; +import { i18n } from '@kbn/i18n'; import { euiThemeVars } from '@kbn/ui-shared-deps/theme'; export interface SingleCharsFieldProps { @@ -124,6 +125,10 @@ export const SingleCharsField: FunctionComponent = ({ maxLength={1} isInvalid={isInvalid} style={{ textAlign: 'center' }} + aria-label={i18n.translate('interactiveSetup.singleCharsField.digitLabel', { + defaultMessage: 'Digit {index}', + values: { index: i + 1 }, + })} /> ); diff --git a/src/plugins/interactive_setup/public/verification_code_form.test.tsx b/src/plugins/interactive_setup/public/verification_code_form.test.tsx new file mode 100644 index 0000000000000..2b7f1a86fcfad --- /dev/null +++ b/src/plugins/interactive_setup/public/verification_code_form.test.tsx @@ -0,0 +1,83 @@ +/* + * 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 { fireEvent, render, waitFor } from '@testing-library/react'; +import React from 'react'; + +import { coreMock } from 'src/core/public/mocks'; + +import { Providers } from './plugin'; +import { VerificationCodeForm } from './verification_code_form'; + +jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ + htmlIdGenerator: () => () => `id-${Math.random()}`, +})); + +describe('VerificationCodeForm', () => { + jest.setTimeout(20_000); + + it('calls enrollment API when submitting form', async () => { + const coreStart = coreMock.createStart(); + coreStart.http.post.mockResolvedValue({}); + + const onSuccess = jest.fn(); + + const { findByRole, findByLabelText } = render( + + + + ); + fireEvent.input(await findByLabelText('Digit 1'), { + target: { value: '1' }, + }); + fireEvent.input(await findByLabelText('Digit 2'), { + target: { value: '2' }, + }); + fireEvent.input(await findByLabelText('Digit 3'), { + target: { value: '3' }, + }); + fireEvent.input(await findByLabelText('Digit 4'), { + target: { value: '4' }, + }); + fireEvent.input(await findByLabelText('Digit 5'), { + target: { value: '5' }, + }); + fireEvent.input(await findByLabelText('Digit 6'), { + target: { value: '6' }, + }); + fireEvent.click(await findByRole('button', { name: 'Verify', hidden: true })); + + await waitFor(() => { + expect(coreStart.http.post).toHaveBeenLastCalledWith('/internal/interactive_setup/verify', { + body: JSON.stringify({ code: '123456' }), + }); + expect(onSuccess).toHaveBeenCalled(); + }); + }); + + it('validates form', async () => { + const coreStart = coreMock.createStart(); + const onSuccess = jest.fn(); + + const { findAllByText, findByRole, findByLabelText } = render( + + + + ); + + fireEvent.click(await findByRole('button', { name: 'Verify', hidden: true })); + + await findAllByText(/Enter a verification code/i); + + fireEvent.input(await findByLabelText('Digit 1'), { + target: { value: '1' }, + }); + + await findAllByText(/Enter all six digits/i); + }); +}); diff --git a/src/plugins/interactive_setup/public/verification_code_form.tsx b/src/plugins/interactive_setup/public/verification_code_form.tsx index 8f4a9ea8c5d01..8bea8229baec3 100644 --- a/src/plugins/interactive_setup/public/verification_code_form.tsx +++ b/src/plugins/interactive_setup/public/verification_code_form.tsx @@ -9,6 +9,7 @@ import { EuiButton, EuiCallOut, + EuiCode, EuiEmptyPrompt, EuiForm, EuiFormRow, @@ -69,8 +70,8 @@ export const VerificationCodeForm: FunctionComponent }), }); } catch (error) { - if (error.response?.status === 403) { - form.setError('code', error.body?.message); + if ((error as IHttpFetchError).response?.status === 403) { + form.setError('code', (error as IHttpFetchError).body?.message); return; } else { throw error; @@ -111,7 +112,10 @@ export const VerificationCodeForm: FunctionComponent

./bin/kibana-verification-code, + }} />

diff --git a/src/plugins/interactive_setup/server/plugin.ts b/src/plugins/interactive_setup/server/plugin.ts index 8c57b6e8514c0..2c3b517e78c5f 100644 --- a/src/plugins/interactive_setup/server/plugin.ts +++ b/src/plugins/interactive_setup/server/plugin.ts @@ -17,7 +17,7 @@ import type { ConfigSchema, ConfigType } from './config'; import { ElasticsearchService } from './elasticsearch_service'; import { KibanaConfigWriter } from './kibana_config_writer'; import { defineRoutes } from './routes'; -import { VerificationCode } from './verification_code'; +import { VerificationService } from './verification_service'; // List of the Elasticsearch hosts Kibana uses by default. const DEFAULT_ELASTICSEARCH_HOSTS = [ @@ -29,7 +29,7 @@ const DEFAULT_ELASTICSEARCH_HOSTS = [ export class InteractiveSetupPlugin implements PrebootPlugin { readonly #logger: Logger; readonly #elasticsearch: ElasticsearchService; - readonly #verificationCode: VerificationCode; + readonly #verification: VerificationService; #elasticsearchConnectionStatusSubscription?: Subscription; @@ -47,7 +47,7 @@ export class InteractiveSetupPlugin implements PrebootPlugin { this.#elasticsearch = new ElasticsearchService( this.initializerContext.logger.get('elasticsearch') ); - this.#verificationCode = new VerificationCode( + this.#verification = new VerificationService( this.initializerContext.logger.get('verification') ); } @@ -73,6 +73,14 @@ export class InteractiveSetupPlugin implements PrebootPlugin { return; } + const verificationCode = this.#verification.setup(); + if (!verificationCode) { + this.#logger.error( + 'Interactive setup mode could not be activated. Ensure Kibana has permission to write to its config folder.' + ); + return; + } + let completeSetup: (result: { shouldReloadConfig: boolean }) => void; core.preboot.holdSetupUntilResolved( 'Validating Elasticsearch connection configuration…', @@ -93,6 +101,7 @@ export class InteractiveSetupPlugin implements PrebootPlugin { elasticsearch: core.elasticsearch, connectionCheckInterval: this.#getConfig().connectionCheck.interval, }); + this.#elasticsearchConnectionStatusSubscription = elasticsearch.connectionStatus$.subscribe( (status) => { if (status === ElasticsearchConnectionStatus.Configured) { @@ -104,10 +113,9 @@ export class InteractiveSetupPlugin implements PrebootPlugin { this.#logger.debug( 'Starting interactive setup mode since Kibana cannot to connect to Elasticsearch at http://localhost:9200.' ); - const { code } = this.#verificationCode; const pathname = core.http.basePath.prepend('/'); const { protocol, hostname, port } = core.http.getServerInfo(); - const url = `${protocol}://${hostname}:${port}${pathname}?code=${code}`; + const url = `${protocol}://${hostname}:${port}${pathname}?code=${verificationCode.code}`; // eslint-disable-next-line no-console console.log(` @@ -135,7 +143,7 @@ Go to ${chalk.cyanBright.underline(url)} to get started. preboot: { ...core.preboot, completeSetup }, kibanaConfigWriter: new KibanaConfigWriter(configPath, this.#logger.get('kibana-config')), elasticsearch, - verificationCode: this.#verificationCode, + verificationCode, getConfig: this.#getConfig.bind(this), }); }); @@ -155,5 +163,6 @@ Go to ${chalk.cyanBright.underline(url)} to get started. } this.#elasticsearch.stop(); + this.#verification.stop(); } } diff --git a/src/plugins/interactive_setup/server/verification_service.test.ts b/src/plugins/interactive_setup/server/verification_service.test.ts new file mode 100644 index 0000000000000..1721362d1c635 --- /dev/null +++ b/src/plugins/interactive_setup/server/verification_service.test.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 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 fs from 'fs'; + +import { loggingSystemMock } from 'src/core/server/mocks'; + +import { VerificationCode } from './verification_code'; +import { VerificationService } from './verification_service'; + +jest.mock('fs'); +jest.mock('@kbn/utils', () => ({ + getDataPath: jest.fn().mockReturnValue('/data/'), +})); + +const loggerMock = loggingSystemMock.createLogger(); + +describe('VerificationService', () => { + describe('setup()', () => { + it('should generate verification code', () => { + const service = new VerificationService(loggerMock); + const setup = service.setup(); + expect(setup).toBeInstanceOf(VerificationCode); + }); + + it('should write verification code to disk', () => { + const service = new VerificationService(loggerMock); + const setup = service.setup()!; + expect(fs.writeFileSync).toHaveBeenCalledWith('/data/verification_code', setup.code); + }); + + it('should not return verification code if cannot write to disk', () => { + const service = new VerificationService(loggerMock); + (fs.writeFileSync as jest.Mock).mockImplementationOnce(() => { + throw new Error('Write error'); + }); + const setup = service.setup(); + expect(fs.writeFileSync).toHaveBeenCalledWith('/data/verification_code', expect.anything()); + expect(setup).toBeUndefined(); + }); + }); + + describe('stop()', () => { + it('should remove verification code from disk', () => { + const service = new VerificationService(loggerMock); + service.stop(); + expect(fs.unlinkSync).toHaveBeenCalledWith('/data/verification_code'); + }); + }); +}); diff --git a/src/plugins/interactive_setup/server/verification_service.ts b/src/plugins/interactive_setup/server/verification_service.ts new file mode 100644 index 0000000000000..b158b23bd3b6d --- /dev/null +++ b/src/plugins/interactive_setup/server/verification_service.ts @@ -0,0 +1,49 @@ +/* + * 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 fs from 'fs'; +import path from 'path'; + +import { getDataPath } from '@kbn/utils'; +import type { Logger } from 'src/core/server'; + +import { getDetailedErrorMessage } from './errors'; +import { VerificationCode } from './verification_code'; + +export class VerificationService { + private fileName: string; + + constructor(private readonly logger: Logger) { + this.fileName = path.join(getDataPath(), 'verification_code'); + } + + public setup() { + const verificationCode = new VerificationCode(this.logger); + + try { + fs.writeFileSync(this.fileName, verificationCode.code); + this.logger.debug(`Successfully wrote verification code to ${this.fileName}`); + return verificationCode; + } catch (error) { + this.logger.error( + `Failed to write verification code to ${this.fileName}: ${getDetailedErrorMessage(error)}.` + ); + } + } + + public stop() { + try { + fs.unlinkSync(this.fileName); + this.logger.debug(`Successfully removed ${this.fileName}`); + } catch (error) { + if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { + this.logger.error(`Failed to remove ${this.fileName}: ${getDetailedErrorMessage(error)}.`); + } + } + } +} diff --git a/src/plugins/vis_type_table/tsconfig.json b/src/plugins/vis_type_table/tsconfig.json deleted file mode 100644 index 16f2f809bde38..0000000000000 --- a/src/plugins/vis_type_table/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./target/types", - "emitDeclarationOnly": true, - "declaration": true, - "declarationMap": true - }, - "include": [ - "common/**/*", - "public/**/*", - "server/**/*", - "*.ts" - ], - "references": [ - { "path": "../../core/tsconfig.json" }, - { "path": "../data/tsconfig.json" }, - { "path": "../visualizations/tsconfig.json" }, - { "path": "../share/tsconfig.json" }, - { "path": "../usage_collection/tsconfig.json" }, - { "path": "../expressions/tsconfig.json" }, - { "path": "../kibana_utils/tsconfig.json" }, - { "path": "../kibana_legacy/tsconfig.json" }, - { "path": "../kibana_react/tsconfig.json" }, - { "path": "../vis_default_editor/tsconfig.json" }, - { "path": "../field_formats/tsconfig.json" } - ] -} diff --git a/src/plugins/vis_type_timelion/README.md b/src/plugins/vis_type_timelion/README.md deleted file mode 100644 index 89d34527c51d6..0000000000000 --- a/src/plugins/vis_type_timelion/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Vis type Timelion - -Contains the timelion visualization and the timelion backend. - -# Generate a parser -If your grammar was changed in `public/chain.peg` you need to re-generate the static parser. You could use a grunt task: - -``` -grunt peg:timelion_chain -``` - -The generated parser will be appeared at `public/_generated_` folder, which is included in `.eslintignore` \ No newline at end of file diff --git a/src/plugins/vis_type_timelion/common/_generated_/chain.js b/src/plugins/vis_type_timelion/common/_generated_/chain.js deleted file mode 100644 index f812b94238d43..0000000000000 --- a/src/plugins/vis_type_timelion/common/_generated_/chain.js +++ /dev/null @@ -1,1780 +0,0 @@ -module.exports = (function() { - "use strict"; - - /* - * Generated by PEG.js 0.9.0. - * - * http://pegjs.org/ - */ - - function peg$subclass(child, parent) { - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor(); - } - - function peg$SyntaxError(message, expected, found, location) { - this.message = message; - this.expected = expected; - this.found = found; - this.location = location; - this.name = "SyntaxError"; - - if (typeof Error.captureStackTrace === "function") { - Error.captureStackTrace(this, peg$SyntaxError); - } - } - - peg$subclass(peg$SyntaxError, Error); - - function peg$parse(input) { - var options = arguments.length > 1 ? arguments[1] : {}, - parser = this, - - peg$FAILED = {}, - - peg$startRuleFunctions = { start: peg$parsestart }, - peg$startRuleFunction = peg$parsestart, - - peg$c0 = function(tree) { - return { - tree: tree.filter(function (o) {return o != null}), - functions: functions, - args: args, - variables: variables - } - }, - peg$c1 = ",", - peg$c2 = { type: "literal", value: ",", description: "\",\"" }, - peg$c3 = function(first, arg) {return arg}, - peg$c4 = function(first, rest) { - return [first].concat(rest); - }, - peg$c5 = "=", - peg$c6 = { type: "literal", value: "=", description: "\"=\"" }, - peg$c7 = function(name, value) { - var arg = { - type: 'namedArg', - name: name, - value: value, - location: simpleLocation(location()), - text: text() - }; - currentArgs.push(arg); - return arg; - }, - peg$c8 = function(value) { - var exception = { - type: 'incompleteArgument', - currentArgs: currentArgs, - currentFunction: currentFunction, - location: simpleLocation(location()), - text: text() - } - error(JSON.stringify(exception)); - }, - peg$c9 = function(name) { - var exception = { - type: 'incompleteArgumentValue', - currentArgs: currentArgs, - currentFunction: currentFunction, - name: name, - location: simpleLocation(location()), - text: text() - } - error(JSON.stringify(exception)); - }, - peg$c10 = function(element) {return element}, - peg$c11 = function(literal) { - var result = ltoo(literal); - result.location = simpleLocation(location()), - result.text = text(); - return result; - }, - peg$c12 = "$", - peg$c13 = { type: "literal", value: "$", description: "\"$\"" }, - peg$c14 = function(name) { - if (variables[name]) { - return variables[name]; - } else { - error('$' + name + ' is not defined') - } - }, - peg$c15 = function(name, value) { - variables[name] = value; - }, - peg$c16 = function(first, series) {return series}, - peg$c17 = function(first, rest) { - return [first].concat(rest) - }, - peg$c18 = /^[a-zA-Z]/, - peg$c19 = { type: "class", value: "[a-zA-Z]", description: "[a-zA-Z]" }, - peg$c20 = /^[.a-zA-Z0-9_\-]/, - peg$c21 = { type: "class", value: "[.a-zA-Z0-9_-]", description: "[.a-zA-Z0-9_-]" }, - peg$c22 = function(first, rest) { - currentFunction = first.join('') + rest.join(''); - currentArgs = []; - return currentFunction; - }, - peg$c23 = function(first, rest) { return first.join('') + rest.join('') }, - peg$c24 = { type: "other", description: "function" }, - peg$c25 = ".", - peg$c26 = { type: "literal", value: ".", description: "\".\"" }, - peg$c27 = "(", - peg$c28 = { type: "literal", value: "(", description: "\"(\"" }, - peg$c29 = ")", - peg$c30 = { type: "literal", value: ")", description: "\")\"" }, - peg$c31 = function(name, arg_list) { - var result = { - type: 'function', - function: name, - arguments: arg_list || [], - location: simpleLocation(location()), - text: text() - } - - result.arguments.forEach(function (arg) { - arg.function = name; - args.push(arg); - }) - - functions.push(result) - return result; - }, - peg$c32 = function(func) { - var exception = { - type: 'incompleteFunction', - function: func, - location: simpleLocation(location()), - text: text() - } - error(JSON.stringify(exception)); - }, - peg$c33 = "@", - peg$c34 = { type: "literal", value: "@", description: "\"@\"" }, - peg$c35 = ":", - peg$c36 = { type: "literal", value: ":", description: "\":\"" }, - peg$c37 = function(plot, series) { - return { - type: 'reference', - plot: plot, - series: series - } - }, - peg$c38 = function(plot) { - return { - type: 'reference', - plot: plot - } - }, - peg$c39 = function(func, rest) {return {type: 'chain', chain: [func].concat(rest)}}, - peg$c40 = function(grouped, functions) { - var first = { - type: 'chainList', - list: grouped - } - first.label = text(); - - return {type: "chain", chain: [first].concat(functions)}; - }, - peg$c41 = { type: "other", description: "literal" }, - peg$c42 = "\"", - peg$c43 = { type: "literal", value: "\"", description: "\"\\\"\"" }, - peg$c44 = function(chars) { return chars.join(''); }, - peg$c45 = "'", - peg$c46 = { type: "literal", value: "'", description: "\"'\"" }, - peg$c47 = "true", - peg$c48 = { type: "literal", value: "true", description: "\"true\"" }, - peg$c49 = function() { return true; }, - peg$c50 = "false", - peg$c51 = { type: "literal", value: "false", description: "\"false\"" }, - peg$c52 = function() { return false; }, - peg$c53 = "null", - peg$c54 = { type: "literal", value: "null", description: "\"null\"" }, - peg$c55 = function() { return null; }, - peg$c56 = /^[^()"',= \t]/, - peg$c57 = { type: "class", value: "[^()\"',=\\ \\t]", description: "[^()\"',=\\ \\t]" }, - peg$c58 = function(string) { // this also matches numbers via Number() - var result = string.join(''); - // Sort of hacky, but PEG doesn't have backtracking so - // a number rule is hard to read, and performs worse - if (isNaN(Number(result))) return result; - return Number(result) - }, - peg$c59 = /^[ \t\r\n]/, - peg$c60 = { type: "class", value: "[\\ \\t\\r\\n]", description: "[\\ \\t\\r\\n]" }, - peg$c61 = "\\", - peg$c62 = { type: "literal", value: "\\", description: "\"\\\\\"" }, - peg$c63 = function(sequence) { return sequence; }, - peg$c64 = /^[^"]/, - peg$c65 = { type: "class", value: "[^\"]", description: "[^\"]" }, - peg$c66 = /^[^']/, - peg$c67 = { type: "class", value: "[^']", description: "[^']" }, - peg$c68 = /^[0-9]/, - peg$c69 = { type: "class", value: "[0-9]", description: "[0-9]" }, - peg$c70 = function(digits) {return parseInt(digits.join(''))}, - - peg$currPos = 0, - peg$savedPos = 0, - peg$posDetailsCache = [{ line: 1, column: 1, seenCR: false }], - peg$maxFailPos = 0, - peg$maxFailExpected = [], - peg$silentFails = 0, - - peg$result; - - if ("startRule" in options) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function text() { - return input.substring(peg$savedPos, peg$currPos); - } - - function location() { - return peg$computeLocation(peg$savedPos, peg$currPos); - } - - function expected(description) { - throw peg$buildException( - null, - [{ type: "other", description: description }], - input.substring(peg$savedPos, peg$currPos), - peg$computeLocation(peg$savedPos, peg$currPos) - ); - } - - function error(message) { - throw peg$buildException( - message, - null, - input.substring(peg$savedPos, peg$currPos), - peg$computeLocation(peg$savedPos, peg$currPos) - ); - } - - function peg$computePosDetails(pos) { - var details = peg$posDetailsCache[pos], - p, ch; - - if (details) { - return details; - } else { - p = pos - 1; - while (!peg$posDetailsCache[p]) { - p--; - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column, - seenCR: details.seenCR - }; - - while (p < pos) { - ch = input.charAt(p); - if (ch === "\n") { - if (!details.seenCR) { details.line++; } - details.column = 1; - details.seenCR = false; - } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { - details.line++; - details.column = 1; - details.seenCR = true; - } else { - details.column++; - details.seenCR = false; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - return details; - } - } - - function peg$computeLocation(startPos, endPos) { - var startPosDetails = peg$computePosDetails(startPos), - endPosDetails = peg$computePosDetails(endPos); - - return { - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column - } - }; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildException(message, expected, found, location) { - function cleanupExpected(expected) { - var i = 1; - - expected.sort(function(a, b) { - if (a.description < b.description) { - return -1; - } else if (a.description > b.description) { - return 1; - } else { - return 0; - } - }); - - while (i < expected.length) { - if (expected[i - 1] === expected[i]) { - expected.splice(i, 1); - } else { - i++; - } - } - } - - function buildMessage(expected, found) { - function stringEscape(s) { - function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } - - return s - .replace(/\\/g, '\\\\') - .replace(/"/g, '\\"') - .replace(/\x08/g, '\\b') - .replace(/\t/g, '\\t') - .replace(/\n/g, '\\n') - .replace(/\f/g, '\\f') - .replace(/\r/g, '\\r') - .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); }) - .replace(/[\u0100-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) - .replace(/[\u1000-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); - } - - var expectedDescs = new Array(expected.length), - expectedDesc, foundDesc, i; - - for (i = 0; i < expected.length; i++) { - expectedDescs[i] = expected[i].description; - } - - expectedDesc = expected.length > 1 - ? expectedDescs.slice(0, -1).join(", ") - + " or " - + expectedDescs[expected.length - 1] - : expectedDescs[0]; - - foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input"; - - return "Expected " + expectedDesc + " but " + foundDesc + " found."; - } - - if (expected !== null) { - cleanupExpected(expected); - } - - return new peg$SyntaxError( - message !== null ? message : buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parsestart() { - var s0, s1, s2; - - s0 = peg$currPos; - s1 = peg$parsespace(); - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parseseries(); - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c0(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsearg_list() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseargument(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parsespace(); - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c1; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c2); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parsespace(); - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - s7 = peg$parseargument(); - if (s7 !== peg$FAILED) { - peg$savedPos = s3; - s4 = peg$c3(s1, s7); - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parsespace(); - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c1; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c2); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parsespace(); - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - s7 = peg$parseargument(); - if (s7 !== peg$FAILED) { - peg$savedPos = s3; - s4 = peg$c3(s1, s7); - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s3 = peg$parsespace(); - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s4 = peg$c1; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c2); } - } - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c4(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseargument() { - var s0, s1, s2, s3, s4, s5; - - s0 = peg$currPos; - s1 = peg$parseargument_name(); - if (s1 !== peg$FAILED) { - s2 = peg$parsespace(); - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 61) { - s3 = peg$c5; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c6); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parsespace(); - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - s5 = peg$parsearg_type(); - if (s5 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c7(s1, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parsespace(); - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 61) { - s2 = peg$c5; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c6); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parsespace(); - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s4 = peg$parsearg_type(); - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c8(s4); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseargument_name(); - if (s1 !== peg$FAILED) { - s2 = peg$parsespace(); - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 61) { - s3 = peg$c5; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c6); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c9(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parsearg_type(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c10(s1); - } - s0 = s1; - } - } - } - - return s0; - } - - function peg$parsearg_type() { - var s0, s1; - - s0 = peg$parsevariable_get(); - if (s0 === peg$FAILED) { - s0 = peg$parseseries_type(); - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseliteral(); - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c11(s1); - } - s0 = s1; - } - } - - return s0; - } - - function peg$parsevariable_get() { - var s0, s1, s2; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 36) { - s1 = peg$c12; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c13); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseargument_name(); - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c14(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsevariable_set() { - var s0, s1, s2, s3, s4, s5, s6; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 36) { - s1 = peg$c12; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c13); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseargument_name(); - if (s2 !== peg$FAILED) { - s3 = peg$parsespace(); - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 61) { - s4 = peg$c5; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c6); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parsespace(); - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - s6 = peg$parsearg_type(); - if (s6 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c15(s2, s6); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseseries_type() { - var s0; - - s0 = peg$parsevariable_set(); - if (s0 === peg$FAILED) { - s0 = peg$parsevariable_get(); - if (s0 === peg$FAILED) { - s0 = peg$parsegroup(); - if (s0 === peg$FAILED) { - s0 = peg$parsechain(); - if (s0 === peg$FAILED) { - s0 = peg$parsereference(); - } - } - } - } - - return s0; - } - - function peg$parseseries() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - s1 = peg$parseseries_type(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parsespace(); - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c1; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c2); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parsespace(); - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - s7 = peg$parseseries_type(); - if (s7 !== peg$FAILED) { - peg$savedPos = s3; - s4 = peg$c16(s1, s7); - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parsespace(); - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c1; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c2); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parsespace(); - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - s7 = peg$parseseries_type(); - if (s7 !== peg$FAILED) { - peg$savedPos = s3; - s4 = peg$c16(s1, s7); - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s3 = peg$c1; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c2); } - } - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c17(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsefunction_name() { - var s0, s1, s2, s3; - - s0 = peg$currPos; - s1 = []; - if (peg$c18.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c19); } - } - if (s2 !== peg$FAILED) { - while (s2 !== peg$FAILED) { - s1.push(s2); - if (peg$c18.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c19); } - } - } - } else { - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s2 = []; - if (peg$c20.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c21); } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - if (peg$c20.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c21); } - } - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c22(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseargument_name() { - var s0, s1, s2, s3; - - s0 = peg$currPos; - s1 = []; - if (peg$c18.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c19); } - } - if (s2 !== peg$FAILED) { - while (s2 !== peg$FAILED) { - s1.push(s2); - if (peg$c18.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c19); } - } - } - } else { - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s2 = []; - if (peg$c20.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c21); } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - if (peg$c20.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c21); } - } - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c23(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsefunction() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$parsespace(); - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 46) { - s2 = peg$c25; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c26); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parsefunction_name(); - if (s3 !== peg$FAILED) { - s4 = peg$parsespace(); - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 40) { - s5 = peg$c27; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c28); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parsespace(); - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - s7 = peg$parsearg_list(); - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parsespace(); - if (s8 === peg$FAILED) { - s8 = null; - } - if (s8 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s9 = peg$c29; - peg$currPos++; - } else { - s9 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c30); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parsespace(); - if (s10 === peg$FAILED) { - s10 = null; - } - if (s10 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c31(s3, s7); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parsefunction_name(); - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c32(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c24); } - } - - return s0; - } - - function peg$parsereference() { - var s0, s1, s2, s3, s4; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 64) { - s1 = peg$c33; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c34); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseinteger(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c35; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c36); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parseinteger(); - if (s4 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c37(s2, s4); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 64) { - s1 = peg$c33; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c34); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseinteger(); - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c38(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - return s0; - } - - function peg$parsechain() { - var s0, s1, s2, s3, s4; - - s0 = peg$currPos; - s1 = peg$parsefunction(); - if (s1 !== peg$FAILED) { - s2 = peg$parsespace(); - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s3 = []; - s4 = peg$parsefunction(); - while (s4 !== peg$FAILED) { - s3.push(s4); - s4 = peg$parsefunction(); - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c39(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsegroup() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c27; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c28); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parsespace(); - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s3 = peg$parseseries(); - if (s3 !== peg$FAILED) { - s4 = peg$parsespace(); - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c29; - peg$currPos++; - } else { - s5 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c30); } - } - if (s5 !== peg$FAILED) { - s6 = []; - s7 = peg$parsefunction(); - while (s7 !== peg$FAILED) { - s6.push(s7); - s7 = peg$parsefunction(); - } - if (s6 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c40(s3, s6); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parseliteral() { - var s0, s1, s2, s3; - - peg$silentFails++; - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c42; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c43); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$parsedq_char(); - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$parsedq_char(); - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c42; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c43); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c44(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c45; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c46); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$parsesq_char(); - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$parsesq_char(); - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c45; - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c46); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c44(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c47) { - s1 = peg$c47; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c48); } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c49(); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c50) { - s1 = peg$c50; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c51); } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c52(); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c53) { - s1 = peg$c53; - peg$currPos += 4; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c54); } - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c55(); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = []; - if (peg$c56.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c57); } - } - if (s2 !== peg$FAILED) { - while (s2 !== peg$FAILED) { - s1.push(s2); - if (peg$c56.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c57); } - } - } - } else { - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c58(s1); - } - s0 = s1; - } - } - } - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c41); } - } - - return s0; - } - - function peg$parsespace() { - var s0, s1; - - s0 = []; - if (peg$c59.test(input.charAt(peg$currPos))) { - s1 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c60); } - } - if (s1 !== peg$FAILED) { - while (s1 !== peg$FAILED) { - s0.push(s1); - if (peg$c59.test(input.charAt(peg$currPos))) { - s1 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c60); } - } - } - } else { - s0 = peg$FAILED; - } - - return s0; - } - - function peg$parsedq_char() { - var s0, s1, s2; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s1 = peg$c61; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c62); } - } - if (s1 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s2 = peg$c42; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c43); } - } - if (s2 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 92) { - s2 = peg$c61; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c62); } - } - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c63(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - if (peg$c64.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c65); } - } - } - - return s0; - } - - function peg$parsesq_char() { - var s0, s1, s2; - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s1 = peg$c61; - peg$currPos++; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c62); } - } - if (s1 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s2 = peg$c45; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c46); } - } - if (s2 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 92) { - s2 = peg$c61; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c62); } - } - } - if (s2 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c63(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - if (peg$c66.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c67); } - } - } - - return s0; - } - - function peg$parseinteger() { - var s0, s1, s2; - - s0 = peg$currPos; - s1 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c69); } - } - if (s2 !== peg$FAILED) { - while (s2 !== peg$FAILED) { - s1.push(s2); - if (peg$c68.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$c69); } - } - } - } else { - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$c70(s1); - } - s0 = s1; - - return s0; - } - - - function ltoo (literal) { - return {type: 'literal', value: literal} - } - - function simpleLocation (location) { - // Returns an object representing the position of the function within the expression, - // demarcated by the position of its first character and last character. We calculate these values - // using the offset because the expression could span multiple lines, and we don't want to deal - // with column and line values. - return { - min: location.start.offset, - max: location.end.offset - } - } - - var currentFunction; - var currentArgs = []; - - var functions = []; - var args = []; - var variables = {}; - - - - peg$result = peg$startRuleFunction(); - - if (peg$result !== peg$FAILED && peg$currPos === input.length) { - return peg$result; - } else { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail({ type: "end", description: "end of input" }); - } - - throw peg$buildException( - null, - peg$maxFailExpected, - peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } - } - - return { - SyntaxError: peg$SyntaxError, - parse: peg$parse - }; -})(); \ No newline at end of file diff --git a/src/plugins/vis_type_timelion/tsconfig.json b/src/plugins/vis_type_timelion/tsconfig.json deleted file mode 100644 index efeab8d73db1e..0000000000000 --- a/src/plugins/vis_type_timelion/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./target/types", - "emitDeclarationOnly": true, - "declaration": true, - "declarationMap": true - }, - "include": [ - "common/**/*", - "public/**/*", - "server/**/*", - "*.ts" - ], - "references": [ - { "path": "../../core/tsconfig.json" }, - { "path": "../visualizations/tsconfig.json" }, - { "path": "../data/tsconfig.json" }, - { "path": "../expressions/tsconfig.json" }, - { "path": "../kibana_utils/tsconfig.json" }, - { "path": "../kibana_react/tsconfig.json" }, - { "path": "../vis_default_editor/tsconfig.json" }, - ] -} diff --git a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js index b470352eec56a..35f0118cc8525 100644 --- a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js +++ b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js @@ -141,6 +141,7 @@ export const TimeSeries = ({ debugState={window._echDebugStateFlag ?? false} showLegend={legend} showLegendExtra={true} + allowBrushingLastHistogramBucket={true} legendPosition={legendPosition} onBrushEnd={onBrushEndListener} onElementClick={(args) => handleElementClick(args)} diff --git a/src/plugins/vis_types/pie/public/components/visualization_noresults.tsx b/src/plugins/vis_types/pie/public/components/visualization_noresults.tsx new file mode 100644 index 0000000000000..1ae5340c9791a --- /dev/null +++ b/src/plugins/vis_types/pie/public/components/visualization_noresults.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { EuiEmptyPrompt, EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +export const VisualizationNoResults = ({ hasNegativeValues = false }) => { + return ( + + {hasNegativeValues + ? i18n.translate('visTypePie.negativeValuesFound', { + defaultMessage: "Pie/donut charts can't render with negative values.", + }) + : i18n.translate('visTypePie.noResultsFoundTitle', { + defaultMessage: 'No results found', + })} + + } + /> + ); +}; diff --git a/src/plugins/vis_types/pie/public/pie_component.test.tsx b/src/plugins/vis_types/pie/public/pie_component.test.tsx index c70cad285f2ae..846daa1e45710 100644 --- a/src/plugins/vis_types/pie/public/pie_component.test.tsx +++ b/src/plugins/vis_types/pie/public/pie_component.test.tsx @@ -10,6 +10,7 @@ import React from 'react'; import { Settings, TooltipType, SeriesIdentifier } from '@elastic/charts'; import { chartPluginMock } from '../../../charts/public/mocks'; import { dataPluginMock } from '../../../data/public/mocks'; +import type { Datatable } from '../../../expressions/public'; import { shallow, mount } from 'enzyme'; import { findTestSubject } from '@elastic/eui/lib/test'; import { act } from 'react-dom/test-utils'; @@ -120,4 +121,64 @@ describe('PieComponent', function () { ]); expect(wrapperProps.fireEvent).toHaveBeenCalled(); }); + + it('renders the no results component if all the values are zero', () => { + const newVisData = ({ + type: 'datatable', + columns: [ + { + id: 'col-1-1', + name: 'Count', + }, + { + id: 'col-0-2', + name: 'filters', + }, + ], + rows: [ + { + 'col-0-2': 'Carrier : "JetBeats" ', + 'col-1-1': 0, + }, + { + 'col-0-2': 'Carrier : "ES-Air" ', + 'col-1-1': 0, + }, + ], + } as unknown) as Datatable; + const newProps = { ...wrapperProps, visData: newVisData }; + const component = mount(); + expect(findTestSubject(component, 'pieVisualizationError').text()).toEqual('No results found'); + }); + + it('renders the no results component if there are negative values', () => { + const newVisData = ({ + type: 'datatable', + columns: [ + { + id: 'col-1-1', + name: 'Count', + }, + { + id: 'col-0-2', + name: 'filters', + }, + ], + rows: [ + { + 'col-0-2': 'Carrier : "JetBeats" ', + 'col-1-1': -10, + }, + { + 'col-0-2': 'Carrier : "ES-Air" ', + 'col-1-1': -10, + }, + ], + } as unknown) as Datatable; + const newProps = { ...wrapperProps, visData: newVisData }; + const component = mount(); + expect(findTestSubject(component, 'pieVisualizationError').text()).toEqual( + "Pie/donut charts can't render with negative values." + ); + }); }); diff --git a/src/plugins/vis_types/pie/public/pie_component.tsx b/src/plugins/vis_types/pie/public/pie_component.tsx index a5475a76e27cd..c41b47f9aa683 100644 --- a/src/plugins/vis_types/pie/public/pie_component.tsx +++ b/src/plugins/vis_types/pie/public/pie_component.tsx @@ -48,6 +48,7 @@ import { getSplitDimensionAccessor, } from './utils'; import { ChartSplit, SMALL_MULTIPLES_ID } from './components/chart_split'; +import { VisualizationNoResults } from './components/visualization_noresults'; import './chart.scss'; @@ -186,10 +187,8 @@ const PieComponent = (props: PieComponentProps) => { const { visData, visParams, services, syncColors } = props; function getSliceValue(d: Datum, metricColumn: DatatableColumn) { - if (typeof d[metricColumn.id] === 'number' && d[metricColumn.id] !== 0) { - return d[metricColumn.id]; - } - return Number.EPSILON; + const value = d[metricColumn.id]; + return Number.isFinite(value) && value >= 0 ? value : 0; } // formatters @@ -285,82 +284,110 @@ const PieComponent = (props: PieComponentProps) => { ? visData.columns[visParams.dimensions.splitRow[0].accessor] : undefined; + /** + * Checks whether data have all zero values. + * If so, the no data container is loaded. + */ + const isAllZeros = useMemo(() => visData.rows.every((row) => row[metricColumn.id] === 0), [ + visData.rows, + metricColumn, + ]); + + /** + * Checks whether data have negative values. + * If so, the no data container is loaded. + */ + const hasNegative = useMemo( + () => + visData.rows.some((row) => { + const value = row[metricColumn.id]; + return typeof value === 'number' && value < 0; + }), + [visData.rows, metricColumn] + ); + + const canShowPieChart = !isAllZeros && !hasNegative; + return (
-
- - - - + ) : ( +
+ { - handleSliceClick( - args[0][0] as LayerValue[], - bucketColumns, - visData, - splitChartDimension, - splitChartFormatter - ); - }} - legendAction={getLegendActions( - canFilter, - getLegendActionEventData(visData), - handleLegendAction, - visParams, - services.actions, - services.fieldFormats - )} - theme={[ - chartTheme, - { - legend: { - labelOptions: { - maxLines: visParams.truncateLegend ? visParams.maxLegendLines ?? 1 : 0, + /> + + + { + handleSliceClick( + args[0][0] as LayerValue[], + bucketColumns, + visData, + splitChartDimension, + splitChartFormatter + ); + }} + legendAction={getLegendActions( + canFilter, + getLegendActionEventData(visData), + handleLegendAction, + visParams, + services.actions, + services.fieldFormats + )} + theme={[ + chartTheme, + { + legend: { + labelOptions: { + maxLines: visParams.truncateLegend ? visParams.maxLegendLines ?? 1 : 0, + }, }, }, - }, - ]} - baseTheme={chartBaseTheme} - onRenderChange={onRenderChange} - /> - getSliceValue(d, metricColumn)} - percentFormatter={(d: number) => percentFormatter.convert(d / 100)} - valueGetter={ - !visParams.labels.show || - visParams.labels.valuesFormat === ValueFormats.VALUE || - !visParams.labels.values - ? undefined - : 'percent' - } - valueFormatter={(d: number) => - !visParams.labels.show || !visParams.labels.values - ? '' - : metricFieldFormatter.convert(d) - } - layers={layers} - config={config} - topGroove={!visParams.labels.show ? 0 : undefined} - /> - -
+ ]} + baseTheme={chartBaseTheme} + onRenderChange={onRenderChange} + /> + getSliceValue(d, metricColumn)} + percentFormatter={(d: number) => percentFormatter.convert(d / 100)} + valueGetter={ + !visParams.labels.show || + visParams.labels.valuesFormat === ValueFormats.VALUE || + !visParams.labels.values + ? undefined + : 'percent' + } + valueFormatter={(d: number) => + !visParams.labels.show || !visParams.labels.values + ? '' + : metricFieldFormatter.convert(d) + } + layers={layers} + config={config} + topGroove={!visParams.labels.show ? 0 : undefined} + /> +
+
+ )}
); }; diff --git a/src/plugins/vis_type_table/README.md b/src/plugins/vis_types/table/README.md similarity index 100% rename from src/plugins/vis_type_table/README.md rename to src/plugins/vis_types/table/README.md diff --git a/src/plugins/vis_type_table/common/index.ts b/src/plugins/vis_types/table/common/index.ts similarity index 100% rename from src/plugins/vis_type_table/common/index.ts rename to src/plugins/vis_types/table/common/index.ts diff --git a/src/plugins/vis_type_table/common/types.ts b/src/plugins/vis_types/table/common/types.ts similarity index 100% rename from src/plugins/vis_type_table/common/types.ts rename to src/plugins/vis_types/table/common/types.ts diff --git a/src/plugins/vis_type_table/config.ts b/src/plugins/vis_types/table/config.ts similarity index 100% rename from src/plugins/vis_type_table/config.ts rename to src/plugins/vis_types/table/config.ts diff --git a/src/plugins/vis_type_table/jest.config.js b/src/plugins/vis_types/table/jest.config.js similarity index 74% rename from src/plugins/vis_type_table/jest.config.js rename to src/plugins/vis_types/table/jest.config.js index a5a925eada3f1..cc6c194aa7cb4 100644 --- a/src/plugins/vis_type_table/jest.config.js +++ b/src/plugins/vis_types/table/jest.config.js @@ -8,12 +8,12 @@ module.exports = { preset: '@kbn/test', - rootDir: '../../..', - roots: ['/src/plugins/vis_type_table'], + rootDir: '../../../..', + roots: ['/src/plugins/vis_types/table'], testRunner: 'jasmine2', - coverageDirectory: '/target/kibana-coverage/jest/src/plugins/vis_type_table', + coverageDirectory: '/target/kibana-coverage/jest/src/plugins/vis_types/table', coverageReporters: ['text', 'html'], collectCoverageFrom: [ - '/src/plugins/vis_type_table/{common,public,server}/**/*.{js,ts,tsx}', + '/src/plugins/vis_types/table/{common,public,server}/**/*.{js,ts,tsx}', ], }; diff --git a/src/plugins/vis_type_table/kibana.json b/src/plugins/vis_types/table/kibana.json similarity index 100% rename from src/plugins/vis_type_table/kibana.json rename to src/plugins/vis_types/table/kibana.json diff --git a/src/plugins/vis_type_table/public/__snapshots__/table_vis_fn.test.ts.snap b/src/plugins/vis_types/table/public/__snapshots__/table_vis_fn.test.ts.snap similarity index 100% rename from src/plugins/vis_type_table/public/__snapshots__/table_vis_fn.test.ts.snap rename to src/plugins/vis_types/table/public/__snapshots__/table_vis_fn.test.ts.snap diff --git a/src/plugins/vis_type_table/public/components/__snapshots__/table_vis_basic.test.tsx.snap b/src/plugins/vis_types/table/public/components/__snapshots__/table_vis_basic.test.tsx.snap similarity index 100% rename from src/plugins/vis_type_table/public/components/__snapshots__/table_vis_basic.test.tsx.snap rename to src/plugins/vis_types/table/public/components/__snapshots__/table_vis_basic.test.tsx.snap diff --git a/src/plugins/vis_type_table/public/components/__snapshots__/table_vis_cell.test.tsx.snap b/src/plugins/vis_types/table/public/components/__snapshots__/table_vis_cell.test.tsx.snap similarity index 100% rename from src/plugins/vis_type_table/public/components/__snapshots__/table_vis_cell.test.tsx.snap rename to src/plugins/vis_types/table/public/components/__snapshots__/table_vis_cell.test.tsx.snap diff --git a/src/plugins/vis_type_table/public/components/index.ts b/src/plugins/vis_types/table/public/components/index.ts similarity index 100% rename from src/plugins/vis_type_table/public/components/index.ts rename to src/plugins/vis_types/table/public/components/index.ts diff --git a/src/plugins/vis_type_table/public/components/table_vis_basic.test.tsx b/src/plugins/vis_types/table/public/components/table_vis_basic.test.tsx similarity index 100% rename from src/plugins/vis_type_table/public/components/table_vis_basic.test.tsx rename to src/plugins/vis_types/table/public/components/table_vis_basic.test.tsx diff --git a/src/plugins/vis_type_table/public/components/table_vis_basic.tsx b/src/plugins/vis_types/table/public/components/table_vis_basic.tsx similarity index 100% rename from src/plugins/vis_type_table/public/components/table_vis_basic.tsx rename to src/plugins/vis_types/table/public/components/table_vis_basic.tsx diff --git a/src/plugins/vis_type_table/public/components/table_vis_cell.test.tsx b/src/plugins/vis_types/table/public/components/table_vis_cell.test.tsx similarity index 100% rename from src/plugins/vis_type_table/public/components/table_vis_cell.test.tsx rename to src/plugins/vis_types/table/public/components/table_vis_cell.test.tsx diff --git a/src/plugins/vis_type_table/public/components/table_vis_cell.tsx b/src/plugins/vis_types/table/public/components/table_vis_cell.tsx similarity index 100% rename from src/plugins/vis_type_table/public/components/table_vis_cell.tsx rename to src/plugins/vis_types/table/public/components/table_vis_cell.tsx diff --git a/src/plugins/vis_type_table/public/components/table_vis_columns.tsx b/src/plugins/vis_types/table/public/components/table_vis_columns.tsx similarity index 100% rename from src/plugins/vis_type_table/public/components/table_vis_columns.tsx rename to src/plugins/vis_types/table/public/components/table_vis_columns.tsx diff --git a/src/plugins/vis_type_table/public/components/table_vis_controls.tsx b/src/plugins/vis_types/table/public/components/table_vis_controls.tsx similarity index 96% rename from src/plugins/vis_type_table/public/components/table_vis_controls.tsx rename to src/plugins/vis_types/table/public/components/table_vis_controls.tsx index 01dd693a31ff8..28e4b84796d98 100644 --- a/src/plugins/vis_type_table/public/components/table_vis_controls.tsx +++ b/src/plugins/vis_types/table/public/components/table_vis_controls.tsx @@ -19,13 +19,13 @@ import { i18n } from '@kbn/i18n'; import { DatatableColumn, DatatableRow } from 'src/plugins/expressions'; import { CoreStart } from 'kibana/public'; -import { useKibana } from '../../../kibana_react/public'; -import { exporters } from '../../../data/public'; +import { useKibana } from '../../../../kibana_react/public'; +import { exporters } from '../../../../data/public'; import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING, downloadFileAs, -} from '../../../share/public'; +} from '../../../../share/public'; import { getFormatService } from '../services'; interface TableVisControlsProps { diff --git a/src/plugins/vis_type_table/public/components/table_vis_options.tsx b/src/plugins/vis_types/table/public/components/table_vis_options.tsx similarity index 96% rename from src/plugins/vis_type_table/public/components/table_vis_options.tsx rename to src/plugins/vis_types/table/public/components/table_vis_options.tsx index 2906a51e5d05f..8a6b8586fce7d 100644 --- a/src/plugins/vis_type_table/public/components/table_vis_options.tsx +++ b/src/plugins/vis_types/table/public/components/table_vis_options.tsx @@ -13,8 +13,12 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { VisEditorOptionsProps } from 'src/plugins/visualizations/public'; -import { search } from '../../../data/public'; -import { SwitchOption, SelectOption, NumberInputOption } from '../../../vis_default_editor/public'; +import { search } from '../../../../data/public'; +import { + SwitchOption, + SelectOption, + NumberInputOption, +} from '../../../../vis_default_editor/public'; import { TableVisParams } from '../../common'; import { totalAggregations } from './utils'; diff --git a/src/plugins/vis_type_table/public/components/table_vis_options_lazy.tsx b/src/plugins/vis_types/table/public/components/table_vis_options_lazy.tsx similarity index 100% rename from src/plugins/vis_type_table/public/components/table_vis_options_lazy.tsx rename to src/plugins/vis_types/table/public/components/table_vis_options_lazy.tsx diff --git a/src/plugins/vis_type_table/public/components/table_vis_split.tsx b/src/plugins/vis_types/table/public/components/table_vis_split.tsx similarity index 100% rename from src/plugins/vis_type_table/public/components/table_vis_split.tsx rename to src/plugins/vis_types/table/public/components/table_vis_split.tsx diff --git a/src/plugins/vis_type_table/public/components/table_visualization.scss b/src/plugins/vis_types/table/public/components/table_visualization.scss similarity index 100% rename from src/plugins/vis_type_table/public/components/table_visualization.scss rename to src/plugins/vis_types/table/public/components/table_visualization.scss diff --git a/src/plugins/vis_type_table/public/components/table_visualization.test.tsx b/src/plugins/vis_types/table/public/components/table_visualization.test.tsx similarity index 97% rename from src/plugins/vis_type_table/public/components/table_visualization.test.tsx rename to src/plugins/vis_types/table/public/components/table_visualization.test.tsx index 44c315cdbd9e4..0de7e8c15105a 100644 --- a/src/plugins/vis_type_table/public/components/table_visualization.test.tsx +++ b/src/plugins/vis_types/table/public/components/table_visualization.test.tsx @@ -13,7 +13,7 @@ jest.mock('../utils', () => ({ import React from 'react'; import { shallow } from 'enzyme'; import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; -import { coreMock } from '../../../../core/public/mocks'; +import { coreMock } from '../../../../../core/public/mocks'; import { TableVisConfig, TableVisData } from '../types'; import TableVisualizationComponent from './table_visualization'; import { useUiState } from '../utils'; diff --git a/src/plugins/vis_type_table/public/components/table_visualization.tsx b/src/plugins/vis_types/table/public/components/table_visualization.tsx similarity index 96% rename from src/plugins/vis_type_table/public/components/table_visualization.tsx rename to src/plugins/vis_types/table/public/components/table_visualization.tsx index c5a4f42cbb65e..356913146890b 100644 --- a/src/plugins/vis_type_table/public/components/table_visualization.tsx +++ b/src/plugins/vis_types/table/public/components/table_visualization.tsx @@ -13,7 +13,7 @@ import classNames from 'classnames'; import { CoreStart } from 'kibana/public'; import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; import type { PersistedState } from 'src/plugins/visualizations/public'; -import { KibanaContextProvider } from '../../../kibana_react/public'; +import { KibanaContextProvider } from '../../../../kibana_react/public'; import { TableVisConfig, TableVisData } from '../types'; import { TableVisBasic } from './table_vis_basic'; import { TableVisSplit } from './table_vis_split'; diff --git a/src/plugins/vis_type_table/public/components/utils.ts b/src/plugins/vis_types/table/public/components/utils.ts similarity index 100% rename from src/plugins/vis_type_table/public/components/utils.ts rename to src/plugins/vis_types/table/public/components/utils.ts diff --git a/src/plugins/vis_type_table/public/index.ts b/src/plugins/vis_types/table/public/index.ts similarity index 100% rename from src/plugins/vis_type_table/public/index.ts rename to src/plugins/vis_types/table/public/index.ts diff --git a/src/plugins/vis_type_table/public/plugin.ts b/src/plugins/vis_types/table/public/plugin.ts similarity index 81% rename from src/plugins/vis_type_table/public/plugin.ts rename to src/plugins/vis_types/table/public/plugin.ts index 2ae8b68bba701..fa02550f5048d 100644 --- a/src/plugins/vis_type_table/public/plugin.ts +++ b/src/plugins/vis_types/table/public/plugin.ts @@ -7,11 +7,11 @@ */ import { CoreSetup, CoreStart, Plugin } from 'kibana/public'; -import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; -import { VisualizationsSetup } from '../../visualizations/public'; -import { UsageCollectionSetup } from '../../usage_collection/public'; +import { Plugin as ExpressionsPublicPlugin } from '../../../expressions/public'; +import { VisualizationsSetup } from '../../../visualizations/public'; +import { UsageCollectionSetup } from '../../../usage_collection/public'; -import { DataPublicPluginStart } from '../../data/public'; +import { DataPublicPluginStart } from '../../../data/public'; import { setFormatService } from './services'; import { registerTableVis } from './register_vis'; diff --git a/src/plugins/vis_type_table/public/register_vis.ts b/src/plugins/vis_types/table/public/register_vis.ts similarity index 100% rename from src/plugins/vis_type_table/public/register_vis.ts rename to src/plugins/vis_types/table/public/register_vis.ts diff --git a/src/plugins/vis_type_table/public/services.ts b/src/plugins/vis_types/table/public/services.ts similarity index 79% rename from src/plugins/vis_type_table/public/services.ts rename to src/plugins/vis_types/table/public/services.ts index 3122e65714ac8..d4d83c9e92c67 100644 --- a/src/plugins/vis_type_table/public/services.ts +++ b/src/plugins/vis_types/table/public/services.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { createGetterSetter } from '../../kibana_utils/public'; -import { DataPublicPluginStart } from '../../data/public'; +import { createGetterSetter } from '../../../kibana_utils/public'; +import { DataPublicPluginStart } from '../../../data/public'; export const [getFormatService, setFormatService] = createGetterSetter< DataPublicPluginStart['fieldFormats'] diff --git a/src/plugins/vis_type_table/public/table_vis_fn.test.ts b/src/plugins/vis_types/table/public/table_vis_fn.test.ts similarity index 92% rename from src/plugins/vis_type_table/public/table_vis_fn.test.ts rename to src/plugins/vis_types/table/public/table_vis_fn.test.ts index c6eb8601824ec..8b08bca160478 100644 --- a/src/plugins/vis_type_table/public/table_vis_fn.test.ts +++ b/src/plugins/vis_types/table/public/table_vis_fn.test.ts @@ -9,8 +9,8 @@ import { createTableVisFn } from './table_vis_fn'; import { tableVisResponseHandler } from './utils'; -import { functionWrapper } from '../../expressions/common/expression_functions/specs/tests/utils'; -import { Datatable } from '../../expressions/common/expression_types/specs'; +import { functionWrapper } from '../../../expressions/common/expression_functions/specs/tests/utils'; +import { Datatable } from '../../../expressions/common/expression_types/specs'; jest.mock('./utils', () => ({ tableVisResponseHandler: jest.fn().mockReturnValue({ diff --git a/src/plugins/vis_type_table/public/table_vis_fn.ts b/src/plugins/vis_types/table/public/table_vis_fn.ts similarity index 97% rename from src/plugins/vis_type_table/public/table_vis_fn.ts rename to src/plugins/vis_types/table/public/table_vis_fn.ts index 9473a9a2663ab..ebddb0b4b7fef 100644 --- a/src/plugins/vis_type_table/public/table_vis_fn.ts +++ b/src/plugins/vis_types/table/public/table_vis_fn.ts @@ -7,8 +7,8 @@ */ import { i18n } from '@kbn/i18n'; -import { ExpressionFunctionDefinition, Datatable, Render } from '../../expressions/public'; -import { prepareLogTable, Dimension } from '../../visualizations/public'; +import { ExpressionFunctionDefinition, Datatable, Render } from '../../../expressions/public'; +import { prepareLogTable, Dimension } from '../../../visualizations/public'; import { TableVisData, TableVisConfig } from './types'; import { VIS_TYPE_TABLE } from '../common'; import { tableVisResponseHandler } from './utils'; diff --git a/src/plugins/vis_type_table/public/table_vis_renderer.tsx b/src/plugins/vis_types/table/public/table_vis_renderer.tsx similarity index 89% rename from src/plugins/vis_type_table/public/table_vis_renderer.tsx rename to src/plugins/vis_types/table/public/table_vis_renderer.tsx index 257755de62d0d..e9f2002b71062 100644 --- a/src/plugins/vis_type_table/public/table_vis_renderer.tsx +++ b/src/plugins/vis_types/table/public/table_vis_renderer.tsx @@ -10,8 +10,8 @@ import React, { lazy } from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { CoreStart } from 'kibana/public'; -import { VisualizationContainer } from '../../visualizations/public'; -import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers'; +import { VisualizationContainer } from '../../../visualizations/public'; +import { ExpressionRenderDefinition } from '../../../expressions/common/expression_renderers'; import { TableVisRenderValue } from './table_vis_fn'; const TableVisualizationComponent = lazy(() => import('./components/table_visualization')); diff --git a/src/plugins/vis_type_table/public/table_vis_type.ts b/src/plugins/vis_types/table/public/table_vis_type.ts similarity index 94% rename from src/plugins/vis_type_table/public/table_vis_type.ts rename to src/plugins/vis_types/table/public/table_vis_type.ts index a49748fe86c96..4664e87cea79b 100644 --- a/src/plugins/vis_type_table/public/table_vis_type.ts +++ b/src/plugins/vis_types/table/public/table_vis_type.ts @@ -8,8 +8,8 @@ import { i18n } from '@kbn/i18n'; -import { AggGroupNames } from '../../data/public'; -import { VIS_EVENT_TO_TRIGGER, VisTypeDefinition } from '../../visualizations/public'; +import { AggGroupNames } from '../../../data/public'; +import { VIS_EVENT_TO_TRIGGER, VisTypeDefinition } from '../../../visualizations/public'; import { TableVisParams, VIS_TYPE_TABLE } from '../common'; import { TableOptions } from './components/table_vis_options_lazy'; import { toExpressionAst } from './to_ast'; diff --git a/src/plugins/vis_type_table/public/to_ast.test.ts b/src/plugins/vis_types/table/public/to_ast.test.ts similarity index 95% rename from src/plugins/vis_type_table/public/to_ast.test.ts rename to src/plugins/vis_types/table/public/to_ast.test.ts index 32b2b5939ed89..e8f987909a534 100644 --- a/src/plugins/vis_type_table/public/to_ast.test.ts +++ b/src/plugins/vis_types/table/public/to_ast.test.ts @@ -9,7 +9,7 @@ import { Vis } from 'src/plugins/visualizations/public'; import { toExpressionAst } from './to_ast'; import { AggTypes, TableVisParams } from '../common'; -import { buildExpressionFunction } from '../../expressions/public'; +import { buildExpressionFunction } from '../../../expressions/public'; const mockSchemas = { metric: [{ accessor: 1, format: { id: 'number' }, params: {}, label: 'Count', aggType: 'count' }], @@ -32,11 +32,11 @@ const mockTableExpression = { toAst: jest.fn(), }; -jest.mock('../../visualizations/public', () => ({ +jest.mock('../../../visualizations/public', () => ({ getVisSchemas: () => mockSchemas, })); -jest.mock('../../expressions/public', () => ({ +jest.mock('../../../expressions/public', () => ({ buildExpression: jest.fn(() => mockTableExpression), buildExpressionFunction: jest.fn(() => mockTableExpressionFunction), })); diff --git a/src/plugins/vis_type_table/public/to_ast.ts b/src/plugins/vis_types/table/public/to_ast.ts similarity index 97% rename from src/plugins/vis_type_table/public/to_ast.ts rename to src/plugins/vis_types/table/public/to_ast.ts index f7fb620db1ca6..8e1c92c8dde4f 100644 --- a/src/plugins/vis_type_table/public/to_ast.ts +++ b/src/plugins/vis_types/table/public/to_ast.ts @@ -9,9 +9,9 @@ import { EsaggsExpressionFunctionDefinition, IndexPatternLoadExpressionFunctionDefinition, -} from '../../data/public'; -import { buildExpression, buildExpressionFunction } from '../../expressions/public'; -import { getVisSchemas, SchemaConfig, VisToExpressionAst } from '../../visualizations/public'; +} from '../../../data/public'; +import { buildExpression, buildExpressionFunction } from '../../../expressions/public'; +import { getVisSchemas, SchemaConfig, VisToExpressionAst } from '../../../visualizations/public'; import { TableVisParams } from '../common'; import { TableExpressionFunctionDefinition } from './table_vis_fn'; diff --git a/src/plugins/vis_type_table/public/types.ts b/src/plugins/vis_types/table/public/types.ts similarity index 100% rename from src/plugins/vis_type_table/public/types.ts rename to src/plugins/vis_types/table/public/types.ts diff --git a/src/plugins/vis_type_table/public/utils/add_percentage_column.test.ts b/src/plugins/vis_types/table/public/utils/add_percentage_column.test.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/add_percentage_column.test.ts rename to src/plugins/vis_types/table/public/utils/add_percentage_column.test.ts diff --git a/src/plugins/vis_type_table/public/utils/add_percentage_column.ts b/src/plugins/vis_types/table/public/utils/add_percentage_column.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/add_percentage_column.ts rename to src/plugins/vis_types/table/public/utils/add_percentage_column.ts diff --git a/src/plugins/vis_type_table/public/utils/create_formatted_table.test.ts b/src/plugins/vis_types/table/public/utils/create_formatted_table.test.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/create_formatted_table.test.ts rename to src/plugins/vis_types/table/public/utils/create_formatted_table.test.ts diff --git a/src/plugins/vis_type_table/public/utils/create_formatted_table.ts b/src/plugins/vis_types/table/public/utils/create_formatted_table.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/create_formatted_table.ts rename to src/plugins/vis_types/table/public/utils/create_formatted_table.ts diff --git a/src/plugins/vis_type_table/public/utils/index.ts b/src/plugins/vis_types/table/public/utils/index.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/index.ts rename to src/plugins/vis_types/table/public/utils/index.ts diff --git a/src/plugins/vis_type_table/public/utils/table_vis_response_handler.test.ts b/src/plugins/vis_types/table/public/utils/table_vis_response_handler.test.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/table_vis_response_handler.test.ts rename to src/plugins/vis_types/table/public/utils/table_vis_response_handler.test.ts diff --git a/src/plugins/vis_type_table/public/utils/table_vis_response_handler.ts b/src/plugins/vis_types/table/public/utils/table_vis_response_handler.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/table_vis_response_handler.ts rename to src/plugins/vis_types/table/public/utils/table_vis_response_handler.ts diff --git a/src/plugins/vis_type_table/public/utils/use/index.ts b/src/plugins/vis_types/table/public/utils/use/index.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/use/index.ts rename to src/plugins/vis_types/table/public/utils/use/index.ts diff --git a/src/plugins/vis_type_table/public/utils/use/use_pagination.test.ts b/src/plugins/vis_types/table/public/utils/use/use_pagination.test.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/use/use_pagination.test.ts rename to src/plugins/vis_types/table/public/utils/use/use_pagination.test.ts diff --git a/src/plugins/vis_type_table/public/utils/use/use_pagination.ts b/src/plugins/vis_types/table/public/utils/use/use_pagination.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/use/use_pagination.ts rename to src/plugins/vis_types/table/public/utils/use/use_pagination.ts diff --git a/src/plugins/vis_type_table/public/utils/use/use_ui_state.test.ts b/src/plugins/vis_types/table/public/utils/use/use_ui_state.test.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/use/use_ui_state.test.ts rename to src/plugins/vis_types/table/public/utils/use/use_ui_state.test.ts diff --git a/src/plugins/vis_type_table/public/utils/use/use_ui_state.ts b/src/plugins/vis_types/table/public/utils/use/use_ui_state.ts similarity index 100% rename from src/plugins/vis_type_table/public/utils/use/use_ui_state.ts rename to src/plugins/vis_types/table/public/utils/use/use_ui_state.ts diff --git a/src/plugins/vis_type_table/server/index.ts b/src/plugins/vis_types/table/server/index.ts similarity index 100% rename from src/plugins/vis_type_table/server/index.ts rename to src/plugins/vis_types/table/server/index.ts diff --git a/src/plugins/vis_type_table/server/usage_collector/get_stats.test.ts b/src/plugins/vis_types/table/server/usage_collector/get_stats.test.ts similarity index 96% rename from src/plugins/vis_type_table/server/usage_collector/get_stats.test.ts rename to src/plugins/vis_types/table/server/usage_collector/get_stats.test.ts index 76f067e3a23d7..4c91def40300e 100644 --- a/src/plugins/vis_type_table/server/usage_collector/get_stats.test.ts +++ b/src/plugins/vis_types/table/server/usage_collector/get_stats.test.ts @@ -7,7 +7,7 @@ */ import { getStats } from './get_stats'; -import type { SavedObjectsClientContract } from '../../../../core/server'; +import type { SavedObjectsClientContract } from '../../../../../core/server'; const mockVisualizations = { saved_objects: [ diff --git a/src/plugins/vis_type_table/server/usage_collector/get_stats.ts b/src/plugins/vis_types/table/server/usage_collector/get_stats.ts similarity index 95% rename from src/plugins/vis_type_table/server/usage_collector/get_stats.ts rename to src/plugins/vis_types/table/server/usage_collector/get_stats.ts index ef948c2d7b70b..ac8d759c94c76 100644 --- a/src/plugins/vis_type_table/server/usage_collector/get_stats.ts +++ b/src/plugins/vis_types/table/server/usage_collector/get_stats.ts @@ -12,8 +12,8 @@ import type { ISavedObjectsRepository, SavedObjectsClientContract, SavedObjectsFindResult, -} from '../../../../core/server'; -import type { SavedVisState } from '../../../visualizations/common'; +} from '../../../../../core/server'; +import type { SavedVisState } from '../../../../visualizations/common'; export interface VisTypeTableUsage { /** diff --git a/src/plugins/vis_type_table/server/usage_collector/index.ts b/src/plugins/vis_types/table/server/usage_collector/index.ts similarity index 100% rename from src/plugins/vis_type_table/server/usage_collector/index.ts rename to src/plugins/vis_types/table/server/usage_collector/index.ts diff --git a/src/plugins/vis_type_table/server/usage_collector/register_usage_collector.test.ts b/src/plugins/vis_types/table/server/usage_collector/register_usage_collector.test.ts similarity index 97% rename from src/plugins/vis_type_table/server/usage_collector/register_usage_collector.test.ts rename to src/plugins/vis_types/table/server/usage_collector/register_usage_collector.test.ts index d32435ac45406..b65c698f219a6 100644 --- a/src/plugins/vis_type_table/server/usage_collector/register_usage_collector.test.ts +++ b/src/plugins/vis_types/table/server/usage_collector/register_usage_collector.test.ts @@ -9,7 +9,7 @@ import { createUsageCollectionSetupMock, createCollectorFetchContextMock, -} from '../../../usage_collection/server/mocks'; +} from '../../../../usage_collection/server/mocks'; import { registerVisTypeTableUsageCollector } from './register_usage_collector'; import { getStats } from './get_stats'; diff --git a/src/plugins/vis_type_table/server/usage_collector/register_usage_collector.ts b/src/plugins/vis_types/table/server/usage_collector/register_usage_collector.ts similarity index 92% rename from src/plugins/vis_type_table/server/usage_collector/register_usage_collector.ts rename to src/plugins/vis_types/table/server/usage_collector/register_usage_collector.ts index 74044c9ae70c0..ed176fc9222bc 100644 --- a/src/plugins/vis_type_table/server/usage_collector/register_usage_collector.ts +++ b/src/plugins/vis_types/table/server/usage_collector/register_usage_collector.ts @@ -7,7 +7,7 @@ */ import { getStats, VisTypeTableUsage } from './get_stats'; -import type { UsageCollectionSetup } from '../../../usage_collection/server'; +import type { UsageCollectionSetup } from '../../../../usage_collection/server'; export function registerVisTypeTableUsageCollector(collectorSet: UsageCollectionSetup) { const collector = collectorSet.makeUsageCollector({ diff --git a/src/plugins/vis_types/table/tsconfig.json b/src/plugins/vis_types/table/tsconfig.json new file mode 100644 index 0000000000000..9325064d571d0 --- /dev/null +++ b/src/plugins/vis_types/table/tsconfig.json @@ -0,0 +1,28 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "common/**/*", + "public/**/*", + "server/**/*", + "*.ts" + ], + "references": [ + { "path": "../../../core/tsconfig.json" }, + { "path": "../../data/tsconfig.json" }, + { "path": "../../visualizations/tsconfig.json" }, + { "path": "../../share/tsconfig.json" }, + { "path": "../../usage_collection/tsconfig.json" }, + { "path": "../../expressions/tsconfig.json" }, + { "path": "../../kibana_utils/tsconfig.json" }, + { "path": "../../kibana_legacy/tsconfig.json" }, + { "path": "../../kibana_react/tsconfig.json" }, + { "path": "../../vis_default_editor/tsconfig.json" }, + { "path": "../../field_formats/tsconfig.json" } + ] +} diff --git a/src/plugins/vis_types/timelion/README.md b/src/plugins/vis_types/timelion/README.md new file mode 100644 index 0000000000000..145774e768e9e --- /dev/null +++ b/src/plugins/vis_types/timelion/README.md @@ -0,0 +1,6 @@ +# Vis type Timelion + +Contains the timelion visualization and the timelion backend. + +# Generate a parser +If your grammar was changed in `packages/@kbn-timelion-grammar` you need to re-generate the static parser. You can do this with `yarn kbn build`. \ No newline at end of file diff --git a/src/plugins/vis_type_timelion/common/constants.ts b/src/plugins/vis_types/timelion/common/constants.ts similarity index 100% rename from src/plugins/vis_type_timelion/common/constants.ts rename to src/plugins/vis_types/timelion/common/constants.ts diff --git a/src/plugins/vis_type_timelion/common/lib/calculate_interval.test.ts b/src/plugins/vis_types/timelion/common/lib/calculate_interval.test.ts similarity index 100% rename from src/plugins/vis_type_timelion/common/lib/calculate_interval.test.ts rename to src/plugins/vis_types/timelion/common/lib/calculate_interval.test.ts diff --git a/src/plugins/vis_type_timelion/common/lib/calculate_interval.ts b/src/plugins/vis_types/timelion/common/lib/calculate_interval.ts similarity index 100% rename from src/plugins/vis_type_timelion/common/lib/calculate_interval.ts rename to src/plugins/vis_types/timelion/common/lib/calculate_interval.ts diff --git a/src/plugins/vis_type_timelion/common/lib/index.ts b/src/plugins/vis_types/timelion/common/lib/index.ts similarity index 100% rename from src/plugins/vis_type_timelion/common/lib/index.ts rename to src/plugins/vis_types/timelion/common/lib/index.ts diff --git a/src/plugins/vis_type_timelion/common/lib/to_milliseconds.ts b/src/plugins/vis_types/timelion/common/lib/to_milliseconds.ts similarity index 100% rename from src/plugins/vis_type_timelion/common/lib/to_milliseconds.ts rename to src/plugins/vis_types/timelion/common/lib/to_milliseconds.ts diff --git a/src/plugins/vis_type_timelion/common/parser.ts b/src/plugins/vis_types/timelion/common/parser.ts similarity index 96% rename from src/plugins/vis_type_timelion/common/parser.ts rename to src/plugins/vis_types/timelion/common/parser.ts index b6c16a6f7b4ed..dc1bbf1e42440 100644 --- a/src/plugins/vis_type_timelion/common/parser.ts +++ b/src/plugins/vis_types/timelion/common/parser.ts @@ -7,7 +7,7 @@ */ // @ts-ignore -import { parse } from './_generated_/chain'; +import { parse } from '@kbn/timelion-grammar'; export interface ExpressionLocation { min: number; diff --git a/src/plugins/vis_type_timelion/common/parser_async.ts b/src/plugins/vis_types/timelion/common/parser_async.ts similarity index 100% rename from src/plugins/vis_type_timelion/common/parser_async.ts rename to src/plugins/vis_types/timelion/common/parser_async.ts diff --git a/src/plugins/vis_type_timelion/common/types.ts b/src/plugins/vis_types/timelion/common/types.ts similarity index 100% rename from src/plugins/vis_type_timelion/common/types.ts rename to src/plugins/vis_types/timelion/common/types.ts diff --git a/src/plugins/vis_type_timelion/common/vis_data.ts b/src/plugins/vis_types/timelion/common/vis_data.ts similarity index 100% rename from src/plugins/vis_type_timelion/common/vis_data.ts rename to src/plugins/vis_types/timelion/common/vis_data.ts diff --git a/src/plugins/vis_type_timelion/config.ts b/src/plugins/vis_types/timelion/config.ts similarity index 100% rename from src/plugins/vis_type_timelion/config.ts rename to src/plugins/vis_types/timelion/config.ts diff --git a/src/plugins/vis_type_timelion/jest.config.js b/src/plugins/vis_types/timelion/jest.config.js similarity index 72% rename from src/plugins/vis_type_timelion/jest.config.js rename to src/plugins/vis_types/timelion/jest.config.js index 5da416935adb9..a6c7d7b3f230f 100644 --- a/src/plugins/vis_type_timelion/jest.config.js +++ b/src/plugins/vis_types/timelion/jest.config.js @@ -8,11 +8,11 @@ module.exports = { preset: '@kbn/test', - rootDir: '../../..', - roots: ['/src/plugins/vis_type_timelion'], - coverageDirectory: '/target/kibana-coverage/jest/src/plugins/vis_type_timelion', + rootDir: '../../../..', + roots: ['/src/plugins/vis_types/timelion'], + coverageDirectory: '/target/kibana-coverage/jest/src/plugins/vis_types/timelion', coverageReporters: ['text', 'html'], collectCoverageFrom: [ - '/src/plugins/vis_type_timelion/{common,public,server}/**/*.{js,ts,tsx}', + '/src/plugins/vis_types/timelion/{common,public,server}/**/*.{js,ts,tsx}', ], }; diff --git a/src/plugins/vis_type_timelion/kibana.json b/src/plugins/vis_types/timelion/kibana.json similarity index 100% rename from src/plugins/vis_type_timelion/kibana.json rename to src/plugins/vis_types/timelion/kibana.json diff --git a/src/plugins/vis_type_timelion/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_types/timelion/public/__snapshots__/to_ast.test.ts.snap similarity index 100% rename from src/plugins/vis_type_timelion/public/__snapshots__/to_ast.test.ts.snap rename to src/plugins/vis_types/timelion/public/__snapshots__/to_ast.test.ts.snap diff --git a/src/plugins/vis_type_timelion/public/components/index.ts b/src/plugins/vis_types/timelion/public/components/index.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/components/index.ts rename to src/plugins/vis_types/timelion/public/components/index.ts diff --git a/src/plugins/vis_type_timelion/public/components/series/area.tsx b/src/plugins/vis_types/timelion/public/components/series/area.tsx similarity index 100% rename from src/plugins/vis_type_timelion/public/components/series/area.tsx rename to src/plugins/vis_types/timelion/public/components/series/area.tsx diff --git a/src/plugins/vis_type_timelion/public/components/series/bar.tsx b/src/plugins/vis_types/timelion/public/components/series/bar.tsx similarity index 100% rename from src/plugins/vis_type_timelion/public/components/series/bar.tsx rename to src/plugins/vis_types/timelion/public/components/series/bar.tsx diff --git a/src/plugins/vis_type_timelion/public/components/series/index.ts b/src/plugins/vis_types/timelion/public/components/series/index.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/components/series/index.ts rename to src/plugins/vis_types/timelion/public/components/series/index.ts diff --git a/src/plugins/vis_type_timelion/public/components/timelion_expression_input.tsx b/src/plugins/vis_types/timelion/public/components/timelion_expression_input.tsx similarity index 98% rename from src/plugins/vis_type_timelion/public/components/timelion_expression_input.tsx rename to src/plugins/vis_types/timelion/public/components/timelion_expression_input.tsx index 569ddf03c941b..dd949f57bce28 100644 --- a/src/plugins/vis_type_timelion/public/components/timelion_expression_input.tsx +++ b/src/plugins/vis_types/timelion/public/components/timelion_expression_input.tsx @@ -11,7 +11,7 @@ import { EuiFormLabel } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { monaco } from '@kbn/monaco'; -import { CodeEditor, useKibana } from '../../../kibana_react/public'; +import { CodeEditor, useKibana } from '../../../../kibana_react/public'; import { suggest, getSuggestion } from './timelion_expression_input_helpers'; import { getArgValueSuggestions } from '../helpers/arg_value_suggestions'; import { ITimelionFunction, TimelionFunctionArgs } from '../../common/types'; diff --git a/src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.test.ts b/src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.test.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.test.ts rename to src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.test.ts diff --git a/src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.ts b/src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/components/timelion_expression_input_helpers.ts rename to src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.ts diff --git a/src/plugins/vis_type_timelion/public/components/timelion_interval.tsx b/src/plugins/vis_types/timelion/public/components/timelion_interval.tsx similarity index 96% rename from src/plugins/vis_type_timelion/public/components/timelion_interval.tsx rename to src/plugins/vis_types/timelion/public/components/timelion_interval.tsx index 047de1bdb0708..fc080ff578bee 100644 --- a/src/plugins/vis_type_timelion/public/components/timelion_interval.tsx +++ b/src/plugins/vis_types/timelion/public/components/timelion_interval.tsx @@ -10,9 +10,9 @@ import React, { useMemo, useCallback } from 'react'; import { EuiFormRow, EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { search } from '../../../data/public'; +import { search } from '../../../../data/public'; const { isValidEsInterval } = search.aggs; -import { useValidation } from '../../../vis_default_editor/public'; +import { useValidation } from '../../../../vis_default_editor/public'; const intervalOptions = [ { diff --git a/src/plugins/vis_type_timelion/public/components/timelion_vis.scss b/src/plugins/vis_types/timelion/public/components/timelion_vis.scss similarity index 100% rename from src/plugins/vis_type_timelion/public/components/timelion_vis.scss rename to src/plugins/vis_types/timelion/public/components/timelion_vis.scss diff --git a/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx b/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx similarity index 95% rename from src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx rename to src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx index 3cc335392b7c4..9a15159b33a1d 100644 --- a/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx +++ b/src/plugins/vis_types/timelion/public/components/timelion_vis_component.tsx @@ -19,8 +19,8 @@ import { } from '@elastic/charts'; import { EuiTitle } from '@elastic/eui'; -import { useKibana } from '../../../kibana_react/public'; -import { useActiveCursor } from '../../../charts/public'; +import { useKibana } from '../../../../kibana_react/public'; +import { useActiveCursor } from '../../../../charts/public'; import { AreaSeriesComponent, BarSeriesComponent } from './series'; @@ -36,9 +36,9 @@ import { colors } from '../helpers/chart_constants'; import { getCharts } from '../helpers/plugin_services'; import type { Sheet } from '../helpers/timelion_request_handler'; -import type { IInterpreterRenderHandlers } from '../../../expressions'; +import type { IInterpreterRenderHandlers } from '../../../../expressions'; import type { TimelionVisDependencies } from '../plugin'; -import type { RangeFilterParams } from '../../../data/public'; +import type { RangeFilterParams } from '../../../../data/public'; import type { Series } from '../helpers/timelion_request_handler'; import './timelion_vis.scss'; diff --git a/src/plugins/vis_type_timelion/public/helpers/arg_value_suggestions.ts b/src/plugins/vis_types/timelion/public/helpers/arg_value_suggestions.ts similarity index 99% rename from src/plugins/vis_type_timelion/public/helpers/arg_value_suggestions.ts rename to src/plugins/vis_types/timelion/public/helpers/arg_value_suggestions.ts index 8685ed3102fa6..b2f60b4092bf7 100644 --- a/src/plugins/vis_type_timelion/public/helpers/arg_value_suggestions.ts +++ b/src/plugins/vis_types/timelion/public/helpers/arg_value_suggestions.ts @@ -10,7 +10,7 @@ import { get } from 'lodash'; import { getIndexPatterns } from './plugin_services'; import { TimelionFunctionArgs } from '../../common/types'; import { TimelionExpressionFunction, TimelionExpressionArgument } from '../../common/parser'; -import { indexPatterns as indexPatternsUtils, KBN_FIELD_TYPES } from '../../../data/public'; +import { indexPatterns as indexPatternsUtils, KBN_FIELD_TYPES } from '../../../../data/public'; export function getArgValueSuggestions() { const indexPatterns = getIndexPatterns(); diff --git a/src/plugins/vis_type_timelion/public/helpers/chart_constants.ts b/src/plugins/vis_types/timelion/public/helpers/chart_constants.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/helpers/chart_constants.ts rename to src/plugins/vis_types/timelion/public/helpers/chart_constants.ts diff --git a/src/plugins/vis_type_timelion/public/helpers/get_timezone.ts b/src/plugins/vis_types/timelion/public/helpers/get_timezone.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/helpers/get_timezone.ts rename to src/plugins/vis_types/timelion/public/helpers/get_timezone.ts diff --git a/src/plugins/vis_type_timelion/public/helpers/panel_utils.ts b/src/plugins/vis_types/timelion/public/helpers/panel_utils.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/helpers/panel_utils.ts rename to src/plugins/vis_types/timelion/public/helpers/panel_utils.ts diff --git a/src/plugins/vis_type_timelion/public/helpers/plugin_services.ts b/src/plugins/vis_types/timelion/public/helpers/plugin_services.ts similarity index 91% rename from src/plugins/vis_type_timelion/public/helpers/plugin_services.ts rename to src/plugins/vis_types/timelion/public/helpers/plugin_services.ts index 58fcf510ff792..0e9014437b325 100644 --- a/src/plugins/vis_type_timelion/public/helpers/plugin_services.ts +++ b/src/plugins/vis_types/timelion/public/helpers/plugin_services.ts @@ -8,7 +8,7 @@ import type { IndexPatternsContract, ISearchStart } from 'src/plugins/data/public'; import type { ChartsPluginStart } from 'src/plugins/charts/public'; -import { createGetterSetter } from '../../../kibana_utils/public'; +import { createGetterSetter } from '../../../../kibana_utils/public'; export const [getIndexPatterns, setIndexPatterns] = createGetterSetter( 'IndexPatterns' diff --git a/src/plugins/vis_type_timelion/public/helpers/tick_formatters.test.ts b/src/plugins/vis_types/timelion/public/helpers/tick_formatters.test.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/helpers/tick_formatters.test.ts rename to src/plugins/vis_types/timelion/public/helpers/tick_formatters.test.ts diff --git a/src/plugins/vis_type_timelion/public/helpers/tick_formatters.ts b/src/plugins/vis_types/timelion/public/helpers/tick_formatters.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/helpers/tick_formatters.ts rename to src/plugins/vis_types/timelion/public/helpers/tick_formatters.ts diff --git a/src/plugins/vis_type_timelion/public/helpers/tick_generator.test.ts b/src/plugins/vis_types/timelion/public/helpers/tick_generator.test.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/helpers/tick_generator.test.ts rename to src/plugins/vis_types/timelion/public/helpers/tick_generator.test.ts diff --git a/src/plugins/vis_type_timelion/public/helpers/tick_generator.ts b/src/plugins/vis_types/timelion/public/helpers/tick_generator.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/helpers/tick_generator.ts rename to src/plugins/vis_types/timelion/public/helpers/tick_generator.ts diff --git a/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts b/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts similarity index 99% rename from src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts rename to src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts index ffadfde6204de..e44d74cfd72ab 100644 --- a/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts +++ b/src/plugins/vis_types/timelion/public/helpers/timelion_request_handler.ts @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import type { KibanaExecutionContext } from 'kibana/public'; -import { KibanaContext, TimeRange, Filter, esQuery, Query } from '../../../data/public'; +import { KibanaContext, TimeRange, Filter, esQuery, Query } from '../../../../data/public'; import { TimelionVisDependencies } from '../plugin'; import { getTimezone } from './get_timezone'; import { TimelionVisParams } from '../timelion_vis_fn'; diff --git a/src/plugins/vis_type_timelion/public/helpers/xaxis_formatter.ts b/src/plugins/vis_types/timelion/public/helpers/xaxis_formatter.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/helpers/xaxis_formatter.ts rename to src/plugins/vis_types/timelion/public/helpers/xaxis_formatter.ts diff --git a/src/plugins/vis_type_timelion/public/index.ts b/src/plugins/vis_types/timelion/public/index.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/index.ts rename to src/plugins/vis_types/timelion/public/index.ts diff --git a/src/plugins/vis_type_timelion/public/legacy/panel_utils.ts b/src/plugins/vis_types/timelion/public/legacy/panel_utils.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/legacy/panel_utils.ts rename to src/plugins/vis_types/timelion/public/legacy/panel_utils.ts diff --git a/src/plugins/vis_type_timelion/public/legacy/tick_formatters.test.ts b/src/plugins/vis_types/timelion/public/legacy/tick_formatters.test.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/legacy/tick_formatters.test.ts rename to src/plugins/vis_types/timelion/public/legacy/tick_formatters.test.ts diff --git a/src/plugins/vis_type_timelion/public/legacy/tick_formatters.ts b/src/plugins/vis_types/timelion/public/legacy/tick_formatters.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/legacy/tick_formatters.ts rename to src/plugins/vis_types/timelion/public/legacy/tick_formatters.ts diff --git a/src/plugins/vis_type_timelion/public/legacy/timelion_vis.scss b/src/plugins/vis_types/timelion/public/legacy/timelion_vis.scss similarity index 100% rename from src/plugins/vis_type_timelion/public/legacy/timelion_vis.scss rename to src/plugins/vis_types/timelion/public/legacy/timelion_vis.scss diff --git a/src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx b/src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx similarity index 98% rename from src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx rename to src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx index ddac86fa73bee..1fdb1b37f1c8b 100644 --- a/src/plugins/vis_type_timelion/public/legacy/timelion_vis_component.tsx +++ b/src/plugins/vis_types/timelion/public/legacy/timelion_vis_component.tsx @@ -13,7 +13,7 @@ import { debounce, compact, get, each, cloneDeep, last, map } from 'lodash'; import { useResizeObserver } from '@elastic/eui'; import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; -import { useKibana } from '../../../kibana_react/public'; +import { useKibana } from '../../../../kibana_react/public'; import { DEFAULT_TIME_FORMAT } from '../../common/lib'; import { @@ -31,7 +31,7 @@ import { tickFormatters } from './tick_formatters'; import { generateTicksProvider } from '../helpers/tick_generator'; import type { TimelionVisDependencies } from '../plugin'; -import type { RangeFilterParams } from '../../../data/common'; +import type { RangeFilterParams } from '../../../../data/common'; import './timelion_vis.scss'; diff --git a/src/plugins/vis_type_timelion/public/plugin.ts b/src/plugins/vis_types/timelion/public/plugin.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/plugin.ts rename to src/plugins/vis_types/timelion/public/plugin.ts diff --git a/src/plugins/vis_type_timelion/public/timelion_options.scss b/src/plugins/vis_types/timelion/public/timelion_options.scss similarity index 100% rename from src/plugins/vis_type_timelion/public/timelion_options.scss rename to src/plugins/vis_types/timelion/public/timelion_options.scss diff --git a/src/plugins/vis_type_timelion/public/timelion_options.tsx b/src/plugins/vis_types/timelion/public/timelion_options.tsx similarity index 96% rename from src/plugins/vis_type_timelion/public/timelion_options.tsx rename to src/plugins/vis_types/timelion/public/timelion_options.tsx index ed22efb38be1c..7879eb88e0bd2 100644 --- a/src/plugins/vis_type_timelion/public/timelion_options.tsx +++ b/src/plugins/vis_types/timelion/public/timelion_options.tsx @@ -10,7 +10,7 @@ import React, { useCallback } from 'react'; import { EuiPanel } from '@elastic/eui'; import { VisEditorOptionsProps } from 'src/plugins/visualizations/public'; -import { KibanaContextProvider } from '../../kibana_react/public'; +import { KibanaContextProvider } from '../../../kibana_react/public'; import { TimelionVisParams } from './timelion_vis_fn'; import { TimelionInterval, TimelionExpressionInput } from './components'; diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts b/src/plugins/vis_types/timelion/public/timelion_vis_fn.ts similarity index 96% rename from src/plugins/vis_type_timelion/public/timelion_vis_fn.ts rename to src/plugins/vis_types/timelion/public/timelion_vis_fn.ts index 2f775728667b6..dd3dfd5cd60a0 100644 --- a/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts +++ b/src/plugins/vis_types/timelion/public/timelion_vis_fn.ts @@ -15,7 +15,7 @@ import { } from './helpers/timelion_request_handler'; import { TIMELION_VIS_NAME } from './timelion_vis_type'; import { TimelionVisDependencies } from './plugin'; -import { KibanaContext, Filter, Query, TimeRange } from '../../data/public'; +import { KibanaContext, Filter, Query, TimeRange } from '../../../data/public'; type Input = KibanaContext | null; type Output = Promise>; diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx b/src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx similarity index 92% rename from src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx rename to src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx index b14055a4d6b63..c74c0f2ee6c2d 100644 --- a/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx +++ b/src/plugins/vis_types/timelion/public/timelion_vis_renderer.tsx @@ -10,12 +10,12 @@ import React, { lazy } from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { ExpressionRenderDefinition } from 'src/plugins/expressions'; -import { KibanaContextProvider } from '../../kibana_react/public'; -import { VisualizationContainer } from '../../visualizations/public'; +import { KibanaContextProvider } from '../../../kibana_react/public'; +import { VisualizationContainer } from '../../../visualizations/public'; import { TimelionVisDependencies } from './plugin'; import { TimelionRenderValue } from './timelion_vis_fn'; import { UI_SETTINGS } from '../common/constants'; -import { RangeFilterParams } from '../../data/public'; +import { RangeFilterParams } from '../../../data/public'; const TimelionVisComponent = lazy(() => import('./components/timelion_vis_component')); const TimelionVisLegacyComponent = lazy(() => import('./legacy/timelion_vis_component')); diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx b/src/plugins/vis_types/timelion/public/timelion_vis_type.tsx similarity index 93% rename from src/plugins/vis_type_timelion/public/timelion_vis_type.tsx rename to src/plugins/vis_types/timelion/public/timelion_vis_type.tsx index d607a26485afe..3462ae8df5cd5 100644 --- a/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx +++ b/src/plugins/vis_types/timelion/public/timelion_vis_type.tsx @@ -9,7 +9,7 @@ import React, { lazy } from 'react'; import { i18n } from '@kbn/i18n'; -import { DefaultEditorSize } from '../../vis_default_editor/public'; +import { DefaultEditorSize } from '../../../vis_default_editor/public'; import { TimelionOptionsProps } from './timelion_options'; import { TimelionVisDependencies } from './plugin'; import { toExpressionAst } from './to_ast'; @@ -17,7 +17,7 @@ import { getIndexPatterns } from './helpers/plugin_services'; import { parseTimelionExpressionAsync } from '../common/parser_async'; -import { VIS_EVENT_TO_TRIGGER, VisParams } from '../../visualizations/public'; +import { VIS_EVENT_TO_TRIGGER, VisParams } from '../../../visualizations/public'; const TimelionOptions = lazy(() => import('./timelion_options')); diff --git a/src/plugins/vis_type_timelion/public/to_ast.test.ts b/src/plugins/vis_types/timelion/public/to_ast.test.ts similarity index 100% rename from src/plugins/vis_type_timelion/public/to_ast.test.ts rename to src/plugins/vis_types/timelion/public/to_ast.test.ts diff --git a/src/plugins/vis_type_timelion/public/to_ast.ts b/src/plugins/vis_types/timelion/public/to_ast.ts similarity index 91% rename from src/plugins/vis_type_timelion/public/to_ast.ts rename to src/plugins/vis_types/timelion/public/to_ast.ts index c743d9ce78f32..cf0a24a0e3d3e 100644 --- a/src/plugins/vis_type_timelion/public/to_ast.ts +++ b/src/plugins/vis_types/timelion/public/to_ast.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { buildExpression, buildExpressionFunction } from '../../expressions/public'; -import { Vis } from '../../visualizations/public'; +import { buildExpression, buildExpressionFunction } from '../../../expressions/public'; +import { Vis } from '../../../visualizations/public'; import { TimelionExpressionFunctionDefinition, TimelionVisParams } from './timelion_vis_fn'; export const toExpressionAst = (vis: Vis) => { diff --git a/src/plugins/vis_type_timelion/server/fit_functions/average.js b/src/plugins/vis_types/timelion/server/fit_functions/average.js similarity index 100% rename from src/plugins/vis_type_timelion/server/fit_functions/average.js rename to src/plugins/vis_types/timelion/server/fit_functions/average.js diff --git a/src/plugins/vis_type_timelion/server/fit_functions/average.test.js b/src/plugins/vis_types/timelion/server/fit_functions/average.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/fit_functions/average.test.js rename to src/plugins/vis_types/timelion/server/fit_functions/average.test.js diff --git a/src/plugins/vis_type_timelion/server/fit_functions/carry.js b/src/plugins/vis_types/timelion/server/fit_functions/carry.js similarity index 100% rename from src/plugins/vis_type_timelion/server/fit_functions/carry.js rename to src/plugins/vis_types/timelion/server/fit_functions/carry.js diff --git a/src/plugins/vis_type_timelion/server/fit_functions/carry.test.js b/src/plugins/vis_types/timelion/server/fit_functions/carry.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/fit_functions/carry.test.js rename to src/plugins/vis_types/timelion/server/fit_functions/carry.test.js diff --git a/src/plugins/vis_type_timelion/server/fit_functions/nearest.js b/src/plugins/vis_types/timelion/server/fit_functions/nearest.js similarity index 100% rename from src/plugins/vis_type_timelion/server/fit_functions/nearest.js rename to src/plugins/vis_types/timelion/server/fit_functions/nearest.js diff --git a/src/plugins/vis_type_timelion/server/fit_functions/none.js b/src/plugins/vis_types/timelion/server/fit_functions/none.js similarity index 100% rename from src/plugins/vis_type_timelion/server/fit_functions/none.js rename to src/plugins/vis_types/timelion/server/fit_functions/none.js diff --git a/src/plugins/vis_type_timelion/server/fit_functions/scale.js b/src/plugins/vis_types/timelion/server/fit_functions/scale.js similarity index 100% rename from src/plugins/vis_type_timelion/server/fit_functions/scale.js rename to src/plugins/vis_types/timelion/server/fit_functions/scale.js diff --git a/src/plugins/vis_type_timelion/server/handlers/chain_runner.js b/src/plugins/vis_types/timelion/server/handlers/chain_runner.js similarity index 100% rename from src/plugins/vis_type_timelion/server/handlers/chain_runner.js rename to src/plugins/vis_types/timelion/server/handlers/chain_runner.js diff --git a/src/plugins/vis_type_timelion/server/handlers/lib/arg_type.js b/src/plugins/vis_types/timelion/server/handlers/lib/arg_type.js similarity index 100% rename from src/plugins/vis_type_timelion/server/handlers/lib/arg_type.js rename to src/plugins/vis_types/timelion/server/handlers/lib/arg_type.js diff --git a/src/plugins/vis_type_timelion/server/handlers/lib/index_arguments.js b/src/plugins/vis_types/timelion/server/handlers/lib/index_arguments.js similarity index 100% rename from src/plugins/vis_type_timelion/server/handlers/lib/index_arguments.js rename to src/plugins/vis_types/timelion/server/handlers/lib/index_arguments.js diff --git a/src/plugins/vis_type_timelion/server/handlers/lib/parse_sheet.js b/src/plugins/vis_types/timelion/server/handlers/lib/parse_sheet.js similarity index 100% rename from src/plugins/vis_type_timelion/server/handlers/lib/parse_sheet.js rename to src/plugins/vis_types/timelion/server/handlers/lib/parse_sheet.js diff --git a/src/plugins/vis_type_timelion/server/handlers/lib/parse_sheet.test.js b/src/plugins/vis_types/timelion/server/handlers/lib/parse_sheet.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/handlers/lib/parse_sheet.test.js rename to src/plugins/vis_types/timelion/server/handlers/lib/parse_sheet.test.js diff --git a/src/plugins/vis_type_timelion/server/handlers/lib/preprocess_chain.js b/src/plugins/vis_types/timelion/server/handlers/lib/preprocess_chain.js similarity index 100% rename from src/plugins/vis_type_timelion/server/handlers/lib/preprocess_chain.js rename to src/plugins/vis_types/timelion/server/handlers/lib/preprocess_chain.js diff --git a/src/plugins/vis_type_timelion/server/handlers/lib/reposition_arguments.js b/src/plugins/vis_types/timelion/server/handlers/lib/reposition_arguments.js similarity index 100% rename from src/plugins/vis_type_timelion/server/handlers/lib/reposition_arguments.js rename to src/plugins/vis_types/timelion/server/handlers/lib/reposition_arguments.js diff --git a/src/plugins/vis_type_timelion/server/handlers/lib/tl_config.js b/src/plugins/vis_types/timelion/server/handlers/lib/tl_config.js similarity index 100% rename from src/plugins/vis_type_timelion/server/handlers/lib/tl_config.js rename to src/plugins/vis_types/timelion/server/handlers/lib/tl_config.js diff --git a/src/plugins/vis_type_timelion/server/handlers/lib/validate_arg.js b/src/plugins/vis_types/timelion/server/handlers/lib/validate_arg.js similarity index 100% rename from src/plugins/vis_type_timelion/server/handlers/lib/validate_arg.js rename to src/plugins/vis_types/timelion/server/handlers/lib/validate_arg.js diff --git a/src/plugins/vis_type_timelion/server/handlers/lib/validate_time.js b/src/plugins/vis_types/timelion/server/handlers/lib/validate_time.js similarity index 100% rename from src/plugins/vis_type_timelion/server/handlers/lib/validate_time.js rename to src/plugins/vis_types/timelion/server/handlers/lib/validate_time.js diff --git a/src/plugins/vis_type_timelion/server/index.ts b/src/plugins/vis_types/timelion/server/index.ts similarity index 95% rename from src/plugins/vis_type_timelion/server/index.ts rename to src/plugins/vis_types/timelion/server/index.ts index 5c5cf8b481f94..396ef8b61c7bc 100644 --- a/src/plugins/vis_type_timelion/server/index.ts +++ b/src/plugins/vis_types/timelion/server/index.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { PluginConfigDescriptor, PluginInitializerContext } from '../../../../src/core/server'; +import { PluginConfigDescriptor, PluginInitializerContext } from '../../../../../src/core/server'; import { configSchema, ConfigSchema } from '../config'; import { TimelionPlugin } from './plugin'; diff --git a/src/plugins/vis_type_timelion/server/lib/alter.js b/src/plugins/vis_types/timelion/server/lib/alter.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/alter.js rename to src/plugins/vis_types/timelion/server/lib/alter.js diff --git a/src/plugins/vis_type_timelion/server/lib/as_sorted.js b/src/plugins/vis_types/timelion/server/lib/as_sorted.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/as_sorted.js rename to src/plugins/vis_types/timelion/server/lib/as_sorted.js diff --git a/src/plugins/vis_type_timelion/server/lib/build_target.js b/src/plugins/vis_types/timelion/server/lib/build_target.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/build_target.js rename to src/plugins/vis_types/timelion/server/lib/build_target.js diff --git a/src/plugins/vis_type_timelion/server/lib/classes/chainable.js b/src/plugins/vis_types/timelion/server/lib/classes/chainable.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/classes/chainable.js rename to src/plugins/vis_types/timelion/server/lib/classes/chainable.js diff --git a/src/plugins/vis_type_timelion/server/lib/classes/datasource.js b/src/plugins/vis_types/timelion/server/lib/classes/datasource.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/classes/datasource.js rename to src/plugins/vis_types/timelion/server/lib/classes/datasource.js diff --git a/src/plugins/vis_type_timelion/server/lib/classes/timelion_function.d.ts b/src/plugins/vis_types/timelion/server/lib/classes/timelion_function.d.ts similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/classes/timelion_function.d.ts rename to src/plugins/vis_types/timelion/server/lib/classes/timelion_function.d.ts diff --git a/src/plugins/vis_type_timelion/server/lib/classes/timelion_function.js b/src/plugins/vis_types/timelion/server/lib/classes/timelion_function.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/classes/timelion_function.js rename to src/plugins/vis_types/timelion/server/lib/classes/timelion_function.js diff --git a/src/plugins/vis_type_timelion/server/lib/config_manager.ts b/src/plugins/vis_types/timelion/server/lib/config_manager.ts similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/config_manager.ts rename to src/plugins/vis_types/timelion/server/lib/config_manager.ts diff --git a/src/plugins/vis_type_timelion/server/lib/functions_md.js b/src/plugins/vis_types/timelion/server/lib/functions_md.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/functions_md.js rename to src/plugins/vis_types/timelion/server/lib/functions_md.js diff --git a/src/plugins/vis_type_timelion/server/lib/get_namespaced_settings.js b/src/plugins/vis_types/timelion/server/lib/get_namespaced_settings.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/get_namespaced_settings.js rename to src/plugins/vis_types/timelion/server/lib/get_namespaced_settings.js diff --git a/src/plugins/vis_type_timelion/server/lib/load_functions.d.ts b/src/plugins/vis_types/timelion/server/lib/load_functions.d.ts similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/load_functions.d.ts rename to src/plugins/vis_types/timelion/server/lib/load_functions.d.ts diff --git a/src/plugins/vis_type_timelion/server/lib/load_functions.js b/src/plugins/vis_types/timelion/server/lib/load_functions.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/load_functions.js rename to src/plugins/vis_types/timelion/server/lib/load_functions.js diff --git a/src/plugins/vis_type_timelion/server/lib/load_functions.test.js b/src/plugins/vis_types/timelion/server/lib/load_functions.test.js similarity index 92% rename from src/plugins/vis_type_timelion/server/lib/load_functions.test.js rename to src/plugins/vis_types/timelion/server/lib/load_functions.test.js index 0f63c92cc05a8..1508670523733 100644 --- a/src/plugins/vis_type_timelion/server/lib/load_functions.test.js +++ b/src/plugins/vis_types/timelion/server/lib/load_functions.test.js @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -const fn = require(`src/plugins/vis_type_timelion/server/lib/load_functions`); +const fn = require(`src/plugins/vis_types/timelion/server/lib/load_functions`); const expect = require('chai').expect; diff --git a/src/plugins/vis_type_timelion/server/lib/offset_time.js b/src/plugins/vis_types/timelion/server/lib/offset_time.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/offset_time.js rename to src/plugins/vis_types/timelion/server/lib/offset_time.js diff --git a/src/plugins/vis_type_timelion/server/lib/offset_time.test.js b/src/plugins/vis_types/timelion/server/lib/offset_time.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/offset_time.test.js rename to src/plugins/vis_types/timelion/server/lib/offset_time.test.js diff --git a/src/plugins/vis_type_timelion/server/lib/process_function_definition.js b/src/plugins/vis_types/timelion/server/lib/process_function_definition.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/process_function_definition.js rename to src/plugins/vis_types/timelion/server/lib/process_function_definition.js diff --git a/src/plugins/vis_type_timelion/server/lib/reduce.js b/src/plugins/vis_types/timelion/server/lib/reduce.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/reduce.js rename to src/plugins/vis_types/timelion/server/lib/reduce.js diff --git a/src/plugins/vis_type_timelion/server/lib/split_interval.js b/src/plugins/vis_types/timelion/server/lib/split_interval.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/split_interval.js rename to src/plugins/vis_types/timelion/server/lib/split_interval.js diff --git a/src/plugins/vis_type_timelion/server/lib/unzip_pairs.js b/src/plugins/vis_types/timelion/server/lib/unzip_pairs.js similarity index 100% rename from src/plugins/vis_type_timelion/server/lib/unzip_pairs.js rename to src/plugins/vis_types/timelion/server/lib/unzip_pairs.js diff --git a/src/plugins/vis_type_timelion/server/plugin.ts b/src/plugins/vis_types/timelion/server/plugin.ts similarity index 94% rename from src/plugins/vis_type_timelion/server/plugin.ts rename to src/plugins/vis_types/timelion/server/plugin.ts index 5bbb5dd1819c4..b44aad5575b19 100644 --- a/src/plugins/vis_type_timelion/server/plugin.ts +++ b/src/plugins/vis_types/timelion/server/plugin.ts @@ -9,8 +9,11 @@ import { i18n } from '@kbn/i18n'; import { TypeOf } from '@kbn/config-schema'; -import type { PluginStart, DataRequestHandlerContext } from '../../../../src/plugins/data/server'; -import { CoreSetup, PluginInitializerContext, Plugin } from '../../../../src/core/server'; +import type { + PluginStart, + DataRequestHandlerContext, +} from '../../../../../src/plugins/data/server'; +import { CoreSetup, PluginInitializerContext, Plugin } from '../../../../../src/core/server'; import { configSchema } from '../config'; import loadFunctions from './lib/load_functions'; import { functionsRoute } from './routes/functions'; diff --git a/src/plugins/vis_type_timelion/server/routes/functions.ts b/src/plugins/vis_types/timelion/server/routes/functions.ts similarity index 100% rename from src/plugins/vis_type_timelion/server/routes/functions.ts rename to src/plugins/vis_types/timelion/server/routes/functions.ts diff --git a/src/plugins/vis_type_timelion/server/routes/run.ts b/src/plugins/vis_types/timelion/server/routes/run.ts similarity index 100% rename from src/plugins/vis_type_timelion/server/routes/run.ts rename to src/plugins/vis_types/timelion/server/routes/run.ts diff --git a/src/plugins/vis_type_timelion/server/routes/validate_es.ts b/src/plugins/vis_types/timelion/server/routes/validate_es.ts similarity index 96% rename from src/plugins/vis_type_timelion/server/routes/validate_es.ts rename to src/plugins/vis_types/timelion/server/routes/validate_es.ts index 70eacc5ce8518..1e894e09c6e1b 100644 --- a/src/plugins/vis_type_timelion/server/routes/validate_es.ts +++ b/src/plugins/vis_types/timelion/server/routes/validate_es.ts @@ -8,7 +8,7 @@ import _ from 'lodash'; import { IRouter } from 'kibana/server'; -import type { DataRequestHandlerContext } from '../../../data/server'; +import type { DataRequestHandlerContext } from '../../../../data/server'; export function validateEsRoute(router: IRouter) { router.get( diff --git a/src/plugins/vis_type_timelion/server/series_functions/abs.js b/src/plugins/vis_types/timelion/server/series_functions/abs.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/abs.js rename to src/plugins/vis_types/timelion/server/series_functions/abs.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/abs.test.js b/src/plugins/vis_types/timelion/server/series_functions/abs.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/abs.test.js rename to src/plugins/vis_types/timelion/server/series_functions/abs.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/aggregate/aggregate.test.js b/src/plugins/vis_types/timelion/server/series_functions/aggregate/aggregate.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/aggregate/aggregate.test.js rename to src/plugins/vis_types/timelion/server/series_functions/aggregate/aggregate.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/aggregate/avg.js b/src/plugins/vis_types/timelion/server/series_functions/aggregate/avg.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/aggregate/avg.js rename to src/plugins/vis_types/timelion/server/series_functions/aggregate/avg.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/aggregate/cardinality.js b/src/plugins/vis_types/timelion/server/series_functions/aggregate/cardinality.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/aggregate/cardinality.js rename to src/plugins/vis_types/timelion/server/series_functions/aggregate/cardinality.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/aggregate/first.js b/src/plugins/vis_types/timelion/server/series_functions/aggregate/first.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/aggregate/first.js rename to src/plugins/vis_types/timelion/server/series_functions/aggregate/first.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/aggregate/index.js b/src/plugins/vis_types/timelion/server/series_functions/aggregate/index.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/aggregate/index.js rename to src/plugins/vis_types/timelion/server/series_functions/aggregate/index.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/aggregate/last.js b/src/plugins/vis_types/timelion/server/series_functions/aggregate/last.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/aggregate/last.js rename to src/plugins/vis_types/timelion/server/series_functions/aggregate/last.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/aggregate/max.js b/src/plugins/vis_types/timelion/server/series_functions/aggregate/max.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/aggregate/max.js rename to src/plugins/vis_types/timelion/server/series_functions/aggregate/max.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/aggregate/min.js b/src/plugins/vis_types/timelion/server/series_functions/aggregate/min.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/aggregate/min.js rename to src/plugins/vis_types/timelion/server/series_functions/aggregate/min.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/aggregate/sum.js b/src/plugins/vis_types/timelion/server/series_functions/aggregate/sum.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/aggregate/sum.js rename to src/plugins/vis_types/timelion/server/series_functions/aggregate/sum.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/bars.js b/src/plugins/vis_types/timelion/server/series_functions/bars.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/bars.js rename to src/plugins/vis_types/timelion/server/series_functions/bars.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/bars.test.js b/src/plugins/vis_types/timelion/server/series_functions/bars.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/bars.test.js rename to src/plugins/vis_types/timelion/server/series_functions/bars.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/color.js b/src/plugins/vis_types/timelion/server/series_functions/color.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/color.js rename to src/plugins/vis_types/timelion/server/series_functions/color.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/color.test.js b/src/plugins/vis_types/timelion/server/series_functions/color.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/color.test.js rename to src/plugins/vis_types/timelion/server/series_functions/color.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/condition.js b/src/plugins/vis_types/timelion/server/series_functions/condition.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/condition.js rename to src/plugins/vis_types/timelion/server/series_functions/condition.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/condition.test.js b/src/plugins/vis_types/timelion/server/series_functions/condition.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/condition.test.js rename to src/plugins/vis_types/timelion/server/series_functions/condition.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/cusum.js b/src/plugins/vis_types/timelion/server/series_functions/cusum.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/cusum.js rename to src/plugins/vis_types/timelion/server/series_functions/cusum.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/cusum.test.js b/src/plugins/vis_types/timelion/server/series_functions/cusum.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/cusum.test.js rename to src/plugins/vis_types/timelion/server/series_functions/cusum.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/derivative.js b/src/plugins/vis_types/timelion/server/series_functions/derivative.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/derivative.js rename to src/plugins/vis_types/timelion/server/series_functions/derivative.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/derivative.test.js b/src/plugins/vis_types/timelion/server/series_functions/derivative.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/derivative.test.js rename to src/plugins/vis_types/timelion/server/series_functions/derivative.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/divide.js b/src/plugins/vis_types/timelion/server/series_functions/divide.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/divide.js rename to src/plugins/vis_types/timelion/server/series_functions/divide.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/divide.test.js b/src/plugins/vis_types/timelion/server/series_functions/divide.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/divide.test.js rename to src/plugins/vis_types/timelion/server/series_functions/divide.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js b/src/plugins/vis_types/timelion/server/series_functions/es/es.test.js similarity index 99% rename from src/plugins/vis_type_timelion/server/series_functions/es/es.test.js rename to src/plugins/vis_types/timelion/server/series_functions/es/es.test.js index c2940c6d7731a..f55ee31f39799 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/es.test.js +++ b/src/plugins/vis_types/timelion/server/series_functions/es/es.test.js @@ -17,7 +17,7 @@ import esResponse from '../fixtures/es_response'; import _ from 'lodash'; import sinon from 'sinon'; import invoke from '../helpers/invoke_series_fn.js'; -import { UI_SETTINGS } from '../../../../data/server'; +import { UI_SETTINGS } from '../../../../../data/server'; describe('es', () => { let tlConfig; diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/index.js b/src/plugins/vis_types/timelion/server/series_functions/es/index.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/es/index.js rename to src/plugins/vis_types/timelion/server/series_functions/es/index.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/lib/agg_body.js b/src/plugins/vis_types/timelion/server/series_functions/es/lib/agg_body.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/es/lib/agg_body.js rename to src/plugins/vis_types/timelion/server/series_functions/es/lib/agg_body.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/lib/agg_response_to_series_list.js b/src/plugins/vis_types/timelion/server/series_functions/es/lib/agg_response_to_series_list.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/es/lib/agg_response_to_series_list.js rename to src/plugins/vis_types/timelion/server/series_functions/es/lib/agg_response_to_series_list.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js b/src/plugins/vis_types/timelion/server/series_functions/es/lib/build_request.js similarity index 97% rename from src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js rename to src/plugins/vis_types/timelion/server/series_functions/es/lib/build_request.js index 7d55a772c7fc1..20e3f71801854 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js +++ b/src/plugins/vis_types/timelion/server/series_functions/es/lib/build_request.js @@ -10,7 +10,7 @@ import _ from 'lodash'; import moment from 'moment'; import { buildAggBody } from './agg_body'; import createDateAgg from './create_date_agg'; -import { UI_SETTINGS } from '../../../../../data/server'; +import { UI_SETTINGS } from '../../../../../../data/server'; export default function buildRequest(config, tlConfig, scriptFields, runtimeFields, timeout) { const bool = { must: [] }; diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/lib/create_date_agg.js b/src/plugins/vis_types/timelion/server/series_functions/es/lib/create_date_agg.js similarity index 97% rename from src/plugins/vis_type_timelion/server/series_functions/es/lib/create_date_agg.js rename to src/plugins/vis_types/timelion/server/series_functions/es/lib/create_date_agg.js index bd6cf8a4b7c5e..e12ad035a2b61 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/lib/create_date_agg.js +++ b/src/plugins/vis_types/timelion/server/series_functions/es/lib/create_date_agg.js @@ -7,7 +7,7 @@ */ import { buildAggBody } from './agg_body'; -import { search, METRIC_TYPES } from '../../../../../data/server'; +import { search, METRIC_TYPES } from '../../../../../../data/server'; const { dateHistogramInterval } = search.aggs; diff --git a/src/plugins/vis_type_timelion/server/series_functions/first.js b/src/plugins/vis_types/timelion/server/series_functions/first.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/first.js rename to src/plugins/vis_types/timelion/server/series_functions/first.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/first.test.js b/src/plugins/vis_types/timelion/server/series_functions/first.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/first.test.js rename to src/plugins/vis_types/timelion/server/series_functions/first.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/fit.js b/src/plugins/vis_types/timelion/server/series_functions/fit.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/fit.js rename to src/plugins/vis_types/timelion/server/series_functions/fit.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/fit.test.js b/src/plugins/vis_types/timelion/server/series_functions/fit.test.js similarity index 98% rename from src/plugins/vis_type_timelion/server/series_functions/fit.test.js rename to src/plugins/vis_types/timelion/server/series_functions/fit.test.js index 7e853d4d74e49..b755a3f80e338 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/fit.test.js +++ b/src/plugins/vis_types/timelion/server/series_functions/fit.test.js @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -const fn = require(`src/plugins/vis_type_timelion/server/series_functions/fit`); +const fn = require(`src/plugins/vis_types/timelion/server/series_functions/fit`); import moment from 'moment'; const expect = require('chai').expect; import invoke from './helpers/invoke_series_fn.js'; diff --git a/src/plugins/vis_type_timelion/server/series_functions/fixtures/bucket_list.js b/src/plugins/vis_types/timelion/server/series_functions/fixtures/bucket_list.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/fixtures/bucket_list.js rename to src/plugins/vis_types/timelion/server/series_functions/fixtures/bucket_list.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/fixtures/es_response.js b/src/plugins/vis_types/timelion/server/series_functions/fixtures/es_response.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/fixtures/es_response.js rename to src/plugins/vis_types/timelion/server/series_functions/fixtures/es_response.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/fixtures/series_list.js b/src/plugins/vis_types/timelion/server/series_functions/fixtures/series_list.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/fixtures/series_list.js rename to src/plugins/vis_types/timelion/server/series_functions/fixtures/series_list.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/fixtures/tl_config.js b/src/plugins/vis_types/timelion/server/series_functions/fixtures/tl_config.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/fixtures/tl_config.js rename to src/plugins/vis_types/timelion/server/series_functions/fixtures/tl_config.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/graphite.js b/src/plugins/vis_types/timelion/server/series_functions/graphite.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/graphite.js rename to src/plugins/vis_types/timelion/server/series_functions/graphite.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/graphite.test.js b/src/plugins/vis_types/timelion/server/series_functions/graphite.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/graphite.test.js rename to src/plugins/vis_types/timelion/server/series_functions/graphite.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/helpers/get_series.js b/src/plugins/vis_types/timelion/server/series_functions/helpers/get_series.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/helpers/get_series.js rename to src/plugins/vis_types/timelion/server/series_functions/helpers/get_series.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/helpers/get_series_list.js b/src/plugins/vis_types/timelion/server/series_functions/helpers/get_series_list.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/helpers/get_series_list.js rename to src/plugins/vis_types/timelion/server/series_functions/helpers/get_series_list.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/helpers/get_single_series_list.js b/src/plugins/vis_types/timelion/server/series_functions/helpers/get_single_series_list.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/helpers/get_single_series_list.js rename to src/plugins/vis_types/timelion/server/series_functions/helpers/get_single_series_list.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/helpers/invoke_series_fn.js b/src/plugins/vis_types/timelion/server/series_functions/helpers/invoke_series_fn.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/helpers/invoke_series_fn.js rename to src/plugins/vis_types/timelion/server/series_functions/helpers/invoke_series_fn.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/hide.js b/src/plugins/vis_types/timelion/server/series_functions/hide.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/hide.js rename to src/plugins/vis_types/timelion/server/series_functions/hide.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/hide.test.js b/src/plugins/vis_types/timelion/server/series_functions/hide.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/hide.test.js rename to src/plugins/vis_types/timelion/server/series_functions/hide.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/holt/index.js b/src/plugins/vis_types/timelion/server/series_functions/holt/index.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/holt/index.js rename to src/plugins/vis_types/timelion/server/series_functions/holt/index.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/holt/lib/des.js b/src/plugins/vis_types/timelion/server/series_functions/holt/lib/des.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/holt/lib/des.js rename to src/plugins/vis_types/timelion/server/series_functions/holt/lib/des.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/holt/lib/ses.js b/src/plugins/vis_types/timelion/server/series_functions/holt/lib/ses.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/holt/lib/ses.js rename to src/plugins/vis_types/timelion/server/series_functions/holt/lib/ses.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/holt/lib/tes.js b/src/plugins/vis_types/timelion/server/series_functions/holt/lib/tes.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/holt/lib/tes.js rename to src/plugins/vis_types/timelion/server/series_functions/holt/lib/tes.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/label.js b/src/plugins/vis_types/timelion/server/series_functions/label.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/label.js rename to src/plugins/vis_types/timelion/server/series_functions/label.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/label.test.js b/src/plugins/vis_types/timelion/server/series_functions/label.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/label.test.js rename to src/plugins/vis_types/timelion/server/series_functions/label.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/legend.js b/src/plugins/vis_types/timelion/server/series_functions/legend.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/legend.js rename to src/plugins/vis_types/timelion/server/series_functions/legend.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/legend.test.js b/src/plugins/vis_types/timelion/server/series_functions/legend.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/legend.test.js rename to src/plugins/vis_types/timelion/server/series_functions/legend.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/lines.js b/src/plugins/vis_types/timelion/server/series_functions/lines.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/lines.js rename to src/plugins/vis_types/timelion/server/series_functions/lines.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/lines.test.js b/src/plugins/vis_types/timelion/server/series_functions/lines.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/lines.test.js rename to src/plugins/vis_types/timelion/server/series_functions/lines.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/log.js b/src/plugins/vis_types/timelion/server/series_functions/log.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/log.js rename to src/plugins/vis_types/timelion/server/series_functions/log.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/log.test.js b/src/plugins/vis_types/timelion/server/series_functions/log.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/log.test.js rename to src/plugins/vis_types/timelion/server/series_functions/log.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/max.js b/src/plugins/vis_types/timelion/server/series_functions/max.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/max.js rename to src/plugins/vis_types/timelion/server/series_functions/max.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/max.test.js b/src/plugins/vis_types/timelion/server/series_functions/max.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/max.test.js rename to src/plugins/vis_types/timelion/server/series_functions/max.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/min.js b/src/plugins/vis_types/timelion/server/series_functions/min.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/min.js rename to src/plugins/vis_types/timelion/server/series_functions/min.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/min.test.js b/src/plugins/vis_types/timelion/server/series_functions/min.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/min.test.js rename to src/plugins/vis_types/timelion/server/series_functions/min.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/movingaverage.js b/src/plugins/vis_types/timelion/server/series_functions/movingaverage.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/movingaverage.js rename to src/plugins/vis_types/timelion/server/series_functions/movingaverage.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/movingaverage.test.js b/src/plugins/vis_types/timelion/server/series_functions/movingaverage.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/movingaverage.test.js rename to src/plugins/vis_types/timelion/server/series_functions/movingaverage.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/movingstd.js b/src/plugins/vis_types/timelion/server/series_functions/movingstd.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/movingstd.js rename to src/plugins/vis_types/timelion/server/series_functions/movingstd.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/movingstd.test.js b/src/plugins/vis_types/timelion/server/series_functions/movingstd.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/movingstd.test.js rename to src/plugins/vis_types/timelion/server/series_functions/movingstd.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/multiply.js b/src/plugins/vis_types/timelion/server/series_functions/multiply.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/multiply.js rename to src/plugins/vis_types/timelion/server/series_functions/multiply.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/multiply.test.js b/src/plugins/vis_types/timelion/server/series_functions/multiply.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/multiply.test.js rename to src/plugins/vis_types/timelion/server/series_functions/multiply.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/points.js b/src/plugins/vis_types/timelion/server/series_functions/points.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/points.js rename to src/plugins/vis_types/timelion/server/series_functions/points.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/points.test.js b/src/plugins/vis_types/timelion/server/series_functions/points.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/points.test.js rename to src/plugins/vis_types/timelion/server/series_functions/points.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/precision.js b/src/plugins/vis_types/timelion/server/series_functions/precision.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/precision.js rename to src/plugins/vis_types/timelion/server/series_functions/precision.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/precision.test.js b/src/plugins/vis_types/timelion/server/series_functions/precision.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/precision.test.js rename to src/plugins/vis_types/timelion/server/series_functions/precision.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/props.js b/src/plugins/vis_types/timelion/server/series_functions/props.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/props.js rename to src/plugins/vis_types/timelion/server/series_functions/props.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/quandl.js b/src/plugins/vis_types/timelion/server/series_functions/quandl.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/quandl.js rename to src/plugins/vis_types/timelion/server/series_functions/quandl.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/quandl.test.js b/src/plugins/vis_types/timelion/server/series_functions/quandl.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/quandl.test.js rename to src/plugins/vis_types/timelion/server/series_functions/quandl.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/range.js b/src/plugins/vis_types/timelion/server/series_functions/range.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/range.js rename to src/plugins/vis_types/timelion/server/series_functions/range.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/range.test.js b/src/plugins/vis_types/timelion/server/series_functions/range.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/range.test.js rename to src/plugins/vis_types/timelion/server/series_functions/range.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/scale_interval.js b/src/plugins/vis_types/timelion/server/series_functions/scale_interval.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/scale_interval.js rename to src/plugins/vis_types/timelion/server/series_functions/scale_interval.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/scale_interval.test.js b/src/plugins/vis_types/timelion/server/series_functions/scale_interval.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/scale_interval.test.js rename to src/plugins/vis_types/timelion/server/series_functions/scale_interval.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/static.js b/src/plugins/vis_types/timelion/server/series_functions/static.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/static.js rename to src/plugins/vis_types/timelion/server/series_functions/static.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/static.test.js b/src/plugins/vis_types/timelion/server/series_functions/static.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/static.test.js rename to src/plugins/vis_types/timelion/server/series_functions/static.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/subtract.js b/src/plugins/vis_types/timelion/server/series_functions/subtract.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/subtract.js rename to src/plugins/vis_types/timelion/server/series_functions/subtract.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/subtract.test.js b/src/plugins/vis_types/timelion/server/series_functions/subtract.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/subtract.test.js rename to src/plugins/vis_types/timelion/server/series_functions/subtract.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/sum.js b/src/plugins/vis_types/timelion/server/series_functions/sum.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/sum.js rename to src/plugins/vis_types/timelion/server/series_functions/sum.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/sum.test.js b/src/plugins/vis_types/timelion/server/series_functions/sum.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/sum.test.js rename to src/plugins/vis_types/timelion/server/series_functions/sum.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/title.js b/src/plugins/vis_types/timelion/server/series_functions/title.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/title.js rename to src/plugins/vis_types/timelion/server/series_functions/title.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/title.test.js b/src/plugins/vis_types/timelion/server/series_functions/title.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/title.test.js rename to src/plugins/vis_types/timelion/server/series_functions/title.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/trend/index.js b/src/plugins/vis_types/timelion/server/series_functions/trend/index.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/trend/index.js rename to src/plugins/vis_types/timelion/server/series_functions/trend/index.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/trend/lib/regress.js b/src/plugins/vis_types/timelion/server/series_functions/trend/lib/regress.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/trend/lib/regress.js rename to src/plugins/vis_types/timelion/server/series_functions/trend/lib/regress.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/trim.js b/src/plugins/vis_types/timelion/server/series_functions/trim.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/trim.js rename to src/plugins/vis_types/timelion/server/series_functions/trim.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/trim.test.js b/src/plugins/vis_types/timelion/server/series_functions/trim.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/trim.test.js rename to src/plugins/vis_types/timelion/server/series_functions/trim.test.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/worldbank.js b/src/plugins/vis_types/timelion/server/series_functions/worldbank.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/worldbank.js rename to src/plugins/vis_types/timelion/server/series_functions/worldbank.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/worldbank_indicators.js b/src/plugins/vis_types/timelion/server/series_functions/worldbank_indicators.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/worldbank_indicators.js rename to src/plugins/vis_types/timelion/server/series_functions/worldbank_indicators.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/yaxis.js b/src/plugins/vis_types/timelion/server/series_functions/yaxis.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/yaxis.js rename to src/plugins/vis_types/timelion/server/series_functions/yaxis.js diff --git a/src/plugins/vis_type_timelion/server/series_functions/yaxis.test.js b/src/plugins/vis_types/timelion/server/series_functions/yaxis.test.js similarity index 100% rename from src/plugins/vis_type_timelion/server/series_functions/yaxis.test.js rename to src/plugins/vis_types/timelion/server/series_functions/yaxis.test.js diff --git a/src/plugins/vis_type_timelion/server/timelion.json b/src/plugins/vis_types/timelion/server/timelion.json similarity index 100% rename from src/plugins/vis_type_timelion/server/timelion.json rename to src/plugins/vis_types/timelion/server/timelion.json diff --git a/src/plugins/vis_type_timelion/server/types.ts b/src/plugins/vis_types/timelion/server/types.ts similarity index 100% rename from src/plugins/vis_type_timelion/server/types.ts rename to src/plugins/vis_types/timelion/server/types.ts diff --git a/src/plugins/vis_type_timelion/server/ui_settings.ts b/src/plugins/vis_types/timelion/server/ui_settings.ts similarity index 100% rename from src/plugins/vis_type_timelion/server/ui_settings.ts rename to src/plugins/vis_types/timelion/server/ui_settings.ts diff --git a/src/plugins/vis_types/timelion/tsconfig.json b/src/plugins/vis_types/timelion/tsconfig.json new file mode 100644 index 0000000000000..8613f381e5e4f --- /dev/null +++ b/src/plugins/vis_types/timelion/tsconfig.json @@ -0,0 +1,24 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "common/**/*", + "public/**/*", + "server/**/*", + "*.ts" + ], + "references": [ + { "path": "../../../core/tsconfig.json" }, + { "path": "../../visualizations/tsconfig.json" }, + { "path": "../../data/tsconfig.json" }, + { "path": "../../expressions/tsconfig.json" }, + { "path": "../../kibana_utils/tsconfig.json" }, + { "path": "../../kibana_react/tsconfig.json" }, + { "path": "../../vis_default_editor/tsconfig.json" }, + ] +} diff --git a/tasks/config/peg.js b/tasks/config/peg.js index 0c299ae5748dd..906767d6db285 100644 --- a/tasks/config/peg.js +++ b/tasks/config/peg.js @@ -6,9 +6,4 @@ * Side Public License, v 1. */ -module.exports = { - timelion_chain: { - src: 'src/plugins/vis_type_timelion/common/chain.peg', - dest: 'src/plugins/vis_type_timelion/common/_generated_/chain.js', - }, -}; +module.exports = {}; diff --git a/test/functional/apps/management/_field_formatter.ts b/test/functional/apps/management/_field_formatter.ts index 65b1f4d324fb1..e070b262af9ed 100644 --- a/test/functional/apps/management/_field_formatter.ts +++ b/test/functional/apps/management/_field_formatter.ts @@ -12,7 +12,6 @@ import { FIELD_FORMAT_IDS } from '../../../../src/plugins/field_formats/common'; import { WebElementWrapper } from '../../services/lib/web_element_wrapper'; export default function ({ getService, getPageObjects }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const browser = getService('browser'); const PageObjects = getPageObjects(['settings', 'common']); @@ -32,13 +31,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'test_field_formatters', 'test_logstash_reader', ]); - await esArchiver.load('test/functional/fixtures/es_archiver/discover'); + await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); await kibanaServer.uiSettings.replace({}); }); after(async function afterAll() { - await PageObjects.settings.navigateTo(); - await esArchiver.emptyKibanaIndex(); + await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); }); describe('set and change field formatter', function describeIndexTests() { diff --git a/test/functional/apps/management/_handle_version_conflict.js b/test/functional/apps/management/_handle_version_conflict.js index 82723ad7ce967..f73489a5185b5 100644 --- a/test/functional/apps/management/_handle_version_conflict.js +++ b/test/functional/apps/management/_handle_version_conflict.js @@ -19,7 +19,7 @@ import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const testSubjects = getService('testSubjects'); - const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); const browser = getService('browser'); const es = getService('es'); const retry = getService('retry'); @@ -30,7 +30,11 @@ export default function ({ getService, getPageObjects }) { describe('index version conflict', function describeIndexTests() { before(async function () { await browser.setWindowSize(1200, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/discover'); + await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); + }); + + after(async () => { + await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); }); it('Should be able to surface version conflict notification while creating scripted field', async function () { diff --git a/test/functional/apps/management/_index_patterns_empty.ts b/test/functional/apps/management/_index_patterns_empty.ts index 038039275b843..e086a6ca18213 100644 --- a/test/functional/apps/management/_index_patterns_empty.ts +++ b/test/functional/apps/management/_index_patterns_empty.ts @@ -32,6 +32,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { path: '/logstash-a', method: 'DELETE', }); + await kibanaServer.savedObjects.clean({ types: ['index-pattern'] }); }); // create index pattern and return to verify list diff --git a/test/functional/apps/management/_mgmt_import_saved_objects.js b/test/functional/apps/management/_mgmt_import_saved_objects.js index b7bca79a25940..cf30b6f4ccf0d 100644 --- a/test/functional/apps/management/_mgmt_import_saved_objects.js +++ b/test/functional/apps/management/_mgmt_import_saved_objects.js @@ -10,21 +10,21 @@ import expect from '@kbn/expect'; import path from 'path'; export default function ({ getService, getPageObjects }) { - const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects(['common', 'settings', 'header', 'savedObjects']); //in 6.4.0 bug the Saved Search conflict would be resolved and get imported but the visualization //that referenced the saved search was not imported.( https://github.com/elastic/kibana/issues/22238) describe('mgmt saved objects', function describeIndexTests() { - beforeEach(async function () { - await esArchiver.emptyKibanaIndex(); - await esArchiver.load('test/functional/fixtures/es_archiver/discover'); + before(async () => { + await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); await PageObjects.settings.navigateTo(); }); - afterEach(async function () { - await esArchiver.unload('test/functional/fixtures/es_archiver/discover'); + after(async () => { + await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); + await kibanaServer.savedObjects.clean({ types: ['search', 'visualization'] }); }); it('should import saved objects mgmt', async function () { diff --git a/test/functional/apps/management/_runtime_fields.js b/test/functional/apps/management/_runtime_fields.js index 745a3f9b079a4..09fa924b0b870 100644 --- a/test/functional/apps/management/_runtime_fields.js +++ b/test/functional/apps/management/_runtime_fields.js @@ -9,7 +9,6 @@ import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { - const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const log = getService('log'); const browser = getService('browser'); @@ -23,16 +22,12 @@ export default function ({ getService, getPageObjects }) { before(async function () { await browser.setWindowSize(1200, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/discover'); - // delete .kibana index and then wait for Kibana to re-create it + await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); await kibanaServer.uiSettings.replace({}); - await kibanaServer.uiSettings.update({}); }); after(async function afterAll() { - await PageObjects.settings.navigateTo(); - await PageObjects.settings.clickKibanaIndexPatterns(); - await PageObjects.settings.removeLogstashIndexPatternIfExist(); + await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); }); describe('create runtime field', function describeIndexTests() { diff --git a/test/functional/apps/management/_scripted_fields.js b/test/functional/apps/management/_scripted_fields.js index 2ff9e55c59ebb..4aa06f4cd9ad7 100644 --- a/test/functional/apps/management/_scripted_fields.js +++ b/test/functional/apps/management/_scripted_fields.js @@ -25,7 +25,6 @@ import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { - const esArchiver = getService('esArchiver'); const kibanaServer = getService('kibanaServer'); const log = getService('log'); const browser = getService('browser'); @@ -46,16 +45,14 @@ export default function ({ getService, getPageObjects }) { before(async function () { await browser.setWindowSize(1200, 800); - await esArchiver.load('test/functional/fixtures/es_archiver/discover'); - // delete .kibana index and then wait for Kibana to re-create it + await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover'); await kibanaServer.uiSettings.replace({}); await kibanaServer.uiSettings.update({ 'doc_table:legacy': true }); }); after(async function afterAll() { - await PageObjects.settings.navigateTo(); - await PageObjects.settings.clickKibanaIndexPatterns(); - await PageObjects.settings.removeLogstashIndexPatternIfExist(); + await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover'); + await kibanaServer.uiSettings.replace({}); }); it('should not allow saving of invalid scripts', async function () { @@ -125,7 +122,7 @@ export default function ({ getService, getPageObjects }) { 'painless', 'number', null, - '1', + '100', script ); await retry.try(async function () { diff --git a/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap b/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap index 141d94e2b168f..c4658ae2ac22c 100644 --- a/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap +++ b/x-pack/plugins/apm/common/__snapshots__/elasticsearch_fieldnames.test.ts.snap @@ -304,7 +304,7 @@ exports[`Span ERROR_LOG_MESSAGE 1`] = `undefined`; exports[`Span ERROR_PAGE_URL 1`] = `undefined`; -exports[`Span EVENT_OUTCOME 1`] = `undefined`; +exports[`Span EVENT_OUTCOME 1`] = `"unknown"`; exports[`Span FCP_FIELD 1`] = `undefined`; @@ -541,7 +541,7 @@ exports[`Transaction ERROR_LOG_MESSAGE 1`] = `undefined`; exports[`Transaction ERROR_PAGE_URL 1`] = `undefined`; -exports[`Transaction EVENT_OUTCOME 1`] = `undefined`; +exports[`Transaction EVENT_OUTCOME 1`] = `"unknown"`; exports[`Transaction FCP_FIELD 1`] = `undefined`; diff --git a/x-pack/plugins/apm/common/elasticsearch_fieldnames.test.ts b/x-pack/plugins/apm/common/elasticsearch_fieldnames.test.ts index 6b24b43e9707d..debf75f79ec7e 100644 --- a/x-pack/plugins/apm/common/elasticsearch_fieldnames.test.ts +++ b/x-pack/plugins/apm/common/elasticsearch_fieldnames.test.ts @@ -30,6 +30,7 @@ describe('Transaction', () => { provider: 'gcp', region: 'europe-west1', }, + event: { outcome: 'unknown' }, http: { request: { method: 'GET' }, response: { status_code: 200 }, @@ -87,6 +88,7 @@ describe('Span', () => { provider: 'gcp', region: 'europe-west1', }, + event: { outcome: 'unknown' }, processor: { name: 'transaction', event: 'span', diff --git a/x-pack/plugins/apm/e2e/.gitignore b/x-pack/plugins/apm/e2e/.gitignore deleted file mode 100644 index 5042f0bca0300..0000000000000 --- a/x-pack/plugins/apm/e2e/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -cypress/screenshots/* -cypress/test-results -cypress/videos/* -/snapshots.js -tmp diff --git a/x-pack/plugins/apm/e2e/README.md b/x-pack/plugins/apm/e2e/README.md deleted file mode 100644 index 3517c74e950c7..0000000000000 --- a/x-pack/plugins/apm/e2e/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# End-To-End (e2e) Test for APM UI - -**Run E2E tests** - - -```sh -# In one terminal -node ./scripts/kibana --no-base-path --dev --no-dev-config --config x-pack/plugins/apm/e2e/ci/kibana.e2e.yml -# In another terminal -x-pack/plugins/apm/e2e/run-e2e.sh -``` - -Starts kibana, APM Server, Elasticsearch (with sample data) and runs the tests. - -If you see errors about not all events being ingested correctly try running `cd kibana/x-pack/plugins/apm/e2e/tmp/apm-integration-testing && docker-compose down -v` diff --git a/x-pack/plugins/apm/e2e/ci/kibana.e2e.yml b/x-pack/plugins/apm/e2e/ci/kibana.e2e.yml deleted file mode 100644 index 19f3f7c8978fa..0000000000000 --- a/x-pack/plugins/apm/e2e/ci/kibana.e2e.yml +++ /dev/null @@ -1,31 +0,0 @@ -# Kibana -server.port: 5701 -xpack.security.encryptionKey: 'something_at_least_32_characters' -csp.strict: false -logging.verbose: true - -# Elasticsearch -# Started via apm-integration-testing -# ./scripts/compose.py start master --no-kibana --elasticsearch-port 9201 --apm-server-port 8201 -elasticsearch.hosts: http://localhost:9201 -elasticsearch.username: 'kibana_system_user' -elasticsearch.password: 'changeme' - -# APM index pattern -apm_oss.indexPattern: apm-* - -# APM Indices -apm_oss.errorIndices: apm-*-error* -apm_oss.sourcemapIndices: apm-*-sourcemap -apm_oss.transactionIndices: apm-*-transaction* -apm_oss.spanIndices: apm-*-span* -apm_oss.metricsIndices: apm-*-metric* -apm_oss.onboardingIndices: apm-*-onboarding* - -# APM options -xpack.apm.enabled: true -xpack.apm.serviceMapEnabled: false -xpack.apm.autocreateApmIndexPattern: true -xpack.apm.ui.enabled: true -xpack.apm.ui.transactionGroupBucketSize: 100 -xpack.apm.ui.maxTraceItems: 1000 diff --git a/x-pack/plugins/apm/e2e/ci/prepare-kibana.sh b/x-pack/plugins/apm/e2e/ci/prepare-kibana.sh deleted file mode 100755 index 9e6198bcc526d..0000000000000 --- a/x-pack/plugins/apm/e2e/ci/prepare-kibana.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash -set -e - -E2E_DIR=x-pack/plugins/apm/e2e -echo "1/2 Install dependencies..." -# shellcheck disable=SC1091 -source src/dev/ci_setup/setup_env.sh true -yarn kbn bootstrap - -echo "2/2 Start Kibana..." -## Might help to avoid FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory -export NODE_OPTIONS="--max-old-space-size=4096" -nohup node ./scripts/kibana --no-base-path --no-watch --dev --no-dev-config --config ${E2E_DIR}/ci/kibana.e2e.yml > ${E2E_DIR}/kibana.log 2>&1 & diff --git a/x-pack/plugins/apm/e2e/ci/run-e2e.sh b/x-pack/plugins/apm/e2e/ci/run-e2e.sh deleted file mode 100755 index c40ab5d646477..0000000000000 --- a/x-pack/plugins/apm/e2e/ci/run-e2e.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash -## -## This is a wrapper to configure the environment with the right tools in the CI -## and run the e2e steps. -## - -E2E_DIR="${0%/*}/.." -# shellcheck disable=SC1091 -source src/dev/ci_setup/setup_env.sh true -set -ex -"${E2E_DIR}"/run-e2e.sh diff --git a/x-pack/plugins/apm/e2e/cypress.json b/x-pack/plugins/apm/e2e/cypress.json deleted file mode 100644 index 19e09e6ad5bbf..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "nodeVersion": "system", - "baseUrl": "http://localhost:5701", - "trashAssetsBeforeRuns": false, - "fileServerFolder": "../", - "fixturesFolder": "./cypress/fixtures", - "integrationFolder": "./cypress/integration", - "pluginsFile": "./cypress/plugins/index.js", - "screenshotsFolder": "./cypress/screenshots", - "supportFile": "./cypress/support/index.ts", - "video": true, - "videoCompression": false, - "videosFolder": "./cypress/videos", - "useRelativeSnapshots": true, - "reporter": "junit", - "reporterOptions": { - "mochaFile": "./cypress/test-results/[hash]-e2e-tests.xml", - "toConsole": false - }, - "testFiles": "**/*.{feature,features}", - "env": { - "elasticsearch_username": "admin", - "elasticsearch_password": "changeme" - }, - "viewportWidth": 1920, - "viewportHeight": 1080 -} diff --git a/x-pack/plugins/apm/e2e/cypress/fixtures/example.json b/x-pack/plugins/apm/e2e/cypress/fixtures/example.json deleted file mode 100644 index da18d9352a17d..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} \ No newline at end of file diff --git a/x-pack/plugins/apm/e2e/cypress/integration/csm_dashboard.feature b/x-pack/plugins/apm/e2e/cypress/integration/csm_dashboard.feature deleted file mode 100644 index 0028f40a68d90..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/integration/csm_dashboard.feature +++ /dev/null @@ -1,34 +0,0 @@ -Feature: CSM Dashboard - - Scenario: Client metrics - When a user browses the APM UI application for RUM Data - Then should have correct client metrics - - Scenario: JS Errors - When a user browses the APM UI application for RUM Data - Then it displays list of relevant js errors - - Scenario: Percentile select - When the user changes the selected percentile - Then it displays client metric related to that percentile - - Scenario Outline: CSM page filters - When the user filters by "" - Then it filters the client metrics "" - Examples: - | filterName | - | OS | - | Location | - - Scenario: Display CSM Data components - When a user browses the APM UI application for RUM Data - Then should display percentile for page load chart - And should display tooltip on hover - - Scenario: Search by url filter focus - When a user clicks inside url search field - Then it displays top pages in the suggestion popover - - Scenario: Search by url filter - When a user enters a query in url search field - Then it should filter results based on query diff --git a/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts b/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts deleted file mode 100644 index 333f047b72658..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/integration/helpers.ts +++ /dev/null @@ -1,36 +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. - */ - -const BASE_URL = Cypress.config().baseUrl; - -/** The default time in ms to wait for a Cypress command to complete */ -export const DEFAULT_TIMEOUT = 60 * 1000; - -export function loginAndWaitForPage( - url: string, - dateRange: { to: string; from: string }, - selectedService?: string -) { - const username = Cypress.env('elasticsearch_username'); - const password = Cypress.env('elasticsearch_password'); - - cy.log(`Authenticating via ${username} / ${password}`); - - let fullUrl = `${BASE_URL}${url}?rangeFrom=${dateRange.from}&rangeTo=${dateRange.to}`; - - if (selectedService) { - fullUrl += `&serviceName=${selectedService}`; - } - cy.visit(fullUrl, { auth: { username, password } }); - - cy.viewport('macbook-15'); - - // wait for loading spinner to disappear - cy.get('#kbn_loading_message', { timeout: DEFAULT_TIMEOUT }).should( - 'not.exist' - ); -} diff --git a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js b/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js deleted file mode 100644 index fc390a64de28c..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - "__version": "6.8.0" -} diff --git a/x-pack/plugins/apm/e2e/cypress/plugins/index.js b/x-pack/plugins/apm/e2e/cypress/plugins/index.js deleted file mode 100644 index bec342118ed5b..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/plugins/index.js +++ /dev/null @@ -1,43 +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. - */ - -// *********************************************************** -// This example plugins/index.js can be used to load plugins -// -// You can change the location of this file or turn off loading -// the plugins file with the 'pluginsFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/plugins-guide -// *********************************************************** - -// This function is called when a project is opened or re-opened (e.g. due to -// the project's config changing) - -// eslint-disable-next-line import/no-extraneous-dependencies -const wp = require('@cypress/webpack-preprocessor'); -const fs = require('fs'); - -module.exports = (on) => { - const options = { - webpackOptions: require('../webpack.config.js'), - }; - on('file:preprocessor', wp(options)); - - // readFileMaybe - on('task', { - // ESLint thinks this is a react component for some reason. - // eslint-disable-next-line react/function-component-definition - readFileMaybe(filename) { - if (fs.existsSync(filename)) { - return fs.readFileSync(filename, 'utf8'); - } - - return null; - }, - }); -}; diff --git a/x-pack/plugins/apm/e2e/cypress/support/commands.js b/x-pack/plugins/apm/e2e/cypress/support/commands.js deleted file mode 100644 index 73895fbbec589..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/commands.js +++ /dev/null @@ -1,32 +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. - */ - -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add("login", (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This is will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/x-pack/plugins/apm/e2e/cypress/support/index.ts b/x-pack/plugins/apm/e2e/cypress/support/index.ts deleted file mode 100644 index 020156fb27915..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/index.ts +++ /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. - */ - -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -import './commands'; - -// @ts-expect-error -import { register } from '@cypress/snapshot'; - -register(); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/breakdown_filter.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/breakdown_filter.ts deleted file mode 100644 index 5b4934eac1f71..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/breakdown_filter.ts +++ /dev/null @@ -1,43 +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 { Given, When, Then } from 'cypress-cucumber-preprocessor/steps'; -import { DEFAULT_TIMEOUT } from './csm_dashboard'; -import { waitForLoadingToFinish } from './utils'; - -/** The default time in ms to wait for a Cypress command to complete */ - -Given(`a user clicks the page load breakdown filter`, () => { - waitForLoadingToFinish(); - cy.get('.euiStat__title-isLoading').should('not.exist'); - const breakDownBtn = cy.get( - '[data-test-subj=pldBreakdownFilter]', - DEFAULT_TIMEOUT - ); - breakDownBtn.click(); -}); - -When(`the user selected the breakdown`, () => { - cy.get('[id="user_agent.name"]', DEFAULT_TIMEOUT).click(); - // click outside popover to close it - cy.get('[data-cy=pageLoadDist]').click(); -}); - -Then(`breakdown series should appear in chart`, () => { - cy.get('.euiLoadingChart').should('not.exist'); - - cy.get('[data-cy=pageLoadDist]').within(() => { - cy.get('button.echLegendItem__label[title=Chrome] ', DEFAULT_TIMEOUT) - .invoke('text') - .should('eq', 'Chrome'); - - cy.get('button.echLegendItem__label', DEFAULT_TIMEOUT).should( - 'have.text', - 'ChromeChrome Mobile WebViewSafariFirefoxMobile SafariChrome MobileChrome Mobile iOSOverall' - ); - }); -}); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/client_metrics_helper.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/client_metrics_helper.ts deleted file mode 100644 index 1ff6ccd423070..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/client_metrics_helper.ts +++ /dev/null @@ -1,36 +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 { DEFAULT_TIMEOUT } from './csm_dashboard'; -import { waitForLoadingToFinish } from './utils'; - -/** - * Verifies the behavior of the client metrics component - * @param metrics array of three elements - * @param checkTitleStatus if it's needed to check title elements - */ -export function verifyClientMetrics( - metrics: string[], - checkTitleStatus: boolean -) { - const clientMetricsSelector = '[data-cy=client-metrics] .euiStat__title'; - - waitForLoadingToFinish(); - - if (checkTitleStatus) { - cy.get('.euiStat__title', DEFAULT_TIMEOUT).should('be.visible'); - cy.get('.euiSelect-isLoading').should('not.exist'); - } - - cy.get('.euiStat__title-isLoading').should('not.exist'); - - cy.get(clientMetricsSelector).eq(0).should('have.text', metrics[0]); - - cy.get(clientMetricsSelector).eq(1).should('have.text', metrics[1]); - - cy.get(clientMetricsSelector).eq(2).should('have.text', metrics[2]); -} diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts deleted file mode 100644 index 47154ee214dc4..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts +++ /dev/null @@ -1,77 +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 { Given, Then } from 'cypress-cucumber-preprocessor/steps'; -import { loginAndWaitForPage } from '../../../integration/helpers'; -import { verifyClientMetrics } from './client_metrics_helper'; -import { waitForLoadingToFinish } from './utils'; - -/** The default time in ms to wait for a Cypress command to complete */ -export const DEFAULT_TIMEOUT = { timeout: 60 * 1000 }; - -Given(`a user browses the APM UI application for RUM Data`, () => { - // Open UX landing page - const RANGE_FROM = 'now-24h'; - const RANGE_TO = 'now'; - loginAndWaitForPage( - `/app/ux`, - { - from: RANGE_FROM, - to: RANGE_TO, - }, - 'client' - ); -}); - -Then(`should have correct client metrics`, () => { - const metrics = ['80 ms', '4 ms', '76 ms', '55']; - - verifyClientMetrics(metrics, true); -}); - -Then(`should display percentile for page load chart`, () => { - const pMarkers = '[data-cy=percentile-markers] span'; - - cy.get('.euiLoadingChart', DEFAULT_TIMEOUT).should('be.visible'); - - waitForLoadingToFinish(); - - cy.get('.euiStat__title-isLoading').should('not.exist'); - - cy.get(pMarkers).eq(0).should('have.text', '50th'); - - cy.get(pMarkers).eq(1).should('have.text', '75th'); - - cy.get(pMarkers).eq(2).should('have.text', '90th'); - - cy.get(pMarkers).eq(3).should('have.text', '95th'); -}); - -Then(`should display chart legend`, () => { - const chartLegend = 'button.echLegendItem__label'; - - waitForLoadingToFinish(); - cy.get('.euiLoadingChart').should('not.exist'); - - cy.get('[data-cy=pageLoadDist]').within(() => { - cy.get(chartLegend, DEFAULT_TIMEOUT).eq(0).should('have.text', 'Overall'); - }); -}); - -Then(`should display tooltip on hover`, () => { - cy.get('.euiLoadingChart').should('not.exist'); - - const pMarkers = '[data-cy=percentile-markers] span.euiToolTipAnchor'; - - waitForLoadingToFinish(); - cy.get('.euiLoadingChart').should('not.exist'); - - const marker = cy.get(pMarkers, DEFAULT_TIMEOUT).eq(0); - marker.invoke('show'); - marker.trigger('mouseover', { force: true }); - cy.get('span[data-cy=percentileTooltipTitle]').should('be.visible'); -}); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts deleted file mode 100644 index 168976d96ddc7..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts +++ /dev/null @@ -1,65 +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 { When, Then } from 'cypress-cucumber-preprocessor/steps'; -import { DEFAULT_TIMEOUT } from './csm_dashboard'; -import { verifyClientMetrics } from './client_metrics_helper'; -import { waitForLoadingToFinish } from './utils'; - -When(/^the user filters by "([^"]*)"$/, (filterName) => { - waitForLoadingToFinish(); - cy.get('.euiStat__title-isLoading').should('not.exist'); - - cy.get( - `button[aria-label="expands filter group for ${filterName} filter"]` - ).click(); - - cy.get(`.euiPopover__panel-isOpen`, DEFAULT_TIMEOUT).within(() => { - if (filterName === 'OS') { - const osItem = cy.get('li.euiSelectableListItem', DEFAULT_TIMEOUT).eq(2); - osItem.should('have.text', 'Mac OS X24 '); - osItem.click(); - - // sometimes click doesn't work as expected so we need to retry here - osItem.invoke('attr', 'aria-selected').then((val) => { - if (val === 'false') { - cy.get('li.euiSelectableListItem', DEFAULT_TIMEOUT).eq(2).click(); - } - }); - } else { - const deItem = cy.get('li.euiSelectableListItem', DEFAULT_TIMEOUT).eq(0); - deItem.should('have.text', 'DE84 '); - deItem.click(); - - // sometimes click doesn't work as expected so we need to retry here - deItem.invoke('attr', 'aria-selected').then((val) => { - if (val === 'false') { - cy.get('li.euiSelectableListItem', DEFAULT_TIMEOUT).eq(0).click(); - } - }); - } - cy.contains('Apply').click(); - }); - - cy.get(`.globalFilterLabel__value`, DEFAULT_TIMEOUT).contains( - filterName === 'OS' ? 'Mac OS X' : 'DE' - ); -}); - -Then(/^it filters the client metrics "([^"]*)"$/, (filterName) => { - waitForLoadingToFinish(); - cy.get('.euiStat__title-isLoading').should('not.exist'); - - const data = - filterName === 'OS' - ? ['82 ms', '5 ms', '77 ms', '8'] - : ['75 ms', '4 ms', '71 ms', '28']; - - verifyClientMetrics(data, true); - - cy.get('[data-cy=clearFilters]', DEFAULT_TIMEOUT).click(); -}); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/js_errors.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/js_errors.ts deleted file mode 100644 index 6bffb96be7f4a..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/js_errors.ts +++ /dev/null @@ -1,24 +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 { Then } from 'cypress-cucumber-preprocessor/steps'; -import { DEFAULT_TIMEOUT } from './csm_dashboard'; -import { getDataTestSubj } from './utils'; - -Then(`it displays list of relevant js errors`, () => { - cy.get('.euiBasicTable-loading').should('not.exist'); - cy.get('.euiStat__title-isLoading').should('not.exist'); - - getDataTestSubj('uxJsErrorsTotal').should('have.text', 'Total errors112'); - - getDataTestSubj('uxJsErrorTable').within(() => { - cy.get('tr.euiTableRow', DEFAULT_TIMEOUT) - .eq(0) - .invoke('text') - .should('eq', 'Error messageTest CaptureErrorImpacted page loads100.0 %'); - }); -}); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts deleted file mode 100644 index 22e6210590192..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts +++ /dev/null @@ -1,22 +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 { When, Then } from 'cypress-cucumber-preprocessor/steps'; -import { verifyClientMetrics } from './client_metrics_helper'; -import { getDataTestSubj } from './utils'; - -When('the user changes the selected percentile', () => { - getDataTestSubj('uxPercentileSelect').select('95'); -}); - -Then(`it displays client metric related to that percentile`, () => { - const metrics = ['165 ms', '14 ms', '151 ms', '55']; - - verifyClientMetrics(metrics, false); - - getDataTestSubj('uxPercentileSelect').select('50'); -}); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts deleted file mode 100644 index 26c3fade5afaa..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts +++ /dev/null @@ -1,22 +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 { When, Then } from 'cypress-cucumber-preprocessor/steps'; -import { verifyClientMetrics } from './client_metrics_helper'; -import { DEFAULT_TIMEOUT } from './csm_dashboard'; -import { waitForLoadingToFinish } from './utils'; - -When('the user changes the selected service name', () => { - waitForLoadingToFinish(); - cy.get(`[data-cy=serviceNameFilter]`, DEFAULT_TIMEOUT).select('client'); -}); - -Then(`it displays relevant client metrics`, () => { - const metrics = ['80 ms', '4 ms', '76 ms', '55']; - - verifyClientMetrics(metrics, false); -}); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/url_search_filter.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/url_search_filter.ts deleted file mode 100644 index a277ff5a9a136..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/url_search_filter.ts +++ /dev/null @@ -1,66 +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 { When, Then } from 'cypress-cucumber-preprocessor/steps'; -import { DEFAULT_TIMEOUT } from './csm_dashboard'; -import { waitForLoadingToFinish } from './utils'; - -When(`a user clicks inside url search field`, () => { - waitForLoadingToFinish(); - cy.get('.euiStat__title-isLoading').should('not.exist'); - cy.get('span[data-cy=csmUrlFilter]', DEFAULT_TIMEOUT).within(() => { - cy.get('input.euiFieldSearch').click(); - }); -}); - -Then(`it displays top pages in the suggestion popover`, () => { - waitForLoadingToFinish(); - - cy.get('div.euiPopover__panel-isOpen', DEFAULT_TIMEOUT).within(() => { - const listOfUrls = cy.get('li.euiSelectableListItem'); - listOfUrls.should('have.length', 5); - - const actualUrlsText = [ - 'http://opbeans-node:3000/dashboardTotal page views: 17Page load duration: 109 ms (median)', - 'http://opbeans-node:3000/ordersTotal page views: 14Page load duration: 72 ms (median)', - ]; - - cy.get('li.euiSelectableListItem') - .eq(0) - .should('have.text', actualUrlsText[0]); - cy.get('li.euiSelectableListItem') - .eq(1) - .should('have.text', actualUrlsText[1]); - }); -}); - -When(`a user enters a query in url search field`, () => { - waitForLoadingToFinish(); - - cy.get('[data-cy=csmUrlFilter]').within(() => { - cy.get('input.euiSelectableSearch').type('cus'); - }); - - waitForLoadingToFinish(); -}); - -Then(`it should filter results based on query`, () => { - waitForLoadingToFinish(); - - cy.get('div.euiPopover__panel-isOpen', DEFAULT_TIMEOUT).within(() => { - const listOfUrls = cy.get('li.euiSelectableListItem'); - listOfUrls.should('have.length', 1); - - const actualUrlsText = [ - 'http://opbeans-node:3000/customersTotal page views: 10Page load duration: 76 ms (median)', - ]; - - cy.get('li.euiSelectableListItem') - .eq(0) - .should('have.text', actualUrlsText[0]); - }); -}); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/utils.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/utils.ts deleted file mode 100644 index 962f36978d87b..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/utils.ts +++ /dev/null @@ -1,18 +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 { DEFAULT_TIMEOUT } from './csm_dashboard'; - -export function waitForLoadingToFinish() { - cy.get('[data-test-subj=globalLoadingIndicator-hidden]', DEFAULT_TIMEOUT); -} - -export function getDataTestSubj(dataTestSubj: string) { - waitForLoadingToFinish(); - - return cy.get(`[data-test-subj=${dataTestSubj}]`, DEFAULT_TIMEOUT); -} diff --git a/x-pack/plugins/apm/e2e/cypress/webpack.config.js b/x-pack/plugins/apm/e2e/cypress/webpack.config.js deleted file mode 100644 index afeb527cd6b08..0000000000000 --- a/x-pack/plugins/apm/e2e/cypress/webpack.config.js +++ /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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -module.exports = { - resolve: { - extensions: ['.ts', '.js'], - symlinks: false, - }, - node: { fs: 'empty', child_process: 'empty', readline: 'empty' }, - module: { - rules: [ - { - test: /\.ts$/, - exclude: [/node_modules/], - include: [/e2e\/cypress/], - use: [ - { - loader: 'ts-loader', - }, - ], - }, - { - test: /\.feature$/, - use: [ - { - loader: 'cypress-cucumber-preprocessor/loader', - }, - ], - }, - { - test: /\.features$/, - use: [ - { - loader: 'cypress-cucumber-preprocessor/lib/featuresLoader', - }, - ], - }, - ], - }, -}; diff --git a/x-pack/plugins/apm/e2e/ingest-data/replay.js b/x-pack/plugins/apm/e2e/ingest-data/replay.js deleted file mode 100644 index 7cda2a8064f7f..0000000000000 --- a/x-pack/plugins/apm/e2e/ingest-data/replay.js +++ /dev/null @@ -1,173 +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. - */ - -/* eslint-disable no-console */ - -/* eslint-disable import/no-extraneous-dependencies */ - -/** - * This script is useful for ingesting previously generated APM data into Elasticsearch via APM Server - * - * You can either: - * 1. Download a static test data file from: https://storage.googleapis.com/apm-ui-e2e-static-data/events.json - * 2. Or, generate the test data file yourself: - * git clone https://github.com/elastic/apm-integration-testing.git - * ./scripts/compose.py start master --no-kibana --with-opbeans-node --apm-server-record - * docker cp localtesting_8.0.0_apm-server-2:/app/events.json . && cat events.json | wc -l - * - * - * - * Run the script: - * - * node replay.js --server-url --secret-token --events ./events.json - * - ************/ - -const { promisify } = require('util'); -const fs = require('fs'); -const path = require('path'); -const axios = require('axios'); -const readFile = promisify(fs.readFile); -const pLimit = require('p-limit'); -const pRetry = require('p-retry'); -const { argv } = require('yargs'); -const ora = require('ora'); -const userAgents = require('./user_agents'); -const userIps = require('./rum_ips'); - -const APM_SERVER_URL = argv.serverUrl; -const SECRET_TOKEN = argv.secretToken; -const EVENTS_PATH = argv.events; - -if (!APM_SERVER_URL) { - console.log('`--server-url` is required'); - process.exit(1); -} - -if (!EVENTS_PATH) { - console.log('`--events` is required'); - process.exit(1); -} - -const requestProgress = { - succeeded: 0, - failed: 0, - total: 0, -}; - -const spinner = ora({ text: 'Warming up...', stream: process.stdout }); - -function incrementSpinnerCount({ success }) { - success ? requestProgress.succeeded++ : requestProgress.failed++; - const remaining = - requestProgress.total - - (requestProgress.succeeded + requestProgress.failed); - - spinner.text = `Remaining: ${remaining}. Succeeded: ${requestProgress.succeeded}. Failed: ${requestProgress.failed}.`; -} -let iterIndex = 0; - -function setItemMetaAndHeaders(item) { - const headers = { - 'content-type': 'application/x-ndjson', - }; - - if (SECRET_TOKEN) { - headers.Authorization = `Bearer ${SECRET_TOKEN}`; - } - - if (item.url === '/intake/v2/rum/events') { - if (iterIndex === userAgents.length) { - // set some event agent to opbean - setRumAgent(item); - iterIndex = 0; - } - headers['User-Agent'] = userAgents[iterIndex]; - headers['X-Forwarded-For'] = userIps[iterIndex]; - iterIndex++; - } - return headers; -} - -function setRumAgent(item) { - if (item.body) { - item.body = item.body.replace( - '"name":"client"', - '"name":"elastic-frontend"' - ); - } -} - -async function insertItem(item, headers) { - try { - const url = `${APM_SERVER_URL}${item.url}`; - - await axios({ - method: item.method, - url, - headers, - data: item.body, - }); - } catch (e) { - console.error( - `${e.response ? JSON.stringify(e.response.data) : e.message}` - ); - throw e; - } -} - -async function init() { - const content = await readFile(path.resolve(EVENTS_PATH)); - const items = content - .toString() - .split('\n') - .filter((item) => item) - .map((item) => JSON.parse(item)) - .filter((item) => { - return ( - item.url === '/intake/v2/events' || item.url === '/intake/v2/rum/events' - ); - }); - - spinner.start(); - requestProgress.total = items.length; - - const limit = pLimit(20); // number of concurrent requests - await Promise.all( - items.map(async (item) => { - try { - const headers = setItemMetaAndHeaders(item); - // retry 5 times with exponential backoff - await pRetry(() => limit(() => insertItem(item, headers)), { - retries: 5, - }); - incrementSpinnerCount({ success: true }); - } catch (e) { - incrementSpinnerCount({ success: false }); - } - }) - ); -} - -init() - .then(() => { - if (requestProgress.succeeded === requestProgress.total) { - spinner.succeed( - `Successfully ingested ${requestProgress.succeeded} of ${requestProgress.total} events` - ); - process.exit(0); - } else { - spinner.fail( - `Ingested ${requestProgress.succeeded} of ${requestProgress.total} events` - ); - process.exit(1); - } - }) - .catch((e) => { - console.log('An error occurred:', e); - process.exit(1); - }); diff --git a/x-pack/plugins/apm/e2e/ingest-data/rum_ips.js b/x-pack/plugins/apm/e2e/ingest-data/rum_ips.js deleted file mode 100644 index 43bb01a7a23f5..0000000000000 --- a/x-pack/plugins/apm/e2e/ingest-data/rum_ips.js +++ /dev/null @@ -1,20 +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. - */ - -const IPS = [ - '89.191.86.214', // check24.de - '167.40.79.24', // canada.ca - '151.101.130.217', // elastic.co - '185.143.68.17', - '151.101.130.217', - '185.143.68.17', - '185.143.68.17', - '151.101.130.217', - '185.143.68.17', -]; - -module.exports = IPS; diff --git a/x-pack/plugins/apm/e2e/ingest-data/user_agents.js b/x-pack/plugins/apm/e2e/ingest-data/user_agents.js deleted file mode 100644 index f8829875bc79e..0000000000000 --- a/x-pack/plugins/apm/e2e/ingest-data/user_agents.js +++ /dev/null @@ -1,24 +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. - */ - -/* eslint-disable no-console */ - -/* eslint-disable import/no-extraneous-dependencies */ - -const UserAgents = [ - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36', - 'Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36', - 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/69.0.3497.105 Mobile/15E148 Safari/605.1', - 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1', - 'Mozilla/5.0 (Linux; Android 7.0; Pixel C Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Safari/537.36', - 'Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.64 Safari/537.36', - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9', - 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:15.0) Gecko/20100101 Firefox/15.0.1', - 'Mozilla/5.0 (CrKey armv7l 1.5.16041) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.0 Safari/537.36', -]; - -module.exports = UserAgents; diff --git a/x-pack/plugins/apm/e2e/run-e2e.sh b/x-pack/plugins/apm/e2e/run-e2e.sh deleted file mode 100755 index 1b3afb4823426..0000000000000 --- a/x-pack/plugins/apm/e2e/run-e2e.sh +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/env bash - -# variables -KIBANA_PORT=5701 -ELASTICSEARCH_PORT=9201 -APM_SERVER_PORT=8201 - -# ensure Docker is running -docker ps &> /dev/null -if [ $? -ne 0 ]; then - echo "⚠️ Please start Docker" - exit 1 -fi - -# formatting -bold=$(tput bold) -normal=$(tput sgr0) - -# paths -E2E_DIR="${0%/*}" -TMP_DIR="tmp" -APM_IT_DIR="tmp/apm-integration-testing" -WAIT_ON_BIN="../../../../node_modules/.bin/wait-on" -CYPRESS_BIN="../../../../node_modules/.bin/cypress" - -cd ${E2E_DIR} - -KIBANA_VERSION=$(node -p "require('../../../package.json').version") - -# -# Ask user to start Kibana -################################################## -echo "" # newline -echo "${bold}To start Kibana please run the following command:${normal} -node ./scripts/kibana --no-base-path --dev --no-dev-config --config x-pack/plugins/apm/e2e/ci/kibana.e2e.yml" - -# -# Create tmp folder -################################################## -echo "" # newline -echo "${bold}Temporary folder${normal}" -echo "Temporary files will be stored in: ${E2E_DIR}${TMP_DIR}" -mkdir -p ${TMP_DIR} - -# -# apm-integration-testing -################################################## -echo "" # newline -echo "${bold}apm-integration-testing (logs: ${E2E_DIR}${TMP_DIR}/apm-it.log)${normal}" - -# pull if folder already exists -if [ -d ${APM_IT_DIR} ]; then - echo "Pulling from master..." - git -C ${APM_IT_DIR} pull &> ${TMP_DIR}/apm-it.log - -# clone if folder does not exists -else - echo "Cloning repository" - git clone "https://github.com/elastic/apm-integration-testing.git" ${APM_IT_DIR} &> ${TMP_DIR}/apm-it.log -fi - -# Stop if clone/pull failed -if [ $? -ne 0 ]; then - echo "⚠️ Initializing apm-integration-testing failed." - exit 1 -fi - -# Start apm-integration-testing -echo "Starting docker-compose" -echo "Using stack version: ${KIBANA_VERSION}" -${APM_IT_DIR}/scripts/compose.py start $KIBANA_VERSION \ - --no-kibana \ - --elasticsearch-port $ELASTICSEARCH_PORT \ - --apm-server-port=$APM_SERVER_PORT \ - --elasticsearch-heap 4g \ - --apm-server-opt queue.mem.events=8192 \ - --apm-server-opt output.elasticsearch.bulk_max_size=4096 \ - &> ${TMP_DIR}/apm-it.log - -# Stop if apm-integration-testing failed to start correctly -if [ $? -ne 0 ]; then - echo "⚠️ apm-integration-testing could not be started" - echo "" # newline - echo "As a last resort, reset docker with:" - echo "" # newline - echo "cd ${E2E_DIR}${APM_IT_DIR} && scripts/compose.py stop && docker system prune --all --force --volumes" - echo "" # newline - - # output logs for excited docker containers - cd ${APM_IT_DIR} && docker-compose ps --filter "status=exited" -q | xargs -L1 docker logs --tail=10 && cd - - - echo "" # newline - echo "Find the full logs in ${E2E_DIR}${TMP_DIR}/apm-it.log" - exit 1 -fi - -# -# Static mock data -################################################## -echo "" # newline -echo "${bold}Static mock data (logs: ${E2E_DIR}${TMP_DIR}/ingest-data.log)${normal}" - -STATIC_MOCK_FILENAME='2020-06-12.json' - -# Download static data if not already done -if [ ! -e "${TMP_DIR}/${STATIC_MOCK_FILENAME}" ]; then - echo "Downloading ${STATIC_MOCK_FILENAME}..." - curl --silent https://storage.googleapis.com/apm-ui-e2e-static-data/${STATIC_MOCK_FILENAME} --output ${TMP_DIR}/${STATIC_MOCK_FILENAME} -fi - -# echo "Deleting existing indices (apm* and .apm*)" -curl --silent --user admin:changeme -XDELETE "localhost:${ELASTICSEARCH_PORT}/.apm*" > /dev/null -curl --silent --user admin:changeme -XDELETE "localhost:${ELASTICSEARCH_PORT}/apm*" > /dev/null - -# Ingest data into APM Server -node ingest-data/replay.js --server-url http://localhost:$APM_SERVER_PORT --events ${TMP_DIR}/${STATIC_MOCK_FILENAME} 2>> ${TMP_DIR}/ingest-data.log - -# Abort if not all events were ingested correctly -if [ $? -ne 0 ]; then - echo "⚠️ Not all events were ingested correctly. This might affect test tests." - echo "Aborting. Please try again." - echo "" # newline - echo "Full logs in ${E2E_DIR}${TMP_DIR}/ingest-data.log:" - - # output logs for excited docker containers - cd ${APM_IT_DIR} && docker-compose ps --filter "status=exited" -q | xargs -L1 docker logs --tail=3 && cd - - - # stop docker containers - cd ${APM_IT_DIR} && ./scripts/compose.py stop > /dev/null && cd - - exit 1 -fi - -# create empty snapshot file if it doesn't exist -SNAPSHOTS_FILE=cypress/integration/snapshots.js -if [ ! -f ${SNAPSHOTS_FILE} ]; then - echo "{}" > ${SNAPSHOTS_FILE} -fi - -# -# Wait for Kibana to start -################################################## -echo "" # newline -echo "${bold}Waiting for Kibana to start...${normal}" -echo "Note: you need to start Kibana manually. Find the instructions at the top." -$WAIT_ON_BIN -i 500 -w 500 http-get://admin:changeme@localhost:$KIBANA_PORT/api/status > /dev/null - -## Workaround to wait for the http server running -## See: https://github.com/elastic/kibana/issues/66326 -if [ -e kibana.log ] ; then - grep -m 1 "Kibana is now available" <(tail -f -n +1 kibana.log) - echo "✅ Kibana server running..." - grep -m 1 "bundles compiled successfully" <(tail -f -n +1 kibana.log) - echo "✅ Kibana bundles have been compiled..." -fi - - -echo "✅ Setup completed successfully. Running tests..." - -# -# run cypress tests -################################################## -$CYPRESS_BIN run --config pageLoadTimeout=100000,watchForFileChanges=true -e2e_status=$? - -# -# Run interactively -################################################## -echo "${bold}If you want to run the test interactively, run:${normal}" -echo "" # newline -echo "cd ${E2E_DIR} && ${CYPRESS_BIN} open --config pageLoadTimeout=100000,watchForFileChanges=true" - -# Report the e2e status at the very end -if [ $e2e_status -ne 0 ]; then - echo "⚠️ Running tests failed." - exit 1 -fi diff --git a/x-pack/plugins/apm/e2e/tsconfig.json b/x-pack/plugins/apm/e2e/tsconfig.json deleted file mode 100644 index 2560a15df9224..0000000000000 --- a/x-pack/plugins/apm/e2e/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../../../tsconfig.base.json", - "include": ["**/*"], - "exclude": ["tmp", "target/**/*"], - "compilerOptions": { - "outDir": "target/types", - "types": ["cypress", "node"] - } -} diff --git a/x-pack/plugins/apm/jest.config.js b/x-pack/plugins/apm/jest.config.js index 77639cb58d497..4fd2e72776943 100644 --- a/x-pack/plugins/apm/jest.config.js +++ b/x-pack/plugins/apm/jest.config.js @@ -12,7 +12,6 @@ module.exports = { rootDir: path.resolve(__dirname, '../../..'), roots: ['/x-pack/plugins/apm'], setupFiles: ['/x-pack/plugins/apm/.storybook/jest_setup.js'], - testPathIgnorePatterns: ['/x-pack/plugins/apm/e2e/'], coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/apm', coverageReporters: ['text', 'html'], collectCoverageFrom: [ diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ImpactfulMetrics/JSErrors.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/ImpactfulMetrics/JSErrors.tsx index a7b1d99072d26..c8956c091d267 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/ImpactfulMetrics/JSErrors.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/ImpactfulMetrics/JSErrors.tsx @@ -16,9 +16,10 @@ import { EuiToolTip, } from '@elastic/eui'; import numeral from '@elastic/numeral'; +import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { useUrlParams } from '../../../../context/url_params_context/use_url_params'; -import { useFetcher } from '../../../../hooks/use_fetcher'; +import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; import { I18LABELS } from '../translations'; import { CsmSharedContext } from '../CsmSharedContext'; import { ErrorDetailLink } from '../../../shared/Links/apm/ErrorDetailLink'; @@ -125,14 +126,21 @@ export function JSErrors() { ) } description={I18LABELS.totalErrors} - isLoading={status !== 'success'} + isLoading={status === FETCH_STATUS.LOADING} /> ({ status === FETCH_STATUS.LOADING ? loadingText : noDataText } loading={status === FETCH_STATUS.LOADING} + error={status === FETCH_STATUS.FAILURE ? errorMessage : ''} columns={columns} rowProps={(term) => { return { @@ -121,3 +122,8 @@ const noDataText = i18n.translate( 'xpack.apm.correlations.correlationsTable.noDataText', { defaultMessage: 'No data' } ); + +const errorMessage = i18n.translate( + 'xpack.apm.correlations.correlationsTable.errorMessage', + { defaultMessage: 'Failed to fetch' } +); diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx index 2cdb808622854..0b505c4f5ade8 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx @@ -5,7 +5,12 @@ * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiLink, + EuiEmptyPrompt, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { useEffect } from 'react'; import uuid from 'uuid'; @@ -20,7 +25,6 @@ import { useTimeRange } from '../../../hooks/use_time_range'; import { useUpgradeAssistantHref } from '../../shared/Links/kibana'; import { SearchBar } from '../../shared/search_bar'; import { getTimeRangeComparison } from '../../shared/time_comparison/get_time_range_comparison'; -import { NoServicesMessage } from './no_services_message'; import { ServiceList } from './service_list'; import { MLCallout } from './service_list/MLCallout'; @@ -179,6 +183,21 @@ export function ServiceInventory() { canCreateJob && !userHasDismissedCallout; + const isLoading = mainStatisticsStatus === FETCH_STATUS.LOADING; + const isFailure = mainStatisticsStatus === FETCH_STATUS.FAILURE; + const noItemsMessage = ( + + {i18n.translate('xpack.apm.servicesTable.notFoundLabel', { + defaultMessage: 'No services found', + })} +
+ } + titleSize="s" + /> + ); + return ( <> @@ -190,10 +209,11 @@ export function ServiceInventory() { )} } + noItemsMessage={noItemsMessage} /> diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.test.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.test.tsx deleted file mode 100644 index 3a3ddcc558679..0000000000000 --- a/x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.test.tsx +++ /dev/null @@ -1,34 +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 { render } from '@testing-library/react'; -import React, { ReactNode } from 'react'; -import { MockApmPluginContextWrapper } from '../../../context/apm_plugin/mock_apm_plugin_context'; -import { FETCH_STATUS } from '../../../hooks/use_fetcher'; -import { NoServicesMessage } from './no_services_message'; - -function Wrapper({ children }: { children?: ReactNode }) { - return {children}; -} - -describe('NoServicesMessage', () => { - Object.values(FETCH_STATUS).forEach((status) => { - [true, false].forEach((historicalDataFound) => { - describe(`when status is ${status}`, () => { - describe(`when historicalDataFound is ${historicalDataFound}`, () => { - it('renders', () => { - expect(() => - render(, { - wrapper: Wrapper, - }) - ).not.toThrowError(); - }); - }); - }); - }); - }); -}); diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.tsx deleted file mode 100644 index 872359262cf02..0000000000000 --- a/x-pack/plugins/apm/public/components/app/service_inventory/no_services_message.tsx +++ /dev/null @@ -1,39 +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 { EuiEmptyPrompt } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import React from 'react'; -import { FETCH_STATUS } from '../../../hooks/use_fetcher'; -import { ErrorStatePrompt } from '../../shared/ErrorStatePrompt'; - -interface Props { - status: FETCH_STATUS | undefined; -} - -export function NoServicesMessage({ status }: Props) { - if (status === FETCH_STATUS.LOADING) { - return null; - } - - if (status === FETCH_STATUS.FAILURE) { - return ; - } - - return ( - - {i18n.translate('xpack.apm.servicesTable.notFoundLabel', { - defaultMessage: 'No services found', - })} -
- } - titleSize="s" - /> - ); -} diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx index e085c5794f80a..17dfee35e221b 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx @@ -214,6 +214,7 @@ interface Props { comparisonData?: ServicesDetailedStatisticsAPIResponse; noItemsMessage?: React.ReactNode; isLoading: boolean; + isFailure?: boolean; } export function ServiceList({ @@ -221,6 +222,7 @@ export function ServiceList({ noItemsMessage, comparisonData, isLoading, + isFailure, }: Props) { const breakpoints = useBreakpoints(); const displayHealthStatus = items.some((item) => 'healthStatus' in item); @@ -296,6 +298,7 @@ export function ServiceList({ - - + - { - setTableOptions({ - pageIndex: newTableOptions.page?.index ?? 0, - sort: newTableOptions.sort - ? { - field: newTableOptions.sort.field as SortField, - direction: newTableOptions.sort.direction, - } - : DEFAULT_SORT, - }); - }} - sorting={{ - enableAllColumns: true, - sort, - }} - /> - - + noItemsMessage={ + status === FETCH_STATUS.LOADING + ? i18n.translate( + 'xpack.apm.serviceOverview.errorsTable.loading', + { defaultMessage: 'Loading...' } + ) + : i18n.translate( + 'xpack.apm.serviceOverview.errorsTable.noResults', + { defaultMessage: 'No errors found' } + ) + } + columns={columns} + items={items} + pagination={{ + pageIndex, + pageSize: PAGE_SIZE, + totalItemCount: totalItems, + pageSizeOptions: [PAGE_SIZE], + hidePerPageOptions: true, + }} + loading={status === FETCH_STATUS.LOADING} + onChange={(newTableOptions: { + page?: { + index: number; + }; + sort?: { field: string; direction: SortDirection }; + }) => { + setTableOptions({ + pageIndex: newTableOptions.page?.index ?? 0, + sort: newTableOptions.sort + ? { + field: newTableOptions.sort.field as SortField, + direction: newTableOptions.sort.direction, + } + : DEFAULT_SORT, + }); + }} + sorting={{ + enableAllColumns: true, + sort, + }} + /> + ); diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx index 9312a3c68a1ec..1df6803fdbbb1 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx @@ -17,7 +17,6 @@ import { useApmServiceContext } from '../../../../context/apm_service/use_apm_se import { useUrlParams } from '../../../../context/url_params_context/use_url_params'; import { FETCH_STATUS } from '../../../../hooks/use_fetcher'; import { APIReturnType } from '../../../../services/rest/createCallApmApi'; -import { TableFetchWrapper } from '../../../shared/table_fetch_wrapper'; import { PAGE_SIZE, SortDirection, @@ -156,33 +155,39 @@ export function ServiceOverviewInstancesTable({ - - - - - + + + ); diff --git a/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx b/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx index 5286b821dd23f..63cd27cba41e8 100644 --- a/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx @@ -65,6 +65,7 @@ export function TraceOverview() { ); diff --git a/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx b/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx index 765a4b1aeae8c..7c4e0ffca1f58 100644 --- a/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx +++ b/x-pack/plugins/apm/public/components/app/trace_overview/trace_list.tsx @@ -30,6 +30,7 @@ const StyledTransactionLink = euiStyled(TransactionDetailLink)` interface Props { items: TraceGroup[]; isLoading: boolean; + isFailure: boolean; } const traceListColumns: Array> = [ @@ -124,10 +125,11 @@ const noItemsMessage = ( /> ); -export function TraceList({ items = [], isLoading }: Props) { +export function TraceList({ items = [], isLoading, isFailure }: Props) { return ( - - - - - + + + ); diff --git a/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap b/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap index 1e01c00543949..e4674b3add880 100644 --- a/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap +++ b/x-pack/plugins/apm/public/components/shared/managed_table/__snapshots__/managed_table.test.tsx.snap @@ -17,6 +17,7 @@ exports[`ManagedTable should render a page-full of items, with defaults 1`] = ` }, ] } + error="" items={ Array [ Object { @@ -74,6 +75,7 @@ exports[`ManagedTable should render when specifying initial values 1`] = ` }, ] } + error="" items={ Array [ Object { diff --git a/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx b/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx index f7009956bcf84..54f0aebbe818c 100644 --- a/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/managed_table/index.tsx @@ -43,6 +43,7 @@ interface Props { ) => T[]; pagination?: boolean; isLoading?: boolean; + error?: boolean; } function defaultSortFn( @@ -68,6 +69,7 @@ function UnoptimizedManagedTable(props: Props) { sortFn = defaultSortFn, pagination = true, isLoading = false, + error = false, } = props; const { @@ -138,6 +140,13 @@ function UnoptimizedManagedTable(props: Props) { return ( >} // EuiBasicTableColumn is stricter than ITableColumn diff --git a/x-pack/plugins/apm/public/components/shared/table_fetch_wrapper/index.tsx b/x-pack/plugins/apm/public/components/shared/table_fetch_wrapper/index.tsx deleted file mode 100644 index 8a87ede9b3daa..0000000000000 --- a/x-pack/plugins/apm/public/components/shared/table_fetch_wrapper/index.tsx +++ /dev/null @@ -1,24 +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, { ReactNode } from 'react'; -import { FETCH_STATUS } from '../../../hooks/use_fetcher'; -import { ErrorStatePrompt } from '../ErrorStatePrompt'; - -export function TableFetchWrapper({ - status, - children, -}: { - status: FETCH_STATUS; - children: ReactNode; -}) { - if (status === FETCH_STATUS.FAILURE) { - return ; - } - - return <>{children}; -} diff --git a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx index 08fc9e54c1444..60612b581e1d4 100644 --- a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx @@ -23,7 +23,6 @@ import { useApmServiceContext } from '../../../context/apm_service/use_apm_servi import { useUrlParams } from '../../../context/url_params_context/use_url_params'; import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher'; import { TransactionOverviewLink } from '../Links/apm/transaction_overview_link'; -import { TableFetchWrapper } from '../table_fetch_wrapper'; import { getTimeRangeComparison } from '../time_comparison/get_time_range_comparison'; import { OverviewTableContainer } from '../overview_table_container'; import { getColumns } from './get_columns'; @@ -302,47 +301,52 @@ export function TransactionsTable({ )} - - + - { - setTableOptions({ - pageIndex: newTableOptions.page?.index ?? 0, - sort: newTableOptions.sort - ? { - field: newTableOptions.sort.field as SortField, - direction: newTableOptions.sort.direction, - } - : DEFAULT_SORT, - }); - }} - /> - - + loading={isLoading} + error={ + status === FETCH_STATUS.FAILURE + ? i18n.translate('xpack.apm.transactionsTable.errorMessage', { + defaultMessage: 'Failed to fetch', + }) + : '' + } + items={transactionGroups} + columns={columns} + pagination={pagination} + sorting={{ sort: { field, direction } }} + onChange={(newTableOptions: { + page?: { + index: number; + }; + sort?: { field: string; direction: SortDirection }; + }) => { + setTableOptions({ + pageIndex: newTableOptions.page?.index ?? 0, + sort: newTableOptions.sort + ? { + field: newTableOptions.sort.field as SortField, + direction: newTableOptions.sort.direction, + } + : DEFAULT_SORT, + }); + }} + /> + diff --git a/x-pack/plugins/apm/scripts/optimize-tsconfig/tsconfig.json b/x-pack/plugins/apm/scripts/optimize-tsconfig/tsconfig.json index 40d42298b967b..31f756eeabde3 100644 --- a/x-pack/plugins/apm/scripts/optimize-tsconfig/tsconfig.json +++ b/x-pack/plugins/apm/scripts/optimize-tsconfig/tsconfig.json @@ -7,7 +7,6 @@ ], "exclude": [ "**/__fixtures__/**/*", - "./x-pack/plugins/apm/e2e", "./x-pack/plugins/apm/ftr_e2e" ], "compilerOptions": { diff --git a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.ts b/x-pack/plugins/apm/typings/es_schemas/raw/fields/event_outcome.ts similarity index 80% rename from x-pack/plugins/apm/e2e/cypress/integration/snapshots.ts rename to x-pack/plugins/apm/typings/es_schemas/raw/fields/event_outcome.ts index 64946c113e777..d0ca41fcba4ed 100644 --- a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.ts +++ b/x-pack/plugins/apm/typings/es_schemas/raw/fields/event_outcome.ts @@ -5,6 +5,4 @@ * 2.0. */ -module.exports = { - __version: '4.9.0', -}; +export type EventOutcome = 'success' | 'failure' | 'unknown'; diff --git a/x-pack/plugins/apm/typings/es_schemas/raw/span_raw.ts b/x-pack/plugins/apm/typings/es_schemas/raw/span_raw.ts index 1de497f2c7cd7..01bc0ed52ecae 100644 --- a/x-pack/plugins/apm/typings/es_schemas/raw/span_raw.ts +++ b/x-pack/plugins/apm/typings/es_schemas/raw/span_raw.ts @@ -6,6 +6,7 @@ */ import { APMBaseDoc } from './apm_base_doc'; +import { EventOutcome } from './fields/event_outcome'; import { Stackframe } from './fields/stackframe'; import { TimestampUs } from './fields/timestamp_us'; @@ -17,7 +18,7 @@ interface Processor { export interface SpanRaw extends APMBaseDoc { processor: Processor; trace: { id: string }; // trace is required - event?: { outcome?: 'success' | 'failure' }; + event?: { outcome?: EventOutcome }; service: { name: string; environment?: string; diff --git a/x-pack/plugins/apm/typings/es_schemas/raw/transaction_raw.ts b/x-pack/plugins/apm/typings/es_schemas/raw/transaction_raw.ts index d6154d7ad4d23..34c391134b604 100644 --- a/x-pack/plugins/apm/typings/es_schemas/raw/transaction_raw.ts +++ b/x-pack/plugins/apm/typings/es_schemas/raw/transaction_raw.ts @@ -8,6 +8,7 @@ import { APMBaseDoc } from './apm_base_doc'; import { Cloud } from './fields/cloud'; import { Container } from './fields/container'; +import { EventOutcome } from './fields/event_outcome'; import { Host } from './fields/host'; import { Http } from './fields/http'; import { Kubernetes } from './fields/kubernetes'; @@ -28,7 +29,7 @@ export interface TransactionRaw extends APMBaseDoc { processor: Processor; timestamp: TimestampUs; trace: { id: string }; // trace is required - event?: { outcome?: 'success' | 'failure' }; + event?: { outcome?: EventOutcome }; transaction: { duration: { us: number }; id: string; diff --git a/x-pack/plugins/cloud/public/fullstory.ts b/x-pack/plugins/cloud/public/fullstory.ts index 25d5320a063bd..4f76abf540cae 100644 --- a/x-pack/plugins/cloud/public/fullstory.ts +++ b/x-pack/plugins/cloud/public/fullstory.ts @@ -14,8 +14,11 @@ export interface FullStoryDeps { packageInfo: PackageInfo; } +export type FullstoryUserVars = Record; + export interface FullStoryApi { - identify(userId: string, userVars?: Record): void; + identify(userId: string, userVars?: FullstoryUserVars): void; + setUserVars(userVars?: FullstoryUserVars): void; event(eventName: string, eventProperties: Record): void; } diff --git a/x-pack/plugins/cloud/public/plugin.test.mocks.ts b/x-pack/plugins/cloud/public/plugin.test.mocks.ts index 4eb206d07bf85..b79fb1bc65130 100644 --- a/x-pack/plugins/cloud/public/plugin.test.mocks.ts +++ b/x-pack/plugins/cloud/public/plugin.test.mocks.ts @@ -10,6 +10,7 @@ import type { FullStoryDeps, FullStoryApi, FullStoryService } from './fullstory' export const fullStoryApiMock: jest.Mocked = { event: jest.fn(), + setUserVars: jest.fn(), identify: jest.fn(), }; export const initializeFullStoryMock = jest.fn(() => ({ diff --git a/x-pack/plugins/cloud/public/plugin.test.ts b/x-pack/plugins/cloud/public/plugin.test.ts index 835a52cb814c8..f3d5bd902c6d7 100644 --- a/x-pack/plugins/cloud/public/plugin.test.ts +++ b/x-pack/plugins/cloud/public/plugin.test.ts @@ -11,6 +11,7 @@ import { homePluginMock } from 'src/plugins/home/public/mocks'; import { securityMock } from '../../security/public/mocks'; import { fullStoryApiMock, initializeFullStoryMock } from './plugin.test.mocks'; import { CloudPlugin, CloudConfigType, loadFullStoryUserId } from './plugin'; +import { Observable, Subject } from 'rxjs'; describe('Cloud Plugin', () => { describe('#setup', () => { @@ -23,10 +24,12 @@ describe('Cloud Plugin', () => { config = {}, securityEnabled = true, currentUserProps = {}, + currentAppId$ = undefined, }: { config?: Partial; securityEnabled?: boolean; currentUserProps?: Record; + currentAppId$?: Observable; }) => { const initContext = coreMock.createPluginInitializerContext({ id: 'cloudId', @@ -39,9 +42,15 @@ describe('Cloud Plugin', () => { }, ...config, }); + const plugin = new CloudPlugin(initContext); const coreSetup = coreMock.createSetup(); + const coreStart = coreMock.createStart(); + if (currentAppId$) { + coreStart.application.currentAppId$ = currentAppId$; + } + coreSetup.getStartServices.mockResolvedValue([coreStart, {}, undefined]); const securitySetup = securityMock.createSetup(); securitySetup.authc.getCurrentUser.mockResolvedValue( securityMock.createMockAuthenticatedUser(currentUserProps) @@ -78,10 +87,46 @@ describe('Cloud Plugin', () => { }); expect(fullStoryApiMock.identify).toHaveBeenCalledWith( - '03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4' + '03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4', + { + version_str: 'version', + version_major_int: -1, + version_minor_int: -1, + version_patch_int: -1, + } ); }); + it('calls FS.setUserVars everytime an app changes', async () => { + const currentAppId$ = new Subject(); + const { plugin } = await setupPlugin({ + config: { full_story: { enabled: true, org_id: 'foo' } }, + currentUserProps: { + username: '1234', + }, + currentAppId$, + }); + + expect(fullStoryApiMock.setUserVars).not.toHaveBeenCalled(); + currentAppId$.next('App1'); + expect(fullStoryApiMock.setUserVars).toHaveBeenCalledWith({ + app_id_str: 'App1', + }); + currentAppId$.next(); + expect(fullStoryApiMock.setUserVars).toHaveBeenCalledWith({ + app_id_str: 'unknown', + }); + + currentAppId$.next('App2'); + expect(fullStoryApiMock.setUserVars).toHaveBeenCalledWith({ + app_id_str: 'App2', + }); + + expect(currentAppId$.observers.length).toBe(1); + plugin.stop(); + expect(currentAppId$.observers.length).toBe(0); + }); + it('does not call FS.identify when security is not available', async () => { await setupPlugin({ config: { full_story: { enabled: true, org_id: 'foo' } }, diff --git a/x-pack/plugins/cloud/public/plugin.ts b/x-pack/plugins/cloud/public/plugin.ts index 29befcee397dd..6053f2eb5b8c3 100644 --- a/x-pack/plugins/cloud/public/plugin.ts +++ b/x-pack/plugins/cloud/public/plugin.ts @@ -12,8 +12,10 @@ import { PluginInitializerContext, HttpStart, IBasePath, + ApplicationStart, } from 'src/core/public'; import { i18n } from '@kbn/i18n'; +import { Subscription } from 'rxjs'; import type { AuthenticatedUser, SecurityPluginSetup, @@ -58,9 +60,15 @@ export interface CloudSetup { isCloudEnabled: boolean; } +interface SetupFullstoryDeps extends CloudSetupDependencies { + application?: Promise; + basePath: IBasePath; +} + export class CloudPlugin implements Plugin { private config!: CloudConfigType; private isCloudEnabled: boolean; + private appSubscription?: Subscription; constructor(private readonly initializerContext: PluginInitializerContext) { this.config = this.initializerContext.config.get(); @@ -68,7 +76,10 @@ export class CloudPlugin implements Plugin { } public setup(core: CoreSetup, { home, security }: CloudSetupDependencies) { - this.setupFullstory({ basePath: core.http.basePath, security }).catch((e) => + const application = core.getStartServices().then(([coreStart]) => { + return coreStart.application; + }); + this.setupFullstory({ basePath: core.http.basePath, security, application }).catch((e) => // eslint-disable-next-line no-console console.debug(`Error setting up FullStory: ${e.toString()}`) ); @@ -138,6 +149,10 @@ export class CloudPlugin implements Plugin { .catch(() => setLinks(true)); } + public stop() { + this.appSubscription?.unsubscribe(); + } + /** * Determines if the current user should see links back to Cloud. * This isn't a true authorization check, but rather a heuristic to @@ -164,10 +179,7 @@ export class CloudPlugin implements Plugin { return user?.roles.includes('superuser') ?? true; } - private async setupFullstory({ - basePath, - security, - }: CloudSetupDependencies & { basePath: IBasePath }) { + private async setupFullstory({ basePath, security, application }: SetupFullstoryDeps) { const { enabled, org_id: orgId } = this.config.full_story; if (!enabled || !orgId) { return; // do not load any fullstory code in the browser if not enabled @@ -198,7 +210,35 @@ export class CloudPlugin implements Plugin { if (userId) { // Do the hashing here to keep it at clear as possible in our source code that we do not send literal user IDs const hashedId = sha256(userId.toString()); - fullStory.identify(hashedId); + application + ?.then(async () => { + const appStart = await application; + this.appSubscription = appStart.currentAppId$.subscribe((appId) => { + // Update the current application every time it changes + fullStory.setUserVars({ + app_id_str: appId ?? 'unknown', + }); + }); + }) + .catch((e) => { + // eslint-disable-next-line no-console + console.error( + `[cloud.full_story] Could not retrieve application service due to error: ${e.toString()}`, + e + ); + }); + const kibanaVer = this.initializerContext.env.packageInfo.version; + // TODO: use semver instead + const parsedVer = (kibanaVer.indexOf('.') > -1 ? kibanaVer.split('.') : []).map((s) => + parseInt(s, 10) + ); + // `str` suffix is required for evn vars, see docs: https://help.fullstory.com/hc/en-us/articles/360020623234 + fullStory.identify(hashedId, { + version_str: kibanaVer, + version_major_int: parsedVer[0] ?? -1, + version_minor_int: parsedVer[1] ?? -1, + version_patch_int: parsedVer[2] ?? -1, + }); } } catch (e) { // eslint-disable-next-line no-console diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/geo_point_content_with_map/geo_point_content_with_map.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/geo_point_content_with_map/geo_point_content_with_map.tsx index 42245742f8b7d..082083fa92ff2 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/geo_point_content_with_map/geo_point_content_with_map.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/geo_point_content_with_map/geo_point_content_with_map.tsx @@ -7,7 +7,7 @@ import React, { FC, useEffect, useState } from 'react'; import { EuiFlexItem } from '@elastic/eui'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../../../src/plugins/data/common'; import { CombinedQuery } from '../../../../index_data_visualizer/types/combined_query'; import { ExpandedRowContent } from '../../stats_table/components/field_data_expanded_row/expanded_row_content'; import { DocumentStatsTable } from '../../stats_table/components/field_data_expanded_row/document_stats'; diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx index 6406012a0540b..ca9c8301bcfba 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx @@ -19,7 +19,7 @@ import { } from '../stats_table/components/field_data_expanded_row'; import { NotInDocsContent } from '../not_in_docs_content'; import { FieldVisConfig } from '../stats_table/types'; -import { IndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../../src/plugins/data/common'; import { CombinedQuery } from '../../../index_data_visualizer/types/combined_query'; import { LoadingIndicator } from '../loading_indicator'; diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts b/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts index a77ca1d589349..1fee95aeb5bfa 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts +++ b/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; import { Action } from '@elastic/eui/src/components/basic_table/action_types'; import { MutableRefObject } from 'react'; import { getCompatibleLensDataType, getLensAttributes } from './lens_utils'; -import { IndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../../../src/plugins/data/common'; import { CombinedQuery } from '../../../../index_data_visualizer/types/combined_query'; import { FieldVisConfig } from '../../stats_table/types'; import { DataVisualizerKibanaReactContextValue } from '../../../../kibana_context'; diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts b/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts index 0b0c0e8fe3f09..3f80bbefcc259 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts +++ b/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts @@ -6,7 +6,7 @@ */ import { i18n } from '@kbn/i18n'; -import type { IndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import type { IndexPattern } from '../../../../../../../../../src/plugins/data/common'; import type { CombinedQuery } from '../../../../index_data_visualizer/types/combined_query'; import type { IndexPatternColumn, diff --git a/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts b/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts index 98d43059e5ee3..54e0b2d5310f3 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts +++ b/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { JOB_FIELD_TYPES } from '../../../../common'; -import type { IndexPatternField } from '../../../../../../../src/plugins/data/common/index_patterns/fields'; +import type { IndexPatternField } from '../../../../../../../src/plugins/data/common'; import { KBN_FIELD_TYPES } from '../../../../../../../src/plugins/data/common'; export const jobTypeAriaLabels = { diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx index 48410aff54577..bc68bdf4b6ce0 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx @@ -14,7 +14,7 @@ import { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState, } from '../../../../../../../../src/plugins/discover/public'; -import type { IndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; +import type { IndexPattern } from '../../../../../../../../src/plugins/data/common'; import { useDataVisualizerKibana } from '../../../kibana_context'; import { useUrlState } from '../../../common/util/url_state'; import { LinkCard } from '../../../common/components/link_card'; diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_pattern_management/index_pattern_management.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_pattern_management/index_pattern_management.tsx index cb81640f328c5..3cec1141a4d35 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_pattern_management/index_pattern_management.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_pattern_management/index_pattern_management.tsx @@ -8,7 +8,7 @@ import React, { useEffect, useRef, useState } from 'react'; import { EuiButtonIcon, EuiContextMenuItem, EuiContextMenuPanel, EuiPopover } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { IndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../../src/plugins/data/common'; import { useDataVisualizerKibana } from '../../../kibana_context'; import { dataVisualizerRefresh$, Refresh } from '../../services/timefilter_refresh_service'; diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx index 191c27b1807d0..91ec1e449bb38 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx @@ -13,7 +13,7 @@ import { QueryStringInput } from '../../../../../../../../src/plugins/data/publi import { ShardSizeFilter } from './shard_size_select'; import { DataVisualizerFieldNamesFilter } from './field_name_filter'; import { DatavisualizerFieldTypeFilter } from './field_type_filter'; -import { IndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../../src/plugins/data/common'; import { JobFieldType } from '../../../../../common/types'; import { ErrorMessage, diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/data_loader/data_loader.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/data_loader/data_loader.ts index 1b92eaddd1343..c4db51dcd81bc 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/data_loader/data_loader.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/data_loader/data_loader.ts @@ -9,7 +9,7 @@ import { CoreSetup } from 'kibana/public'; import { estypes } from '@elastic/elasticsearch'; import { i18n } from '@kbn/i18n'; -import { IndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../src/plugins/data/common'; import { NON_AGGREGATABLE_FIELD_TYPES, OMIT_FIELDS } from '../../../../common/constants'; import { FieldRequestConfig } from '../../../../common/types'; import { getVisualizerFieldStats, getVisualizerOverallStats } from '../services/visualizer_stats'; diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx index 2835588625a6e..9a8987967fe69 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx @@ -29,7 +29,7 @@ import { isRisonSerializationRequired, } from '../common/util/url_state'; import { useDataVisualizerKibana } from '../kibana_context'; -import { IndexPattern } from '../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../src/plugins/data/common'; import { ResultLink } from '../common/components/results_links'; export type IndexDataVisualizerSpec = typeof IndexDataVisualizer; diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts index cfe127aec543e..cb80e491fc7e5 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts @@ -17,7 +17,7 @@ import { } from '@kbn/es-query'; import { estypes } from '@elastic/elasticsearch'; import { SavedSearchSavedObject } from '../../../../common/types'; -import { IndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../src/plugins/data/common'; import { SEARCH_QUERY_LANGUAGE, SearchQueryLanguage } from '../types/combined_query'; import { getEsQueryConfig, Query } from '../../../../../../../src/plugins/data/public'; diff --git a/x-pack/plugins/enterprise_search/README.md b/x-pack/plugins/enterprise_search/README.md index 5c8d767de3099..64855dc1395ab 100644 --- a/x-pack/plugins/enterprise_search/README.md +++ b/x-pack/plugins/enterprise_search/README.md @@ -2,9 +2,7 @@ ## Overview -This plugin provides beta Kibana user interfaces for managing the Enterprise Search solution and its products, App Search and Workplace Search. - -> :warning: The Kibana interface for Enterprise Search is a beta feature. It is subject to change and is not covered by the same level of support as generally available features. This interface will become the sole management panel for Enterprise Search with the 8.0 release. Until then, the standalone Enterprise Search UI remains available and supported. +This plugin provides Kibana user interfaces for managing the Enterprise Search solution and its products, App Search and Workplace Search. ### App Search diff --git a/x-pack/plugins/enterprise_search/common/constants.ts b/x-pack/plugins/enterprise_search/common/constants.ts index f162f5810cb61..bc60c917094f8 100644 --- a/x-pack/plugins/enterprise_search/common/constants.ts +++ b/x-pack/plugins/enterprise_search/common/constants.ts @@ -55,6 +55,7 @@ export const WORKPLACE_SEARCH_PLUGIN = { } ), URL: '/app/enterprise_search/workplace_search', + NON_ADMIN_URL: '/app/enterprise_search/workplace_search/p', SUPPORT_URL: 'https://discuss.elastic.co/c/enterprise-search/workplace-search/', }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx index c8dd9523f62f4..33b7658788f62 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx @@ -28,9 +28,10 @@ interface ProductCardProps { URL: string; }; image: string; + url?: string; } -export const ProductCard: React.FC = ({ product, image }) => { +export const ProductCard: React.FC = ({ product, image, url }) => { const { sendEnterpriseSearchTelemetry } = useActions(TelemetryLogic); const { config } = useValues(KibanaLogic); @@ -68,7 +69,7 @@ export const ProductCard: React.FC = ({ product, image }) => { footer={ sendEnterpriseSearchTelemetry({ diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx index ee0209c1a124d..c713507083b08 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx @@ -11,6 +11,8 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; + import { LicenseCallout } from '../license_callout'; import { ProductCard } from '../product_card'; import { SetupGuideCta } from '../setup_guide'; @@ -18,10 +20,15 @@ import { TrialCallout } from '../trial_callout'; import { ProductSelector } from './'; +const props = { + access: {}, + isWorkplaceSearchAdmin: true, +}; + describe('ProductSelector', () => { it('renders the overview page, product cards, & setup guide CTAs with no host set', () => { setMockValues({ config: { host: '' } }); - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.find(ProductCard)).toHaveLength(2); expect(wrapper.find(SetupGuideCta)).toHaveLength(1); @@ -30,12 +37,21 @@ describe('ProductSelector', () => { it('renders the license and trial callouts', () => { setMockValues({ config: { host: 'localhost' } }); - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.find(TrialCallout)).toHaveLength(1); expect(wrapper.find(LicenseCallout)).toHaveLength(1); }); + it('passes correct URL when Workplace Search user is not an admin', () => { + setMockValues({ config: { host: '' } }); + const wrapper = shallow(); + + expect(wrapper.find(ProductCard).last().prop('url')).toEqual( + WORKPLACE_SEARCH_PLUGIN.NON_ADMIN_URL + ); + }); + describe('access checks when host is set', () => { beforeEach(() => { setMockValues({ config: { host: 'localhost' } }); @@ -43,7 +59,10 @@ describe('ProductSelector', () => { it('does not render the App Search card if the user does not have access to AS', () => { const wrapper = shallow( - + ); expect(wrapper.find(ProductCard)).toHaveLength(1); @@ -52,7 +71,10 @@ describe('ProductSelector', () => { it('does not render the Workplace Search card if the user does not have access to WS', () => { const wrapper = shallow( - + ); expect(wrapper.find(ProductCard)).toHaveLength(1); @@ -60,7 +82,7 @@ describe('ProductSelector', () => { }); it('does not render any cards if the user does not have access', () => { - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.find(ProductCard)).toHaveLength(0); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx index f42a043e7cd81..690122efc2f20 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx @@ -34,9 +34,13 @@ interface ProductSelectorProps { hasAppSearchAccess?: boolean; hasWorkplaceSearchAccess?: boolean; }; + isWorkplaceSearchAdmin: boolean; } -export const ProductSelector: React.FC = ({ access }) => { +export const ProductSelector: React.FC = ({ + access, + isWorkplaceSearchAdmin, +}) => { const { hasAppSearchAccess, hasWorkplaceSearchAccess } = access; const { config } = useValues(KibanaLogic); @@ -44,6 +48,10 @@ export const ProductSelector: React.FC = ({ access }) => { const shouldShowAppSearchCard = !config.host || hasAppSearchAccess; const shouldShowWorkplaceSearchCard = !config.host || hasWorkplaceSearchAccess; + const WORKPLACE_SEARCH_URL = isWorkplaceSearchAdmin + ? WORKPLACE_SEARCH_PLUGIN.URL + : WORKPLACE_SEARCH_PLUGIN.NON_ADMIN_URL; + return ( @@ -84,7 +92,11 @@ export const ProductSelector: React.FC = ({ access }) => { )} {shouldShowWorkplaceSearchCard && ( - + )} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx index b1aab0dacabde..17387ae482325 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx @@ -19,11 +19,12 @@ import { ProductSelector } from './components/product_selector'; import { SetupGuide } from './components/setup_guide'; import { ROOT_PATH, SETUP_GUIDE_PATH } from './routes'; -export const EnterpriseSearch: React.FC = ({ access = {} }) => { +export const EnterpriseSearch: React.FC = ({ access = {}, workplaceSearch }) => { const { errorConnecting } = useValues(HttpLogic); const { config } = useValues(KibanaLogic); const showErrorConnecting = !!(config.host && errorConnecting); + const isWorkplaceSearchAdmin = !!workplaceSearch?.account?.isAdmin; return ( @@ -31,7 +32,11 @@ export const EnterpriseSearch: React.FC = ({ access = {} }) => { - {showErrorConnecting ? : } + {showErrorConnecting ? ( + + ) : ( + + )} ); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx index 282c7ca5721cb..3fbae0a564c17 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx @@ -13,7 +13,6 @@ import { EuiEmptyPrompt, EuiCode } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { KibanaLogic } from '../kibana'; -import { BetaNotification } from '../layout/beta'; import { EuiButtonTo } from '../react_router_helpers'; import './error_state_prompt.scss'; @@ -100,7 +99,6 @@ export const ErrorStatePrompt: React.FC = () => { defaultMessage="Review setup guide" /> , - , ]} /> ); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.scss b/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.scss deleted file mode 100644 index adf2dc16d8327..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.scss +++ /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. - */ - -@include euiBreakpoint('m', 'l', 'xl') { - .betaSidebarNotification { - .euiSideNav { - display: flex; - flex-direction: column; - - .euiSideNav__content { - flex-grow: 1; - display: flex; - flex-direction: column; - justify-content: space-between; - } - } - } -} - -.betaNotification { - width: 350px; -} diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.test.tsx deleted file mode 100644 index b8b6f6c257b22..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.test.tsx +++ /dev/null @@ -1,129 +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 '../../__mocks__/enterprise_search_url.mock'; - -import React from 'react'; - -import { shallow, ShallowWrapper } from 'enzyme'; - -import { EuiPopover, EuiPopoverTitle, EuiLink } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; - -import { shallowWithIntl } from '../../test_helpers'; - -import { BetaNotification, appendBetaNotificationItem } from './beta'; - -describe('BetaNotification', () => { - const getToggleButton = (wrapper: ShallowWrapper) => { - return shallow(
{wrapper.prop('button')}
).childAt(0); - }; - - it('renders', () => { - const wrapper = shallow(); - - expect(wrapper.type()).toEqual(EuiPopover); - expect(wrapper.find(EuiPopoverTitle).prop('children')).toEqual( - 'Enterprise Search in Kibana is a beta user interface' - ); - }); - - describe('open/close popover state', () => { - const wrapper = shallow(); - - it('is initially closed', () => { - expect(wrapper.find(EuiPopover).prop('isOpen')).toBe(false); - }); - - it('opens the popover when the toggle button is pressed', () => { - getToggleButton(wrapper).simulate('click'); - - expect(wrapper.find(EuiPopover).prop('isOpen')).toBe(true); - }); - - it('closes the popover', () => { - wrapper.prop('closePopover')(); - - expect(wrapper.find(EuiPopover).prop('isOpen')).toBe(false); - }); - }); - - describe('toggle button props', () => { - it('defaults to a size of xs and flush', () => { - const wrapper = shallow(); - const toggleButton = getToggleButton(wrapper); - - expect(toggleButton.prop('size')).toEqual('xs'); - expect(toggleButton.prop('flush')).toEqual('both'); - }); - - it('passes down custom button props', () => { - const wrapper = shallow(); - const toggleButton = getToggleButton(wrapper); - - expect(toggleButton.prop('size')).toEqual('m'); - }); - }); - - describe('links', () => { - const wrapper = shallowWithIntl(); - const links = wrapper.find(FormattedMessage).dive(); - - it('renders a documentation link', () => { - const docLink = links.find(EuiLink).first(); - - expect(docLink.prop('href')).toContain('/user-interfaces.html'); - }); - - it('renders a link back to the standalone UI', () => { - const switchLink = links.find(EuiLink).last(); - - expect(switchLink.prop('href')).toBe('http://localhost:3002'); - }); - }); -}); - -describe('appendBetaNotificationItem', () => { - const mockSideNav = { - name: 'Hello world', - items: [ - { id: '1', name: 'Link 1' }, - { id: '2', name: 'Link 2' }, - ], - }; - - it('inserts a beta notification into a side nav items array', () => { - appendBetaNotificationItem(mockSideNav); - - expect(mockSideNav).toEqual({ - name: 'Hello world', - items: [ - { id: '1', name: 'Link 1' }, - { id: '2', name: 'Link 2' }, - { - id: 'beta', - name: '', - renderItem: expect.any(Function), - }, - ], - }); - }); - - it('renders the BetaNotification component as a side nav item', () => { - const SideNavItem = (mockSideNav.items[2] as any).renderItem; - const wrapper = shallow(); - - expect(wrapper.find(BetaNotification)).toHaveLength(1); - }); - - it('does nothing if no side nav was passed', () => { - const mockEmptySideNav = undefined; - appendBetaNotificationItem(mockEmptySideNav); - - expect(mockEmptySideNav).toEqual(undefined); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.tsx deleted file mode 100644 index 1f4c8328cc874..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/beta.tsx +++ /dev/null @@ -1,104 +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, { useState } from 'react'; - -import { - EuiPopover, - EuiPopoverTitle, - EuiPopoverFooter, - EuiButtonEmpty, - EuiButtonEmptyProps, - EuiText, - EuiLink, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; - -import { KibanaPageTemplateProps } from '../../../../../../../src/plugins/kibana_react/public'; - -import { docLinks } from '../doc_links'; -import { getEnterpriseSearchUrl } from '../enterprise_search_url'; - -import './beta.scss'; - -interface Props { - buttonProps?: EuiButtonEmptyProps; -} - -export const BetaNotification: React.FC = ({ buttonProps }) => { - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const togglePopover = () => setIsPopoverOpen((isOpen) => !isOpen); - const closePopover = () => setIsPopoverOpen(false); - - return ( - - {i18n.translate('xpack.enterpriseSearch.beta.buttonLabel', { - defaultMessage: 'This is a beta user interface', - })} - - } - isOpen={isPopoverOpen} - closePopover={closePopover} - anchorPosition="rightDown" - repositionOnScroll - > - - {i18n.translate('xpack.enterpriseSearch.beta.popover.title', { - defaultMessage: 'Enterprise Search in Kibana is a beta user interface', - })} - -
- -

- {i18n.translate('xpack.enterpriseSearch.beta.popover.description', { - defaultMessage: - 'The Kibana interface for Enterprise Search is a beta feature. It is subject to change and is not covered by the same level of support as generally available features. This interface will become the sole management panel for Enterprise Search with the 8.0 release. Until then, the standalone Enterprise Search UI remains available and supported.', - })} -

-
-
- - - Learn more - - ), - standaloneUILink: ( - switch to the Enterprise Search UI - ), - }} - /> - -
- ); -}; - -export const appendBetaNotificationItem = (sideNav: KibanaPageTemplateProps['solutionNav']) => { - if (sideNav) { - sideNav.items.push({ - id: 'beta', - name: '', - renderItem: () => , - }); - } -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.test.tsx index bc612de884f8b..5b02756e44b52 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.test.tsx @@ -7,8 +7,6 @@ import { setMockValues } from '../../__mocks__/kea_logic'; -jest.mock('./beta', () => ({ appendBetaNotificationItem: jest.fn() })); // Mostly adding this to get tests passing. Should be removed once we're out of beta - import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx index 202c9b6a59e8d..affec11921545 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/layout/page_template.tsx @@ -23,8 +23,6 @@ import { HttpLogic } from '../http'; import { BreadcrumbTrail } from '../kibana_chrome/generate_breadcrumbs'; import { Loading } from '../loading'; -import { appendBetaNotificationItem } from './beta'; - import './page_template.scss'; /* @@ -63,8 +61,6 @@ export const EnterpriseSearchPageTemplate: React.FC = ({ const hasCustomEmptyState = !!emptyState; const showCustomEmptyState = hasCustomEmptyState && isEmptyState; - appendBetaNotificationItem(solutionNav); - return ( = ({ }} isEmptyState={isEmptyState && !isLoading} solutionNav={solutionNav ? { icon: 'logoEnterpriseSearch', ...solutionNav } : undefined} - pageSideBarProps={{ className: 'betaSidebarNotification' }} > {setPageChrome} {readOnlyMode && ( diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/credential_item/credential_item.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/credential_item/credential_item.tsx index 61eaa4e42f8dd..e4067e1f98e5d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/credential_item/credential_item.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/credential_item/credential_item.tsx @@ -19,6 +19,21 @@ import { EuiFieldPassword, EuiToolTip, } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +export const COPY_TOOLTIP = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.credentialItem.copy.tooltip', + { + defaultMessage: 'Copy to clipboard', + } +); + +export const COPIED_TOOLTIP = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.credentialItem.copied.tooltip', + { + defaultMessage: 'Copied!', + } +); interface CredentialItemProps { label: string; @@ -37,6 +52,14 @@ export const CredentialItem: React.FC = ({ }) => { const [isVisible, setIsVisible] = useState(false); + const SHOW_CREDENTIAL_TOOLTIP = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.credentialItem.show.tooltip', + { + defaultMessage: 'Show {credential}.', + values: { credential: label }, + } + ); + return ( = ({ {!hideCopy && ( - + {(copy) => ( = ({ )} - + setIsVisible(!isVisible)} iconType={isVisible ? 'eyeClosed' : 'eye'} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_callout/license_callout.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_callout/license_callout.tsx index f278cda96ae83..270daf195bd38 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_callout/license_callout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/license_callout/license_callout.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { EuiLink, EuiFlexItem, EuiFlexGroup, EuiText } from '@elastic/eui'; +import { EXPLORE_PLATINUM_FEATURES_LINK } from '../../../constants'; import { ENT_SEARCH_LICENSE_MANAGEMENT } from '../../../routes'; interface LicenseCalloutProps { @@ -20,7 +21,7 @@ export const LicenseCallout: React.FC = ({ message }) => { <> {message}{' '} - Explore Platinum features + {EXPLORE_PLATINUM_FEATURES_LINK} ); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/constants.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/constants.ts index d4fa2059f62fb..3666a794617ac 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/constants.ts @@ -583,8 +583,8 @@ export const NON_PLATINUM_OAUTH_DESCRIPTION = i18n.translate( } ); -export const NON_PLATINUM_OAUTH_LINK = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.nonPlatinumOauthLinkLabel', +export const EXPLORE_PLATINUM_FEATURES_LINK = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.explorePlatinumFeatures.link', { defaultMessage: 'Explore Platinum features', } @@ -734,6 +734,10 @@ export const FIELD_LABEL = i18n.translate('xpack.enterpriseSearch.workplaceSearc defaultMessage: 'Field', }); +export const LABEL_LABEL = i18n.translate('xpack.enterpriseSearch.workplaceSearch.label.label', { + defaultMessage: 'Label', +}); + export const DESCRIPTION_LABEL = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.description.label', { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx index 965d71abd5101..18e147100a410 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/config_completed.tsx @@ -30,6 +30,7 @@ import { } from '../../../../routes'; import { + CONFIG_COMPLETED_PRIVATE_SOURCES_DISABLED_LINK, CONFIG_COMPLETED_PRIVATE_SOURCES_DOCS_LINK, CONFIG_COMPLETED_CONFIGURE_NEW_BUTTON, } from './constants'; @@ -114,7 +115,7 @@ export const ConfigCompleted: React.FC = ({ values={{ securityLink: ( - enable private source connection + {CONFIG_COMPLETED_PRIVATE_SOURCES_DISABLED_LINK} ), }} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx index d17e8b84efb2b..15941f14d5ab1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configuration_intro.tsx @@ -28,6 +28,7 @@ import { CONFIG_INTRO_STEPS_TEXT, CONFIG_INTRO_STEP1_HEADING, CONFIG_INTRO_STEP1_TEXT, + CONFIG_INTRO_STEP1_BADGE, CONFIG_INTRO_STEP2_HEADING, CONFIG_INTRO_STEP2_TITLE, CONFIG_INTRO_STEP2_TEXT, @@ -108,7 +109,9 @@ export const ConfigurationIntro: React.FC = ({ id="xpack.enterpriseSearch.workplaceSearch.contentSource.configIntro.step1.title" defaultMessage="Configure an OAuth application {badge}" values={{ - badge: One-Time Action, + badge: ( + {CONFIG_INTRO_STEP1_BADGE} + ), }} /> diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx index b142ddcf4937e..1529875e66af5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.tsx @@ -22,8 +22,10 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { CUSTOM_SOURCE_DOCS_URL } from '../../../../routes'; +import { SOURCE_NAME_LABEL } from '../../constants'; + import { AddSourceLogic } from './add_source_logic'; -import { CONFIG_CUSTOM_BUTTON } from './constants'; +import { CONFIG_CUSTOM_BUTTON, CONFIG_CUSTOM_LINK_TEXT } from './constants'; interface ConfigureCustomProps { header: React.ReactNode; @@ -57,12 +59,12 @@ export const ConfigureCustom: React.FC = ({

{helpText}

- Read the documentation + {CONFIG_CUSTOM_LINK_TEXT} ), }} @@ -70,7 +72,7 @@ export const ConfigureCustom: React.FC = ({

- + = ({ - {SOURCE_FEATURES_EXPLORE_BUTTON} + {EXPLORE_PLATINUM_FEATURES_LINK} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/constants.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/constants.ts index 2bf185ee048bd..a2e6de8d9c7f5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/constants.ts @@ -101,6 +101,13 @@ export const AVAILABLE_SOURCE_CUSTOM_SOURCE_BUTTON = i18n.translate( } ); +export const CONFIG_COMPLETED_PRIVATE_SOURCES_DISABLED_LINK = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.configCompleted.privateDisabled.link', + { + defaultMessage: 'enable private source connection', + } +); + export const CONFIG_COMPLETED_PRIVATE_SOURCES_DOCS_LINK = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.contentSource.configCompleted.privateDisabled.button', { @@ -136,6 +143,13 @@ export const CONFIG_INTRO_STEP1_HEADING = i18n.translate( } ); +export const CONFIG_INTRO_STEP1_BADGE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.configIntro.step1.badge', + { + defaultMessage: 'One-Time Action', + } +); + export const CONFIG_INTRO_STEP1_TEXT = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.contentSource.configIntro.step1.text', { @@ -173,6 +187,13 @@ export const CONFIG_CUSTOM_BUTTON = i18n.translate( } ); +export const CONFIG_CUSTOM_LINK_TEXT = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.configCustom.docs.link.text', + { + defaultMessage: 'Read the documentation', + } +); + export const CONFIG_OAUTH_LABEL = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.contentSource.configOauth.label', { @@ -293,6 +314,13 @@ export const SAVE_CUSTOM_VISUAL_WALKTHROUGH_TITLE = i18n.translate( } ); +export const SAVE_CUSTOM_VISUAL_WALKTHROUGH_LINK = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.saveCustom.visualWalkthrough.link', + { + defaultMessage: 'Check out the documentation', + } +); + export const SAVE_CUSTOM_STYLING_RESULTS_TITLE = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.contentSource.saveCustom.stylingResults.title', { @@ -300,6 +328,13 @@ export const SAVE_CUSTOM_STYLING_RESULTS_TITLE = i18n.translate( } ); +export const SAVE_CUSTOM_STYLING_RESULTS_LINK = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.saveCustom.stylingResults.link', + { + defaultMessage: 'Display Settings', + } +); + export const SAVE_CUSTOM_DOC_PERMISSIONS_TITLE = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.contentSource.saveCustom.docPermissions.title', { @@ -307,6 +342,13 @@ export const SAVE_CUSTOM_DOC_PERMISSIONS_TITLE = i18n.translate( } ); +export const SAVE_CUSTOM_DOC_PERMISSIONS_LINK = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.saveCustom.docPermissions.link', + { + defaultMessage: 'Document-level permissions', + } +); + export const INCLUDED_FEATURES_TITLE = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.contentSource.includedFeaturesTitle', { @@ -314,31 +356,80 @@ export const INCLUDED_FEATURES_TITLE = i18n.translate( } ); -export const SOURCE_FEATURES_SEARCHABLE = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.searchable.text', +export const SOURCE_FEATURES_SYNC_FREQUENCY_TITLE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.syncFrequency.title', + { + defaultMessage: 'Syncs every 2 hours', + } +); + +export const SOURCE_FEATURES_SYNC_FREQUENCY_TIME = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.syncFrequency.time', + { + defaultMessage: '2 hours', + } +); + +export const SOURCE_FEATURES_SYNCED_ITEMS_TITLE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.syncedItems.title', + { + defaultMessage: 'Synced items', + } +); + +export const SOURCE_FEATURES_SEARCHABLE_TITLE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.searchable.title', + { + defaultMessage: 'Searchable content', + } +); + +export const SOURCE_FEATURES_SEARCHABLE_DESCRIPTION = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.searchable.description', { defaultMessage: 'The following items are searchable:', } ); -export const SOURCE_FEATURES_REMOTE_FEATURE = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.remote.text', +export const SOURCE_FEATURES_REMOTE_FEATURE_TITLE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.remote.title', + { + defaultMessage: 'Always up-to-date', + } +); + +export const SOURCE_FEATURES_REMOTE_FEATURE_DESCRIPTION = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.remote.description', { defaultMessage: 'Message data and other information is searchable in real-time from the Workplace Search experience.', } ); -export const SOURCE_FEATURES_PRIVATE_FEATURE = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.private.text', +export const SOURCE_FEATURES_PRIVATE_FEATURE_TITLE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.private.title', + { + defaultMessage: 'Always private', + } +); + +export const SOURCE_FEATURES_PRIVATE_FEATURE_DESCRIPTION = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.private.description', { defaultMessage: 'Results returned are specific and relevant to you. Connecting this source does not expose your personal data to other search users - only you.', } ); -export const SOURCE_FEATURES_GLOBAL_ACCESS_PERMISSIONS_FEATURE = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.globalAccessPermissions.text', +export const SOURCE_FEATURES_GLOBAL_ACCESS_PERMISSIONS_FEATURE_TITLE = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.globalAccessPermissions.title', + { + defaultMessage: 'Global access permissions', + } +); + +export const SOURCE_FEATURES_GLOBAL_ACCESS_PERMISSIONS_FEATURE_DESCRIPTION = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.globalAccessPermissions.description', { defaultMessage: 'All documents accessible to the connecting service user will be synchronized and made available to the organization’s users, or group’s users. Documents are immediately available for search', @@ -360,12 +451,6 @@ export const SOURCE_FEATURES_DOCUMENT_LEVEL_PERMISSIONS_FEATURE = i18n.translate } ); -export const SOURCE_FEATURES_EXPLORE_BUTTON = i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.explore.button', - { - defaultMessage: 'Explore Platinum features', - } -); export const CONNECT_WHICH_OPTION_LINK = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.contentSource.connect.whichOption.link', { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx index bbece2f68c717..dbec5d1808167 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_custom.tsx @@ -46,8 +46,11 @@ import { SAVE_CUSTOM_API_KEYS_TITLE, SAVE_CUSTOM_API_KEYS_BODY, SAVE_CUSTOM_VISUAL_WALKTHROUGH_TITLE, + SAVE_CUSTOM_VISUAL_WALKTHROUGH_LINK, SAVE_CUSTOM_STYLING_RESULTS_TITLE, + SAVE_CUSTOM_STYLING_RESULTS_LINK, SAVE_CUSTOM_DOC_PERMISSIONS_TITLE, + SAVE_CUSTOM_DOC_PERMISSIONS_LINK, } from './constants'; interface SaveCustomProps { @@ -140,7 +143,7 @@ export const SaveCustom: React.FC = ({ values={{ link: ( - Check out the documentation + {SAVE_CUSTOM_VISUAL_WALKTHROUGH_LINK} ), }} @@ -168,7 +171,7 @@ export const SaveCustom: React.FC = ({ isOrganization )} > - Display Settings + {SAVE_CUSTOM_STYLING_RESULTS_LINK} ), }} @@ -193,7 +196,7 @@ export const SaveCustom: React.FC = ({ values={{ link: ( - Document-level permissions + {SAVE_CUSTOM_DOC_PERMISSIONS_LINK} ), }} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx index 02856320aa535..940cb9cb7372a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.tsx @@ -26,10 +26,17 @@ import { Features, FeatureIds } from '../../../../types'; import { INCLUDED_FEATURES_TITLE, - SOURCE_FEATURES_SEARCHABLE, - SOURCE_FEATURES_REMOTE_FEATURE, - SOURCE_FEATURES_PRIVATE_FEATURE, - SOURCE_FEATURES_GLOBAL_ACCESS_PERMISSIONS_FEATURE, + SOURCE_FEATURES_SYNC_FREQUENCY_TITLE, + SOURCE_FEATURES_SYNC_FREQUENCY_TIME, + SOURCE_FEATURES_SYNCED_ITEMS_TITLE, + SOURCE_FEATURES_SEARCHABLE_TITLE, + SOURCE_FEATURES_SEARCHABLE_DESCRIPTION, + SOURCE_FEATURES_REMOTE_FEATURE_TITLE, + SOURCE_FEATURES_REMOTE_FEATURE_DESCRIPTION, + SOURCE_FEATURES_PRIVATE_FEATURE_TITLE, + SOURCE_FEATURES_PRIVATE_FEATURE_DESCRIPTION, + SOURCE_FEATURES_GLOBAL_ACCESS_PERMISSIONS_FEATURE_TITLE, + SOURCE_FEATURES_GLOBAL_ACCESS_PERMISSIONS_FEATURE_DESCRIPTION, } from './constants'; interface ConnectInstanceProps { @@ -76,7 +83,7 @@ export const SourceFeatures: React.FC = ({ features, objTy }; const SyncFrequencyFeature = ( - +

= ({ features, objTy defaultMessage="This source gets new content from {name} every {duration} (following the initial sync)." values={{ name, - duration: 2 hours, + duration: {SOURCE_FEATURES_SYNC_FREQUENCY_TIME}, }} />

@@ -93,10 +100,10 @@ export const SourceFeatures: React.FC = ({ features, objTy ); const SyncedItemsFeature = ( - + <> -

{SOURCE_FEATURES_SEARCHABLE}

+

{SOURCE_FEATURES_SEARCHABLE_DESCRIPTION}

@@ -111,10 +118,10 @@ export const SourceFeatures: React.FC = ({ features, objTy ); const SearchableContentFeature = ( - + -

{SOURCE_FEATURES_SEARCHABLE}

+

{SOURCE_FEATURES_SEARCHABLE_DESCRIPTION}

    @@ -127,25 +134,25 @@ export const SourceFeatures: React.FC = ({ features, objTy ); const RemoteFeature = ( - + -

    {SOURCE_FEATURES_REMOTE_FEATURE}

    +

    {SOURCE_FEATURES_REMOTE_FEATURE_DESCRIPTION}

    ); const PrivateFeature = ( - + -

    {SOURCE_FEATURES_PRIVATE_FEATURE}

    +

    {SOURCE_FEATURES_PRIVATE_FEATURE_DESCRIPTION}

    ); const GlobalAccessPermissionsFeature = ( - + -

    {SOURCE_FEATURES_GLOBAL_ACCESS_PERMISSIONS_FEATURE}

    +

    {SOURCE_FEATURES_GLOBAL_ACCESS_PERMISSIONS_FEATURE_DESCRIPTION}

    ); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/constants.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/constants.ts index d6ee25da6e2b1..bd86eb31005af 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/constants.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/constants.ts @@ -80,6 +80,55 @@ export const TITLE_LABEL = i18n.translate( } ); +export const URL_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.url.label', + { + defaultMessage: 'URL', + } +); + +export const COLOR_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.color.label', + { + defaultMessage: 'Color', + } +); + +export const TYPE_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.type.label', + { + defaultMessage: 'Type', + } +); + +export const MEDIA_TYPE_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.mediaType.label', + { + defaultMessage: 'Media Type', + } +); + +export const CREATED_BY_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.createdBy.label', + { + defaultMessage: 'Created By', + } +); + +export const UPDATED_BY_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.updatedBy.label', + { + defaultMessage: 'Updated By', + } +); + +export const OPTIONAL_AREA_TEXT = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.optionalArea.text', + { + defaultMessage: 'This area is optional', + } +); + export const EMPTY_FIELDS_DESCRIPTION = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.emptyFields.description', { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.tsx index 717eebf5cf873..132adedb829ac 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/field_editor_modal.tsx @@ -23,7 +23,13 @@ import { EuiSelect, } from '@elastic/eui'; -import { CANCEL_BUTTON, FIELD_LABEL, UPDATE_LABEL, ADD_LABEL } from '../../../../constants'; +import { + CANCEL_BUTTON, + FIELD_LABEL, + LABEL_LABEL, + UPDATE_LABEL, + ADD_LABEL, +} from '../../../../constants'; import { DisplaySettingsLogic } from './display_settings_logic'; @@ -67,7 +73,7 @@ export const FieldEditorModal: React.FC = () => { - + { onChange={(e) => setName(e.target.value)} /> - + { { onChange={(e) => setTitleField(e.target.value)} /> - + { onChange={(e) => setUrlField(e.target.value)} /> - + { /> { /> { /> { /> {

    {CONTENT_SUMMARY_TITLE}

    - {!summary && } + {!summary && } {!!summary && (totalDocuments === 0 ? ( emptyState @@ -233,22 +235,18 @@ export const Overview: React.FC = () => {
    {GROUP_ACCESS_TITLE}
    - - {groups.map((group, index) => ( - - + + {groups.map((group, index) => ( + - - {group.name} - - - - ))} - + /> + ))} + + ); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.tsx index a97cc85cb822a..78d4d36cf0995 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/source_content.tsx @@ -46,6 +46,8 @@ import { GO_BUTTON, RESET_BUTTON, SOURCE_CONTENT_TITLE, + SEARCH_CONTENT_PLACEHOLDER, + FILTER_CONTENT_PLACEHOLDER, CONTENT_LOADING_TEXT, } from '../constants'; import { SourceLogic } from '../source_logic'; @@ -197,13 +199,9 @@ export const SourceContent: React.FC = () => { = () => { const { closeNewGroupModal, saveNewGroup, setNewGroupName } = useActions(GroupsLogic); @@ -55,7 +61,7 @@ export const AddGroupModal: React.FC<{}> = () => { - + = ({ const { contentSources } = useValues(GroupsLogic); const allSelected = numSelected === allItems.length; - const isSources = label === 'shared content sources'; - const showEmptyState = isSources && contentSources.length < 1; + const showEmptyState = contentSources.length < 1; const handleClose = () => hideModal(group); const handleSelectAll = () => selectAll(allSelected ? [] : allItems); @@ -125,13 +138,7 @@ export const GroupManagerModal: React.FC = ({ - {i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.groups.groupManagerSelectAllToggle', - { - defaultMessage: '{action} All', - values: { action: allSelected ? 'Deselect' : 'Select' }, - } - )} + {allSelected ? ADD_SOURCE_MODAL_DESELECT_BUTTON : ADD_SOURCE_MODAL_SELECT_BUTTON} diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.tsx index 3c44261cc911f..41a1c92107661 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.tsx @@ -31,6 +31,14 @@ const GROUP_TABLE_HEADER = i18n.translate( defaultMessage: 'Group', } ); + +const GROUPS_PAGINATION_LABEL = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.groups.groupsTable.groupPagination.label', + { + defaultMessage: 'Groups', + } +); + const SOURCES_TABLE_HEADER = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.groups.groupsTable.sourcesTableHeader', { @@ -51,7 +59,7 @@ export const GroupsTable: React.FC<{}> = () => { const clearFiltersLink = hasFiltersSet ? : undefined; const paginationOptions = { - itemLabel: 'Groups', + itemLabel: GROUPS_PAGINATION_LABEL, totalPages, totalItems, activePage, diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx index b0cc35fe10dff..b908211b83a43 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx @@ -41,11 +41,31 @@ const USERS_TITLE = i18n.translate( { defaultMessage: 'Users & invitations' } ); +const INVITE_FIRST_USERS_BUTTON = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.overviewOnboardingUsersCard.inviteFirstUsers.button', + { defaultMessage: 'Invite users' } +); + +const INVITE_MORE_USERS_BUTTON = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.overviewOnboardingUsersCard.inviteMoreUsers.button', + { defaultMessage: 'Invite more users' } +); + const ONBOARDING_SOURCES_CARD_DESCRIPTION = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.overviewOnboardingSourcesCard.description', { defaultMessage: 'Add shared sources for your organization to start searching.' } ); +const ADD_FIRST_SOURCES_BUTTON = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sourcesOnboardingCard.addFirstSources.button', + { defaultMessage: 'Add sources' } +); + +const ADD_MORE_SOURCES_BUTTON = i18n.translate( + 'xpack.enterpriseSearch.workplaceSearch.sourcesOnboardingCard.addMoreSources.button', + { defaultMessage: 'Add more sources' } +); + const USERS_CARD_DESCRIPTION = i18n.translate( 'xpack.enterpriseSearch.workplaceSearch.overviewUsersCard.title', { defaultMessage: 'Nice, you’ve invited colleagues to search with you.' } @@ -82,13 +102,7 @@ export const OnboardingSteps: React.FC = () => { description={ hasOrgSources ? SOURCES_CARD_DESCRIPTION : ONBOARDING_SOURCES_CARD_DESCRIPTION } - actionTitle={i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.sourcesOnboardingCard.buttonLabel', - { - defaultMessage: 'Add {label} sources', - values: { label: sourcesCount > 0 ? 'more' : '' }, - } - )} + actionTitle={sourcesCount > 0 ? ADD_MORE_SOURCES_BUTTON : ADD_FIRST_SOURCES_BUTTON} actionPath={ADD_SOURCE_PATH} complete={hasOrgSources} /> @@ -97,13 +111,7 @@ export const OnboardingSteps: React.FC = () => { testSubj="usersButton" icon="user" description={hasUsers ? USERS_CARD_DESCRIPTION : ONBOARDING_USERS_CARD_DESCRIPTION} - actionTitle={i18n.translate( - 'xpack.enterpriseSearch.workplaceSearch.usersOnboardingCard.buttonLabel', - { - defaultMessage: 'Invite {label} users', - values: { label: accountsCount > 0 ? 'more' : '' }, - } - )} + actionTitle={accountsCount > 0 ? INVITE_MORE_USERS_BUTTON : INVITE_FIRST_USERS_BUTTON} actionPath={USERS_AND_ROLES_PATH} complete={hasUsers} /> diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.tsx index 075d95f726030..b55828f78344c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/settings/components/oauth_application.tsx @@ -47,7 +47,7 @@ import { SAVE_CHANGES_BUTTON, NON_PLATINUM_OAUTH_TITLE, NON_PLATINUM_OAUTH_DESCRIPTION, - NON_PLATINUM_OAUTH_LINK, + EXPLORE_PLATINUM_FEATURES_LINK, } from '../../../constants'; import { ENT_SEARCH_LICENSE_MANAGEMENT } from '../../../routes'; import { SettingsLogic } from '../settings_logic'; @@ -101,7 +101,7 @@ export const OauthApplication: React.FC = () => { {NON_PLATINUM_OAUTH_DESCRIPTION} - {NON_PLATINUM_OAUTH_LINK} + {EXPLORE_PLATINUM_FEATURES_LINK} ); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx index 05692a0ecab8c..61300bac47734 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/setup_guide/setup_guide.tsx @@ -55,7 +55,10 @@ export const SetupGuide: React.FC = () => { - Get started with Workplace Search + diff --git a/x-pack/plugins/file_upload/server/utils/runtime_field_utils.ts b/x-pack/plugins/file_upload/server/utils/runtime_field_utils.ts index 921741110d2a3..aba6effe175c0 100644 --- a/x-pack/plugins/file_upload/server/utils/runtime_field_utils.ts +++ b/x-pack/plugins/file_upload/server/utils/runtime_field_utils.ts @@ -6,7 +6,7 @@ */ import { estypes } from '@elastic/elasticsearch'; -import { RUNTIME_FIELD_TYPES } from '../../../../../src/plugins/data/common/index_patterns'; +import { RUNTIME_FIELD_TYPES } from '../../../../../src/plugins/data/common'; type RuntimeType = typeof RUNTIME_FIELD_TYPES[number]; diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index 4dc67a6771531..c58d064006a2b 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -2410,6 +2410,16 @@ }, "description": { "type": "string" + }, + "monitoring_enabled": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "metrics", + "logs" + ] + } } } }, diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index f2a12c0edb8a6..5a5b9838885ae 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -1513,6 +1513,13 @@ components: type: string description: type: string + monitoring_enabled: + type: array + items: + type: string + enum: + - metrics + - logs new_package_policy: title: New package policy type: object diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/new_agent_policy.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/new_agent_policy.yaml index 06048c81d979a..1184e41c5fded 100644 --- a/x-pack/plugins/fleet/common/openapi/components/schemas/new_agent_policy.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/new_agent_policy.yaml @@ -7,3 +7,10 @@ properties: type: string description: type: string + monitoring_enabled: + type: array + items: + type: string + enum: + - metrics + - logs diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx index f89bd5ef48d72..8229aced234fa 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx @@ -420,14 +420,14 @@ export const AgentPolicyForm: React.FunctionComponent = ({ <> {' '} { return ( - {formState === 'CONFIRM' && agentPolicy && ( - setFormState('VALID')} - /> - )} - {packageInfo && ( - - )} - - - - - - - {!isLoadingAgentPolicyStep && agentPolicy && packageInfo && formState === 'INVALID' ? ( - - ) : null} - - - - - {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} - - - - - - - - - - - - - + + {formState === 'CONFIRM' && agentPolicy && ( + setFormState('VALID')} + /> + )} + {packageInfo && ( + + )} + + + + + + + {!isLoadingAgentPolicyStep && + agentPolicy && + packageInfo && + formState === 'INVALID' ? ( + + ) : null} + + + + + {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} + + + + + + + + + + + + + + ); }; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx index a36bc988da89f..040070bcff7c4 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx @@ -25,6 +25,7 @@ import { EuiFlyoutBody, EuiFlyoutHeader, EuiTitle, + EuiErrorBoundary, } from '@elastic/eui'; import styled from 'styled-components'; @@ -510,93 +511,95 @@ export const EditPackagePolicyForm = memo<{ return ( - {isLoadingData ? ( - - ) : loadingError || !agentPolicy || !packageInfo ? ( - - } - error={ - loadingError || - i18n.translate('xpack.fleet.editPackagePolicy.errorLoadingDataMessage', { - defaultMessage: 'There was an error loading this integration information', - }) - } - /> - ) : ( - <> - + {isLoadingData ? ( + + ) : loadingError || !agentPolicy || !packageInfo ? ( + + } + error={ + loadingError || + i18n.translate('xpack.fleet.editPackagePolicy.errorLoadingDataMessage', { + defaultMessage: 'There was an error loading this integration information', + }) + } /> - {formState === 'CONFIRM' && ( - setFormState('VALID')} + ) : ( + <> + - )} - {isUpgrade && dryRunData && ( - <> - - - - )} - {configurePackage} - {/* Extra space to accomodate the EuiBottomBar height */} - - - - - - {agentPolicy && packageInfo && formState === 'INVALID' ? ( - - ) : null} - - - - - - - - - - - - - - - - - - - )} + {formState === 'CONFIRM' && ( + setFormState('VALID')} + /> + )} + {isUpgrade && dryRunData && ( + <> + + + + )} + {configurePackage} + {/* Extra space to accomodate the EuiBottomBar height */} + + + + + + {agentPolicy && packageInfo && formState === 'INVALID' ? ( + + ) : null} + + + + + + + + + + + + + + + + + + + )} + ); }); diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx index 1cfdc45fb7dba..42746229e5ace 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps.tsx @@ -42,7 +42,7 @@ export const DownloadStep = () => { diff --git a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx index 34476f4e3062e..e79066b0145d2 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx @@ -253,7 +253,7 @@ export function PieComponent( { meta: { type: 'number' }, } ) - ).toEqual(-100); + ).toEqual(0); }); - it('returns epsilon when metric is 0 without fallback', () => { + it('returns 0 when metric value is 0', () => { expect( getSliceValue( { a: 'Cat', b: 'Home', c: 0 }, @@ -46,7 +46,20 @@ describe('render helpers', () => { meta: { type: 'number' }, } ) - ).toEqual(Number.EPSILON); + ).toEqual(0); + }); + + it('returns 0 when metric value is infinite', () => { + expect( + getSliceValue( + { a: 'Cat', b: 'Home', c: Number.POSITIVE_INFINITY }, + { + id: 'c', + name: 'C', + meta: { type: 'number' }, + } + ) + ).toEqual(0); }); }); diff --git a/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts b/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts index 4a5587feaf271..d2858efa90153 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts +++ b/x-pack/plugins/lens/public/pie_visualization/render_helpers.ts @@ -10,10 +10,8 @@ import { Datatable, DatatableColumn } from 'src/plugins/expressions/public'; import { LensFilterEvent } from '../types'; export function getSliceValue(d: Datum, metricColumn: DatatableColumn) { - if (typeof d[metricColumn.id] === 'number' && d[metricColumn.id] !== 0) { - return d[metricColumn.id]; - } - return Number.EPSILON; + const value = d[metricColumn.id]; + return Number.isFinite(value) && value >= 0 ? value : 0; } export function getFilterContext( diff --git a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap index 69307d3d90cab..6326d8680757e 100644 --- a/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap +++ b/x-pack/plugins/lens/public/xy_visualization/__snapshots__/expression.test.tsx.snap @@ -5,6 +5,7 @@ exports[`xy_expression XYChart component it renders area 1`] = ` renderer="canvas" > { }} /> ); - wrapper.find(Settings).first().prop('onBrushEnd')!({ x: [1585757732783, 1585758880838] }); expect(onSelectRange).toHaveBeenCalledWith({ @@ -1075,6 +1074,22 @@ describe('xy_expression', () => { expect(wrapper.find(Settings).first().prop('onBrushEnd')).toBeUndefined(); }); + test('allowBrushingLastHistogramBucket is true for date histogram data', () => { + const { args } = sampleArgs(); + + const wrapper = mountWithIntl( + + ); + expect(wrapper.find(Settings).at(0).prop('allowBrushingLastHistogramBucket')).toEqual(true); + }); + test('onElementClick returns correct context data', () => { const geometry: GeometryValue = { x: 5, y: 1, accessor: 'y1', mark: null, datum: {} }; const series = { @@ -1335,6 +1350,36 @@ describe('xy_expression', () => { }); }); + test('allowBrushingLastHistogramBucket should be fakse for ordinal data', () => { + const { args, data } = sampleArgs(); + + const wrapper = mountWithIntl( + + ); + + expect(wrapper.find(Settings).at(0).prop('allowBrushingLastHistogramBucket')).toEqual(false); + }); + test('onElementClick is not triggering event on non-interactive mode', () => { const { args, data } = sampleArgs(); diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index b7f1a9dabf3c7..026d9da71beea 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -516,6 +516,7 @@ export function XYChart({ boundary: document.getElementById('app-fixed-viewport') ?? undefined, headerFormatter: (d) => safeXAccessorLabelRenderer(d.value), }} + allowBrushingLastHistogramBucket={Boolean(isTimeViz)} rotation={shouldRotate ? 90 : 0} xDomain={xDomain} onBrushEnd={interactive ? brushHandler : undefined} diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx index da320e871072c..3eaf2bea96760 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/builder.stories.tsx @@ -11,10 +11,7 @@ import { HttpStart } from 'kibana/public'; import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; import { EuiThemeProvider } from '../../../../../../../src/plugins/kibana_react/common'; -import { - fields, - getField, -} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields, getField } from '../../../../../../../src/plugins/data/common/mocks'; import { getEntryMatchAnyMock } from '../../../../common/schemas/types/entry_match_any.mock'; import { getEntryMatchMock } from '../../../../common/schemas/types/entry_match.mock'; import { getEntryExistsMock } from '../../../../common/schemas/types/entry_exists.mock'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx index 9bf2ca0fc017a..080f6095dc18a 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.stories.tsx @@ -15,7 +15,7 @@ import { } from '@kbn/securitysolution-io-ts-list-types'; import { AutocompleteStart } from '../../../../../../../src/plugins/data/public'; -import { fields } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields } from '../../../../../../../src/plugins/data/common/mocks'; import { EuiThemeProvider } from '../../../../../../../src/plugins/kibana_react/common'; import { BuilderEntryItem, EntryItemProps } from './entry_renderer'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx index f692ad96988cf..f25a30471ee9e 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx @@ -22,10 +22,7 @@ import { import { useFindLists } from '@kbn/securitysolution-list-hooks'; import { FieldSpec } from 'src/plugins/data/common'; -import { - fields, - getField, -} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields, getField } from '../../../../../../../src/plugins/data/common/mocks'; import { dataPluginMock } from '../../../../../../../src/plugins/data/public/mocks'; import { coreMock } from '../../../../../../../src/core/public/mocks'; import { getFoundListSchemaMock } from '../../../../common/schemas/response/found_list_schema.mock'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.test.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.test.tsx index b896f2a44f67b..ccda52e280586 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.test.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_item_renderer.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { mount } from 'enzyme'; import { dataPluginMock } from 'src/plugins/data/public/mocks'; -import { fields } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields } from '../../../../../../../src/plugins/data/common/mocks'; import { EuiThemeProvider } from '../../../../../../../src/plugins/kibana_react/common'; import { getExceptionListItemSchemaMock } from '../../../../common/schemas/response/exception_list_item_schema.mock'; import { getEntryMatchMock } from '../../../../common/schemas/types/entry_match.mock'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.test.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.test.tsx index 532f3457ca645..d9dfbfeee299d 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.test.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.test.tsx @@ -12,10 +12,7 @@ import { coreMock } from 'src/core/public/mocks'; import { dataPluginMock } from 'src/plugins/data/public/mocks'; import { EuiThemeProvider } from '../../../../../../../src/plugins/kibana_react/common'; -import { - fields, - getField, -} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields, getField } from '../../../../../../../src/plugins/data/common/mocks'; import { getExceptionListItemSchemaMock } from '../../../../common/schemas/response/exception_list_item_schema.mock'; import { getEntryMatchAnyMock } from '../../../../common/schemas/types/entry_match_any.mock'; import { getEmptyValue } from '../../../common/empty_value'; diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts b/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts index 8592408dde56e..bff7f389c6ac9 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts +++ b/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts @@ -57,10 +57,7 @@ import { IndexPatternBase, IndexPatternFieldBase } from '@kbn/es-query'; import { ENTRIES_WITH_IDS } from '../../../../common/constants.mock'; import { getEntryExistsMock } from '../../../../common/schemas/types/entry_exists.mock'; import { getExceptionListItemSchemaMock } from '../../../../common/schemas/response/exception_list_item_schema.mock'; -import { - fields, - getField, -} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields, getField } from '../../../../../../../src/plugins/data/common/mocks'; import { FieldSpec } from '../../../../../../../src/plugins/data/common'; import { getEntryNestedMock } from '../../../../common/schemas/types/entry_nested.mock'; import { getEntryMatchMock } from '../../../../common/schemas/types/entry_match.mock'; diff --git a/x-pack/plugins/maps/public/classes/fields/agg/agg_field_types.ts b/x-pack/plugins/maps/public/classes/fields/agg/agg_field_types.ts index ca3ef1e1e53c5..e54c846883c20 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/agg_field_types.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/agg_field_types.ts @@ -6,7 +6,7 @@ */ import { IField } from '../field'; -import { IndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../src/plugins/data/common'; import { IESAggSource } from '../../sources/es_agg_source'; import { FIELD_ORIGIN } from '../../../../common/constants'; diff --git a/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts b/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts index 37941af81f9df..141f6aea5d301 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IndexPattern } from 'src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from 'src/plugins/data/common'; import { i18n } from '@kbn/i18n'; import { AGG_TYPE } from '../../../../common/constants'; import { IESAggField, CountAggFieldParams } from './agg_field_types'; diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx index f0cec4abf0b14..e65e6ff4c463b 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx @@ -49,7 +49,7 @@ import { } from '../../../../common/descriptor_types'; import { ImmutableSourceProperty, SourceEditorArgs } from '../source'; import { ISearchSource } from '../../../../../../../src/plugins/data/common/search/search_source'; -import { IndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../src/plugins/data/common'; import { Adapters } from '../../../../../../../src/plugins/inspector/common/adapters'; import { isValidStringConfig } from '../../util/valid_string_config'; import { ITiledSingleLayerMvtParams } from '../tiled_single_layer_vector_source/tiled_single_layer_vector_source'; diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.ts index 949dc990c44fe..23f896a4b9e8f 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/get_docvalue_source_fields.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../../../../src/plugins/data/common'; import { getField } from '../../../../../common/elasticsearch_util'; export interface ScriptField { diff --git a/x-pack/plugins/maps/public/components/force_refresh_checkbox.tsx b/x-pack/plugins/maps/public/components/force_refresh_checkbox.tsx index 1b0d021b2efdb..b705d1a6dce21 100644 --- a/x-pack/plugins/maps/public/components/force_refresh_checkbox.tsx +++ b/x-pack/plugins/maps/public/components/force_refresh_checkbox.tsx @@ -15,7 +15,7 @@ interface Props { } export function ForceRefreshCheckbox({ applyForceRefresh, setApplyForceRefresh }: Props) { - const onRespondToForceRefreshChange = (event: EuiSwitchEvent) => { + const onChange = (event: EuiSwitchEvent) => { setApplyForceRefresh(event.target.checked); }; @@ -24,7 +24,7 @@ export function ForceRefreshCheckbox({ applyForceRefresh, setApplyForceRefresh } diff --git a/x-pack/plugins/maps/public/components/global_time_checkbox.tsx b/x-pack/plugins/maps/public/components/global_time_checkbox.tsx index ae0c50c063b68..70d6859b8b02a 100644 --- a/x-pack/plugins/maps/public/components/global_time_checkbox.tsx +++ b/x-pack/plugins/maps/public/components/global_time_checkbox.tsx @@ -24,7 +24,7 @@ export function GlobalTimeCheckbox({ applyGlobalTime, label, setApplyGlobalTime { { } setApplyGlobalQuery={this._onApplyGlobalQueryChange} label={i18n.translate('xpack.maps.layerPanel.join.applyGlobalQueryCheckboxLabel', { - defaultMessage: `Apply global filter to join`, + defaultMessage: `Apply global search to join`, })} /> ); diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_button/toc_entry_button.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_button/toc_entry_button.tsx index eabb2b782272b..eb703eadeecfb 100644 --- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_button/toc_entry_button.tsx +++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry_button/toc_entry_button.tsx @@ -117,7 +117,7 @@ export class TOCEntryButton extends Component { footnotes.push({ icon: , message: i18n.translate('xpack.maps.layer.isUsingSearchMsg', { - defaultMessage: 'Results narrowed by query and filters', + defaultMessage: 'Results narrowed by global search', }), }); } @@ -125,7 +125,7 @@ export class TOCEntryButton extends Component { footnotes.push({ icon: , message: i18n.translate('xpack.maps.layer.isUsingTimeFilter', { - defaultMessage: 'Results narrowed by time filter', + defaultMessage: 'Results narrowed by global time', }), }); } diff --git a/x-pack/plugins/maps/public/embeddable/types.ts b/x-pack/plugins/maps/public/embeddable/types.ts index 090a6c8d02043..7214aa78e04d3 100644 --- a/x-pack/plugins/maps/public/embeddable/types.ts +++ b/x-pack/plugins/maps/public/embeddable/types.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IndexPattern } from '../../../../../src/plugins/data/common/index_patterns'; +import type { IndexPattern } from '../../../../../src/plugins/data/common'; import { Embeddable, EmbeddableInput, diff --git a/x-pack/plugins/maps/public/lazy_load_bundle/index.ts b/x-pack/plugins/maps/public/lazy_load_bundle/index.ts index 7157b145f828d..1cbf009ffd5fa 100644 --- a/x-pack/plugins/maps/public/lazy_load_bundle/index.ts +++ b/x-pack/plugins/maps/public/lazy_load_bundle/index.ts @@ -5,8 +5,7 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { IndexPatternsContract } from 'src/plugins/data/public/index_patterns'; +import { IndexPatternsContract } from 'src/plugins/data/public'; import { AppMountParameters } from 'kibana/public'; import { IContainer } from '../../../../../src/plugins/embeddable/public'; import { LayerDescriptor } from '../../common/descriptor_types'; diff --git a/x-pack/plugins/maps/public/render_app.tsx b/x-pack/plugins/maps/public/render_app.tsx index c3f13e70fbd5c..de67939b1a42a 100644 --- a/x-pack/plugins/maps/public/render_app.tsx +++ b/x-pack/plugins/maps/public/render_app.tsx @@ -98,6 +98,7 @@ export async function renderApp( setHeaderActionMenu={setHeaderActionMenu} stateTransfer={stateTransfer} originatingApp={originatingApp} + key={routeProps.match.params.savedMapId ? routeProps.match.params.savedMapId : 'new'} /> ); } diff --git a/x-pack/plugins/maps/server/kibana_server_services.ts b/x-pack/plugins/maps/server/kibana_server_services.ts index 6b59b460ad2c9..e3c612f415c4d 100644 --- a/x-pack/plugins/maps/server/kibana_server_services.ts +++ b/x-pack/plugins/maps/server/kibana_server_services.ts @@ -7,9 +7,10 @@ import { ElasticsearchClient, ISavedObjectsRepository } from 'kibana/server'; import { SavedObjectsClient } from '../../../../src/core/server'; -import { IndexPatternsCommonService } from '../../../../src/plugins/data/server'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { IndexPatternsServiceStart } from '../../../../src/plugins/data/server/index_patterns'; +import { + IndexPatternsCommonService, + IndexPatternsServiceStart, +} from '../../../../src/plugins/data/server'; let internalRepository: ISavedObjectsRepository; export const setInternalRepository = ( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx index 4b772669729f6..c4c96adbf441d 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx @@ -13,7 +13,7 @@ import { debounce } from 'lodash'; import { fromKueryExpression, luceneStringToDsl, toElasticsearchQuery } from '@kbn/es-query'; import { estypes } from '@elastic/elasticsearch'; import { Dictionary } from '../../../../../../../common/types/common'; -import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common'; import { Query, QueryStringInput } from '../../../../../../../../../../src/plugins/data/public'; import { diff --git a/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx b/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx index 0756bf60500ef..6e8b5f762558f 100644 --- a/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx +++ b/x-pack/plugins/ml/public/application/explorer/components/explorer_query_bar/explorer_query_bar.tsx @@ -10,7 +10,7 @@ import { EuiCode, EuiInputPopover } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { fromKueryExpression, luceneStringToDsl, toElasticsearchQuery } from '@kbn/es-query'; import { Query, QueryStringInput } from '../../../../../../../../src/plugins/data/public'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; import { SEARCH_QUERY_LANGUAGE, ErrorMessage } from '../../../../../common/constants/search'; import { explorerService } from '../../explorer_dashboard_service'; import { InfluencersFilterQuery } from '../../../../../common/types/es_client'; diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx index 6489333e4e576..f6769abb610b8 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.test.tsx @@ -16,7 +16,7 @@ import React from 'react'; import { CustomUrlEditor } from './editor'; import { TIME_RANGE_TYPE, URL_TYPE } from './constants'; import { CustomUrlSettings } from './utils'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; function prepareTest(customUrl: CustomUrlSettings, setEditCustomUrlFn: (url: UrlConfig) => void) { const savedCustomUrls = [ diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx index 164226a0aaaaa..e22eb1484df2e 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/editor.tsx @@ -29,7 +29,7 @@ import { isValidLabel } from '../../../util/custom_url_utils'; import { TIME_RANGE_TYPE, URL_TYPE } from './constants'; import { UrlConfig } from '../../../../../common/types/custom_urls'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; function getLinkToOptions() { return [ diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx index da4c9b0b0cc00..ce93080558016 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/edit_job_flyout/tabs/custom_urls.tsx @@ -37,7 +37,7 @@ import { loadSavedDashboards, loadIndexPatterns } from '../edit_utils'; import { openCustomUrlWindow } from '../../../../../util/custom_url_utils'; import { Job } from '../../../../../../../common/types/anomaly_detection_jobs'; import { UrlConfig } from '../../../../../../../common/types/custom_urls'; -import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../../../../../src/plugins/data/common'; import { MlKibanaReactContextValue } from '../../../../../contexts/kibana'; const MAX_NUMBER_DASHBOARDS = 1000; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts b/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts index 41f27500cea72..7f83d0601a319 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.test.ts @@ -6,7 +6,7 @@ */ import { IUiSettingsClient } from 'kibana/public'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; import { SavedSearchSavedObject } from '../../../../../common/types/kibana'; import { createSearchItems } from './new_job_utils'; diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx index 298abd4dcc241..65d26b844e960 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx @@ -21,7 +21,7 @@ import { AnomalyChartsEmbeddableOutput, AnomalyChartsServices, } from '..'; -import type { IndexPattern } from '../../../../../../src/plugins/data/common/index_patterns'; +import type { IndexPattern } from '../../../../../../src/plugins/data/common'; import { EmbeddableLoading } from '../common/components/embeddable_loading_fallback'; export const getDefaultExplorerChartsPanelTitle = (jobIds: JobId[]) => i18n.translate('xpack.ml.anomalyChartsEmbeddable.title', { diff --git a/x-pack/plugins/ml/public/embeddables/types.ts b/x-pack/plugins/ml/public/embeddables/types.ts index 436eee0698708..7c93fb31e9a6c 100644 --- a/x-pack/plugins/ml/public/embeddables/types.ts +++ b/x-pack/plugins/ml/public/embeddables/types.ts @@ -27,7 +27,7 @@ import { ANOMALY_SWIMLANE_EMBEDDABLE_TYPE, } from './constants'; import { MlResultsService } from '../application/services/results_service'; -import { IndexPattern } from '../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern } from '../../../../../src/plugins/data/common'; export interface AnomalySwimlaneEmbeddableCustomInput { jobIds: JobId[]; diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_auth/ml/auth_high_count_logon_events_for_a_source_ip.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_auth/ml/auth_high_count_logon_events_for_a_source_ip.json index 0fe4b7805d077..cdf219152c7fd 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_auth/ml/auth_high_count_logon_events_for_a_source_ip.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_auth/ml/auth_high_count_logon_events_for_a_source_ip.json @@ -1,6 +1,6 @@ { "job_type": "anomaly_detector", - "description": "Security: Authentication - looks for an unusually large spike in successful authentication events events from a particular source IP address. This can be due to password spraying, user enumeration or brute force activity.", + "description": "Security: Authentication - looks for an unusually large spike in successful authentication events from a particular source IP address. This can be due to password spraying, user enumeration or brute force activity.", "groups": [ "security", "authentication" diff --git a/x-pack/plugins/monitoring/public/application/hooks/use_charts.tsx b/x-pack/plugins/monitoring/public/application/hooks/use_charts.tsx new file mode 100644 index 0000000000000..25d7f139e5bbe --- /dev/null +++ b/x-pack/plugins/monitoring/public/application/hooks/use_charts.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 moment from 'moment'; +import { useContext, useState, useEffect, useRef } from 'react'; +import { useHistory } from 'react-router-dom'; +import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; +import { MonitoringTimeContainer } from '../hooks/use_monitoring_time'; + +export function useCharts() { + const { services } = useKibana<{ data: any }>(); + const history = useHistory(); + const { handleTimeChange } = useContext(MonitoringTimeContainer.Context); + + const [zoomInLevel, setZoomInLevel] = useState(0); + + // We need something to know when the onBrush event was fired because the pop state event + // is also fired when the onBrush event is fired (although only on the first onBrush event) and + // causing the zoomInLevel to change. + // In Angular, this was handled by removing the listener before updating the state and adding + // it again after some milliseconds, but the same trick didn't work in React. + const [onBrushHappened, _setOnBrushHappened] = useState(false); + + const onBrushHappenedRef = useRef(onBrushHappened); + + const setOnBrushHappened = (data: boolean) => { + onBrushHappenedRef.current = data; + _setOnBrushHappened(data); + }; + + useEffect(() => { + const popstateHandler = () => { + if (onBrushHappenedRef.current) { + setOnBrushHappened(false); + } else { + setZoomInLevel((currentZoomInLevel) => { + if (currentZoomInLevel > 0) { + return currentZoomInLevel - 1; + } + return 0; + }); + } + }; + + window.addEventListener('popstate', popstateHandler); + return () => window.removeEventListener('popstate', popstateHandler); + }, []); + + const onBrush = ({ xaxis }: any) => { + const { to, from } = xaxis; + const timezone = services.uiSettings?.get('dateFormat:tz'); + const offset = getOffsetInMS(timezone); + const fromTime = moment(from - offset); + const toTime = moment(to - offset); + handleTimeChange(fromTime.toISOString(), toTime.toISOString()); + setOnBrushHappened(true); + setZoomInLevel(zoomInLevel + 1); + }; + + const zoomInfo = { + zoomOutHandler: () => history.goBack(), + showZoomOutBtn: () => zoomInLevel > 0, + }; + + return { + onBrush, + zoomInfo, + }; +} + +const getOffsetInMS = (timezone: string) => { + if (timezone === 'Browser') { + return 0; + } + const offsetInMinutes = moment.tz(timezone).utcOffset(); + const offsetInMS = offsetInMinutes * 1 * 60 * 1000; + return offsetInMS; +}; diff --git a/x-pack/plugins/monitoring/public/application/hooks/use_monitoring_time.ts b/x-pack/plugins/monitoring/public/application/hooks/use_monitoring_time.ts index 8a343a5c61cd6..e512f90d76e69 100644 --- a/x-pack/plugins/monitoring/public/application/hooks/use_monitoring_time.ts +++ b/x-pack/plugins/monitoring/public/application/hooks/use_monitoring_time.ts @@ -4,9 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useCallback, useState } from 'react'; +import { useCallback, useState, useContext } from 'react'; import createContainer from 'constate'; import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; +import { Legacy } from '../../legacy_shims'; +import { GlobalStateContext } from '../../application/global_state_context'; interface TimeOptions { from: string; @@ -25,6 +27,8 @@ const DEFAULT_REFRESH_INTERVAL_PAUSE = false; export const useMonitoringTime = () => { const { services } = useKibana<{ data: any }>(); + const state = useContext(GlobalStateContext); + const defaultTimeRange = { ...DEFAULT_TIMERANGE, ...services.data?.query.timefilter.timefilter.getTime(), @@ -39,8 +43,14 @@ export const useMonitoringTime = () => { const handleTimeChange = useCallback( (start: string, end: string) => { setTimeRange({ ...currentTimerange, from: start, to: end }); + state.time = { + from: start, + to: end, + }; + Legacy.shims.timefilter.setTime(state.time); + state.save?.(); }, - [currentTimerange, setTimeRange] + [currentTimerange, setTimeRange, state] ); return { diff --git a/x-pack/plugins/monitoring/public/application/index.tsx b/x-pack/plugins/monitoring/public/application/index.tsx index 8d6c718d77ebb..6db9343035237 100644 --- a/x-pack/plugins/monitoring/public/application/index.tsx +++ b/x-pack/plugins/monitoring/public/application/index.tsx @@ -18,6 +18,8 @@ import { GlobalStateProvider } from './global_state_context'; import { ExternalConfigContext, ExternalConfig } from './external_config_context'; import { createPreserveQueryHistory } from './preserve_query_history'; import { RouteInit } from './route_init'; +import { ElasticsearchOverviewPage } from './pages/elasticsearch/overview'; +import { CODE_PATH_ELASTICSEARCH } from '../../common/constants'; import { MonitoringTimeContainer } from './hooks/use_monitoring_time'; import { BreadcrumbContainer } from './hooks/use_breadcrumbs'; @@ -72,6 +74,14 @@ const MonitoringApp: React.FC<{ codePaths={['all']} fetchAllClusters={false} /> + + {/* ElasticSearch Views */} + = () => { { id: 'clusterName', label: clusters[0].cluster_name, - disabled: false, - description: clusters[0].cluster_name, - onClick: () => {}, testSubj: 'clusterName', + route: '/overview', }, ]; } diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/elasticsearch_template.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/elasticsearch_template.tsx new file mode 100644 index 0000000000000..13e21912df896 --- /dev/null +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/elasticsearch_template.tsx @@ -0,0 +1,69 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { includes } from 'lodash'; +import { PageTemplate } from '../page_template'; +import { TabMenuItem, PageTemplateProps } from '../page_template'; +import { ML_SUPPORTED_LICENSES } from '../../../../common/constants'; + +interface ElasticsearchTemplateProps extends PageTemplateProps { + cluster: any; +} + +export const ElasticsearchTemplate: React.FC = ({ + cluster, + ...props +}) => { + const tabs: TabMenuItem[] = [ + { + id: 'overview', + label: i18n.translate('xpack.monitoring.esNavigation.overviewLinkText', { + defaultMessage: 'Overview', + }), + route: '/elasticsearch', + }, + { + id: 'nodes', + label: i18n.translate('xpack.monitoring.esNavigation.nodesLinkText', { + defaultMessage: 'Nodes', + }), + route: '/elasticsearch/nodes', + }, + { + id: 'indices', + label: i18n.translate('xpack.monitoring.esNavigation.indicesLinkText', { + defaultMessage: 'Indices', + }), + route: '/elasticsearch/indices', + }, + ]; + + if (mlIsSupported(cluster.license)) { + tabs.push({ + id: 'ml', + label: i18n.translate('xpack.monitoring.esNavigation.jobsLinkText', { + defaultMessage: 'Machine learning jobs', + }), + route: '/elasticsearch/ml_jobs', + }); + } + + if (cluster.isCcrEnabled) { + tabs.push({ + id: 'ccr', + label: i18n.translate('xpack.monitoring.esNavigation.ccrLinkText', { + defaultMessage: 'CCR', + }), + route: '/elasticsearch/ccr', + }); + } + + return ; +}; + +const mlIsSupported = (license: any) => includes(ML_SUPPORTED_LICENSES, license.type); diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/overview.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/overview.tsx new file mode 100644 index 0000000000000..4e885229b436a --- /dev/null +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/overview.tsx @@ -0,0 +1,97 @@ +/* + * 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, { useContext, useState, useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; +import { find } from 'lodash'; +import { ElasticsearchTemplate } from './elasticsearch_template'; +import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; +import { GlobalStateContext } from '../../global_state_context'; +import { ElasticsearchOverview } from '../../../components/elasticsearch'; +import { ComponentProps } from '../../route_init'; +import { useCharts } from '../../hooks/use_charts'; + +export const ElasticsearchOverviewPage: React.FC = ({ clusters }) => { + const globalState = useContext(GlobalStateContext); + const { zoomInfo, onBrush } = useCharts(); + const { services } = useKibana<{ data: any }>(); + const clusterUuid = globalState.cluster_uuid; + const ccs = globalState.ccs; + const cluster = find(clusters, { + cluster_uuid: clusterUuid, + }); + const [data, setData] = useState(null); + const [showShardActivityHistory, setShowShardActivityHistory] = useState(false); + const toggleShardActivityHistory = () => { + setShowShardActivityHistory(!showShardActivityHistory); + }; + const filterShardActivityData = (shardActivity: any) => { + return shardActivity.filter((row: any) => { + return showShardActivityHistory || row.stage !== 'DONE'; + }); + }; + + const title = i18n.translate('xpack.monitoring.elasticsearch.overview.title', { + defaultMessage: 'Elasticsearch', + }); + + const pageTitle = i18n.translate('xpack.monitoring.elasticsearch.overview.pageTitle', { + defaultMessage: 'Elasticsearch overview', + }); + + const getPageData = useCallback(async () => { + const bounds = services.data?.query.timefilter.timefilter.getBounds(); + const url = `../api/monitoring/v1/clusters/${clusterUuid}/elasticsearch`; + + const response = await services.http?.fetch(url, { + method: 'POST', + body: JSON.stringify({ + ccs, + timeRange: { + min: bounds.min.toISOString(), + max: bounds.max.toISOString(), + }, + }), + }); + + setData(response); + }, [ccs, clusterUuid, services.data?.query.timefilter.timefilter, services.http]); + + const renderOverview = (overviewData: any) => { + if (overviewData === null) { + return null; + } + const { clusterStatus, metrics, shardActivity, logs } = overviewData || {}; + const shardActivityData = shardActivity && filterShardActivityData(shardActivity); // no filter on data = null + + return ( + + ); + }; + + return ( + +
    {renderOverview(data)}
    +
    + ); +}; diff --git a/x-pack/plugins/monitoring/public/application/pages/page_template.tsx b/x-pack/plugins/monitoring/public/application/pages/page_template.tsx index 9ce717b37051b..7c6a6c56a1322 100644 --- a/x-pack/plugins/monitoring/public/application/pages/page_template.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/page_template.tsx @@ -7,24 +7,26 @@ import { EuiTab, EuiTabs } from '@elastic/eui'; import React, { useContext, useState, useEffect } from 'react'; +import { useHistory } from 'react-router-dom'; import { useTitle } from '../hooks/use_title'; import { MonitoringToolbar } from '../../components/shared/toolbar'; import { MonitoringTimeContainer } from '../hooks/use_monitoring_time'; import { PageLoading } from '../../components'; +import { getSetupModeState, isSetupModeFeatureEnabled } from '../setup_mode/setup_mode'; +import { SetupModeFeature } from '../../../common/enums'; export interface TabMenuItem { id: string; label: string; - description: string; - disabled: boolean; - onClick: () => void; - testSubj: string; + testSubj?: string; + route: string; } -interface PageTemplateProps { +export interface PageTemplateProps { title: string; pageTitle?: string; tabs?: TabMenuItem[]; getPageData?: () => Promise; + product?: string; } export const PageTemplate: React.FC = ({ @@ -32,12 +34,14 @@ export const PageTemplate: React.FC = ({ pageTitle, tabs, getPageData, + product, children, }) => { useTitle('', title); const { currentTimerange } = useContext(MonitoringTimeContainer.Context); const [loaded, setLoaded] = useState(false); + const history = useHistory(); useEffect(() => { getPageData?.() @@ -55,6 +59,10 @@ export const PageTemplate: React.FC = ({ }); }; + const createHref = (route: string) => history.createHref({ pathname: route }); + + const isTabSelected = (route: string) => history.location.pathname === route; + return (
    @@ -64,10 +72,11 @@ export const PageTemplate: React.FC = ({ return ( {item.label} @@ -79,3 +88,31 @@ export const PageTemplate: React.FC = ({
    ); }; + +function isDisabledTab(product: string | undefined) { + const setupMode = getSetupModeState(); + if (!isSetupModeFeatureEnabled(SetupModeFeature.MetricbeatMigration)) { + return false; + } + + if (!setupMode.data) { + return false; + } + + if (!product) { + return false; + } + + const data = setupMode.data[product] || {}; + if (data.totalUniqueInstanceCount === 0) { + return true; + } + if ( + data.totalUniqueInternallyCollectedCount === 0 && + data.totalUniqueFullyMigratedCount === 0 && + data.totalUniquePartiallyMigratedCount === 0 + ) { + return true; + } + return false; +} diff --git a/x-pack/plugins/monitoring/public/application/route_init.tsx b/x-pack/plugins/monitoring/public/application/route_init.tsx index cf3b0c6646d0f..8a9a906dbd563 100644 --- a/x-pack/plugins/monitoring/public/application/route_init.tsx +++ b/x-pack/plugins/monitoring/public/application/route_init.tsx @@ -10,9 +10,12 @@ import { useClusters } from './hooks/use_clusters'; import { GlobalStateContext } from './global_state_context'; import { getClusterFromClusters } from '../lib/get_cluster_from_clusters'; +export interface ComponentProps { + clusters: []; +} interface RouteInitProps { path: string; - component: React.ComponentType; + component: React.ComponentType; codePaths: string[]; fetchAllClusters: boolean; unsetGlobalState?: boolean; @@ -58,7 +61,12 @@ export const RouteInit: React.FC = ({ } } - return loaded ? : null; + const Component = component; + return loaded ? ( + + + + ) : null; }; const isExpired = (license: any): boolean => { diff --git a/x-pack/plugins/monitoring/public/components/chart/get_chart_options.js b/x-pack/plugins/monitoring/public/components/chart/get_chart_options.js index 5cf983829b5e0..641125dd3e943 100644 --- a/x-pack/plugins/monitoring/public/components/chart/get_chart_options.js +++ b/x-pack/plugins/monitoring/public/components/chart/get_chart_options.js @@ -10,8 +10,17 @@ import { merge } from 'lodash'; import { CHART_LINE_COLOR, CHART_TEXT_COLOR } from '../../../common/constants'; export async function getChartOptions(axisOptions) { - const $injector = Legacy.shims.getAngularInjector(); - const timezone = $injector.get('config').get('dateFormat:tz'); + let timezone; + try { + const $injector = Legacy.shims.getAngularInjector(); + timezone = $injector.get('config').get('dateFormat:tz'); + } catch (error) { + if (error.message === 'Angular has been removed.') { + timezone = Legacy.shims.uiSettings?.get('dateFormat:tz'); + } else { + throw error; + } + } const opts = { legend: { show: false, diff --git a/x-pack/plugins/apm/e2e/cypress/typings/index.d.ts b/x-pack/plugins/monitoring/public/components/elasticsearch/index.d.ts similarity index 73% rename from x-pack/plugins/apm/e2e/cypress/typings/index.d.ts rename to x-pack/plugins/monitoring/public/components/elasticsearch/index.d.ts index 256db47dc74fd..4460b8432134b 100644 --- a/x-pack/plugins/apm/e2e/cypress/typings/index.d.ts +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/index.d.ts @@ -5,8 +5,4 @@ * 2.0. */ -declare namespace Cypress { - interface Chainable { - snapshot: () => {}; - } -} +export const ElasticsearchOverview: FunctionComponent; diff --git a/x-pack/plugins/monitoring/public/components/logs/logs.js b/x-pack/plugins/monitoring/public/components/logs/logs.js index 409b773a24856..3021240a157d3 100644 --- a/x-pack/plugins/monitoring/public/components/logs/logs.js +++ b/x-pack/plugins/monitoring/public/components/logs/logs.js @@ -16,9 +16,18 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { Reason } from './reason'; const getFormattedDateTimeLocal = (timestamp) => { - const injector = Legacy.shims.getAngularInjector(); - const timezone = injector.get('config').get('dateFormat:tz'); - return formatDateTimeLocal(timestamp, timezone); + try { + const injector = Legacy.shims.getAngularInjector(); + const timezone = injector.get('config').get('dateFormat:tz'); + return formatDateTimeLocal(timestamp, timezone); + } catch (error) { + if (error.message === 'Angular has been removed.') { + const timezone = Legacy.shims.uiSettings?.get('dateFormat:tz'); + return formatDateTimeLocal(timestamp, timezone); + } else { + throw error; + } + } }; const columnTimestampTitle = i18n.translate('xpack.monitoring.logs.listing.timestampTitle', { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/utils.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/utils.ts index 1af4e83ed1f54..c7d2d21581e7a 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/utils.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/utils.ts @@ -7,7 +7,7 @@ import rison, { RisonValue } from 'rison-node'; import type { SeriesUrl, UrlFilter } from '../types'; import type { AllSeries, AllShortSeries } from '../hooks/use_series_storage'; -import { IndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; +import { IndexPattern } from '../../../../../../../../src/plugins/data/common'; import { esFilters, ExistsFilter } from '../../../../../../../../src/plugins/data/public'; import { URL_KEYS } from './constants/url_constants'; import { PersistableFilter } from '../../../../../../lens/common'; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx index bad9f0d7ff415..04a3d2886718b 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx @@ -34,10 +34,7 @@ import * as useValuesListHook from '../../../hooks/use_values_list'; import indexPatternData from './configurations/test_data/test_index_pattern.json'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { setIndexPatterns } from '../../../../../../../src/plugins/data/public/services'; -import { - IndexPattern, - IndexPatternsContract, -} from '../../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { IndexPattern, IndexPatternsContract } from '../../../../../../../src/plugins/data/common'; import { createStubIndexPattern } from '../../../../../../../src/plugins/data/common/stubs'; import { AppDataType, UrlFilter } from './types'; import { dataPluginMock } from '../../../../../../../src/plugins/data/public/mocks'; diff --git a/x-pack/plugins/observability/public/hooks/use_es_search.ts b/x-pack/plugins/observability/public/hooks/use_es_search.ts index 27c4081a99775..70ffdbba22c58 100644 --- a/x-pack/plugins/observability/public/hooks/use_es_search.ts +++ b/x-pack/plugins/observability/public/hooks/use_es_search.ts @@ -12,7 +12,7 @@ import { useKibana } from '../../../../../src/plugins/kibana_react/public'; import { isCompleteResponse } from '../../../../../src/plugins/data/common'; import { useFetcher } from './use_fetcher'; -export const useEsSearch = ( +export const useEsSearch = ( params: TParams, fnDeps: any[] ) => { @@ -43,7 +43,7 @@ export const useEsSearch = ( const { rawResponse } = response as any; - return { data: rawResponse as ESSearchResponse, loading }; + return { data: rawResponse as ESSearchResponse, loading }; }; export function createEsParams(params: T): T { diff --git a/x-pack/plugins/observability/public/index.ts b/x-pack/plugins/observability/public/index.ts index 380190aa7f223..710bed3adb890 100644 --- a/x-pack/plugins/observability/public/index.ts +++ b/x-pack/plugins/observability/public/index.ts @@ -60,6 +60,7 @@ export { export const LazyAlertsFlyout = lazy(() => import('./pages/alerts/alerts_flyout')); export { useFetcher, FETCH_STATUS } from './hooks/use_fetcher'; +export { useEsSearch, createEsParams } from './hooks/use_es_search'; export * from './typings'; diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts index c87c202c0ec1f..2170b50f195b4 100644 --- a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/index.ts @@ -7,9 +7,9 @@ import apm from 'elastic-apm-node'; import { i18n } from '@kbn/i18n'; +import { getDataPath } from '@kbn/utils'; import del from 'del'; import fs from 'fs'; -import os from 'os'; import path from 'path'; import puppeteer from 'puppeteer'; import * as Rx from 'rxjs'; @@ -59,7 +59,7 @@ export class HeadlessChromiumDriverFactory { logger.warning(`Enabling the Chromium sandbox provides an additional layer of protection.`); } - this.userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chromium-')); + this.userDataDir = fs.mkdtempSync(path.join(getDataPath(), 'chromium-')); this.getChromiumArgs = (viewport: ViewportConfig) => args({ userDataDir: this.userDataDir, diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts index 9cfd0949eba99..aa27e46b85acb 100644 --- a/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver_factory/start_logs.ts @@ -10,9 +10,10 @@ import { spawn } from 'child_process'; import del from 'del'; import { mkdtempSync } from 'fs'; import { uniq } from 'lodash'; -import os, { tmpdir } from 'os'; +import os from 'os'; import { join } from 'path'; import { createInterface } from 'readline'; +import { getDataPath } from '@kbn/utils'; import { fromEvent, merge, of, timer } from 'rxjs'; import { catchError, map, reduce, takeUntil, tap } from 'rxjs/operators'; import { ReportingCore } from '../../../'; @@ -61,7 +62,7 @@ export const browserStartLogs = ( const config = core.getConfig(); const proxy = config.get('capture', 'browser', 'chromium', 'proxy'); const disableSandbox = config.get('capture', 'browser', 'chromium', 'disableSandbox'); - const userDataDir = mkdtempSync(join(tmpdir(), 'chromium-')); + const userDataDir = mkdtempSync(join(getDataPath(), 'chromium-')); const platform = process.platform; const architecture = os.arch(); diff --git a/x-pack/plugins/security_solution/common/types/timeline/note/index.ts b/x-pack/plugins/security_solution/common/types/timeline/note/index.ts index 074e4132efdff..4bda81d75d92e 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/note/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/note/index.ts @@ -31,6 +31,12 @@ export const SavedNoteRuntimeType = runtimeTypes.intersection([ export interface SavedNote extends runtimeTypes.TypeOf {} +/** + * This type represents a note type stored in a saved object that does not include any fields that reference + * other saved objects. + */ +export type NoteWithoutExternalRefs = Omit; + /** * Note Saved object type with metadata */ diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.test.tsx index 9a6879dfe6cc9..ac70d5276beb9 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/add_exception_modal/index.test.tsx @@ -16,7 +16,7 @@ import { ExceptionBuilder } from '../../../../shared_imports'; import { useAsync } from '@kbn/securitysolution-hook-utils'; import { getExceptionListSchemaMock } from '../../../../../../lists/common/schemas/response/exception_list_schema.mock'; import { useFetchIndex } from '../../../containers/source'; -import { stubIndexPattern } from 'src/plugins/data/common/index_patterns/index_pattern.stub'; +import { stubIndexPattern } from 'src/plugins/data/common/stubs'; import { useAddOrUpdateException } from '../use_add_exception'; import { useFetchOrCreateRuleExceptionList } from '../use_fetch_or_create_rule_exception_list'; import { useSignalIndex } from '../../../../detections/containers/detection_engine/alerts/use_signal_index'; diff --git a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx index 209d7d8fa273b..5e90a1b5fdf1f 100644 --- a/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/exceptions/helpers.test.tsx @@ -39,7 +39,7 @@ import { import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock'; import { getEntryMatchMock } from '../../../../../lists/common/schemas/types/entry_match.mock'; import { getCommentsArrayMock } from '../../../../../lists/common/schemas/types/comment.mock'; -import { fields } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields } from '../../../../../../../src/plugins/data/common/mocks'; import { ENTRIES, OLD_DATE_RELATIVE_TO_DATE_NOW } from '../../../../../lists/common/constants.mock'; import { CodeSignature } from '../../../../common/ecs/file'; import { IndexPatternBase } from '@kbn/es-query'; diff --git a/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.test.tsx index e9f26cfabb2b7..d5f86d310f968 100644 --- a/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.test.tsx @@ -10,10 +10,7 @@ import React from 'react'; import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; import { EntryItem } from './entry_item'; -import { - fields, - getField, -} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields, getField } from '../../../../../../../src/plugins/data/common/mocks'; import { IndexPattern } from 'src/plugins/data/public'; jest.mock('../../../common/lib/kibana'); diff --git a/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.test.tsx b/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.test.tsx index 24a0f94e05883..0e5f379a18767 100644 --- a/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.test.tsx @@ -5,10 +5,7 @@ * 2.0. */ -import { - fields, - getField, -} from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields, getField } from '../../../../../../../src/plugins/data/common/mocks'; import { Entry, EmptyEntry, ThreatMapEntries, FormattedEntry } from './types'; import { FieldSpec, IndexPattern } from '../../../../../../../src/plugins/data/common'; import moment from 'moment-timezone'; diff --git a/x-pack/plugins/security_solution/public/common/components/threat_match/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/threat_match/index.test.tsx index 058703ce369f7..872f78d91eebb 100644 --- a/x-pack/plugins/security_solution/public/common/components/threat_match/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/threat_match/index.test.tsx @@ -10,7 +10,7 @@ import { ThemeProvider } from 'styled-components'; import { mount } from 'enzyme'; import { waitFor } from '@testing-library/react'; -import { fields } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields } from '../../../../../../../src/plugins/data/common/mocks'; import { useKibana } from '../../../common/lib/kibana'; diff --git a/x-pack/plugins/security_solution/public/common/components/threat_match/list_item.test.tsx b/x-pack/plugins/security_solution/public/common/components/threat_match/list_item.test.tsx index 39fc5dee82e8c..d6704b3a9cf17 100644 --- a/x-pack/plugins/security_solution/public/common/components/threat_match/list_item.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/threat_match/list_item.test.tsx @@ -10,7 +10,7 @@ import { ThemeProvider } from 'styled-components'; import { mount } from 'enzyme'; import { useKibana } from '../../../common/lib/kibana'; -import { fields } from '../../../../../../../src/plugins/data/common/index_patterns/fields/fields.mocks'; +import { fields } from '../../../../../../../src/plugins/data/common/mocks'; import { ListItemComponent } from './list_item'; import { ThreatMapEntries } from './types'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx index 51c2cad069d7d..1793b31197f7d 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx @@ -10,7 +10,7 @@ import { mount, shallow } from 'enzyme'; import { ThemeProvider } from 'styled-components'; import { act } from '@testing-library/react'; -import { stubIndexPattern } from 'src/plugins/data/common/index_patterns/index_pattern.stub'; +import { stubIndexPattern } from 'src/plugins/data/common/stubs'; import { StepAboutRule } from '.'; import { useFetchIndex } from '../../../../common/containers/source'; import { mockAboutStepRule } from '../../../pages/detection_engine/rules/all/__mocks__/mock'; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/constants.ts b/x-pack/plugins/security_solution/server/lib/timeline/constants.ts index 9e761a1f5c318..e38096bc2e82c 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/constants.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/constants.ts @@ -15,3 +15,8 @@ export const SAVED_QUERY_ID_REF_NAME = 'savedQueryId'; * https://github.com/elastic/kibana/blob/master/src/plugins/data/public/query/saved_query/saved_query_service.ts#L54 */ export const SAVED_QUERY_TYPE = 'query'; + +/** + * The reference name for the timeline ID field within the notes and pinned events saved object definition + */ +export const TIMELINE_ID_REF_NAME = 'timelineId'; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/notes/persist_note.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/notes/persist_note.ts index 32fd87f39620b..ad94f06f2d34f 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/notes/persist_note.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/notes/persist_note.ts @@ -42,18 +42,16 @@ export const persistNoteRoute = ( const frameworkRequest = await buildFrameworkRequest(context, security, request); const { note } = request.body; const noteId = request.body?.noteId ?? null; - const version = request.body?.version ?? null; - const res = await persistNote( - frameworkRequest, + const res = await persistNote({ + request: frameworkRequest, noteId, - version, - { + note: { ...note, timelineId: note.timelineId || null, }, - true - ); + overrideOwner: true, + }); return response.ok({ body: { data: { persistNote: res } }, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts index f5e5b7dfb8ae9..c76b0858a6e42 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.test.ts @@ -119,7 +119,7 @@ describe('createTimelines', () => { }); test('persistNotes', () => { - expect((persistNotes as jest.Mock).mock.calls[0][4]).toEqual([ + expect((persistNotes as jest.Mock).mock.calls[0][3]).toEqual([ { created: 1603885051655, createdBy: 'elastic', diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.ts index e202230bf5cce..b393c753853f5 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/create_timelines/helpers.ts @@ -54,7 +54,6 @@ export const createTimelines = async ({ isImmutable ); const newTimelineSavedObjectId = responseTimeline.timeline.savedObjectId; - const newTimelineVersion = responseTimeline.timeline.version; let myPromises: unknown[] = []; if (pinnedEventIds != null && !isEmpty(pinnedEventIds)) { @@ -73,7 +72,6 @@ export const createTimelines = async ({ persistNotes( frameworkRequest, timelineSavedObjectId ?? newTimelineSavedObjectId, - newTimelineVersion, existingNoteIds, notes, overrideNotesOwner diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts index 2f51b23d73676..e0962e1fdce27 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/timelines/import_timelines/index.test.ts @@ -257,25 +257,13 @@ describe('import timelines', () => { test('should provide no noteSavedObjectId when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][1]).toBeNull(); - }); - - test('should provide new timeline version when Creating notes for a timeline', async () => { - const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][1]).toBeNull(); - }); - - test('should provide note content when Creating notes for a timeline', async () => { - const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][2]).toEqual(mockCreatedTimeline.version); + expect(mockPersistNote.mock.calls[0][0].noteId).toBeNull(); }); test('should provide new notes with original author info when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][3]).toEqual({ + expect(mockPersistNote.mock.calls[0][0].note).toEqual({ eventId: undefined, note: 'original note', created: '1584830796960', @@ -284,7 +272,7 @@ describe('import timelines', () => { updatedBy: 'original author A', timelineId: mockCreatedTimeline.savedObjectId, }); - expect(mockPersistNote.mock.calls[1][3]).toEqual({ + expect(mockPersistNote.mock.calls[1][0].note).toEqual({ eventId: mockUniqueParsedObjects[0].eventNotes[0].eventId, note: 'original event note', created: '1584830796960', @@ -293,7 +281,7 @@ describe('import timelines', () => { updatedBy: 'original author B', timelineId: mockCreatedTimeline.savedObjectId, }); - expect(mockPersistNote.mock.calls[2][3]).toEqual({ + expect(mockPersistNote.mock.calls[2][0].note).toEqual({ eventId: mockUniqueParsedObjects[0].eventNotes[1].eventId, note: 'event note2', created: '1584830796960', @@ -310,7 +298,7 @@ describe('import timelines', () => { const mockRequest = await getImportTimelinesRequest(); await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][3]).toEqual({ + expect(mockPersistNote.mock.calls[0][0].note).toEqual({ created: mockUniqueParsedObjects[0].globalNotes[0].created, createdBy: mockUniqueParsedObjects[0].globalNotes[0].createdBy, updated: mockUniqueParsedObjects[0].globalNotes[0].updated, @@ -319,7 +307,7 @@ describe('import timelines', () => { note: mockUniqueParsedObjects[0].globalNotes[0].note, timelineId: mockCreatedTimeline.savedObjectId, }); - expect(mockPersistNote.mock.calls[1][3]).toEqual({ + expect(mockPersistNote.mock.calls[1][0].note).toEqual({ created: mockUniqueParsedObjects[0].eventNotes[0].created, createdBy: mockUniqueParsedObjects[0].eventNotes[0].createdBy, updated: mockUniqueParsedObjects[0].eventNotes[0].updated, @@ -328,7 +316,7 @@ describe('import timelines', () => { note: mockUniqueParsedObjects[0].eventNotes[0].note, timelineId: mockCreatedTimeline.savedObjectId, }); - expect(mockPersistNote.mock.calls[2][3]).toEqual({ + expect(mockPersistNote.mock.calls[2][0].note).toEqual({ created: mockUniqueParsedObjects[0].eventNotes[1].created, createdBy: mockUniqueParsedObjects[0].eventNotes[1].createdBy, updated: mockUniqueParsedObjects[0].eventNotes[1].updated, @@ -640,19 +628,13 @@ describe('import timeline templates', () => { test('should provide no noteSavedObjectId when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][1]).toBeNull(); - }); - - test('should provide new timeline version when Creating notes for a timeline', async () => { - const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][2]).toEqual(mockCreatedTemplateTimeline.version); + expect(mockPersistNote.mock.calls[0][0].noteId).toBeNull(); }); test('should exclude event notes when creating notes', async () => { const mockRequest = await getImportTimelinesRequest(); await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][3]).toEqual({ + expect(mockPersistNote.mock.calls[0][0].note).toEqual({ eventId: undefined, note: mockUniqueParsedTemplateTimelineObjects[0].globalNotes[0].note, created: mockUniqueParsedTemplateTimelineObjects[0].globalNotes[0].created, @@ -792,19 +774,13 @@ describe('import timeline templates', () => { test('should provide noteSavedObjectId when Creating notes for a timeline', async () => { const mockRequest = await getImportTimelinesRequest(); await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][1]).toBeNull(); - }); - - test('should provide new timeline version when Creating notes for a timeline', async () => { - const mockRequest = await getImportTimelinesRequest(); - await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][2]).toEqual(mockCreatedTemplateTimeline.version); + expect(mockPersistNote.mock.calls[0][0].noteId).toBeNull(); }); test('should exclude event notes when creating notes', async () => { const mockRequest = await getImportTimelinesRequest(); await server.inject(mockRequest, context); - expect(mockPersistNote.mock.calls[0][3]).toEqual({ + expect(mockPersistNote.mock.calls[0][0].note).toEqual({ eventId: undefined, note: mockUniqueParsedTemplateTimelineObjects[0].globalNotes[0].note, created: mockUniqueParsedTemplateTimelineObjects[0].globalNotes[0].created, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/field_migrator.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/field_migrator.ts new file mode 100644 index 0000000000000..608c104440e78 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/field_migrator.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TIMELINE_ID_REF_NAME } from '../../constants'; +import { timelineSavedObjectType } from '../../saved_object_mappings'; +import { FieldMigrator } from '../../utils/migrator'; + +/** + * A migrator to handle moving specific fields that reference the timeline saved object to the references field within a note saved + * object. + */ +export const noteFieldsMigrator = new FieldMigrator([ + { path: 'timelineId', type: timelineSavedObjectType, name: TIMELINE_ID_REF_NAME }, +]); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/index.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/index.ts index 34914517da683..81941853c57a3 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/index.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/index.ts @@ -28,13 +28,17 @@ export interface Notes { search: string | null, sort: SortNote | null ) => Promise; - persistNote: ( - request: FrameworkRequest, - noteId: string | null, - version: string | null, - note: SavedNote, - overrideOwner: boolean - ) => Promise; + persistNote: ({ + request, + noteId, + note, + overrideOwner, + }: { + request: FrameworkRequest; + noteId: string | null; + note: SavedNote; + overrideOwner: boolean; + }) => Promise; convertSavedObjectToSavedNote: ( savedObject: unknown, timelineVersion?: string | undefined | null diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/persist_notes.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/persist_notes.ts index 58b4e33444d94..612c9083cb343 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/persist_notes.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/persist_notes.ts @@ -13,7 +13,6 @@ import { NoteResult } from '../../../../../common/types/timeline/note'; export const persistNotes = async ( frameworkRequest: FrameworkRequest, timelineSavedObjectId: string, - timelineVersion?: string | null, existingNoteIds?: string[], newNotes?: NoteResult[], overrideOwner: boolean = true @@ -26,13 +25,12 @@ export const persistNotes = async ( timelineSavedObjectId, overrideOwner ); - return persistNote( - frameworkRequest, - overrideOwner ? existingNoteIds?.find((nId) => nId === note.noteId) ?? null : null, - timelineVersion ?? null, - newNote, - overrideOwner - ); + return persistNote({ + request: frameworkRequest, + noteId: overrideOwner ? existingNoteIds?.find((nId) => nId === note.noteId) ?? null : null, + note: newNote, + overrideOwner, + }); }) ?? [] ); }; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts index 91caaa8cc8a8b..29a2aa809b808 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/notes/saved_object.ts @@ -25,11 +25,13 @@ import { NoteResult, ResponseNotes, ResponseNote, + NoteWithoutExternalRefs, } from '../../../../../common/types/timeline/note'; import { FrameworkRequest } from '../../../framework'; import { noteSavedObjectType } from '../../saved_object_mappings/notes'; -import { convertSavedObjectToSavedTimeline, pickSavedTimeline } from '../timelines'; +import { createTimeline } from '../timelines'; import { timelineSavedObjectType } from '../../saved_object_mappings'; +import { noteFieldsMigrator } from './field_migrator'; export const deleteNote = async (request: FrameworkRequest, noteIds: string[]) => { const savedObjectsClient = request.context.core.savedObjects.client; @@ -42,8 +44,7 @@ export const deleteNote = async (request: FrameworkRequest, noteIds: string[]) = export const deleteNoteByTimelineId = async (request: FrameworkRequest, timelineId: string) => { const options: SavedObjectsFindOptions = { type: noteSavedObjectType, - search: timelineId, - searchFields: ['timelineId'], + hasReference: { type: timelineSavedObjectType, id: timelineId }, }; const notesToBeDeleted = await getAllSavedNote(request, options); const savedObjectsClient = request.context.core.savedObjects.client; @@ -81,8 +82,7 @@ export const getNotesByTimelineId = async ( ): Promise => { const options: SavedObjectsFindOptions = { type: noteSavedObjectType, - search: timelineId, - searchFields: ['timelineId'], + hasReference: { type: timelineSavedObjectType, id: timelineId }, }; const notesByTimelineId = await getAllSavedNote(request, options); return notesByTimelineId.notes; @@ -106,62 +106,29 @@ export const getAllNotes = async ( return getAllSavedNote(request, options); }; -export const persistNote = async ( - request: FrameworkRequest, - noteId: string | null, - version: string | null, - note: SavedNote, - overrideOwner: boolean = true -): Promise => { +export const persistNote = async ({ + request, + noteId, + note, + overrideOwner = true, +}: { + request: FrameworkRequest; + noteId: string | null; + note: SavedNote; + overrideOwner?: boolean; +}): Promise => { try { - const savedObjectsClient = request.context.core.savedObjects.client; - if (noteId == null) { - const timelineVersionSavedObject = - note.timelineId == null - ? await (async () => { - const timelineResult = convertSavedObjectToSavedTimeline( - await savedObjectsClient.create( - timelineSavedObjectType, - pickSavedTimeline(null, {}, request.user) - ) - ); - note.timelineId = timelineResult.savedObjectId; - return timelineResult.version; - })() - : null; - - // Create new note - return { - code: 200, - message: 'success', - note: convertSavedObjectToSavedNote( - await savedObjectsClient.create( - noteSavedObjectType, - overrideOwner ? pickSavedNote(noteId, note, request.user) : note - ), - timelineVersionSavedObject != null ? timelineVersionSavedObject : undefined - ), - }; + return await createNote({ + request, + noteId, + note, + overrideOwner, + }); } // Update existing note - - const existingNote = await getSavedNote(request, noteId); - return { - code: 200, - message: 'success', - note: convertSavedObjectToSavedNote( - await savedObjectsClient.update( - noteSavedObjectType, - noteId, - overrideOwner ? pickSavedNote(noteId, note, request.user) : note, - { - version: existingNote.version || undefined, - } - ) - ), - }; + return await updateNote({ request, noteId, note, overrideOwner }); } catch (err) { if (getOr(null, 'output.statusCode', err) === 403) { const noteToReturn: NoteResult = { @@ -181,22 +148,142 @@ export const persistNote = async ( } }; +const createNote = async ({ + request, + noteId, + note, + overrideOwner = true, +}: { + request: FrameworkRequest; + noteId: string | null; + note: SavedNote; + overrideOwner?: boolean; +}) => { + const savedObjectsClient = request.context.core.savedObjects.client; + const userInfo = request.user; + + const shallowCopyOfNote = { ...note }; + let timelineVersion: string | undefined; + + if (note.timelineId == null) { + const { timeline: timelineResult } = await createTimeline({ + timelineId: null, + timeline: {}, + savedObjectsClient, + userInfo, + }); + + shallowCopyOfNote.timelineId = timelineResult.savedObjectId; + timelineVersion = timelineResult.version; + } + + const noteWithCreator = overrideOwner + ? pickSavedNote(noteId, shallowCopyOfNote, userInfo) + : shallowCopyOfNote; + + const { + transformedFields: migratedAttributes, + references, + } = noteFieldsMigrator.extractFieldsToReferences({ + data: noteWithCreator, + }); + + const createdNote = await savedObjectsClient.create( + noteSavedObjectType, + migratedAttributes, + { + references, + } + ); + + const repopulatedSavedObject = noteFieldsMigrator.populateFieldsFromReferences(createdNote); + + const convertedNote = convertSavedObjectToSavedNote(repopulatedSavedObject, timelineVersion); + + // Create new note + return { + code: 200, + message: 'success', + note: convertedNote, + }; +}; + +const updateNote = async ({ + request, + noteId, + note, + overrideOwner = true, +}: { + request: FrameworkRequest; + noteId: string; + note: SavedNote; + overrideOwner?: boolean; +}) => { + const savedObjectsClient = request.context.core.savedObjects.client; + const userInfo = request.user; + + const existingNote = await savedObjectsClient.get( + noteSavedObjectType, + noteId + ); + + const noteWithCreator = overrideOwner ? pickSavedNote(noteId, note, userInfo) : note; + + const { + transformedFields: migratedPatchAttributes, + references, + } = noteFieldsMigrator.extractFieldsToReferences({ + data: noteWithCreator, + existingReferences: existingNote.references, + }); + + const updatedNote = await savedObjectsClient.update( + noteSavedObjectType, + noteId, + migratedPatchAttributes, + { + version: existingNote.version || undefined, + references, + } + ); + + const populatedNote = noteFieldsMigrator.populateFieldsFromReferencesForPatch({ + dataBeforeRequest: note, + dataReturnedFromRequest: updatedNote, + }); + + const convertedNote = convertSavedObjectToSavedNote(populatedNote); + + return { + code: 200, + message: 'success', + note: convertedNote, + }; +}; + const getSavedNote = async (request: FrameworkRequest, NoteId: string) => { const savedObjectsClient = request.context.core.savedObjects.client; - const savedObject = await savedObjectsClient.get(noteSavedObjectType, NoteId); + const savedObject = await savedObjectsClient.get( + noteSavedObjectType, + NoteId + ); + + const populatedNote = noteFieldsMigrator.populateFieldsFromReferences(savedObject); - return convertSavedObjectToSavedNote(savedObject); + return convertSavedObjectToSavedNote(populatedNote); }; const getAllSavedNote = async (request: FrameworkRequest, options: SavedObjectsFindOptions) => { const savedObjectsClient = request.context.core.savedObjects.client; - const savedObjects = await savedObjectsClient.find(options); + const savedObjects = await savedObjectsClient.find(options); return { totalCount: savedObjects.total, - notes: savedObjects.saved_objects.map((savedObject) => - convertSavedObjectToSavedNote(savedObject) - ), + notes: savedObjects.saved_objects.map((savedObject) => { + const populatedNote = noteFieldsMigrator.populateFieldsFromReferences(savedObject); + + return convertSavedObjectToSavedNote(populatedNote); + }), }; }; @@ -233,11 +320,9 @@ const pickSavedNote = ( if (noteId == null) { savedNote.created = new Date().valueOf(); savedNote.createdBy = userInfo?.username ?? UNAUTHENTICATED_USER; - savedNote.updated = new Date().valueOf(); - savedNote.updatedBy = userInfo?.username ?? UNAUTHENTICATED_USER; - } else if (noteId != null) { - savedNote.updated = new Date().valueOf(); - savedNote.updatedBy = userInfo?.username ?? UNAUTHENTICATED_USER; } + + savedNote.updated = new Date().valueOf(); + savedNote.updatedBy = userInfo?.username ?? UNAUTHENTICATED_USER; return savedNote; }; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts index d35a023e8df5a..d25d2ece7d246 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object/timelines/index.ts @@ -426,7 +426,7 @@ export const persistTimeline = async ( } }; -const createTimeline = async ({ +export const createTimeline = async ({ timelineId, timeline, savedObjectsClient, diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/index.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/index.ts index 0b8c698bc3ea7..e4c8858321e14 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/index.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/index.ts @@ -6,3 +6,4 @@ */ export { timelinesMigrations } from './timelines'; +export { notesMigrations } from './notes'; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/notes.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/notes.test.ts new file mode 100644 index 0000000000000..0aa847cac34cd --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/notes.test.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TIMELINE_ID_REF_NAME } from '../../constants'; +import { migrateNoteTimelineIdToReferences, TimelineId } from './notes'; + +describe('notes migrations', () => { + describe('7.16.0 timelineId', () => { + it('removes the timelineId from the migrated document', () => { + const migratedDoc = migrateNoteTimelineIdToReferences({ + id: '1', + type: 'awesome', + attributes: { timelineId: '123' }, + }); + + expect(migratedDoc.attributes).toEqual({}); + expect(migratedDoc.references).toEqual([ + // importing the timeline saved object type from the timeline saved object causes a circular import and causes the jest tests to fail + { id: '123', name: TIMELINE_ID_REF_NAME, type: 'siem-ui-timeline' }, + ]); + }); + + it('preserves additional fields when migrating timeline id', () => { + const migratedDoc = migrateNoteTimelineIdToReferences({ + id: '1', + type: 'awesome', + attributes: ({ awesome: 'yes', timelineId: '123' } as unknown) as TimelineId, + }); + + expect(migratedDoc.attributes).toEqual({ awesome: 'yes' }); + expect(migratedDoc.references).toEqual([ + { id: '123', name: TIMELINE_ID_REF_NAME, type: 'siem-ui-timeline' }, + ]); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/notes.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/notes.ts new file mode 100644 index 0000000000000..a8d753e916afb --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/notes.ts @@ -0,0 +1,43 @@ +/* + * 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 { + SavedObjectMigrationMap, + SavedObjectSanitizedDoc, + SavedObjectUnsanitizedDoc, +} from 'kibana/server'; +import { timelineSavedObjectType } from '..'; +import { TIMELINE_ID_REF_NAME } from '../../constants'; +import { createMigratedDoc, createReference } from './utils'; + +export interface TimelineId { + timelineId?: string | null; +} + +export const migrateNoteTimelineIdToReferences = ( + doc: SavedObjectUnsanitizedDoc +): SavedObjectSanitizedDoc => { + const { timelineId, ...restAttributes } = doc.attributes; + + const { references: docReferences = [] } = doc; + const timelineIdReferences = createReference( + timelineId, + TIMELINE_ID_REF_NAME, + timelineSavedObjectType + ); + + return createMigratedDoc({ + doc, + attributes: restAttributes, + docReferences, + migratedReferences: timelineIdReferences, + }); +}; + +export const notesMigrations: SavedObjectMigrationMap = { + '7.16.0': migrateNoteTimelineIdToReferences, +}; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/timelines.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/timelines.ts index 7c26df4a475e9..45733d7737b62 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/timelines.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/timelines.ts @@ -11,7 +11,7 @@ import { SavedObjectUnsanitizedDoc, } from 'kibana/server'; import { SAVED_QUERY_ID_REF_NAME, SAVED_QUERY_TYPE } from '../../constants'; -import { createReference } from './utils'; +import { createMigratedDoc, createReference } from './utils'; export interface SavedQueryId { savedQueryId?: string | null; @@ -29,13 +29,12 @@ export const migrateSavedQueryIdToReferences = ( SAVED_QUERY_TYPE ); - return { - ...doc, - attributes: { - ...restAttributes, - }, - references: [...docReferences, ...savedQueryIdReferences], - }; + return createMigratedDoc({ + doc, + attributes: restAttributes, + docReferences, + migratedReferences: savedQueryIdReferences, + }); }; export const timelinesMigrations: SavedObjectMigrationMap = { diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/utils.test.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/utils.test.ts index cdf4124dc9c45..02e3fca996d5d 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/utils.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { createReference } from './utils'; +import { createMigratedDoc, createReference } from './utils'; describe('migration utils', () => { describe('createReference', () => { @@ -23,4 +23,52 @@ describe('migration utils', () => { expect(createReference(null, 'name', 'type')).toHaveLength(0); }); }); + + describe('createMigratedDoc', () => { + it('overwrites the attributes of the original doc', () => { + const doc = { + id: '1', + attributes: { + hello: '1', + }, + type: 'yes', + }; + + expect( + createMigratedDoc({ doc, attributes: {}, docReferences: [], migratedReferences: [] }) + ).toEqual({ + id: '1', + attributes: {}, + type: 'yes', + references: [], + }); + }); + + it('combines the references', () => { + const doc = { + id: '1', + attributes: { + hello: '1', + }, + type: 'yes', + }; + + expect( + createMigratedDoc({ + doc, + attributes: {}, + docReferences: [{ id: '1', name: 'name', type: 'type' }], + migratedReferences: [{ id: '5', name: 'name5', type: 'type5' }], + }) + ).toEqual({ + id: '1', + attributes: {}, + type: 'yes', + references: [ + { id: '1', name: 'name', type: 'type' }, + { id: '5', name: 'name5', type: 'type5' }, + ], + }); + }); + }); }); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/utils.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/utils.ts index 8efa6bb0ec93d..ff9b56e6ae2c9 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/migrations/utils.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { SavedObjectReference } from 'kibana/server'; +import { + SavedObjectReference, + SavedObjectSanitizedDoc, + SavedObjectUnsanitizedDoc, +} from 'kibana/server'; export function createReference( id: string | null | undefined, @@ -14,3 +18,21 @@ export function createReference( ): SavedObjectReference[] { return id != null ? [{ id, name, type }] : []; } + +export const createMigratedDoc = ({ + doc, + attributes, + docReferences, + migratedReferences, +}: { + doc: SavedObjectUnsanitizedDoc; + attributes: object; + docReferences: SavedObjectReference[]; + migratedReferences: SavedObjectReference[]; +}): SavedObjectSanitizedDoc => ({ + ...doc, + attributes: { + ...attributes, + }, + references: [...docReferences, ...migratedReferences], +}); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/notes.ts b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/notes.ts index 5815747d3e720..387f78e5059f4 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/notes.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/saved_object_mappings/notes.ts @@ -6,14 +6,12 @@ */ import { SavedObjectsType } from '../../../../../../../src/core/server'; +import { notesMigrations } from './migrations'; export const noteSavedObjectType = 'siem-ui-timeline-note'; export const noteSavedObjectMappings: SavedObjectsType['mappings'] = { properties: { - timelineId: { - type: 'keyword', - }, eventId: { type: 'keyword', }, @@ -40,4 +38,5 @@ export const noteType: SavedObjectsType = { hidden: false, namespaceType: 'single', mappings: noteSavedObjectMappings, + migrations: notesMigrations, }; diff --git a/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/boundary_index_expression.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/boundary_index_expression.tsx index 76f8eaacb8789..e1eb91af5958e 100644 --- a/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/boundary_index_expression.tsx +++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/boundary_index_expression.tsx @@ -16,8 +16,8 @@ import { ES_GEO_SHAPE_TYPES, GeoContainmentAlertParams } from '../../types'; import { GeoIndexPatternSelect } from '../util_components/geo_index_pattern_select'; import { SingleFieldSelect } from '../util_components/single_field_select'; import { ExpressionWithPopover } from '../util_components/expression_with_popover'; -import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; +import { IFieldType } from '../../../../../../../../src/plugins/data/common'; +import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; interface Props { alertParams: GeoContainmentAlertParams; diff --git a/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_by_expression.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_by_expression.tsx index a194bd40d9931..333dd69ce50f5 100644 --- a/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_by_expression.tsx +++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_by_expression.tsx @@ -12,7 +12,7 @@ import _ from 'lodash'; import { IErrorObject } from '../../../../../../triggers_actions_ui/public'; import { SingleFieldSelect } from '../util_components/single_field_select'; import { ExpressionWithPopover } from '../util_components/expression_with_popover'; -import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields'; +import { IFieldType } from '../../../../../../../../src/plugins/data/common'; interface Props { errors: IErrorObject; diff --git a/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_index_expression.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_index_expression.tsx index a3ffe7a3ade0c..e2068ca1b178f 100644 --- a/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_index_expression.tsx +++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_index_expression.tsx @@ -20,8 +20,8 @@ import { ES_GEO_FIELD_TYPES } from '../../types'; import { GeoIndexPatternSelect } from '../util_components/geo_index_pattern_select'; import { SingleFieldSelect } from '../util_components/single_field_select'; import { ExpressionWithPopover } from '../util_components/expression_with_popover'; -import { IFieldType } from '../../../../../../../../src/plugins/data/common/index_patterns/fields'; -import { IIndexPattern } from '../../../../../../../../src/plugins/data/common/index_patterns'; +import { IFieldType } from '../../../../../../../../src/plugins/data/common'; +import { IIndexPattern } from '../../../../../../../../src/plugins/data/common'; interface Props { dateField: string; diff --git a/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx b/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx index 25234126689b9..cdc5c12659ce6 100644 --- a/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx +++ b/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx @@ -14,7 +14,7 @@ import { GeoContainmentAlertParams } from '../types'; import { EntityIndexExpression } from './expressions/entity_index_expression'; import { EntityByExpression } from './expressions/entity_by_expression'; import { BoundaryIndexExpression } from './expressions/boundary_index_expression'; -import { IIndexPattern } from '../../../../../../../src/plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../../src/plugins/data/common'; import { esQuery, esKuery, diff --git a/x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts b/x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts index 907907e978123..8670b709494f0 100644 --- a/x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/index_fields/index.ts @@ -12,9 +12,8 @@ import { IndexPatternsFetcher, ISearchStrategy, SearchStrategyDependencies, + FieldDescriptor, } from '../../../../../../src/plugins/data/server'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { FieldDescriptor } from '../../../../../../src/plugins/data/server/index_patterns'; // TODO cleanup path import { diff --git a/x-pack/plugins/timelines/server/search_strategy/index_fields/mock.ts b/x-pack/plugins/timelines/server/search_strategy/index_fields/mock.ts index 76fa1d064b342..f55cd069ecd57 100644 --- a/x-pack/plugins/timelines/server/search_strategy/index_fields/mock.ts +++ b/x-pack/plugins/timelines/server/search_strategy/index_fields/mock.ts @@ -5,8 +5,7 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { FieldDescriptor } from '../../../../../../src/plugins/data/server/index_patterns'; +import { FieldDescriptor } from '../../../../../../src/plugins/data/server'; export const mockAuditbeatIndexField: FieldDescriptor[] = [ { diff --git a/x-pack/plugins/transform/public/app/common/request.test.ts b/x-pack/plugins/transform/public/app/common/request.test.ts index 6a64c6af6428f..4caeb8789bb53 100644 --- a/x-pack/plugins/transform/public/app/common/request.test.ts +++ b/x-pack/plugins/transform/public/app/common/request.test.ts @@ -29,7 +29,7 @@ import { PivotQuery, } from './request'; import { LatestFunctionConfigUI } from '../../../common/types/transform'; -import { RuntimeField } from '../../../../../../src/plugins/data/common/index_patterns'; +import { RuntimeField } from '../../../../../../src/plugins/data/common'; const simpleQuery: PivotQuery = { query_string: { query: 'airline:AAL' } }; diff --git a/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx b/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx index 68f6fea3aa943..880ac83fce8b7 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx +++ b/x-pack/plugins/transform/public/app/hooks/use_index_data.test.tsx @@ -27,7 +27,7 @@ jest.mock('./use_api'); import { useAppDependencies } from '../__mocks__/app_dependencies'; import { MlSharedContext } from '../__mocks__/shared_context'; -import { RuntimeField } from '../../../../../../src/plugins/data/common/index_patterns'; +import { RuntimeField } from '../../../../../../src/plugins/data/common'; const query: SimpleQuery = { query_string: { diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx index 6bf1abc2cc61f..7ccf986d5d497 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_create/step_create_form.tsx @@ -50,7 +50,7 @@ import { PutTransformsLatestRequestSchema, PutTransformsPivotRequestSchema, } from '../../../../../../common/api_schemas/transforms'; -import type { RuntimeField } from '../../../../../../../../../src/plugins/data/common/index_patterns'; +import type { RuntimeField } from '../../../../../../../../../src/plugins/data/common'; import { isPopulatedObject } from '../../../../../../common/shared_imports'; import { isLatestTransform } from '../../../../../../common/types/transform'; diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/common.test.ts b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/common.test.ts index 5891e8b330b94..9b8dcc1a623e3 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/common.test.ts +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/common.test.ts @@ -8,7 +8,7 @@ import { getPivotDropdownOptions } from '../common'; import { IndexPattern } from '../../../../../../../../../../src/plugins/data/public'; import { FilterAggForm } from './filter_agg/components'; -import type { RuntimeField } from '../../../../../../../../../../src/plugins/data/common/index_patterns'; +import type { RuntimeField } from '../../../../../../../../../../src/plugins/data/common'; describe('Transform: Define Pivot Common', () => { test('getPivotDropdownOptions()', () => { diff --git a/x-pack/plugins/transform/public/app/services/es_index_service.ts b/x-pack/plugins/transform/public/app/services/es_index_service.ts index 46d4cab60f734..d9014602cc393 100644 --- a/x-pack/plugins/transform/public/app/services/es_index_service.ts +++ b/x-pack/plugins/transform/public/app/services/es_index_service.ts @@ -7,7 +7,7 @@ import { HttpSetup, SavedObjectsClientContract } from 'kibana/public'; import { API_BASE_PATH } from '../../../common/constants'; -import { IIndexPattern } from '../../../../../../src/plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../src/plugins/data/common'; export class IndexService { async canDeleteIndex(http: HttpSetup) { diff --git a/x-pack/plugins/transform/server/routes/api/transforms.ts b/x-pack/plugins/transform/server/routes/api/transforms.ts index aa30a60b3421c..165293af4da73 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms.ts @@ -60,7 +60,7 @@ import { addBasePath } from '../index'; import { isRequestTimeout, fillResultsWithTimeouts, wrapError, wrapEsError } from './error_utils'; import { registerTransformsAuditMessagesRoutes } from './transforms_audit_messages'; import { registerTransformNodesRoutes } from './transforms_nodes'; -import { IIndexPattern } from '../../../../../../src/plugins/data/common/index_patterns'; +import { IIndexPattern } from '../../../../../../src/plugins/data/common'; import { isLatestTransform } from '../../../common/types/transform'; import { isKeywordDuplicate } from '../../../common/utils/field_utils'; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 082562b4e9819..e3fef367766b5 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2460,7 +2460,6 @@ "discover.fieldChooser.filter.availableFieldsTitle": "利用可能なフィールド", "discover.fieldChooser.filter.fieldSelectorLabel": "{id}フィルターオプションの選択", "discover.fieldChooser.filter.filterByTypeLabel": "タイプでフィルタリング", - "discover.fieldChooser.filter.hideMissingFieldsLabel": "未入力のフィールドを非表示", "discover.fieldChooser.filter.indexAndFieldsSectionAriaLabel": "インデックスとフィールド", "discover.fieldChooser.filter.popularTitle": "人気", "discover.fieldChooser.filter.searchableLabel": "検索可能", @@ -9755,10 +9754,6 @@ "xpack.enterpriseSearch.appSearch.tokens.search.description": "エンドポイントのみの検索では、公開検索キーが使用されます。", "xpack.enterpriseSearch.appSearch.tokens.search.name": "公開検索キー", "xpack.enterpriseSearch.appSearch.tokens.update": "APIキー'{name}'が更新されました", - "xpack.enterpriseSearch.beta.buttonLabel": "これはベータ版のユーザーインターフェースです", - "xpack.enterpriseSearch.beta.popover.description": "エンタープライズサーチのKibanaインターフェースはベータ版の機能です。この機能は変更される可能性があり、公開されている機能と同じレベルのサポートは受けられません。このインターフェースは、8.0リリースのエンタープライズサーチの唯一の管理パネルです。それまでは、スタンドアロンのエンタープライズサーチUIが提供され、サポートされます。", - "xpack.enterpriseSearch.beta.popover.footerDetail": "{learnMoreLink}または{standaloneUILink}。", - "xpack.enterpriseSearch.beta.popover.title": "Kibanaのエンタープライズサーチはベータ版のユーザーインターフェースです", "xpack.enterpriseSearch.emailLabel": "メール", "xpack.enterpriseSearch.enterpriseSearch.setupGuide.description": "場所を問わず、何でも検索。組織を支える多忙なチームのために、パワフルでモダンな検索エクスペリエンスを簡単に導入できます。Webサイトやアプリ、ワークプレイスに事前調整済みの検索をすばやく追加しましょう。何でもシンプルに検索できます。", "xpack.enterpriseSearch.enterpriseSearch.setupGuide.notConfigured": "エンタープライズサーチはまだKibanaインスタンスで構成されていません。", @@ -9963,7 +9958,6 @@ "xpack.enterpriseSearch.workplaceSearch.contentSource.configCompleted.privateDisabled.button": "非公開コンテンツソースの詳細。", "xpack.enterpriseSearch.workplaceSearch.contentSource.configCompleted.privateDisabled.message": "必ずセキュリティ設定で{securityLink}してください。", "xpack.enterpriseSearch.workplaceSearch.contentSource.configCustom.button": "カスタムAPIソースの作成", - "xpack.enterpriseSearch.workplaceSearch.contentSource.configCustom.docs.link": "カスタムAPIソースの詳細については、{link}。", "xpack.enterpriseSearch.workplaceSearch.contentSource.configDocs.applicationPortal.button": "{name}アプリケーションポータル", "xpack.enterpriseSearch.workplaceSearch.contentSource.configIntro.alt.text": "接続の例", "xpack.enterpriseSearch.workplaceSearch.contentSource.configIntro.configure.button": "{name}の構成", @@ -10027,11 +10021,6 @@ "xpack.enterpriseSearch.workplaceSearch.contentSource.schema.updated.message": "スキーマが更新されました。", "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.documentLevelPermissions.text": "ドキュメントレベルのアクセス権は、定義されたルールに基づいて、ユーザーコンテンツアクセスを管理します。個人またはグループの特定のドキュメントへのアクセスを許可または拒否します。", "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.documentLevelPermissions.title": "プラチナライセンスで提供されているドキュメントレベルのアクセス権", - "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.explore.button": "プラチナ機能の詳細", - "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.globalAccessPermissions.text": "接続しているサービスユーザーがアクセス可能なすべてのドキュメントは同期され、組織のユーザーまたはグループのユーザーが使用できるようになります。ドキュメントは直ちに検索で使用できます", - "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.private.text": "返された結果は自分に固有で関連性があります。このソースを接続しても、個人データは他の検索ユーザーに公開されません。", - "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.remote.text": "メッセージデータと他の情報は、Workplace Searchエクスペリエンスからリアルタイムで検索可能です。", - "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.searchable.text": "次の項目は検索可能です。", "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.syncFrequency.text": "このソースは、(初回の同期の後){duration}ごとに{name}から新しいコンテンツを取得します。", "xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.displaySettings.description": "カスタムAPIソース検索結果の内容と表示をカスタマイズします。", "xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.displaySettings.title": "表示設定", @@ -10083,7 +10072,6 @@ "xpack.enterpriseSearch.workplaceSearch.groups.filterSources.buttonText": "ソース", "xpack.enterpriseSearch.workplaceSearch.groups.groupDeleted": "グループ「{groupName}」が正常に削除されました。", "xpack.enterpriseSearch.workplaceSearch.groups.groupManagerHeaderTitle": "{label}を管理", - "xpack.enterpriseSearch.workplaceSearch.groups.groupManagerSelectAllToggle": "{action}すべて", "xpack.enterpriseSearch.workplaceSearch.groups.groupManagerSourceEmpty.body": "まだ共有コンテンツソースが追加されていない可能性があります。", "xpack.enterpriseSearch.workplaceSearch.groups.groupManagerSourceEmpty.title": "おっと!", "xpack.enterpriseSearch.workplaceSearch.groups.groupManagerUpdateAddSourceButton": "共有ソースを追加", @@ -10146,7 +10134,6 @@ "xpack.enterpriseSearch.workplaceSearch.nav.settingsSourcePrioritization": "コンテンツソースコネクター", "xpack.enterpriseSearch.workplaceSearch.nav.sources": "ソース", "xpack.enterpriseSearch.workplaceSearch.nonPlatinumOauthDescription": "Workplace Search検索APIを安全に使用するために、OAuthアプリケーションを構成します。プラチナライセンスにアップグレードして、検索APIを有効にし、OAuthアプリケーションを作成します。", - "xpack.enterpriseSearch.workplaceSearch.nonPlatinumOauthLinkLabel": "プラチナ機能の詳細", "xpack.enterpriseSearch.workplaceSearch.nonPlatinumOauthTitle": "カスタム検索アプリケーションのOAuthを構成", "xpack.enterpriseSearch.workplaceSearch.oauth.description": "組織のOAuthクライアントを作成します。", "xpack.enterpriseSearch.workplaceSearch.oauthAuthorize.authorizationDescription": "{strongClientName}によるアカウントの使用を許可しますか?", @@ -10351,7 +10338,6 @@ "xpack.enterpriseSearch.workplaceSearch.sources.settingsModal.text": "ソースドキュメントはWorkplace Searchから削除されます。{lineBreak}{name}を削除しますか?", "xpack.enterpriseSearch.workplaceSearch.sources.shared.empty.description": "コンテンツソースが自分と共有されたら、ここに表示され、検索エクスペリエンスで使用できます。", "xpack.enterpriseSearch.workplaceSearch.sources.shared.empty.title": "コンテンツソースがありません", - "xpack.enterpriseSearch.workplaceSearch.sources.sourceContent.searchBar.placeholder": "{prefix}コンテンツ...", "xpack.enterpriseSearch.workplaceSearch.sources.sourceContent.title": "ソースコンテンツ", "xpack.enterpriseSearch.workplaceSearch.sources.sourceDisabled.button": "プラチナライセンスの詳細", "xpack.enterpriseSearch.workplaceSearch.sources.sourceDisabled.description": "組織のライセンスレベルが変更されました。データは安全ですが、ドキュメントレベルのアクセス権はサポートされなくなり、このソースの検索は無効になっています。このソースを再有効化するには、プラチナライセンスにアップグレードしてください。", @@ -10386,7 +10372,6 @@ "xpack.enterpriseSearch.workplaceSearch.sources.time.header": "時間", "xpack.enterpriseSearch.workplaceSearch.sources.totalDocuments.label": "合計ドキュメント数", "xpack.enterpriseSearch.workplaceSearch.sources.understandButton": "理解します", - "xpack.enterpriseSearch.workplaceSearch.sourcesOnboardingCard.buttonLabel": "{label}ソースを追加", "xpack.enterpriseSearch.workplaceSearch.sourcesView.modal.docPermissions.description": "ユーザーおよびグループマッピングが構成されるまでは、ドキュメントをWorkplace Searchから検索できません。{documentPermissionsLink}", "xpack.enterpriseSearch.workplaceSearch.sourcesView.modal.heading": "{addedSourceName}には追加の構成が必要です", "xpack.enterpriseSearch.workplaceSearch.sourcesView.modal.success": "{addedSourceName}は正常に接続されました。初期コンテンツ同期がすでに実行中です。ドキュメントレベルのアクセス権情報を同期することを選択したので、{externalIdentitiesLink}を使用してユーザーおよびグループマッピングを指定する必要があります。", @@ -10394,7 +10379,6 @@ "xpack.enterpriseSearch.workplaceSearch.title": "Workplace Search", "xpack.enterpriseSearch.workplaceSearch.update.label": "更新", "xpack.enterpriseSearch.workplaceSearch.url.label": "URL", - "xpack.enterpriseSearch.workplaceSearch.usersOnboardingCard.buttonLabel": "{label}ユーザーを招待", "xpack.eventLog.savedObjectProviderRegistry.getProvidersClient.noDefaultProvider": "イベントログにはデフォルトプロバイダーが必要です。", "xpack.features.advancedSettingsFeatureName": "高度な設定", "xpack.features.dashboardFeatureName": "ダッシュボード", @@ -26889,4 +26873,4 @@ "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "フィールドを選択してください。", "xpack.watcher.watcherDescription": "アラートの作成、管理、監視によりデータへの変更を検知します。" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index f4bb126eb6d92..786eb5bef3286 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2485,7 +2485,6 @@ "discover.fieldChooser.filter.availableFieldsTitle": "可用字段", "discover.fieldChooser.filter.fieldSelectorLabel": "{id} 筛选选项的选择", "discover.fieldChooser.filter.filterByTypeLabel": "按类型筛选", - "discover.fieldChooser.filter.hideMissingFieldsLabel": "隐藏缺失字段", "discover.fieldChooser.filter.indexAndFieldsSectionAriaLabel": "索引和字段", "discover.fieldChooser.filter.popularTitle": "常见", "discover.fieldChooser.filter.searchableLabel": "可搜索", @@ -9855,10 +9854,6 @@ "xpack.enterpriseSearch.appSearch.tokens.search.description": "公有搜索密钥仅用于搜索终端。", "xpack.enterpriseSearch.appSearch.tokens.search.name": "公有搜索密钥", "xpack.enterpriseSearch.appSearch.tokens.update": "API 密钥“{name}”已更新", - "xpack.enterpriseSearch.beta.buttonLabel": "这是公测版用户界面", - "xpack.enterpriseSearch.beta.popover.description": "Kibana 的企业搜索界面是公测版功能。其可能会进行更改,不提供与正式发行的功能一样的支持等级。此界面将成为 8.0 版本中企业搜索的唯一管理面板。届时,单机版企业搜索 UI 仍可用且受支持。", - "xpack.enterpriseSearch.beta.popover.footerDetail": "{learnMoreLink}或{standaloneUILink}。", - "xpack.enterpriseSearch.beta.popover.title": "Kibana 中的 Enterprise Search 是公测版用户界面", "xpack.enterpriseSearch.emailLabel": "电子邮件", "xpack.enterpriseSearch.enterpriseSearch.setupGuide.description": "随时随地进行全面搜索。为工作繁忙的团队轻松实现强大的现代搜索体验。将预先调整的搜索功能快速添加到您的网站、应用或工作区。全面搜索就是这么简单。", "xpack.enterpriseSearch.enterpriseSearch.setupGuide.notConfigured": "企业搜索尚未在您的 Kibana 实例中配置。", @@ -10064,7 +10059,6 @@ "xpack.enterpriseSearch.workplaceSearch.contentSource.configCompleted.privateDisabled.button": "详细了解专用内容源。", "xpack.enterpriseSearch.workplaceSearch.contentSource.configCompleted.privateDisabled.message": "切记在安全设置中{securityLink}。", "xpack.enterpriseSearch.workplaceSearch.contentSource.configCustom.button": "创建定制 API 源", - "xpack.enterpriseSearch.workplaceSearch.contentSource.configCustom.docs.link": "{link}以详细了解定制 API 源。", "xpack.enterpriseSearch.workplaceSearch.contentSource.configDocs.applicationPortal.button": "{name} 应用程序门户", "xpack.enterpriseSearch.workplaceSearch.contentSource.configIntro.alt.text": "连接图示", "xpack.enterpriseSearch.workplaceSearch.contentSource.configIntro.configure.button": "配置 {name}", @@ -10128,11 +10122,6 @@ "xpack.enterpriseSearch.workplaceSearch.contentSource.schema.updated.message": "架构已更新。", "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.documentLevelPermissions.text": "文档级别权限根据定义的规则管理用户内容访问权限。允许或拒绝个人和组对特定文档的访问。", "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.documentLevelPermissions.title": "适用于白金级许可证的文档级别权限", - "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.explore.button": "了解白金级功能", - "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.globalAccessPermissions.text": "连接服务可访问的所有文档将同步,并提供给组织的用户或组的用户。文档立即可供搜索", - "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.private.text": "返回的结果特定于您且与您相关。连接此源不会将您的个人数据暴露给其他搜索用户 - 只有您可以看到。", - "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.remote.text": "在 Workplace Search 中,可实时搜索消息数据和其他信息。", - "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.searchable.text": "以下项目可搜索:", "xpack.enterpriseSearch.workplaceSearch.contentSource.sourceFeatures.syncFrequency.text": "此源每 {duration} 从 {name} 获取新内容(在初始同步后)。", "xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.displaySettings.description": "对定制 API 源搜索结果的内容和样式进行定制。", "xpack.enterpriseSearch.workplaceSearch.contentSources.displaySettings.displaySettings.title": "显示设置", @@ -10184,7 +10173,6 @@ "xpack.enterpriseSearch.workplaceSearch.groups.filterSources.buttonText": "源", "xpack.enterpriseSearch.workplaceSearch.groups.groupDeleted": "组“{groupName}”已成功删除。", "xpack.enterpriseSearch.workplaceSearch.groups.groupManagerHeaderTitle": "管理 {label}", - "xpack.enterpriseSearch.workplaceSearch.groups.groupManagerSelectAllToggle": "全部{action}", "xpack.enterpriseSearch.workplaceSearch.groups.groupManagerSourceEmpty.body": "可能您尚未添加任何共享内容源。", "xpack.enterpriseSearch.workplaceSearch.groups.groupManagerSourceEmpty.title": "哎哟!", "xpack.enterpriseSearch.workplaceSearch.groups.groupManagerUpdateAddSourceButton": "添加共享源", @@ -10247,7 +10235,6 @@ "xpack.enterpriseSearch.workplaceSearch.nav.settingsSourcePrioritization": "内容源连接器", "xpack.enterpriseSearch.workplaceSearch.nav.sources": "源", "xpack.enterpriseSearch.workplaceSearch.nonPlatinumOauthDescription": "配置 OAuth 应用程序,以安全使用 Workplace Search 搜索 API。升级到白金级许可证,以启用搜索 API 并创建您的 OAuth 应用程序。", - "xpack.enterpriseSearch.workplaceSearch.nonPlatinumOauthLinkLabel": "了解白金级功能", "xpack.enterpriseSearch.workplaceSearch.nonPlatinumOauthTitle": "正在为定制搜索应用程序配置 OAuth", "xpack.enterpriseSearch.workplaceSearch.oauth.description": "为您的组织创建 OAuth 客户端。", "xpack.enterpriseSearch.workplaceSearch.oauthAuthorize.authorizationDescription": "授权 {strongClientName} 使用您的帐户?", @@ -10453,7 +10440,6 @@ "xpack.enterpriseSearch.workplaceSearch.sources.settingsModal.text": "将从 Workplace Search 中删除您的源文档。{lineBreak}确定要移除 {name}?", "xpack.enterpriseSearch.workplaceSearch.sources.shared.empty.description": "内容源共享给您后,其将显示在此处,并可通过搜索体验获取。", "xpack.enterpriseSearch.workplaceSearch.sources.shared.empty.title": "没有可用的内容源", - "xpack.enterpriseSearch.workplaceSearch.sources.sourceContent.searchBar.placeholder": "{prefix} 内容......", "xpack.enterpriseSearch.workplaceSearch.sources.sourceContent.title": "源内容", "xpack.enterpriseSearch.workplaceSearch.sources.sourceDisabled.button": "了解白金级许可证", "xpack.enterpriseSearch.workplaceSearch.sources.sourceDisabled.description": "您的组织的许可证级别已更改。您的数据是安全的,但不再支持文档级别权限,且已禁止搜索此源。升级到白金级许可证,以重新启用此源。", @@ -10488,7 +10474,6 @@ "xpack.enterpriseSearch.workplaceSearch.sources.time.header": "时间", "xpack.enterpriseSearch.workplaceSearch.sources.totalDocuments.label": "总文档数", "xpack.enterpriseSearch.workplaceSearch.sources.understandButton": "我理解", - "xpack.enterpriseSearch.workplaceSearch.sourcesOnboardingCard.buttonLabel": "添加 {label} 源", "xpack.enterpriseSearch.workplaceSearch.sourcesOnboardingCard.description": "您已添加 {sourcesCount, number} 个共享{sourcesCount, plural, other {源}}。祝您搜索愉快。", "xpack.enterpriseSearch.workplaceSearch.sourcesView.modal.docPermissions.description": "只有在配置用户和组映射后,才能在 Workplace Search 中搜索文档。{documentPermissionsLink}。", "xpack.enterpriseSearch.workplaceSearch.sourcesView.modal.heading": "{addedSourceName} 需要其他配置。", @@ -10497,7 +10482,6 @@ "xpack.enterpriseSearch.workplaceSearch.title": "Workplace Search", "xpack.enterpriseSearch.workplaceSearch.update.label": "更新", "xpack.enterpriseSearch.workplaceSearch.url.label": "URL", - "xpack.enterpriseSearch.workplaceSearch.usersOnboardingCard.buttonLabel": "邀请 {label} 用户", "xpack.eventLog.savedObjectProviderRegistry.getProvidersClient.noDefaultProvider": "事件日志需要默认提供程序。", "xpack.features.advancedSettingsFeatureName": "高级设置", "xpack.features.dashboardFeatureName": "仪表板", @@ -27335,4 +27319,4 @@ "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "此字段必填。", "xpack.watcher.watcherDescription": "通过创建、管理和监测警报来检测数据中的更改。" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/uptime/common/constants/rest_api.ts b/x-pack/plugins/uptime/common/constants/rest_api.ts index b49ccc3222a07..655f9629b848b 100644 --- a/x-pack/plugins/uptime/common/constants/rest_api.ts +++ b/x-pack/plugins/uptime/common/constants/rest_api.ts @@ -6,7 +6,6 @@ */ export enum API_URLS { - CERTS = '/api/uptime/certs', INDEX_PATTERN = `/api/uptime/index_pattern`, INDEX_STATUS = '/api/uptime/index_status', MONITOR_LIST = `/api/uptime/monitor/list`, diff --git a/x-pack/plugins/uptime/common/requests/get_certs_request_body.ts b/x-pack/plugins/uptime/common/requests/get_certs_request_body.ts new file mode 100644 index 0000000000000..5a729c7e3b96d --- /dev/null +++ b/x-pack/plugins/uptime/common/requests/get_certs_request_body.ts @@ -0,0 +1,183 @@ +/* + * 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 { estypes } from '@elastic/elasticsearch'; +import { CertResult, GetCertsParams, Ping } from '../runtime_types'; +import { createEsQuery } from '../utils/es_search'; + +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { CertificatesResults } from '../../server/lib/requests/get_certs'; +import { asMutableArray } from '../utils/as_mutable_array'; + +enum SortFields { + 'issuer' = 'tls.server.x509.issuer.common_name', + 'not_after' = 'tls.server.x509.not_after', + 'not_before' = 'tls.server.x509.not_before', + 'common_name' = 'tls.server.x509.subject.common_name', +} + +export const DEFAULT_SORT = 'not_after'; +export const DEFAULT_DIRECTION = 'asc'; +export const DEFAULT_SIZE = 20; +export const DEFAULT_FROM = 'now-5m'; +export const DEFAULT_TO = 'now'; + +export const getCertsRequestBody = ({ + pageIndex, + search, + notValidBefore, + notValidAfter, + size = DEFAULT_SIZE, + to = DEFAULT_TO, + from = DEFAULT_FROM, + sortBy = DEFAULT_SORT, + direction = DEFAULT_DIRECTION, +}: GetCertsParams) => { + const sort = SortFields[sortBy as keyof typeof SortFields]; + + const searchRequest = createEsQuery({ + body: { + from: pageIndex * size, + size, + sort: asMutableArray([ + { + [sort]: { + order: direction, + }, + }, + ]), + query: { + bool: { + ...(search + ? { + minimum_should_match: 1, + should: [ + { + multi_match: { + query: escape(search), + type: 'phrase_prefix' as const, + fields: [ + 'monitor.id.text', + 'monitor.name.text', + 'url.full.text', + 'tls.server.x509.subject.common_name.text', + 'tls.server.x509.issuer.common_name.text', + ], + }, + }, + ], + } + : {}), + filter: [ + { + exists: { + field: 'tls.server.hash.sha256', + }, + }, + { + range: { + 'monitor.timespan': { + gte: from, + lte: to, + }, + }, + }, + ...(notValidBefore + ? [ + { + range: { + 'tls.certificate_not_valid_before': { + lte: notValidBefore, + }, + }, + }, + ] + : []), + ...(notValidAfter + ? [ + { + range: { + 'tls.certificate_not_valid_after': { + lte: notValidAfter, + }, + }, + }, + ] + : []), + ] as estypes.QueryDslQueryContainer, + }, + }, + _source: [ + 'monitor.id', + 'monitor.name', + 'tls.server.x509.issuer.common_name', + 'tls.server.x509.subject.common_name', + 'tls.server.hash.sha1', + 'tls.server.hash.sha256', + 'tls.server.x509.not_after', + 'tls.server.x509.not_before', + ], + collapse: { + field: 'tls.server.hash.sha256', + inner_hits: { + _source: { + includes: ['monitor.id', 'monitor.name', 'url.full'], + }, + collapse: { + field: 'monitor.id', + }, + name: 'monitors', + sort: [{ 'monitor.id': 'asc' as const }], + }, + }, + aggs: { + total: { + cardinality: { + field: 'tls.server.hash.sha256', + }, + }, + }, + }, + }); + + return searchRequest.body; +}; + +export const processCertsResult = (result: CertificatesResults): CertResult => { + const certs = result.hits?.hits?.map((hit) => { + const ping = hit._source; + const server = ping.tls?.server!; + + const notAfter = server?.x509?.not_after; + const notBefore = server?.x509?.not_before; + const issuer = server?.x509?.issuer?.common_name; + const commonName = server?.x509?.subject?.common_name; + const sha1 = server?.hash?.sha1; + const sha256 = server?.hash?.sha256; + + const monitors = hit.inner_hits!.monitors.hits.hits.map((monitor) => { + const monitorPing = monitor._source as Ping; + + return { + name: monitorPing?.monitor.name, + id: monitorPing?.monitor.id, + url: monitorPing?.url?.full, + }; + }); + + return { + monitors, + issuer, + sha1, + sha256: sha256 as string, + not_after: notAfter, + not_before: notBefore, + common_name: commonName, + }; + }); + const total = result.aggregations?.total?.value ?? 0; + return { certs, total }; +}; diff --git a/x-pack/plugins/uptime/common/runtime_types/certs.ts b/x-pack/plugins/uptime/common/runtime_types/certs.ts index 3a5e885292500..c1a411effb903 100644 --- a/x-pack/plugins/uptime/common/runtime_types/certs.ts +++ b/x-pack/plugins/uptime/common/runtime_types/certs.ts @@ -9,10 +9,7 @@ import * as t from 'io-ts'; export const GetCertsParamsType = t.intersection([ t.type({ - index: t.number, - size: t.number, - sortBy: t.string, - direction: t.string, + pageIndex: t.number, }), t.partial({ search: t.string, @@ -20,6 +17,9 @@ export const GetCertsParamsType = t.intersection([ notValidAfter: t.string, from: t.string, to: t.string, + sortBy: t.string, + direction: t.string, + size: t.number, }), ]); diff --git a/x-pack/plugins/uptime/common/utils/es_search.ts b/x-pack/plugins/uptime/common/utils/es_search.ts new file mode 100644 index 0000000000000..ba72d09a4e8ef --- /dev/null +++ b/x-pack/plugins/uptime/common/utils/es_search.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { estypes } from '@elastic/elasticsearch'; + +export function createEsQuery(params: T): T { + return params; +} diff --git a/x-pack/plugins/uptime/public/components/certificates/__snapshots__/certificates_list.test.tsx.snap b/x-pack/plugins/uptime/public/components/certificates/__snapshots__/certificates_list.test.tsx.snap deleted file mode 100644 index dc808ffcdd22b..0000000000000 --- a/x-pack/plugins/uptime/public/components/certificates/__snapshots__/certificates_list.test.tsx.snap +++ /dev/null @@ -1,105 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CertificateList shallow renders expected elements for valid props 1`] = ` - - - - - -`; diff --git a/x-pack/plugins/uptime/public/components/certificates/cert_search.tsx b/x-pack/plugins/uptime/public/components/certificates/cert_search.tsx index 08650edbaac23..391d38921fee5 100644 --- a/x-pack/plugins/uptime/public/components/certificates/cert_search.tsx +++ b/x-pack/plugins/uptime/public/components/certificates/cert_search.tsx @@ -5,9 +5,10 @@ * 2.0. */ -import React, { ChangeEvent } from 'react'; +import React, { ChangeEvent, useState } from 'react'; import { EuiFieldSearch } from '@elastic/eui'; import styled from 'styled-components'; +import useDebounce from 'react-use/lib/useDebounce'; import * as labels from './translations'; const WrapFieldSearch = styled('div')` @@ -19,10 +20,20 @@ interface Props { } export const CertificateSearch: React.FC = ({ setSearch }) => { + const [debouncedValue, setDebouncedValue] = useState(''); + const onChange = (e: ChangeEvent) => { - setSearch(e.target.value); + setDebouncedValue(e.target.value); }; + useDebounce( + () => { + setSearch(debouncedValue); + }, + 350, + [debouncedValue] + ); + return ( { - const { data: certificates } = useSelector(certificatesSelector); + const total = useSelector(certificatesSelector); return ( {certificates?.total ?? 0}, + total: {total ?? 0}, }} /> ); diff --git a/x-pack/plugins/uptime/public/components/certificates/certificates_list.test.tsx b/x-pack/plugins/uptime/public/components/certificates/certificates_list.test.tsx index ec6a5d91a67c3..ff54267b8b8b4 100644 --- a/x-pack/plugins/uptime/public/components/certificates/certificates_list.test.tsx +++ b/x-pack/plugins/uptime/public/components/certificates/certificates_list.test.tsx @@ -6,11 +6,11 @@ */ import React from 'react'; -import { shallowWithRouter } from '../../lib'; import { CertificateList, CertSort } from './certificates_list'; +import { render } from '../../lib/helper/rtl_helpers'; describe('CertificateList', () => { - it('shallow renders expected elements for valid props', () => { + it('render empty state', () => { const page = { index: 0, size: 10, @@ -20,8 +20,59 @@ describe('CertificateList', () => { direction: 'asc', }; + const { getByText } = render( + + ); + expect( - shallowWithRouter() - ).toMatchSnapshot(); + getByText('No Certificates found. Note: Certificates are only visible for Heartbeat 7.8+') + ).toBeInTheDocument(); + }); + + it('renders certificates list', () => { + const page = { + index: 0, + size: 10, + }; + const sort: CertSort = { + field: 'not_after', + direction: 'asc', + }; + + const { getByText } = render( + + ); + + expect(getByText('BadSSL Expired')).toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/uptime/public/components/certificates/certificates_list.tsx b/x-pack/plugins/uptime/public/components/certificates/certificates_list.tsx index f01cdc5dfb9c8..69b39538cb3e0 100644 --- a/x-pack/plugins/uptime/public/components/certificates/certificates_list.tsx +++ b/x-pack/plugins/uptime/public/components/certificates/certificates_list.tsx @@ -7,13 +7,11 @@ import React from 'react'; import moment from 'moment'; -import { useSelector } from 'react-redux'; import { Direction, EuiBasicTable } from '@elastic/eui'; -import { certificatesSelector } from '../../state/certificates/certificates'; import { CertStatus } from './cert_status'; import { CertMonitors } from './cert_monitors'; import * as labels from './translations'; -import { Cert, CertMonitor } from '../../../common/runtime_types'; +import { Cert, CertMonitor, CertResult } from '../../../common/runtime_types'; import { FingerprintCol } from './fingerprint_col'; import { LOADING_CERTIFICATES, NO_CERTS_AVAILABLE } from './translations'; @@ -40,11 +38,10 @@ interface Props { page: Page; sort: CertSort; onChange: (page: Page, sort: CertSort) => void; + certificates: CertResult & { loading?: boolean }; } -export const CertificateList: React.FC = ({ page, sort, onChange }) => { - const { data: certificates, loading } = useSelector(certificatesSelector); - +export const CertificateList: React.FC = ({ page, certificates, sort, onChange }) => { const onTableChange = (newVal: Partial) => { onChange(newVal.page as Page, newVal.sort as CertSort); }; @@ -100,7 +97,7 @@ export const CertificateList: React.FC = ({ page, sort, onChange }) => { return ( = ({ page, sort, onChange }) => { }, }} noItemsMessage={ - loading ? ( + certificates.loading ? ( LOADING_CERTIFICATES ) : ( {NO_CERTS_AVAILABLE} diff --git a/x-pack/plugins/uptime/public/components/certificates/use_cert_search.ts b/x-pack/plugins/uptime/public/components/certificates/use_cert_search.ts new file mode 100644 index 0000000000000..22531faff2da1 --- /dev/null +++ b/x-pack/plugins/uptime/public/components/certificates/use_cert_search.ts @@ -0,0 +1,60 @@ +/* + * 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 { useSelector } from 'react-redux'; +import { useContext } from 'react'; +import { useEsSearch, createEsParams } from '../../../../observability/public'; + +import { CertResult, GetCertsParams, Ping } from '../../../common/runtime_types'; + +import { selectDynamicSettings } from '../../state/selectors'; +import { + DEFAULT_DIRECTION, + DEFAULT_FROM, + DEFAULT_SIZE, + DEFAULT_SORT, + DEFAULT_TO, + getCertsRequestBody, + processCertsResult, +} from '../../../common/requests/get_certs_request_body'; +import { UptimeRefreshContext } from '../../contexts'; + +export const useCertSearch = ({ + pageIndex, + size = DEFAULT_SIZE, + search, + sortBy = DEFAULT_SORT, + direction = DEFAULT_DIRECTION, +}: GetCertsParams): CertResult & { loading?: boolean } => { + const settings = useSelector(selectDynamicSettings); + const { lastRefresh } = useContext(UptimeRefreshContext); + + const searchBody = getCertsRequestBody({ + pageIndex, + size, + search, + sortBy, + direction, + to: DEFAULT_TO, + from: DEFAULT_FROM, + }); + + const esParams = createEsParams({ + index: settings.settings?.heartbeatIndices, + body: searchBody, + }); + + const { data: result, loading } = useEsSearch(esParams, [ + settings.settings?.heartbeatIndices, + size, + pageIndex, + lastRefresh, + search, + ]); + + return result ? { ...processCertsResult(result), loading } : { certs: [], total: 0, loading }; +}; diff --git a/x-pack/plugins/uptime/public/hooks/__snapshots__/use_url_params.test.tsx.snap b/x-pack/plugins/uptime/public/hooks/__snapshots__/use_url_params.test.tsx.snap index 0b8893e36a366..31b78a8f810f0 100644 --- a/x-pack/plugins/uptime/public/hooks/__snapshots__/use_url_params.test.tsx.snap +++ b/x-pack/plugins/uptime/public/hooks/__snapshots__/use_url_params.test.tsx.snap @@ -197,6 +197,7 @@ exports[`useUrlParams deletes keys that do not have truthy values 1`] = ` }, ], }, + Symbol(observable): [MockFunction], } } > @@ -426,6 +427,7 @@ exports[`useUrlParams gets the expected values using the context 1`] = ` }, ], }, + Symbol(observable): [MockFunction], } } > diff --git a/x-pack/plugins/uptime/public/lib/__mocks__/uptime_store.mock.ts b/x-pack/plugins/uptime/public/lib/__mocks__/uptime_store.mock.ts index c0b4c893d93d8..b70aab338f053 100644 --- a/x-pack/plugins/uptime/public/lib/__mocks__/uptime_store.mock.ts +++ b/x-pack/plugins/uptime/public/lib/__mocks__/uptime_store.mock.ts @@ -95,10 +95,7 @@ export const mockState: AppState = { }, }, certificates: { - certs: { - data: null, - loading: false, - }, + total: 0, }, selectedFilters: null, alerts: { diff --git a/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.tsx b/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.tsx index ead9ad3dcb23f..8c4ec2fa611fc 100644 --- a/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.tsx +++ b/x-pack/plugins/uptime/public/lib/helper/helper_with_redux.tsx @@ -16,6 +16,7 @@ export const MountWithReduxProvider: React.FC<{ state?: AppState }> = ({ childre getState: jest.fn().mockReturnValue(state || { selectedFilters: null }), subscribe: jest.fn(), replaceReducer: jest.fn(), + [Symbol.observable]: jest.fn(), }} > {children} diff --git a/x-pack/plugins/uptime/public/pages/certificates.tsx b/x-pack/plugins/uptime/public/pages/certificates.tsx index 4b8617d594547..787238eb8ea6e 100644 --- a/x-pack/plugins/uptime/public/pages/certificates.tsx +++ b/x-pack/plugins/uptime/public/pages/certificates.tsx @@ -7,13 +7,13 @@ import { useDispatch } from 'react-redux'; import { EuiSpacer } from '@elastic/eui'; -import React, { useContext, useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useTrackPageview } from '../../../observability/public'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; import { getDynamicSettings } from '../state/actions/dynamic_settings'; -import { UptimeRefreshContext } from '../contexts'; -import { getCertificatesAction } from '../state/certificates/certificates'; import { CertificateList, CertificateSearch, CertSort } from '../components/certificates'; +import { useCertSearch } from '../components/certificates/use_cert_search'; +import { setCertificatesTotalAction } from '../state/certificates/certificates'; const DEFAULT_PAGE_SIZE = 10; const LOCAL_STORAGE_KEY = 'xpack.uptime.certList.pageSize'; @@ -40,22 +40,21 @@ export const CertificatesPage: React.FC = () => { const dispatch = useDispatch(); - const { lastRefresh } = useContext(UptimeRefreshContext); - useEffect(() => { dispatch(getDynamicSettings()); }, [dispatch]); + const certificates = useCertSearch({ + search, + size: page.size, + pageIndex: page.index, + sortBy: sort.field, + direction: sort.direction, + }); + useEffect(() => { - dispatch( - getCertificatesAction.get({ - search, - ...page, - sortBy: sort.field, - direction: sort.direction, - }) - ); - }, [dispatch, page, search, sort.direction, sort.field, lastRefresh]); + dispatch(setCertificatesTotalAction({ total: certificates.total })); + }, [certificates.total, dispatch]); return ( <> @@ -70,6 +69,7 @@ export const CertificatesPage: React.FC = () => { localStorage.setItem(LOCAL_STORAGE_KEY, pageVal.size.toString()); }} sort={sort} + certificates={certificates} /> ); diff --git a/x-pack/plugins/uptime/public/state/api/certificates.ts b/x-pack/plugins/uptime/public/state/api/certificates.ts deleted file mode 100644 index 33fb584cfc818..0000000000000 --- a/x-pack/plugins/uptime/public/state/api/certificates.ts +++ /dev/null @@ -1,14 +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 { API_URLS } from '../../../common/constants'; -import { apiService } from './utils'; -import { CertResultType, GetCertsParams } from '../../../common/runtime_types'; - -export const fetchCertificates = async (params: GetCertsParams) => { - return await apiService.get(API_URLS.CERTS, params, CertResultType); -}; diff --git a/x-pack/plugins/uptime/public/state/certificates/certificates.ts b/x-pack/plugins/uptime/public/state/certificates/certificates.ts index ca2d5e7a17a46..b5e5376c00df9 100644 --- a/x-pack/plugins/uptime/public/state/certificates/certificates.ts +++ b/x-pack/plugins/uptime/public/state/certificates/certificates.ts @@ -5,40 +5,27 @@ * 2.0. */ -import { handleActions } from 'redux-actions'; -import { takeLatest } from 'redux-saga/effects'; -import { createAsyncAction } from '../actions/utils'; -import { asyncInitState, handleAsyncAction } from '../reducers/utils'; -import { CertResult, GetCertsParams } from '../../../common/runtime_types'; +import { Action, createAction, handleActions } from 'redux-actions'; import { AppState } from '../index'; -import { AsyncInitState } from '../reducers/types'; -import { fetchEffectFactory } from '../effects/fetch_effect'; -import { fetchCertificates } from '../api/certificates'; -export const getCertificatesAction = createAsyncAction( - 'GET_CERTIFICATES' -); +export const setCertificatesTotalAction = createAction('SET_CERTIFICATES_TOTAL'); export interface CertificatesState { - certs: AsyncInitState; + total: number; } const initialState = { - certs: asyncInitState(), + total: 0, }; export const certificatesReducer = handleActions( { - ...handleAsyncAction('certs', getCertificatesAction), + [String(setCertificatesTotalAction)]: (state, action: Action) => ({ + ...state, + total: action.payload.total, + }), }, initialState ); -export function* fetchCertificatesEffect() { - yield takeLatest( - getCertificatesAction.get, - fetchEffectFactory(fetchCertificates, getCertificatesAction.success, getCertificatesAction.fail) - ); -} - -export const certificatesSelector = ({ certificates }: AppState) => certificates.certs; +export const certificatesSelector = ({ certificates }: AppState) => certificates.total; diff --git a/x-pack/plugins/uptime/public/state/effects/index.ts b/x-pack/plugins/uptime/public/state/effects/index.ts index df02180b1c28d..68acdb54ed7ff 100644 --- a/x-pack/plugins/uptime/public/state/effects/index.ts +++ b/x-pack/plugins/uptime/public/state/effects/index.ts @@ -16,7 +16,6 @@ import { fetchPingsEffect, fetchPingHistogramEffect } from './ping'; import { fetchMonitorDurationEffect } from './monitor_duration'; import { fetchMLJobEffect } from './ml_anomaly'; import { fetchIndexStatusEffect } from './index_status'; -import { fetchCertificatesEffect } from '../certificates/certificates'; import { fetchAlertsEffect } from '../alerts/alerts'; import { fetchJourneyStepsEffect } from './journey'; import { fetchNetworkEventsEffect } from './network_events'; @@ -39,7 +38,6 @@ export function* rootEffect() { yield fork(fetchMLJobEffect); yield fork(fetchMonitorDurationEffect); yield fork(fetchIndexStatusEffect); - yield fork(fetchCertificatesEffect); yield fork(fetchAlertsEffect); yield fork(fetchJourneyStepsEffect); yield fork(fetchNetworkEventsEffect); diff --git a/x-pack/plugins/uptime/public/state/reducers/index_pattern.ts b/x-pack/plugins/uptime/public/state/reducers/index_pattern.ts index d16860850bd78..c4fae4660168d 100644 --- a/x-pack/plugins/uptime/public/state/reducers/index_pattern.ts +++ b/x-pack/plugins/uptime/public/state/reducers/index_pattern.ts @@ -7,7 +7,7 @@ import { handleActions, Action } from 'redux-actions'; import { getIndexPattern, getIndexPatternSuccess, getIndexPatternFail } from '../actions'; -import type { IndexPattern } from '../../../../../../src/plugins/data/common/index_patterns'; +import type { IndexPattern } from '../../../../../../src/plugins/data/common'; export interface IndexPatternState { index_pattern: IndexPattern | null; diff --git a/x-pack/plugins/uptime/public/state/selectors/index.test.ts b/x-pack/plugins/uptime/public/state/selectors/index.test.ts index 520ebdac0c1e0..89a201d1391cb 100644 --- a/x-pack/plugins/uptime/public/state/selectors/index.test.ts +++ b/x-pack/plugins/uptime/public/state/selectors/index.test.ts @@ -93,10 +93,7 @@ describe('state selectors', () => { }, }, certificates: { - certs: { - data: null, - loading: false, - }, + total: 0, }, selectedFilters: null, alerts: { diff --git a/x-pack/plugins/uptime/server/lib/alerts/tls.test.ts b/x-pack/plugins/uptime/server/lib/alerts/tls.test.ts index 36e9e9fb36ab0..b069d368b2a39 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/tls.test.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/tls.test.ts @@ -6,11 +6,10 @@ */ import moment from 'moment'; import { ALERT_SEVERITY_WARNING, ALERT_SEVERITY } from '@kbn/rule-data-utils'; -import { tlsAlertFactory, getCertSummary, DEFAULT_SIZE } from './tls'; +import { tlsAlertFactory, getCertSummary } from './tls'; import { TLS } from '../../../common/constants/alerts'; import { CertResult, DynamicSettings } from '../../../common/runtime_types'; import { createRuleTypeMocks, bootstrapDependencies } from './test_utils'; -import { DEFAULT_FROM, DEFAULT_TO } from '../../rest_api/certs/certs'; import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants'; import { savedObjectsAdapter, UMSavedObjectsAdapter } from '../saved_objects'; @@ -123,10 +122,8 @@ describe('tls alert', () => { }); expect(mockGetter).toBeCalledWith( expect.objectContaining({ - from: DEFAULT_FROM, - to: DEFAULT_TO, - index: 0, - size: DEFAULT_SIZE, + pageIndex: 0, + size: 1000, notValidAfter: `now+${DYNAMIC_SETTINGS_DEFAULTS.certExpirationThreshold}d`, notValidBefore: `now-${DYNAMIC_SETTINGS_DEFAULTS.certAgeThreshold}d`, sortBy: 'common_name', diff --git a/x-pack/plugins/uptime/server/lib/alerts/tls.ts b/x-pack/plugins/uptime/server/lib/alerts/tls.ts index 63636ddfe5906..8e49c07f62c42 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/tls.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/tls.ts @@ -13,7 +13,6 @@ import { TLS } from '../../../common/constants/alerts'; import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants'; import { Cert, CertResult } from '../../../common/runtime_types'; import { commonStateTranslations, tlsTranslations } from './translations'; -import { DEFAULT_FROM, DEFAULT_TO } from '../../rest_api/certs/certs'; import { TlsTranslations } from '../../../common/translations'; import { ActionGroupIdsOf } from '../../../../alerting/common'; @@ -23,8 +22,6 @@ import { createUptimeESClient } from '../lib'; export type ActionGroupIds = ActionGroupIdsOf; -export const DEFAULT_SIZE = 20; - interface TlsAlertState { commonName: string; issuer: string; @@ -130,10 +127,8 @@ export const tlsAlertFactory: UptimeAlertTypeFactory = (_server, const { certs, total }: CertResult = await libs.requests.getCerts({ uptimeEsClient, - from: DEFAULT_FROM, - to: DEFAULT_TO, - index: 0, - size: DEFAULT_SIZE, + pageIndex: 0, + size: 1000, notValidAfter: `now+${ dynamicSettings?.certExpirationThreshold ?? DYNAMIC_SETTINGS_DEFAULTS.certExpirationThreshold diff --git a/x-pack/plugins/uptime/server/lib/alerts/tls_legacy.ts b/x-pack/plugins/uptime/server/lib/alerts/tls_legacy.ts index 812925f22b24b..fe49fc8416482 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/tls_legacy.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/tls_legacy.ts @@ -13,7 +13,6 @@ import { TLS_LEGACY } from '../../../common/constants/alerts'; import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants'; import { Cert, CertResult } from '../../../common/runtime_types'; import { commonStateTranslations, tlsTranslations } from './translations'; -import { DEFAULT_FROM, DEFAULT_TO } from '../../rest_api/certs/certs'; import { ActionGroupIdsOf } from '../../../../alerting/common'; import { AlertInstanceContext } from '../../../../alerting/common'; @@ -21,13 +20,16 @@ import { AlertInstance } from '../../../../alerting/server'; import { savedObjectsAdapter } from '../saved_objects'; import { createUptimeESClient } from '../lib'; +import { + DEFAULT_FROM, + DEFAULT_SIZE, + DEFAULT_TO, +} from '../../../common/requests/get_certs_request_body'; export type ActionGroupIds = ActionGroupIdsOf; type TLSAlertInstance = AlertInstance, AlertInstanceContext, ActionGroupIds>; -const DEFAULT_SIZE = 20; - interface TlsAlertState { count: number; agingCount: number; @@ -125,7 +127,7 @@ export const tlsLegacyAlertFactory: UptimeAlertTypeFactory = (_s uptimeEsClient, from: DEFAULT_FROM, to: DEFAULT_TO, - index: 0, + pageIndex: 0, size: DEFAULT_SIZE, notValidAfter: `now+${ dynamicSettings?.certExpirationThreshold ?? diff --git a/x-pack/plugins/uptime/server/lib/lib.ts b/x-pack/plugins/uptime/server/lib/lib.ts index cf00841313536..9b8ea6b98c8be 100644 --- a/x-pack/plugins/uptime/server/lib/lib.ts +++ b/x-pack/plugins/uptime/server/lib/lib.ts @@ -58,9 +58,9 @@ export function createUptimeESClient({ return { baseESClient: esClient, - async search( + async search( params: TParams - ): Promise<{ body: ESSearchResponse }> { + ): Promise<{ body: ESSearchResponse }> { let res: any; let esError: any; const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings( @@ -155,7 +155,3 @@ export function debugESCall({ } console.log(`\n`); } - -export function createEsQuery(params: T): T { - return params; -} diff --git a/x-pack/plugins/uptime/server/lib/requests/get_certs.test.ts b/x-pack/plugins/uptime/server/lib/requests/get_certs.test.ts index 6e06dea0436db..a6b37215c141a 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_certs.test.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_certs.test.ts @@ -94,7 +94,7 @@ describe('getCerts', () => { const result = await getCerts({ uptimeEsClient, - index: 1, + pageIndex: 1, from: 'now-2d', to: 'now+1h', search: 'my_common_name', diff --git a/x-pack/plugins/uptime/server/lib/requests/get_certs.ts b/x-pack/plugins/uptime/server/lib/requests/get_certs.ts index 86a9825f8a485..e5e9b74fb3a5b 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_certs.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_certs.ts @@ -5,170 +5,37 @@ * 2.0. */ +import { PromiseType } from 'utility-types'; import { UMElasticsearchQueryFn } from '../adapters'; import { CertResult, GetCertsParams, Ping } from '../../../common/runtime_types'; +import { + getCertsRequestBody, + processCertsResult, +} from '../../../common/requests/get_certs_request_body'; +import { UptimeESClient } from '../lib'; + +export const getCerts: UMElasticsearchQueryFn = async ( + requestParams +) => { + const result = await getCertsResults(requestParams); + + return processCertsResult(result); +}; -enum SortFields { - 'issuer' = 'tls.server.x509.issuer.common_name', - 'not_after' = 'tls.server.x509.not_after', - 'not_before' = 'tls.server.x509.not_before', - 'common_name' = 'tls.server.x509.subject.common_name', -} - -export const getCerts: UMElasticsearchQueryFn = async ({ - uptimeEsClient, - index, - from, - to, - size, - search, - notValidBefore, - notValidAfter, - sortBy, - direction, -}) => { - const sort = SortFields[sortBy as keyof typeof SortFields]; +export type CertificatesResults = PromiseType>; - const searchBody = { - from: index * size, - size, - sort: [ - { - [sort]: { - order: direction as 'asc' | 'desc', - }, - }, - ], - query: { - bool: { - ...(search - ? { - minimum_should_match: 1, - should: [ - { - multi_match: { - query: escape(search), - type: 'phrase_prefix' as const, - fields: [ - 'monitor.id.text', - 'monitor.name.text', - 'url.full.text', - 'tls.server.x509.subject.common_name.text', - 'tls.server.x509.issuer.common_name.text', - ], - }, - }, - ], - } - : {}), - filter: [ - { - exists: { - field: 'tls.server.hash.sha256', - }, - }, - { - range: { - 'monitor.timespan': { - gte: from, - lte: to, - }, - }, - }, - ], - }, - }, - _source: [ - 'monitor.id', - 'monitor.name', - 'tls.server.x509.issuer.common_name', - 'tls.server.x509.subject.common_name', - 'tls.server.hash.sha1', - 'tls.server.hash.sha256', - 'tls.server.x509.not_after', - 'tls.server.x509.not_before', - ], - collapse: { - field: 'tls.server.hash.sha256', - inner_hits: { - _source: { - includes: ['monitor.id', 'monitor.name', 'url.full'], - }, - collapse: { - field: 'monitor.id', - }, - name: 'monitors', - sort: [{ 'monitor.id': 'asc' as const }], - }, - }, - aggs: { - total: { - cardinality: { - field: 'tls.server.hash.sha256', - }, - }, - }, - }; +const getCertsResults = async ( + requestParams: GetCertsParams & { uptimeEsClient: UptimeESClient } +) => { + const { uptimeEsClient } = requestParams; - if (notValidBefore || notValidAfter) { - const validityFilters: any = { - bool: { - should: [], - }, - }; - if (notValidBefore) { - validityFilters.bool.should.push({ - range: { - 'tls.certificate_not_valid_before': { - lte: notValidBefore, - }, - }, - }); - } - if (notValidAfter) { - validityFilters.bool.should.push({ - range: { - 'tls.certificate_not_valid_after': { - lte: notValidAfter, - }, - }, - }); - } + const searchBody = getCertsRequestBody(requestParams); - searchBody.query.bool.filter.push(validityFilters); - } + const request = { body: searchBody }; - const { body: result } = await uptimeEsClient.search({ + const { body: result } = await uptimeEsClient.search({ body: searchBody, }); - const certs = (result?.hits?.hits ?? []).map((hit) => { - const ping = hit._source as Ping; - const server = ping.tls?.server!; - - const notAfter = server?.x509?.not_after; - const notBefore = server?.x509?.not_before; - const issuer = server?.x509?.issuer?.common_name; - const commonName = server?.x509?.subject?.common_name; - const sha1 = server?.hash?.sha1; - const sha256 = server?.hash?.sha256; - - const monitors = hit.inner_hits!.monitors.hits.hits.map((monitor: any) => ({ - name: monitor._source?.monitor.name, - id: monitor._source?.monitor.id, - url: monitor._source?.url?.full, - })); - - return { - monitors, - issuer, - sha1, - sha256: sha256 as string, - not_after: notAfter, - not_before: notBefore, - common_name: commonName, - }; - }); - const total = result?.aggregations?.total?.value ?? 0; - return { certs, total }; + return result; }; diff --git a/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts b/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts index 33615bb8516b5..c5ac246fe9357 100644 --- a/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts +++ b/x-pack/plugins/uptime/server/lib/requests/get_ping_histogram.ts @@ -10,7 +10,7 @@ import { GetPingHistogramParams, HistogramResult } from '../../../common/runtime import { QUERY } from '../../../common/constants'; import { getHistogramInterval } from '../helper/get_histogram_interval'; import { UMElasticsearchQueryFn } from '../adapters/framework'; -import { createEsQuery } from '../lib'; +import { createEsQuery } from '../../../common/utils/es_search'; export const getPingHistogram: UMElasticsearchQueryFn< GetPingHistogramParams, diff --git a/x-pack/plugins/uptime/server/rest_api/certs/certs.ts b/x-pack/plugins/uptime/server/rest_api/certs/certs.ts deleted file mode 100644 index f974ee6bee76a..0000000000000 --- a/x-pack/plugins/uptime/server/rest_api/certs/certs.ts +++ /dev/null @@ -1,54 +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 { schema } from '@kbn/config-schema'; -import { API_URLS } from '../../../common/constants'; -import { UMServerLibs } from '../../lib/lib'; -import { UMRestApiRouteFactory } from '../types'; - -export const DEFAULT_FROM = 'now-5m'; -export const DEFAULT_TO = 'now'; - -const DEFAULT_SIZE = 25; -const DEFAULT_SORT = 'not_after'; -const DEFAULT_DIRECTION = 'asc'; - -export const createGetCertsRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({ - method: 'GET', - path: API_URLS.CERTS, - validate: { - query: schema.object({ - from: schema.maybe(schema.string()), - to: schema.maybe(schema.string()), - search: schema.maybe(schema.string()), - index: schema.maybe(schema.number()), - size: schema.maybe(schema.number()), - sortBy: schema.maybe(schema.string()), - direction: schema.maybe(schema.string()), - }), - }, - handler: async ({ uptimeEsClient, request }): Promise => { - const index = request.query?.index ?? 0; - const size = request.query?.size ?? DEFAULT_SIZE; - const from = request.query?.from ?? DEFAULT_FROM; - const to = request.query?.to ?? DEFAULT_TO; - const sortBy = request.query?.sortBy ?? DEFAULT_SORT; - const direction = request.query?.direction ?? DEFAULT_DIRECTION; - const { search } = request.query; - - return await libs.requests.getCerts({ - uptimeEsClient, - index, - search, - size, - from, - to, - sortBy, - direction, - }); - }, -}); diff --git a/x-pack/plugins/uptime/server/rest_api/index.ts b/x-pack/plugins/uptime/server/rest_api/index.ts index 8ae878669ba32..0196a6d192e8e 100644 --- a/x-pack/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/plugins/uptime/server/rest_api/index.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { createGetCertsRoute } from './certs/certs'; import { createGetOverviewFilters } from './overview_filters'; import { createGetPingHistogramRoute, @@ -35,7 +34,6 @@ export { createRouteWithAuth } from './create_route_with_auth'; export { uptimeRouteWrapper } from './uptime_route_wrapper'; export const restApiRoutes: UMRestApiRouteFactory[] = [ - createGetCertsRoute, createGetOverviewFilters, createGetPingsRoute, createGetIndexPatternRoute, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/enqueue.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/enqueue.ts index 533570ae4c16d..3094269932640 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/enqueue.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/enqueue.ts @@ -23,7 +23,8 @@ export default function ({ getService }: FtrProviderContext) { const retry = getService('retry'); const esTestIndexTool = new ESTestIndexTool(es, retry); - describe('enqueue', () => { + // Failing: See https://github.com/elastic/kibana/issues/111812 + describe.skip('enqueue', () => { const objectRemover = new ObjectRemover(supertest); before(async () => { diff --git a/x-pack/test/api_integration/apis/features/features/features.ts b/x-pack/test/api_integration/apis/features/features/features.ts index c157c8ae354ac..e48ac32dfd991 100644 --- a/x-pack/test/api_integration/apis/features/features/features.ts +++ b/x-pack/test/api_integration/apis/features/features/features.ts @@ -113,7 +113,6 @@ export default function ({ getService }: FtrProviderContext) { 'infrastructure', 'logs', 'maps', - 'observabilityCases', 'osquery', 'uptime', 'siem', diff --git a/x-pack/test/api_integration/apis/security/privileges.ts b/x-pack/test/api_integration/apis/security/privileges.ts index 42666e10341f1..913d16ad52df0 100644 --- a/x-pack/test/api_integration/apis/security/privileges.ts +++ b/x-pack/test/api_integration/apis/security/privileges.ts @@ -33,7 +33,6 @@ export default function ({ getService }: FtrProviderContext) { stackAlerts: ['all', 'read'], ml: ['all', 'read'], siem: ['all', 'read', 'minimal_all', 'minimal_read', 'cases_all', 'cases_read'], - observabilityCases: ['all', 'read'], uptime: ['all', 'read'], infrastructure: ['all', 'read'], logs: ['all', 'read'], diff --git a/x-pack/test/api_integration/apis/security/privileges_basic.ts b/x-pack/test/api_integration/apis/security/privileges_basic.ts index 368d5361b7e1c..1ad7e803bad37 100644 --- a/x-pack/test/api_integration/apis/security/privileges_basic.ts +++ b/x-pack/test/api_integration/apis/security/privileges_basic.ts @@ -32,7 +32,6 @@ export default function ({ getService }: FtrProviderContext) { maps: ['all', 'read'], canvas: ['all', 'read'], infrastructure: ['all', 'read'], - observabilityCases: ['all', 'read'], logs: ['all', 'read'], uptime: ['all', 'read'], apm: ['all', 'read'], diff --git a/x-pack/test/api_integration/apis/security_solution/timeline_migrations.ts b/x-pack/test/api_integration/apis/security_solution/timeline_migrations.ts index 820e0945f1511..9863ebb7ba646 100644 --- a/x-pack/test/api_integration/apis/security_solution/timeline_migrations.ts +++ b/x-pack/test/api_integration/apis/security_solution/timeline_migrations.ts @@ -7,6 +7,7 @@ import expect from '@kbn/expect'; import { SavedTimeline } from '../../../../plugins/security_solution/common/types/timeline'; +import { SavedNote } from '../../../../plugins/security_solution/common/types/timeline/note'; import { FtrProviderContext } from '../../ftr_provider_context'; import { getSavedObjectFromES } from './utils'; @@ -15,6 +16,10 @@ interface TimelineWithoutSavedQueryId { 'siem-ui-timeline': Omit; } +interface NoteWithoutTimelineId { + 'siem-ui-timeline-note': Omit; +} + export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); @@ -23,48 +28,106 @@ export default function ({ getService }: FtrProviderContext) { const es = getService('es'); describe('7.16.0', () => { - before(async () => { - await esArchiver.load( - 'x-pack/test/functional/es_archives/security_solution/timelines/7.15.0' - ); - }); + describe('notes timelineId', () => { + before(async () => { + await esArchiver.load( + 'x-pack/test/functional/es_archives/security_solution/timelines/7.15.0' + ); + }); - after(async () => { - await esArchiver.unload( - 'x-pack/test/functional/es_archives/security_solution/timelines/7.15.0' - ); - }); + after(async () => { + await esArchiver.unload( + 'x-pack/test/functional/es_archives/security_solution/timelines/7.15.0' + ); + }); - it('removes the savedQueryId', async () => { - const timelines = await getSavedObjectFromES( - es, - 'siem-ui-timeline', - { - ids: { values: ['siem-ui-timeline:8dc70950-1012-11ec-9ad3-2d7c6600c0f7'] }, - } - ); - - expect(timelines.body.hits.hits[0]._source?.['siem-ui-timeline']).to.not.have.property( - 'savedQueryId' - ); - }); + it('removes the timelineId in the saved object', async () => { + const timelines = await getSavedObjectFromES( + es, + 'siem-ui-timeline-note', + { + ids: { + values: [ + 'siem-ui-timeline-note:989002c0-126e-11ec-83d2-db1096c73738', + 'siem-ui-timeline-note:f09b5980-1271-11ec-83d2-db1096c73738', + ], + }, + } + ); + + expect( + timelines.body.hits.hits[0]._source?.['siem-ui-timeline-note'] + ).to.not.have.property('timelineId'); + + expect( + timelines.body.hits.hits[1]._source?.['siem-ui-timeline-note'] + ).to.not.have.property('timelineId'); + }); + + it('preserves the eventId in the saved object after migration', async () => { + const resp = await supertest + .get('/api/timeline') + .query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' }); - it('preserves the title in the saved object after migration', async () => { - const resp = await supertest - .get('/api/timeline') - .query({ id: '8dc70950-1012-11ec-9ad3-2d7c6600c0f7' }) - .set('kbn-xsrf', 'true'); + expect(resp.body.data.getOneTimeline.notes[0].eventId).to.be('Edo00XsBEVtyvU-8LGNe'); + }); - expect(resp.body.data.getOneTimeline.title).to.be('Awesome Timeline'); + it('returns the timelineId in the response', async () => { + const resp = await supertest + .get('/api/timeline') + .query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' }); + + expect(resp.body.data.getOneTimeline.notes[0].timelineId).to.be( + '6484cc90-126e-11ec-83d2-db1096c73738' + ); + expect(resp.body.data.getOneTimeline.notes[1].timelineId).to.be( + '6484cc90-126e-11ec-83d2-db1096c73738' + ); + }); }); - it('returns the savedQueryId in the response', async () => { - const resp = await supertest - .get('/api/timeline') - .query({ id: '8dc70950-1012-11ec-9ad3-2d7c6600c0f7' }) - .set('kbn-xsrf', 'true'); + describe('savedQueryId', () => { + before(async () => { + await esArchiver.load( + 'x-pack/test/functional/es_archives/security_solution/timelines/7.15.0' + ); + }); + + after(async () => { + await esArchiver.unload( + 'x-pack/test/functional/es_archives/security_solution/timelines/7.15.0' + ); + }); + + it('removes the savedQueryId', async () => { + const timelines = await getSavedObjectFromES( + es, + 'siem-ui-timeline', + { + ids: { values: ['siem-ui-timeline:8dc70950-1012-11ec-9ad3-2d7c6600c0f7'] }, + } + ); + + expect(timelines.body.hits.hits[0]._source?.['siem-ui-timeline']).to.not.have.property( + 'savedQueryId' + ); + }); + + it('preserves the title in the saved object after migration', async () => { + const resp = await supertest + .get('/api/timeline') + .query({ id: '8dc70950-1012-11ec-9ad3-2d7c6600c0f7' }); + + expect(resp.body.data.getOneTimeline.title).to.be('Awesome Timeline'); + }); + + it('returns the savedQueryId in the response', async () => { + const resp = await supertest + .get('/api/timeline') + .query({ id: '8dc70950-1012-11ec-9ad3-2d7c6600c0f7' }); - expect(resp.body.data.getOneTimeline.savedQueryId).to.be("It's me"); + expect(resp.body.data.getOneTimeline.savedQueryId).to.be("It's me"); + }); }); }); }); diff --git a/x-pack/test/api_integration/apis/uptime/rest/certs.ts b/x-pack/test/api_integration/apis/uptime/rest/certs.ts index c9c8efe3f3a11..b9bc38801d394 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/certs.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/certs.ts @@ -9,9 +9,12 @@ import expect from '@kbn/expect'; import moment from 'moment'; import { isRight } from 'fp-ts/lib/Either'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { API_URLS } from '../../../../../plugins/uptime/common/constants'; import { CertType } from '../../../../../plugins/uptime/common/runtime_types'; import { makeChecksWithStatus } from './helper/make_checks'; +import { + processCertsResult, + getCertsRequestBody, +} from '../../../../../plugins/uptime/common/requests/get_certs_request_body'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); @@ -21,8 +24,18 @@ export default function ({ getService }: FtrProviderContext) { describe('certs api', () => { describe('empty index', async () => { it('returns empty array for no data', async () => { - const apiResponse = await supertest.get(API_URLS.CERTS); - expect(JSON.stringify(apiResponse.body)).to.eql('{"certs":[],"total":0}'); + const apiResponse = await supertest + .post(`/internal/search/ese`) + .set('kbn-xsrf', 'true') + .send({ + params: { + index: 'heartbeat-*', + body: getCertsRequestBody({ pageIndex: 0, size: 10 }), + }, + }); + + const result = processCertsResult(apiResponse.body.rawResponse); + expect(JSON.stringify(result)).to.eql('{"certs":[],"total":0}'); }); }); @@ -67,19 +80,29 @@ export default function ({ getService }: FtrProviderContext) { }); it('retrieves expected cert data', async () => { - const apiResponse = await supertest.get(API_URLS.CERTS); - const { body } = apiResponse; + const { body } = await supertest + .post(`/internal/search/ese`) + .set('kbn-xsrf', 'true') + .send({ + params: { + index: 'heartbeat-*', + body: getCertsRequestBody({ pageIndex: 0, size: 10 }), + }, + }); + + const result = processCertsResult(body.rawResponse); - expect(body.certs).not.to.be(undefined); - expect(Array.isArray(body.certs)).to.be(true); - expect(body.certs).to.have.length(1); + expect(result.certs).not.to.be(undefined); + expect(Array.isArray(result.certs)).to.be(true); + expect(result.certs).to.have.length(1); - const decoded = CertType.decode(body.certs[0]); + const decoded = CertType.decode(result.certs[0]); expect(isRight(decoded)).to.be(true); - const cert = body.certs[0]; + const cert = result.certs[0]; expect(Array.isArray(cert.monitors)).to.be(true); expect(cert.monitors[0]).to.eql({ + name: undefined, id: monitorId, url: 'http://localhost:5678/pattern?r=200x5,500x1', }); diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/common/cases/import_export.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/common/cases/import_export.ts index df4e858e8a290..90c2cfb5b8e4f 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/common/cases/import_export.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/common/cases/import_export.ts @@ -29,7 +29,8 @@ export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const es = getService('es'); - describe('import and export cases', () => { + // FLAKY: https://github.com/elastic/kibana/issues/112353 + describe.skip('import and export cases', () => { const actionsRemover = new ActionsRemover(supertest); afterEach(async () => { diff --git a/x-pack/test/functional/apps/apm/feature_controls/apm_security.ts b/x-pack/test/functional/apps/apm/feature_controls/apm_security.ts index 6f6d29db1ef0c..7cfdf87aaf9ea 100644 --- a/x-pack/test/functional/apps/apm/feature_controls/apm_security.ts +++ b/x-pack/test/functional/apps/apm/feature_controls/apm_security.ts @@ -64,7 +64,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const navLinks = await appsMenu.readLinks(); expect(navLinks.map((link) => link.text)).to.eql([ 'Overview', - 'Alerts', 'APM', 'User Experience', 'Stack Management', @@ -117,13 +116,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows apm navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql([ - 'Overview', - 'Alerts', - 'APM', - 'User Experience', - 'Stack Management', - ]); + expect(navLinks).to.eql(['Overview', 'APM', 'User Experience', 'Stack Management']); }); it('can navigate to APM app', async () => { diff --git a/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts b/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts index 03fe2409bd834..0118cfdafc2b3 100644 --- a/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts +++ b/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts @@ -62,7 +62,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows metrics navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Alerts', 'Metrics', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Metrics', 'Stack Management']); }); describe('infrastructure landing page without data', () => { @@ -160,7 +160,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows metrics navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Alerts', 'Metrics', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Metrics', 'Stack Management']); }); describe('infrastructure landing page without data', () => { diff --git a/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts b/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts index e08d8e260811f..d5e22af657d6a 100644 --- a/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts +++ b/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts @@ -59,7 +59,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows logs navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Alerts', 'Logs', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Logs', 'Stack Management']); }); describe('logs landing page without data', () => { @@ -122,7 +122,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows logs navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Alerts', 'Logs', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Logs', 'Stack Management']); }); describe('logs landing page without data', () => { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/date_nanos_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection/date_nanos_job.ts index d351e8f7057e4..ca330bb8e6a0a 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/date_nanos_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/date_nanos_job.ts @@ -114,7 +114,8 @@ export default function ({ getService }: FtrProviderContext) { }, ]; - describe('job on data set with date_nanos time field', function () { + // Failing: See https://github.com/elastic/kibana/issues/112194 + describe.skip('job on data set with date_nanos time field', function () { this.tags(['mlqa']); before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/event_rate_nanos'); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection/multi_metric_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection/multi_metric_job.ts index 0c1b1620eb413..9cc570256f8f1 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection/multi_metric_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection/multi_metric_job.ts @@ -71,7 +71,8 @@ export default function ({ getService }: FtrProviderContext) { const calendarId = `wizard-test-calendar_${Date.now()}`; - describe('multi metric', function () { + // Failing: See https://github.com/elastic/kibana/issues/112174 + describe.skip('multi metric', function () { this.tags(['mlqa']); before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); diff --git a/x-pack/test/functional/apps/reporting/reporting.ts b/x-pack/test/functional/apps/reporting/reporting.ts index 8a0d9937fc213..0d8034f046e02 100644 --- a/x-pack/test/functional/apps/reporting/reporting.ts +++ b/x-pack/test/functional/apps/reporting/reporting.ts @@ -11,17 +11,22 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { const pageObjects = getPageObjects(['dashboard', 'common', 'reporting']); const es = getService('es'); - const esArchiver = getService('esArchiver'); + const kibanaServer = getService('kibanaServer'); + const retry = getService('retry'); describe('Reporting', function () { this.tags(['smoke', 'ciGroup2']); before(async () => { - await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/packaging'); + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/packaging' + ); }); after(async () => { - await esArchiver.unload('x-pack/test/functional/es_archives/packaging'); + await kibanaServer.importExport.unload( + 'x-pack/test/functional/fixtures/kbn_archiver/packaging' + ); await es.deleteByQuery({ index: '.reporting-*', refresh: true, diff --git a/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts b/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts index 977a384062f79..7867170c1801c 100644 --- a/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts +++ b/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts @@ -68,7 +68,6 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const navLinks = await appsMenu.readLinks(); expect(navLinks.map((link) => link.text)).to.eql([ 'Overview', - 'Alerts', 'Uptime', 'Stack Management', ]); @@ -122,7 +121,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows uptime navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Alerts', 'Uptime', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Uptime', 'Stack Management']); }); it('can navigate to Uptime app', async () => { diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index f8e8ce76bace1..95a962388cdd6 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -87,8 +87,6 @@ export default async function ({ readConfigFile }) { '--xpack.encryptedSavedObjects.encryptionKey="DkdXazszSCYexXqz4YktBGHCRkV6hyNK"', '--xpack.discoverEnhanced.actions.exploreDataInContextMenu.enabled=true', '--savedObjects.maxImportPayloadBytes=10485760', // for OSS test management/_import_objects - '--xpack.observability.unsafe.cases.enabled=true', - '--xpack.observability.unsafe.alertingExperience.enabled=true', // NOTE: Can be removed once enabled by default ], }, uiSettings: { diff --git a/x-pack/test/functional/es_archives/packaging/data.json.gz b/x-pack/test/functional/es_archives/packaging/data.json.gz deleted file mode 100644 index 69c9e4cb4d8a2..0000000000000 Binary files a/x-pack/test/functional/es_archives/packaging/data.json.gz and /dev/null differ diff --git a/x-pack/test/functional/es_archives/packaging/mappings.json b/x-pack/test/functional/es_archives/packaging/mappings.json deleted file mode 100644 index 0ec1e12567460..0000000000000 --- a/x-pack/test/functional/es_archives/packaging/mappings.json +++ /dev/null @@ -1,2519 +0,0 @@ -{ - "type": "index", - "value": { - "aliases": { - ".kibana": { - } - }, - "index": ".kibana_1", - "mappings": { - "_meta": { - "migrationMappingPropertyHashes": { - "action": "6e96ac5e648f57523879661ea72525b7", - "action_task_params": "a9d49f184ee89641044be0ca2950fa3a", - "alert": "0359d7fcc04da9878ee9aadbda38ba55", - "api_key_pending_invalidation": "16f515278a295f6245149ad7c5ddedb7", - "apm-indices": "9bb9b2bf1fa636ed8619cbab5ce6a1dd", - "apm-telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "app_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "application_usage_daily": "43b8830d5d0df85a6823d290885fc9fd", - "application_usage_totals": "3d1b76c39bfb2cc8296b024d73854724", - "application_usage_transactional": "3d1b76c39bfb2cc8296b024d73854724", - "background-session": "721df406dbb7e35ac22e4df6c3ad2b2a", - "canvas-element": "7390014e1091044523666d97247392fc", - "canvas-workpad": "b0a1706d356228dbdcb4a17e6b9eb231", - "canvas-workpad-template": "ae2673f678281e2c055d764b153e9715", - "cases": "477f214ff61acc3af26a7b7818e380c1", - "cases-comments": "8a50736330e953bca91747723a319593", - "cases-configure": "387c5f3a3bda7e0ae0dd4e106f914a69", - "cases-user-actions": "32277330ec6b721abe3b846cfd939a71", - "config": "c63748b75f39d0c54de12d12c1ccbc20", - "dashboard": "40554caf09725935e2c02e02563a2d07", - "endpoint:user-artifact": "4a11183eee21e6fbad864f7a30b39ad0", - "endpoint:user-artifact-manifest": "4b9c0e7cfaf86d82a7ee9ed68065e50d", - "enterprise_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "epm-packages": "2b83397e3eaaaa8ef15e38813f3721c3", - "exception-list": "67f055ab8c10abd7b2ebfd969b836788", - "exception-list-agnostic": "67f055ab8c10abd7b2ebfd969b836788", - "file-upload-telemetry": "0ed4d3e1983d1217a30982630897092e", - "fleet-agent-actions": "9511b565b1cc6441a42033db3d5de8e9", - "fleet-agent-events": "e20a508b6e805189356be381dbfac8db", - "fleet-agents": "cb661e8ede2b640c42c8e5ef99db0683", - "fleet-enrollment-api-keys": "a69ef7ae661dab31561d6c6f052ef2a7", - "graph-workspace": "cd7ba1330e6682e9cc00b78850874be1", - "index-pattern": "45915a1ad866812242df474eb0479052", - "infrastructure-ui-source": "3d1b76c39bfb2cc8296b024d73854724", - "ingest-agent-policies": "8b0733cce189659593659dad8db426f0", - "ingest-outputs": "8854f34453a47e26f86a29f8f3b80b4e", - "ingest-package-policies": "f74dfe498e1849267cda41580b2be110", - "ingest_manager_settings": "02a03095f0e05b7a538fa801b88a217f", - "inventory-view": "3d1b76c39bfb2cc8296b024d73854724", - "kql-telemetry": "d12a98a6f19a2d273696597547e064ee", - "lens": "52346cfec69ff7b47d5f0c12361a2797", - "lens-ui-telemetry": "509bfa5978586998e05f9e303c07a327", - "map": "4a05b35c3a3a58fbc72dd0202dc3487f", - "maps-telemetry": "5ef305b18111b77789afefbd36b66171", - "metrics-explorer-view": "3d1b76c39bfb2cc8296b024d73854724", - "migrationVersion": "4a1746014a75ade3a714e1db5763276f", - "ml-job": "3bb64c31915acf93fc724af137a0891b", - "ml-telemetry": "257fd1d4b4fdbb9cb4b8a3b27da201e9", - "monitoring-telemetry": "2669d5ec15e82391cf58df4294ee9c68", - "namespace": "2f4316de49999235636386fe51dc06c1", - "namespaces": "2f4316de49999235636386fe51dc06c1", - "originId": "2f4316de49999235636386fe51dc06c1", - "query": "11aaeb7f5f7fa5bb43f25e18ce26e7d9", - "references": "7997cf5a56cc02bdc9c93361bde732b0", - "sample-data-telemetry": "7d3cfeb915303c9641c59681967ffeb4", - "search": "43012c7ebc4cb57054e0a490e4b43023", - "search-telemetry": "3d1b76c39bfb2cc8296b024d73854724", - "siem-detection-engine-rule-actions": "6569b288c169539db10cb262bf79de18", - "siem-detection-engine-rule-status": "ae783f41c6937db6b7a2ef5c93a9e9b0", - "siem-ui-timeline": "d12c5474364d737d17252acf1dc4585c", - "siem-ui-timeline-note": "8874706eedc49059d4cf0f5094559084", - "siem-ui-timeline-pinned-event": "20638091112f0e14f0e443d512301c29", - "space": "c5ca8acafa0beaa4d08d014a97b6bc6b", - "tag": "83d55da58f6530f7055415717ec06474", - "telemetry": "36a616f7026dfa617d6655df850fe16d", - "tsvb-validation-telemetry": "3a37ef6c8700ae6fc97d5c7da00e9215", - "type": "2f4316de49999235636386fe51dc06c1", - "ui-metric": "0d409297dc5ebe1e3a1da691c6ee32e3", - "updated_at": "00da57df13e94e9d98437d13ace4bfe0", - "upgrade-assistant-reindex-operation": "215107c281839ea9b3ad5f6419819763", - "upgrade-assistant-telemetry": "56702cec857e0a9dacfb696655b4ff7b", - "uptime-dynamic-settings": "3d1b76c39bfb2cc8296b024d73854724", - "url": "c7f66a0df8b1b52f17c28c4adb111105", - "visualization": "f819cf6636b75c9e76ba733a0c6ef355", - "workplace_search_telemetry": "3d1b76c39bfb2cc8296b024d73854724" - } - }, - "dynamic": "strict", - "properties": { - "action": { - "properties": { - "actionTypeId": { - "type": "keyword" - }, - "config": { - "enabled": false, - "type": "object" - }, - "name": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "secrets": { - "type": "binary" - } - } - }, - "action_task_params": { - "properties": { - "actionId": { - "type": "keyword" - }, - "apiKey": { - "type": "binary" - }, - "params": { - "enabled": false, - "type": "object" - } - } - }, - "alert": { - "properties": { - "actions": { - "properties": { - "actionRef": { - "type": "keyword" - }, - "actionTypeId": { - "type": "keyword" - }, - "group": { - "type": "keyword" - }, - "params": { - "enabled": false, - "type": "object" - } - }, - "type": "nested" - }, - "alertTypeId": { - "type": "keyword" - }, - "apiKey": { - "type": "binary" - }, - "apiKeyOwner": { - "type": "keyword" - }, - "consumer": { - "type": "keyword" - }, - "createdAt": { - "type": "date" - }, - "createdBy": { - "type": "keyword" - }, - "enabled": { - "type": "boolean" - }, - "executionStatus": { - "properties": { - "error": { - "properties": { - "message": { - "type": "keyword" - }, - "reason": { - "type": "keyword" - } - } - }, - "lastExecutionDate": { - "type": "date" - }, - "status": { - "type": "keyword" - } - } - }, - "meta": { - "properties": { - "versionApiKeyLastmodified": { - "type": "keyword" - } - } - }, - "muteAll": { - "type": "boolean" - }, - "mutedInstanceIds": { - "type": "keyword" - }, - "name": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "params": { - "enabled": false, - "type": "object" - }, - "schedule": { - "properties": { - "interval": { - "type": "keyword" - } - } - }, - "scheduledTaskId": { - "type": "keyword" - }, - "tags": { - "type": "keyword" - }, - "throttle": { - "type": "keyword" - }, - "updatedAt": { - "type": "date" - }, - "updatedBy": { - "type": "keyword" - } - } - }, - "api_key_pending_invalidation": { - "properties": { - "apiKeyId": { - "type": "keyword" - }, - "createdAt": { - "type": "date" - } - } - }, - "apm-indices": { - "properties": { - "apm_oss": { - "properties": { - "errorIndices": { - "type": "keyword" - }, - "metricsIndices": { - "type": "keyword" - }, - "onboardingIndices": { - "type": "keyword" - }, - "sourcemapIndices": { - "type": "keyword" - }, - "spanIndices": { - "type": "keyword" - }, - "transactionIndices": { - "type": "keyword" - } - } - } - } - }, - "apm-telemetry": { - "dynamic": "false", - "type": "object" - }, - "app_search_telemetry": { - "dynamic": "false", - "type": "object" - }, - "application_usage_daily": { - "dynamic": "false", - "properties": { - "timestamp": { - "type": "date" - } - } - }, - "application_usage_totals": { - "dynamic": "false", - "type": "object" - }, - "application_usage_transactional": { - "dynamic": "false", - "type": "object" - }, - "background-session": { - "properties": { - "created": { - "type": "date" - }, - "expires": { - "type": "date" - }, - "idMapping": { - "enabled": false, - "type": "object" - }, - "initialState": { - "enabled": false, - "type": "object" - }, - "name": { - "type": "keyword" - }, - "restoreState": { - "enabled": false, - "type": "object" - }, - "status": { - "type": "keyword" - } - } - }, - "canvas-element": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "content": { - "type": "text" - }, - "help": { - "type": "text" - }, - "image": { - "type": "text" - }, - "name": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "canvas-workpad": { - "dynamic": "false", - "properties": { - "@created": { - "type": "date" - }, - "@timestamp": { - "type": "date" - }, - "name": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "canvas-workpad-template": { - "dynamic": "false", - "properties": { - "help": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "name": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "tags": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "template_key": { - "type": "keyword" - } - } - }, - "cases": { - "properties": { - "closed_at": { - "type": "date" - }, - "closed_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "connector": { - "properties": { - "fields": { - "properties": { - "key": { - "type": "text" - }, - "value": { - "type": "text" - } - } - }, - "id": { - "type": "keyword" - }, - "name": { - "type": "text" - }, - "type": { - "type": "keyword" - } - } - }, - "created_at": { - "type": "date" - }, - "created_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "description": { - "type": "text" - }, - "external_service": { - "properties": { - "connector_id": { - "type": "keyword" - }, - "connector_name": { - "type": "keyword" - }, - "external_id": { - "type": "keyword" - }, - "external_title": { - "type": "text" - }, - "external_url": { - "type": "text" - }, - "pushed_at": { - "type": "date" - }, - "pushed_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - } - } - }, - "status": { - "type": "keyword" - }, - "tags": { - "type": "keyword" - }, - "title": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - } - } - }, - "cases-comments": { - "properties": { - "alertId": { - "type": "keyword" - }, - "comment": { - "type": "text" - }, - "created_at": { - "type": "date" - }, - "created_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "index": { - "type": "keyword" - }, - "pushed_at": { - "type": "date" - }, - "pushed_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - } - } - }, - "cases-configure": { - "properties": { - "closure_type": { - "type": "keyword" - }, - "connector": { - "properties": { - "fields": { - "properties": { - "key": { - "type": "text" - }, - "value": { - "type": "text" - } - } - }, - "id": { - "type": "keyword" - }, - "name": { - "type": "text" - }, - "type": { - "type": "keyword" - } - } - }, - "created_at": { - "type": "date" - }, - "created_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - } - } - }, - "cases-user-actions": { - "properties": { - "action": { - "type": "keyword" - }, - "action_at": { - "type": "date" - }, - "action_by": { - "properties": { - "email": { - "type": "keyword" - }, - "full_name": { - "type": "keyword" - }, - "username": { - "type": "keyword" - } - } - }, - "action_field": { - "type": "keyword" - }, - "new_value": { - "type": "text" - }, - "old_value": { - "type": "text" - } - } - }, - "config": { - "dynamic": "false", - "properties": { - "buildNum": { - "type": "keyword" - } - } - }, - "dashboard": { - "properties": { - "description": { - "type": "text" - }, - "hits": { - "doc_values": false, - "index": false, - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "index": false, - "type": "text" - } - } - }, - "optionsJSON": { - "index": false, - "type": "text" - }, - "panelsJSON": { - "index": false, - "type": "text" - }, - "refreshInterval": { - "properties": { - "display": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "pause": { - "doc_values": false, - "index": false, - "type": "boolean" - }, - "section": { - "doc_values": false, - "index": false, - "type": "integer" - }, - "value": { - "doc_values": false, - "index": false, - "type": "integer" - } - } - }, - "timeFrom": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "timeRestore": { - "doc_values": false, - "index": false, - "type": "boolean" - }, - "timeTo": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "endpoint:user-artifact": { - "properties": { - "body": { - "type": "binary" - }, - "compressionAlgorithm": { - "index": false, - "type": "keyword" - }, - "created": { - "index": false, - "type": "date" - }, - "decodedSha256": { - "index": false, - "type": "keyword" - }, - "decodedSize": { - "index": false, - "type": "long" - }, - "encodedSha256": { - "type": "keyword" - }, - "encodedSize": { - "index": false, - "type": "long" - }, - "encryptionAlgorithm": { - "index": false, - "type": "keyword" - }, - "identifier": { - "type": "keyword" - } - } - }, - "endpoint:user-artifact-manifest": { - "properties": { - "created": { - "index": false, - "type": "date" - }, - "ids": { - "index": false, - "type": "keyword" - }, - "schemaVersion": { - "type": "keyword" - }, - "semanticVersion": { - "index": false, - "type": "keyword" - } - } - }, - "enterprise_search_telemetry": { - "dynamic": "false", - "type": "object" - }, - "epm-packages": { - "properties": { - "es_index_patterns": { - "enabled": false, - "type": "object" - }, - "install_source": { - "type": "keyword" - }, - "install_started_at": { - "type": "date" - }, - "install_status": { - "type": "keyword" - }, - "install_version": { - "type": "keyword" - }, - "installed_es": { - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - }, - "type": "nested" - }, - "installed_kibana": { - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - }, - "type": "nested" - }, - "internal": { - "type": "boolean" - }, - "name": { - "type": "keyword" - }, - "removable": { - "type": "boolean" - }, - "version": { - "type": "keyword" - } - } - }, - "exception-list": { - "properties": { - "_tags": { - "type": "keyword" - }, - "comments": { - "properties": { - "comment": { - "type": "keyword" - }, - "created_at": { - "type": "keyword" - }, - "created_by": { - "type": "keyword" - }, - "id": { - "type": "keyword" - }, - "updated_at": { - "type": "keyword" - }, - "updated_by": { - "type": "keyword" - } - } - }, - "created_at": { - "type": "keyword" - }, - "created_by": { - "type": "keyword" - }, - "description": { - "type": "keyword" - }, - "entries": { - "properties": { - "entries": { - "properties": { - "field": { - "type": "keyword" - }, - "operator": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" - } - } - }, - "field": { - "type": "keyword" - }, - "list": { - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "operator": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" - } - } - }, - "immutable": { - "type": "boolean" - }, - "item_id": { - "type": "keyword" - }, - "list_id": { - "type": "keyword" - }, - "list_type": { - "type": "keyword" - }, - "meta": { - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "os_types": { - "type": "keyword" - }, - "tags": { - "type": "keyword" - }, - "tie_breaker_id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "updated_by": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - }, - "exception-list-agnostic": { - "properties": { - "_tags": { - "type": "keyword" - }, - "comments": { - "properties": { - "comment": { - "type": "keyword" - }, - "created_at": { - "type": "keyword" - }, - "created_by": { - "type": "keyword" - }, - "id": { - "type": "keyword" - }, - "updated_at": { - "type": "keyword" - }, - "updated_by": { - "type": "keyword" - } - } - }, - "created_at": { - "type": "keyword" - }, - "created_by": { - "type": "keyword" - }, - "description": { - "type": "keyword" - }, - "entries": { - "properties": { - "entries": { - "properties": { - "field": { - "type": "keyword" - }, - "operator": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" - } - } - }, - "field": { - "type": "keyword" - }, - "list": { - "properties": { - "id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "operator": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "value": { - "fields": { - "text": { - "type": "text" - } - }, - "type": "keyword" - } - } - }, - "immutable": { - "type": "boolean" - }, - "item_id": { - "type": "keyword" - }, - "list_id": { - "type": "keyword" - }, - "list_type": { - "type": "keyword" - }, - "meta": { - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "os_types": { - "type": "keyword" - }, - "tags": { - "type": "keyword" - }, - "tie_breaker_id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "updated_by": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - }, - "file-upload-telemetry": { - "properties": { - "filesUploadedTotalCount": { - "type": "long" - } - } - }, - "fleet-agent-actions": { - "properties": { - "ack_data": { - "type": "text" - }, - "agent_id": { - "type": "keyword" - }, - "created_at": { - "type": "date" - }, - "data": { - "type": "binary" - }, - "policy_id": { - "type": "keyword" - }, - "policy_revision": { - "type": "integer" - }, - "sent_at": { - "type": "date" - }, - "type": { - "type": "keyword" - } - } - }, - "fleet-agent-events": { - "properties": { - "action_id": { - "type": "keyword" - }, - "agent_id": { - "type": "keyword" - }, - "data": { - "type": "text" - }, - "message": { - "type": "text" - }, - "payload": { - "type": "text" - }, - "policy_id": { - "type": "keyword" - }, - "stream_id": { - "type": "keyword" - }, - "subtype": { - "type": "keyword" - }, - "timestamp": { - "type": "date" - }, - "type": { - "type": "keyword" - } - } - }, - "fleet-agents": { - "properties": { - "access_api_key_id": { - "type": "keyword" - }, - "active": { - "type": "boolean" - }, - "current_error_events": { - "index": false, - "type": "text" - }, - "default_api_key": { - "type": "binary" - }, - "default_api_key_id": { - "type": "keyword" - }, - "enrolled_at": { - "type": "date" - }, - "last_checkin": { - "type": "date" - }, - "last_checkin_status": { - "type": "keyword" - }, - "last_updated": { - "type": "date" - }, - "local_metadata": { - "type": "flattened" - }, - "packages": { - "type": "keyword" - }, - "policy_id": { - "type": "keyword" - }, - "policy_revision": { - "type": "integer" - }, - "shared_id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "unenrolled_at": { - "type": "date" - }, - "unenrollment_started_at": { - "type": "date" - }, - "updated_at": { - "type": "date" - }, - "upgrade_started_at": { - "type": "date" - }, - "upgraded_at": { - "type": "date" - }, - "user_provided_metadata": { - "type": "flattened" - }, - "version": { - "type": "keyword" - } - } - }, - "fleet-enrollment-api-keys": { - "properties": { - "active": { - "type": "boolean" - }, - "api_key": { - "type": "binary" - }, - "api_key_id": { - "type": "keyword" - }, - "created_at": { - "type": "date" - }, - "expire_at": { - "type": "date" - }, - "name": { - "type": "keyword" - }, - "policy_id": { - "type": "keyword" - }, - "type": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - } - } - }, - "graph-workspace": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "type": "text" - } - } - }, - "numLinks": { - "type": "integer" - }, - "numVertices": { - "type": "integer" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - }, - "wsState": { - "type": "text" - } - } - }, - "index-pattern": { - "dynamic": "false", - "properties": { - "title": { - "type": "text" - }, - "type": { - "type": "keyword" - } - } - }, - "infrastructure-ui-source": { - "dynamic": "false", - "type": "object" - }, - "ingest-agent-policies": { - "properties": { - "description": { - "type": "text" - }, - "is_default": { - "type": "boolean" - }, - "monitoring_enabled": { - "index": false, - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "namespace": { - "type": "keyword" - }, - "package_policies": { - "type": "keyword" - }, - "revision": { - "type": "integer" - }, - "status": { - "type": "keyword" - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "type": "keyword" - } - } - }, - "ingest-outputs": { - "properties": { - "ca_sha256": { - "index": false, - "type": "keyword" - }, - "config": { - "type": "flattened" - }, - "config_yaml": { - "type": "text" - }, - "fleet_enroll_password": { - "type": "binary" - }, - "fleet_enroll_username": { - "type": "binary" - }, - "hosts": { - "type": "keyword" - }, - "is_default": { - "type": "boolean" - }, - "name": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "ingest-package-policies": { - "properties": { - "created_at": { - "type": "date" - }, - "created_by": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "enabled": { - "type": "boolean" - }, - "inputs": { - "enabled": false, - "properties": { - "config": { - "type": "flattened" - }, - "enabled": { - "type": "boolean" - }, - "streams": { - "properties": { - "compiled_stream": { - "type": "flattened" - }, - "config": { - "type": "flattened" - }, - "data_stream": { - "properties": { - "dataset": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "enabled": { - "type": "boolean" - }, - "id": { - "type": "keyword" - }, - "vars": { - "type": "flattened" - } - }, - "type": "nested" - }, - "type": { - "type": "keyword" - }, - "vars": { - "type": "flattened" - } - }, - "type": "nested" - }, - "name": { - "type": "keyword" - }, - "namespace": { - "type": "keyword" - }, - "output_id": { - "type": "keyword" - }, - "package": { - "properties": { - "name": { - "type": "keyword" - }, - "title": { - "type": "keyword" - }, - "version": { - "type": "keyword" - } - } - }, - "policy_id": { - "type": "keyword" - }, - "revision": { - "type": "integer" - }, - "updated_at": { - "type": "date" - }, - "updated_by": { - "type": "keyword" - } - } - }, - "ingest_manager_settings": { - "properties": { - "agent_auto_upgrade": { - "type": "keyword" - }, - "has_seen_add_data_notice": { - "index": false, - "type": "boolean" - }, - "kibana_ca_sha256": { - "type": "keyword" - }, - "kibana_urls": { - "type": "keyword" - }, - "package_auto_upgrade": { - "type": "keyword" - } - } - }, - "inventory-view": { - "dynamic": "false", - "type": "object" - }, - "kql-telemetry": { - "properties": { - "optInCount": { - "type": "long" - }, - "optOutCount": { - "type": "long" - } - } - }, - "lens": { - "properties": { - "description": { - "type": "text" - }, - "expression": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "state": { - "type": "flattened" - }, - "title": { - "type": "text" - }, - "visualizationType": { - "type": "keyword" - } - } - }, - "lens-ui-telemetry": { - "properties": { - "count": { - "type": "integer" - }, - "date": { - "type": "date" - }, - "name": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - } - }, - "map": { - "properties": { - "description": { - "type": "text" - }, - "layerListJSON": { - "type": "text" - }, - "mapStateJSON": { - "type": "text" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "maps-telemetry": { - "enabled": false, - "type": "object" - }, - "metrics-explorer-view": { - "dynamic": "false", - "type": "object" - }, - "migrationVersion": { - "dynamic": "true", - "properties": { - "config": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "dashboard": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "index-pattern": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "lens": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "search": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "space": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "ml-job": { - "properties": { - "datafeed_id": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "job_id": { - "fields": { - "keyword": { - "type": "keyword" - } - }, - "type": "text" - }, - "type": { - "type": "keyword" - } - } - }, - "ml-telemetry": { - "properties": { - "file_data_visualizer": { - "properties": { - "index_creation_count": { - "type": "long" - } - } - } - } - }, - "monitoring-telemetry": { - "properties": { - "reportedClusterUuids": { - "type": "keyword" - } - } - }, - "namespace": { - "type": "keyword" - }, - "namespaces": { - "type": "keyword" - }, - "originId": { - "type": "keyword" - }, - "query": { - "properties": { - "description": { - "type": "text" - }, - "filters": { - "enabled": false, - "type": "object" - }, - "query": { - "properties": { - "language": { - "type": "keyword" - }, - "query": { - "index": false, - "type": "keyword" - } - } - }, - "timefilter": { - "enabled": false, - "type": "object" - }, - "title": { - "type": "text" - } - } - }, - "references": { - "properties": { - "id": { - "type": "keyword" - }, - "name": { - "type": "keyword" - }, - "type": { - "type": "keyword" - } - }, - "type": "nested" - }, - "sample-data-telemetry": { - "properties": { - "installCount": { - "type": "long" - }, - "unInstallCount": { - "type": "long" - } - } - }, - "search": { - "properties": { - "columns": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "description": { - "type": "text" - }, - "hits": { - "doc_values": false, - "index": false, - "type": "integer" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "index": false, - "type": "text" - } - } - }, - "sort": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "title": { - "type": "text" - }, - "version": { - "type": "integer" - } - } - }, - "search-telemetry": { - "dynamic": "false", - "type": "object" - }, - "siem-detection-engine-rule-actions": { - "properties": { - "actions": { - "properties": { - "action_type_id": { - "type": "keyword" - }, - "group": { - "type": "keyword" - }, - "id": { - "type": "keyword" - }, - "params": { - "enabled": false, - "type": "object" - } - } - }, - "alertThrottle": { - "type": "keyword" - }, - "ruleAlertId": { - "type": "keyword" - }, - "ruleThrottle": { - "type": "keyword" - } - } - }, - "siem-detection-engine-rule-status": { - "properties": { - "alertId": { - "type": "keyword" - }, - "bulkCreateTimeDurations": { - "type": "float" - }, - "gap": { - "type": "text" - }, - "lastFailureAt": { - "type": "date" - }, - "lastFailureMessage": { - "type": "text" - }, - "lastLookBackDate": { - "type": "date" - }, - "lastSuccessAt": { - "type": "date" - }, - "lastSuccessMessage": { - "type": "text" - }, - "searchAfterTimeDurations": { - "type": "float" - }, - "status": { - "type": "keyword" - }, - "statusDate": { - "type": "date" - } - } - }, - "siem-ui-timeline": { - "properties": { - "columns": { - "properties": { - "aggregatable": { - "type": "boolean" - }, - "category": { - "type": "keyword" - }, - "columnHeaderType": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "example": { - "type": "text" - }, - "id": { - "type": "keyword" - }, - "indexes": { - "type": "keyword" - }, - "name": { - "type": "text" - }, - "placeholder": { - "type": "text" - }, - "searchable": { - "type": "boolean" - }, - "type": { - "type": "keyword" - } - } - }, - "created": { - "type": "date" - }, - "createdBy": { - "type": "text" - }, - "dataProviders": { - "properties": { - "and": { - "properties": { - "enabled": { - "type": "boolean" - }, - "excluded": { - "type": "boolean" - }, - "id": { - "type": "keyword" - }, - "kqlQuery": { - "type": "text" - }, - "name": { - "type": "text" - }, - "queryMatch": { - "properties": { - "displayField": { - "type": "text" - }, - "displayValue": { - "type": "text" - }, - "field": { - "type": "text" - }, - "operator": { - "type": "text" - }, - "value": { - "type": "text" - } - } - }, - "type": { - "type": "text" - } - } - }, - "enabled": { - "type": "boolean" - }, - "excluded": { - "type": "boolean" - }, - "id": { - "type": "keyword" - }, - "kqlQuery": { - "type": "text" - }, - "name": { - "type": "text" - }, - "queryMatch": { - "properties": { - "displayField": { - "type": "text" - }, - "displayValue": { - "type": "text" - }, - "field": { - "type": "text" - }, - "operator": { - "type": "text" - }, - "value": { - "type": "text" - } - } - }, - "type": { - "type": "text" - } - } - }, - "dateRange": { - "properties": { - "end": { - "type": "date" - }, - "start": { - "type": "date" - } - } - }, - "description": { - "type": "text" - }, - "eventType": { - "type": "keyword" - }, - "excludedRowRendererIds": { - "type": "text" - }, - "favorite": { - "properties": { - "favoriteDate": { - "type": "date" - }, - "fullName": { - "type": "text" - }, - "keySearch": { - "type": "text" - }, - "userName": { - "type": "text" - } - } - }, - "filters": { - "properties": { - "exists": { - "type": "text" - }, - "match_all": { - "type": "text" - }, - "meta": { - "properties": { - "alias": { - "type": "text" - }, - "controlledBy": { - "type": "text" - }, - "disabled": { - "type": "boolean" - }, - "field": { - "type": "text" - }, - "formattedValue": { - "type": "text" - }, - "index": { - "type": "keyword" - }, - "key": { - "type": "keyword" - }, - "negate": { - "type": "boolean" - }, - "params": { - "type": "text" - }, - "type": { - "type": "keyword" - }, - "value": { - "type": "text" - } - } - }, - "missing": { - "type": "text" - }, - "query": { - "type": "text" - }, - "range": { - "type": "text" - }, - "script": { - "type": "text" - } - } - }, - "indexNames": { - "type": "text" - }, - "kqlMode": { - "type": "keyword" - }, - "kqlQuery": { - "properties": { - "filterQuery": { - "properties": { - "kuery": { - "properties": { - "expression": { - "type": "text" - }, - "kind": { - "type": "keyword" - } - } - }, - "serializedQuery": { - "type": "text" - } - } - } - } - }, - "savedQueryId": { - "type": "keyword" - }, - "sort": { - "properties": { - "columnId": { - "type": "keyword" - }, - "sortDirection": { - "type": "keyword" - } - } - }, - "status": { - "type": "keyword" - }, - "templateTimelineId": { - "type": "text" - }, - "templateTimelineVersion": { - "type": "integer" - }, - "timelineType": { - "type": "keyword" - }, - "title": { - "type": "text" - }, - "updated": { - "type": "date" - }, - "updatedBy": { - "type": "text" - } - } - }, - "siem-ui-timeline-note": { - "properties": { - "created": { - "type": "date" - }, - "createdBy": { - "type": "text" - }, - "eventId": { - "type": "keyword" - }, - "note": { - "type": "text" - }, - "timelineId": { - "type": "keyword" - }, - "updated": { - "type": "date" - }, - "updatedBy": { - "type": "text" - } - } - }, - "siem-ui-timeline-pinned-event": { - "properties": { - "created": { - "type": "date" - }, - "createdBy": { - "type": "text" - }, - "eventId": { - "type": "keyword" - }, - "timelineId": { - "type": "keyword" - }, - "updated": { - "type": "date" - }, - "updatedBy": { - "type": "text" - } - } - }, - "space": { - "properties": { - "_reserved": { - "type": "boolean" - }, - "color": { - "type": "keyword" - }, - "description": { - "type": "text" - }, - "disabledFeatures": { - "type": "keyword" - }, - "imageUrl": { - "index": false, - "type": "text" - }, - "initials": { - "type": "keyword" - }, - "name": { - "fields": { - "keyword": { - "ignore_above": 2048, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "tag": { - "properties": { - "color": { - "type": "text" - }, - "description": { - "type": "text" - }, - "name": { - "type": "text" - } - } - }, - "telemetry": { - "properties": { - "allowChangingOptInStatus": { - "type": "boolean" - }, - "enabled": { - "type": "boolean" - }, - "lastReported": { - "type": "date" - }, - "lastVersionChecked": { - "type": "keyword" - }, - "reportFailureCount": { - "type": "integer" - }, - "reportFailureVersion": { - "type": "keyword" - }, - "sendUsageFrom": { - "type": "keyword" - }, - "userHasSeenNotice": { - "type": "boolean" - } - } - }, - "tsvb-validation-telemetry": { - "properties": { - "failedRequests": { - "type": "long" - } - } - }, - "type": { - "type": "keyword" - }, - "ui-metric": { - "properties": { - "count": { - "type": "integer" - } - } - }, - "updated_at": { - "type": "date" - }, - "upgrade-assistant-reindex-operation": { - "properties": { - "errorMessage": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "indexName": { - "type": "keyword" - }, - "lastCompletedStep": { - "type": "long" - }, - "locked": { - "type": "date" - }, - "newIndexName": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "reindexOptions": { - "properties": { - "openAndClose": { - "type": "boolean" - }, - "queueSettings": { - "properties": { - "queuedAt": { - "type": "long" - }, - "startedAt": { - "type": "long" - } - } - } - } - }, - "reindexTaskId": { - "fields": { - "keyword": { - "ignore_above": 256, - "type": "keyword" - } - }, - "type": "text" - }, - "reindexTaskPercComplete": { - "type": "float" - }, - "runningReindexCount": { - "type": "integer" - }, - "status": { - "type": "integer" - } - } - }, - "upgrade-assistant-telemetry": { - "properties": { - "features": { - "properties": { - "deprecation_logging": { - "properties": { - "enabled": { - "null_value": true, - "type": "boolean" - } - } - } - } - }, - "ui_open": { - "properties": { - "cluster": { - "null_value": 0, - "type": "long" - }, - "indices": { - "null_value": 0, - "type": "long" - }, - "overview": { - "null_value": 0, - "type": "long" - } - } - }, - "ui_reindex": { - "properties": { - "close": { - "null_value": 0, - "type": "long" - }, - "open": { - "null_value": 0, - "type": "long" - }, - "start": { - "null_value": 0, - "type": "long" - }, - "stop": { - "null_value": 0, - "type": "long" - } - } - } - } - }, - "uptime-dynamic-settings": { - "dynamic": "false", - "type": "object" - }, - "url": { - "properties": { - "accessCount": { - "type": "long" - }, - "accessDate": { - "type": "date" - }, - "createDate": { - "type": "date" - }, - "url": { - "fields": { - "keyword": { - "ignore_above": 2048, - "type": "keyword" - } - }, - "type": "text" - } - } - }, - "visualization": { - "properties": { - "description": { - "type": "text" - }, - "kibanaSavedObjectMeta": { - "properties": { - "searchSourceJSON": { - "index": false, - "type": "text" - } - } - }, - "savedSearchRefName": { - "doc_values": false, - "index": false, - "type": "keyword" - }, - "title": { - "type": "text" - }, - "uiStateJSON": { - "index": false, - "type": "text" - }, - "version": { - "type": "integer" - }, - "visState": { - "index": false, - "type": "text" - } - } - }, - "workplace_search_telemetry": { - "dynamic": "false", - "type": "object" - } - } - }, - "settings": { - "index": { - "auto_expand_replicas": "0-1", - "number_of_replicas": "0", - "number_of_shards": "1" - } - } - } -} - -{ - "type": "index", - "value": { - "aliases": { - }, - "index": "foo", - "mappings": { - "properties": { - "field": { - "type": "long" - } - } - }, - "settings": { - "index": { - "number_of_replicas": "1", - "number_of_shards": "1" - } - } - } -} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/data.json.gz b/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/data.json.gz index 9f45c0303ff7a..e942ef732b22a 100644 Binary files a/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/data.json.gz and b/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/data.json.gz differ diff --git a/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/mappings.json b/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/mappings.json index da616b9d19f67..7561dbb8dc6d2 100644 --- a/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/mappings.json +++ b/x-pack/test/functional/es_archives/security_solution/timelines/7.15.0/mappings.json @@ -3,6 +3,8 @@ "value": { "aliases": { ".kibana": { + }, + ".kibana_7.15.0": { } }, "index": ".kibana_1", diff --git a/x-pack/test/functional/fixtures/kbn_archiver/packaging.json b/x-pack/test/functional/fixtures/kbn_archiver/packaging.json new file mode 100644 index 0000000000000..77f19d7fe7cbe --- /dev/null +++ b/x-pack/test/functional/fixtures/kbn_archiver/packaging.json @@ -0,0 +1,143 @@ +{ + "attributes": { + "fieldAttrs": "{}", + "fields": "[]", + "title": "foo" + }, + "coreMigrationVersion": "7.16.0", + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "migrationVersion": { + "index-pattern": "7.11.0" + }, + "references": [], + "type": "index-pattern", + "updated_at": "2020-11-23T19:56:26.810Z", + "version": "WzM4LDJd" +} + +{ + "attributes": { + "columns": [ + "_source" + ], + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "sort": [], + "title": "search", + "version": 1 + }, + "coreMigrationVersion": "7.16.0", + "id": "0c0b1700-2dc6-11eb-8af3-cb3aa84dbabd", + "migrationVersion": { + "search": "7.9.3" + }, + "references": [ + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "search", + "updated_at": "2020-11-23T19:56:59.376Z", + "version": "WzQ3LDJd" +} + +{ + "attributes": { + "description": "", + "state": { + "datasourceStates": { + "indexpattern": { + "layers": { + "c6af0915-fc1c-41b5-b195-7b05a51b0271": { + "columnOrder": [ + "0ee222c6-215d-4adc-aac0-b45469d5f9c1" + ], + "columns": { + "0ee222c6-215d-4adc-aac0-b45469d5f9c1": { + "dataType": "number", + "isBucketed": false, + "label": "Average of field", + "operationType": "average", + "scale": "ratio", + "sourceField": "field" + } + } + } + } + } + }, + "filters": [], + "query": { + "language": "kuery", + "query": "" + }, + "visualization": { + "accessor": "0ee222c6-215d-4adc-aac0-b45469d5f9c1", + "layerId": "c6af0915-fc1c-41b5-b195-7b05a51b0271", + "layerType": "data" + } + }, + "title": "visualization", + "visualizationType": "lnsMetric" + }, + "coreMigrationVersion": "7.16.0", + "id": "2be82220-2dc6-11eb-8af3-cb3aa84dbabd", + "migrationVersion": { + "lens": "7.15.0" + }, + "references": [ + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "indexpattern-datasource-current-indexpattern", + "type": "index-pattern" + }, + { + "id": "f8a1e9a0-2dc5-11eb-8af3-cb3aa84dbabd", + "name": "indexpattern-datasource-layer-c6af0915-fc1c-41b5-b195-7b05a51b0271", + "type": "index-pattern" + } + ], + "type": "lens", + "updated_at": "2020-11-23T19:57:52.834Z", + "version": "WzUyLDJd" +} + +{ + "attributes": { + "description": "", + "hits": 0, + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}" + }, + "optionsJSON": "{\"hidePanelTitles\":false,\"useMargins\":true}", + "panelsJSON": "[{\"version\":\"8.0.0\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"6ec4f48e-5704-47ef-8cde-9aa671a2c27a\"},\"panelIndex\":\"6ec4f48e-5704-47ef-8cde-9aa671a2c27a\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_0\"},{\"version\":\"8.0.0\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"a719fa94-58cc-4023-b95d-5aec25315045\"},\"panelIndex\":\"a719fa94-58cc-4023-b95d-5aec25315045\",\"embeddableConfig\":{\"enhancements\":{}},\"panelRefName\":\"panel_1\"}]", + "timeRestore": false, + "title": "dashboard", + "version": 1 + }, + "coreMigrationVersion": "7.16.0", + "id": "37b49c50-2dc6-11eb-8af3-cb3aa84dbabd", + "migrationVersion": { + "dashboard": "7.15.0" + }, + "references": [ + { + "id": "2be82220-2dc6-11eb-8af3-cb3aa84dbabd", + "name": "panel_0", + "type": "lens" + }, + { + "id": "0c0b1700-2dc6-11eb-8af3-cb3aa84dbabd", + "name": "panel_1", + "type": "search" + } + ], + "type": "dashboard", + "updated_at": "2020-11-23T19:58:12.629Z", + "version": "WzUzLDJd" +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index f895c607e572d..7b7c09fc72cab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2909,6 +2909,10 @@ version "0.0.0" uid "" +"@kbn/timelion-grammar@link:bazel-bin/packages/kbn-timelion-grammar": + version "0.0.0" + uid "" + "@kbn/tinymath@link:bazel-bin/packages/kbn-tinymath": version "0.0.0" uid "" @@ -23784,23 +23788,7 @@ redux-thunks@^1.0.0: resolved "https://registry.yarnpkg.com/redux-thunks/-/redux-thunks-1.0.0.tgz#56e03b86d281a2664c884ab05c543d9ab1673658" integrity sha1-VuA7htKBomZMiEqwXFQ9mrFnNlg= -redux@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.0.tgz#aa698a92b729315d22b34a0553d7e6533555cc03" - integrity sha512-NnnHF0h0WVE/hXyrB6OlX67LYRuaf/rJcbWvnHHEPCF/Xa/AZpwhs/20WyqzQae5x4SD2F9nPObgBh2rxAgLiA== - dependencies: - loose-envify "^1.1.0" - symbol-observable "^1.2.0" - -redux@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.4.tgz#4ee1aeb164b63d6a1bcc57ae4aa0b6e6fa7a3796" - integrity sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q== - dependencies: - loose-envify "^1.4.0" - symbol-observable "^1.2.0" - -redux@^4.0.5: +redux@^4.0.0, redux@^4.0.4, redux@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==